Đồ hoạ

Biểu tượng HAL đồ hoạ Android

Khung Android cung cấp nhiều API kết xuất đồ hoạ cho 2D và 3D tương tác với các cách triển khai trình điều khiển đồ hoạ của nhà sản xuất. Vì vậy, bạn cần hiểu rõ cách các API đó hoạt động ở cấp độ cao hơn. Trang này giới thiệu lớp trừu tượng phần cứng (HAL) đồ hoạ mà các trình điều khiển đó được xây dựng dựa trên. Trước khi tiếp tục với phần này, hãy tìm hiểu các thuật ngữ sau:

canvas (thuật ngữ chung), Canvas (phần tử API)
Canvas là một bề mặt vẽ xử lý việc kết hợp các bit thực với một bitmap hoặc đối tượng Surface. Lớp Canvas có các phương thức để vẽ bitmap, đường kẻ, hình tròn, hình chữ nhật, văn bản, v.v. trên máy tính tiêu chuẩn và được liên kết với một bitmap hoặc bề mặt. Canvas là cách đơn giản và dễ dàng nhất để vẽ các đối tượng 2D trên màn hình. Lớp cơ sở là Canvas.
drawable
Drawable là một tài nguyên hình ảnh đã được biên dịch, có thể dùng làm nền, tiêu đề hoặc phần khác của màn hình. Thông thường, một đối tượng có thể vẽ sẽ được tải vào một phần tử khác trên giao diện người dùng, chẳng hạn như làm hình nền. Một đối tượng có thể vẽ không thể nhận các sự kiện, nhưng sẽ chỉ định nhiều thuộc tính khác như trạng thái và lịch biểu để cho phép các lớp con như đối tượng hoạt ảnh hoặc thư viện hình ảnh. Nhiều đối tượng có thể vẽ được tải từ các tệp tài nguyên có thể vẽ – tệp XML hoặc tệp bitmap mô tả hình ảnh. Tài nguyên có thể vẽ được biên dịch thành các lớp con của android.graphics.drawable. Để biết thêm thông tin về các thành phần có thể vẽ và các tài nguyên khác, hãy xem phần Tổng quan về tài nguyên ứng dụng.
tài nguyên bố cục
Tài nguyên bố cục là một tệp XML mô tả bố cục của màn hình hoạt động. Để biết thêm thông tin, hãy xem bài viết Tài nguyên bố cục.
9-patch (9-patch, NinePatch)
Nine-patch là một tài nguyên bitmap có thể thay đổi kích thước và có thể dùng cho nền hoặc các hình ảnh khác trên thiết bị. Để biết thêm thông tin, hãy xem phần Nine-patch.
OpenGL ES
OpenGL ES là một API nhiều nền tảng để kết xuất đồ hoạ 2D và 3D. Android cung cấp các thư viện OpenGL ES để kết xuất 3D tăng tốc phần cứng. Đối với hoạt động kết xuất 2D, canvas là lựa chọn đơn giản hơn. OpenGL ES có trong Bộ công cụ phát triển gốc của Android (NDK). Các gói android.opengljavax.microedition.khronos.opengles hiển thị chức năng OpenGL ES.
nền tảng (thuật ngữ chung), Surface (phần tử API)
Một giao diện đại diện cho một khối bộ nhớ được kết hợp với màn hình. Một vùng chứa canvas để vẽ và cung cấp nhiều phương thức trợ giúp để vẽ các lớp và đổi kích thước đối tượng Surface. Hãy sử dụng lớp SurfaceView thay vì sử dụng trực tiếp lớp Surface.
surface view (thuật ngữ chung), SurfaceView (phần tử API)
SurfaceView là một đối tượng View bao bọc một đối tượng Surface để vẽ và cung cấp các phương thức để chỉ định kích thước và định dạng của đối tượng đó một cách linh động. Một khung hiển thị cung cấp cách vẽ độc lập với luồng giao diện người dùng cho các hoạt động sử dụng nhiều tài nguyên, chẳng hạn như trò chơi hoặc bản xem trước camera, nhưng do đó, khung hiển thị này sẽ sử dụng thêm bộ nhớ. Một khung hiển thị bề mặt hỗ trợ cả đồ hoạ canvas và OpenGL ES. Lớp cơ sở cho đối tượng SurfaceViewSurfaceView.
chủ đề
Giao diện là một tập hợp các thuộc tính, chẳng hạn như kích thước văn bản và màu nền, được kết hợp với nhau để xác định nhiều chế độ cài đặt hiển thị mặc định. Android cung cấp một số giao diện chuẩn, được liệt kê trong R.style và bắt đầu bằng Theme_.
khung hiển thị (thuật ngữ chung), View (phần tử API)
Khung hiển thị vẽ một vùng hình chữ nhật trên màn hình và xử lý các sự kiện nhấp, nhấn phím và các sự kiện tương tác khác. Lớp View là lớp cơ sở cho hầu hết các thành phần bố cục của một hoạt động hoặc màn hình hộp thoại, chẳng hạn như hộp văn bản và cửa sổ. Một đối tượng View nhận các lệnh gọi từ đối tượng mẹ (xem ViewGroup) để tự vẽ và thông báo cho đối tượng mẹ về kích thước và vị trí ưu tiên của đối tượng. Đối tượng mẹ có thể không tuân theo kích thước và vị trí này. Để biết thêm thông tin, hãy xem View.
nhóm khung hiển thị (thuật ngữ chung), ViewGroup (phần tử API)
Một nhóm khung hiển thị sẽ nhóm một tập hợp các khung hiển thị con. Nhóm thành phần hiển thị chịu trách nhiệm quyết định vị trí của các thành phần hiển thị con và kích thước của chúng, cũng như gọi từng thành phần để vẽ chính chúng khi thích hợp. Một số nhóm thành phần hiển thị không hiển thị và chỉ dành cho bố cục, trong khi các nhóm khác có giao diện người dùng vốn có, chẳng hạn như hộp danh sách có thể cuộn. Các nhóm khung hiển thị nằm trong gói android.widget nhưng mở rộng lớp ViewGroup.
hệ phân cấp khung hiển thị
Hệ phân cấp khung hiển thị là một cách sắp xếp các đối tượng khung hiển thị và nhóm khung hiển thị, xác định giao diện người dùng cho từng thành phần của ứng dụng. Hệ phân cấp này bao gồm các nhóm khung hiển thị chứa một hoặc nhiều khung hiển thị con hoặc nhóm khung hiển thị. Bạn có thể nhận được một bản trình bày trực quan về hệ phân cấp khung hiển thị để gỡ lỗi và tối ưu hoá bằng cách sử dụng Trình xem hệ phân cấp đi kèm với Android SDK.
Vulkan
Vulkan là một API đa nền tảng có mức hao tổn thấp dành cho đồ hoạ 3D hiệu suất cao.
tiện ích
Tiện ích là một trong số các lớp con hiển thị được triển khai đầy đủ, hiển thị các phần tử biểu mẫu và các thành phần khác trên giao diện người dùng, chẳng hạn như hộp văn bản hoặc trình đơn bật lên. Vì một tiện ích được triển khai đầy đủ, nên tiện ích này sẽ xử lý việc đo lường, tự vẽ và phản hồi các sự kiện trên màn hình. Các tiện ích nằm trong gói android.widget.
window (thuật ngữ chung), Window (phần tử API)
Trong một ứng dụng Android, cửa sổ là một đối tượng bắt nguồn từ lớp trừu tượng Window. Lớp này chỉ định các phần tử của một cửa sổ chung, chẳng hạn như giao diện, văn bản trên thanh tiêu đề, vị trí và nội dung của trình đơn. Hộp thoại và hoạt động sử dụng một cách triển khai lớp Window để kết xuất một đối tượng Window. Bạn không cần triển khai lớp Window hoặc sử dụng các cửa sổ trong ứng dụng.

Nhà phát triển ứng dụng vẽ hình ảnh lên màn hình theo 3 cách: bằng Canvas, OpenGL ES hoặc Vulkan.

Thành phần đồ hoạ Android

Bất kể nhà phát triển sử dụng API kết xuất nào, mọi thứ đều được kết xuất lên một nền tảng. Surface đại diện cho phía nhà sản xuất của hàng đợi vùng đệm thường được SurfaceFlinger sử dụng. Mọi cửa sổ được tạo trên nền tảng Android đều được hỗ trợ bởi một thành phần. Tất cả các bề mặt hiển thị được kết xuất đều được SurfaceFlinger kết hợp trên màn hình.

Sơ đồ sau đây cho thấy cách các thành phần chính hoạt động cùng nhau:

thành phần kết xuất hình ảnh

Hình 1. Cách hiển thị các nền tảng.

Các thành phần chính được mô tả trong các phần sau.

Nhà sản xuất luồng hình ảnh

Trình tạo luồng hình ảnh có thể là bất cứ thứ gì tạo ra các vùng đệm đồ hoạ để sử dụng. Ví dụ: OpenGL ES, Canvas 2D và bộ giải mã video mediaserver.

Người dùng luồng hình ảnh

Đối tượng sử dụng phổ biến nhất của luồng hình ảnh là SurfaceFlinger, dịch vụ hệ thống sử dụng các bề mặt hiện đang hiển thị và kết hợp chúng trên màn hình bằng thông tin do Trình quản lý cửa sổ cung cấp. SurfaceFlinger là dịch vụ duy nhất có thể sửa đổi nội dung của màn hình. SurfaceFlinger sử dụng OpenGL và Trình kết hợp phần cứng (HWC) để kết hợp một nhóm nền tảng.

Các ứng dụng OpenGL ES khác cũng có thể sử dụng luồng hình ảnh, chẳng hạn như ứng dụng camera sử dụng luồng hình ảnh xem trước của camera. Các ứng dụng không phải GL cũng có thể là người dùng, chẳng hạn như lớp ImageReader.

Hardware Composer

Lớp trừu tượng phần cứng cho hệ thống con hiển thị. SurfaceFlinger có thể uỷ quyền một số công việc kết hợp nhất định cho HWC để giảm tải công việc từ OpenGL và GPU. SurfaceFlinger hoạt động như một ứng dụng OpenGL ES khác. Vì vậy, khi SurfaceFlinger đang tích cực kết hợp một hoặc hai vùng đệm thành vùng đệm thứ ba, chẳng hạn như khi dùng OpenGL ES. Điều này giúp việc kết hợp tiêu thụ ít điện năng hơn so với việc để GPU thực hiện mọi hoạt động tính toán.

HAL Trình kết hợp phần cứng thực hiện nửa còn lại của công việc và là điểm trung tâm cho mọi hoạt động kết xuất đồ hoạ trên Android. HWC phải hỗ trợ các sự kiện, một trong số đó là VSync (một sự kiện khác là hotplug để hỗ trợ HDMI cắm và chạy).

Gralloc

Bạn cần trình phân bổ bộ nhớ đồ hoạ (Gralloc) để phân bổ bộ nhớ do nhà sản xuất hình ảnh yêu cầu. Để biết thông tin chi tiết, hãy xem phần BufferQueue và Gralloc.

Luồng dữ liệu

Sơ đồ sau đây mô tả quy trình đồ hoạ của Android:

luồng dữ liệu đồ hoạ

Hình 2. Luồng dữ liệu đồ hoạ thông qua Android.

Các đối tượng ở bên trái là trình kết xuất tạo ra các vùng đệm đồ hoạ, chẳng hạn như màn hình chính, thanh trạng thái và giao diện người dùng hệ thống. SurfaceFlinger là trình kết hợp và HWC là trình kết hợp.

BufferQueue

BufferQueue cung cấp mối liên kết giữa các thành phần đồ hoạ trong Android. Đây là một cặp hàng đợi giúp điều chỉnh chu kỳ hằng số của các vùng đệm từ nhà sản xuất đến người tiêu dùng. Sau khi các nhà sản xuất chuyển vùng đệm, SurfaceFlinger chịu trách nhiệm tổng hợp mọi thứ lên màn hình.

Sơ đồ sau đây minh hoạ quy trình giao tiếp BufferQueue:

Quy trình giao tiếp BufferQueue

Hình 3. Quy trình giao tiếp BufferQueue.

BufferQueue chứa logic liên kết các ứng dụng tạo luồng hình ảnh và ứng dụng sử dụng luồng hình ảnh với nhau. Một số ví dụ về nhà sản xuất hình ảnh là bản xem trước của camera do HAL camera hoặc trò chơi OpenGL ES tạo ra. Một số ví dụ về các đối tượng sử dụng hình ảnh là SurfaceFlinger hoặc một ứng dụng khác hiển thị luồng OpenGL ES, chẳng hạn như ứng dụng camera hiển thị kính ngắm camera.

BufferQueue là một cấu trúc dữ liệu kết hợp một nhóm vùng đệm với một hàng đợi và sử dụng giao tiếp giữa các quy trình (IPC) của Binder để truyền các vùng đệm giữa các quy trình. Giao diện nhà sản xuất hoặc những gì bạn truyền cho người muốn tạo vùng đệm đồ hoạ là IGraphicBufferProducer (một phần của SurfaceTexture). BufferQueue thường được dùng để kết xuất vào một Surface và sử dụng với GL Consumer, cùng với các tác vụ khác.

BufferQueue có thể hoạt động ở 3 chế độ:

chế độ tương tự như đồng bộ
Theo mặc định, BufferQueue hoạt động ở chế độ tương tự như chế độ đồng bộ, trong đó mọi vùng đệm đến từ nhà sản xuất đều được gửi đi ở phía người dùng. Không có vùng đệm nào bị loại bỏ trong chế độ này. Và nếu nhà sản xuất quá nhanh và tạo ra các vùng đệm nhanh hơn tốc độ tiêu thụ, thì nhà sản xuất sẽ chặn và chờ các vùng đệm trống.
chế độ không chặn
BufferQueue cũng có thể hoạt động ở chế độ không chặn, trong đó chế độ này sẽ tạo ra lỗi thay vì chờ bộ đệm trong những trường hợp đó. Trong chế độ này, không có vùng đệm nào bị loại bỏ. Điều này hữu ích để tránh các tình trạng bế tắc tiềm ẩn trong phần mềm ứng dụng có thể không hiểu các phần phụ thuộc phức tạp của khung đồ hoạ.
chế độ loại bỏ
BufferQueue có thể được định cấu hình để loại bỏ các vùng đệm cũ thay vì tạo lỗi hoặc chờ. Ví dụ: nếu thực hiện kết xuất GL vào một khung hiển thị kết cấu và vẽ nhanh nhất có thể, thì các vùng đệm phải được thả.

Để thực hiện hầu hết công việc này, SurfaceFlinger chỉ đóng vai trò là một ứng dụng OpenGL ES khác. Vì vậy, khi SurfaceFlinger đang tích cực kết hợp một hoặc hai vùng đệm thành vùng đệm thứ ba, chẳng hạn như khi đang sử dụng OpenGL ES.

HAL Trình kết hợp phần cứng thực hiện nửa còn lại của công việc. HAL này đóng vai trò là điểm trung tâm cho mọi hoạt động kết xuất đồ hoạ trên Android.