Đồ hoạ

Biểu tượng Android Graphics HAL

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

canvas (thuật ngữ chung), Canvas (thành phần API)
Canvas là một nền tảng vẽ xử lý việc kết hợp các bit thực tế với bitmap hoặc đối tượng Surface. Canvas có các phương thức vẽ máy tính tiêu chuẩn của bitmap, đường kẻ, hình tròn, hình chữ nhật, văn bản, v.v. và được liên kết với 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.
có thể vẽ
Đối tượng có thể vẽ 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. Đối tượng có thể vẽ thường được tải vào một thành phần giao diện người dùng khác, chẳng hạn như hình nền. Đối tượng có thể vẽ không thể nhận sự kiện, nhưng sẽ gán nhiều thuộc tính khác như trạng thái và lịch biểu để bật các lớp con như đối tượng ảnh động 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 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ề đối tượng có thể vẽ và các tài nguyên khác, hãy xem phần Tài nguyên.
tài nguyên bố cục
Tài nguyên bố cục là 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 phần Tài nguyên bố cục.
nine-patch (9-patch, NinePatch)
9-patch là một tài nguyên bitmap có thể đổi kích thước, có thể dùng làm 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 9-patch.
OpenGL ES
OpenGL ES là một API đa 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 hình ảnh 3D tăng tốc phần cứng. Đối với chế độ 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 mã gốc của Android (NDK). Các gói android.opengljavax.microedition.khronos.opengles hiển thị chức năng OpenGL ES.
surface (thuật ngữ chung), Surface (thành phần API)
Mặt là một khối bộ nhớ được kết hợp với màn hình. Một nền tảng chứa một canvas để vẽ và cung cấp nhiều phương thức trợ giúp để vẽ các lớp cũng như đổi kích thước đối tượng Surface. Sử dụng lớp SurfaceView thay vì lớp Surface.
thành phần hiển thị trên nền tảng (thuật ngữ chung), SurfaceView (thành phần API)
Khung hiển thị bề mặt là một đối tượng View bao bọc đối tượng Surface để vẽ và hiển thị 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. Chế độ xem giao diện cung cấp một cách để vẽ độc lập với luồng giao diện người dùng cho các thao tác tốn nhiều tài nguyên, chẳng hạn như trò chơi hoặc bản xem trước của máy ảnh, nhưng do đó, chế độ xem này sẽ sử dụng thêm bộ nhớ. Chế độ xem bề mặt hỗ trợ cả canvas và đồ hoạ 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 đóng gói cùng 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à có tiền tố là Theme_.
thành phần hiển thị (thuật ngữ chung), View (thành phần API)
Thành phần 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 tương tác khác như lượt nhấp, thao tác nhấn phím. 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ổ. Đố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 thủ kích thước và vị trí đó. Để biết thêm thông tin, hãy xem View.
nhóm thành phần hiển thị (thuật ngữ chung), ViewGroup (thành phần API)
Nhóm thành phần hiển thị nhóm một tập hợp các thành phần hiển thị con. Nhóm thành phần hiển thị chịu trách nhiệm quyết định vị trí đặt thành phần hiển thị con và kích thước của các thành phần hiển thị con, cũng như gọi từng thành phần hiển thị con để tự vẽ 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 một số khác có giao diện người dùng nội tại, chẳng hạn như hộp danh sách cuộn. Các nhóm thành phần hiển thị nằm trong gói 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à 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ể xem hình ảnh trực quan của 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 SDK Android.
Vulkan
Vulkan là một API nhiều 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 một nhóm các lớp con thành phần 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 giao diện người dùng khác, chẳng hạn như hộp văn bản hoặc trình đơn bật lên. Vì được triển khai đầy đủ, tiện ích sẽ tự xử lý việc đo lường, vẽ và phản hồi các sự kiện trên màn hình. Tiện ích nằm trong gói android.widget.
cửa sổ (thuật ngữ chung), Window (thành phần API)
Trong ứ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 cách triển khai lớp Window để hiển thị đối tượng Window. Bạn không cần triển khai lớp Window hoặc sử dụng 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 bề mặt. Bề mặt đại diện cho phía nhà sản xuất của hàng đợi vùng đệm mà SurfaceFlinger thường 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 nền tảng. 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 kết xuất các nền tảng.

Các thành phần chính được mô tả dưới đây:

Trình tạo luồng hình ảnh

Trình tạo luồng hình ảnh có thể là bất kỳ đối tượng nào tạo 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

Người 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 nền tảng hiện đang hiển thị và kết hợp các nền tả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 tổng hợp phần cứng để tổng 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 máy ảnh sử dụng luồng hình ảnh xem trước của máy ảnh. Các ứng dụng không phải GL cũng có thể là người dùng, ví dụ: lớp ImageReader.

Trình soạn nhạc phần cứng

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

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

Gralloc

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

Luồng dữ liệu

Hãy xem sơ đồ sau đây để biết nội dung mô tả quy trình đồ hoạ 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 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à Hardware Composer là trình soạn nhạc.

BufferQueue

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

Hãy xem sơ đồ sau đây để biết 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 trình tạo luồng hình ảnh và trình tiêu thụ luồng hình ảnh với nhau. Một số ví dụ về trình tạo hình ảnh là bản xem trước của máy ảnh do HAL máy ảnh hoặc trò chơi OpenGL ES tạo ra. Một số ví dụ về trình 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 máy ảnh hiển thị kính ngắm máy ảnh.

BufferQueue là một cấu trúc dữ liệu kết hợp nhóm bộ đệm với hàng đợi và sử dụng Binder IPC để truyền bộ đệm giữa các quy trình. Giao diện nhà sản xuất hoặc nội dung 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 cho một Surface và tiêu thụ bằng một GL Consumer, cùng với các tác vụ khác.

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

Chế độ giống đồng bộ – Theo mặc định, BufferQueue hoạt động ở chế độ giống đồng bộ, trong đó mọi vùng đệm đến từ nhà sản xuất sẽ chuyển đến người tiêu dùng. Không có vùng đệm nào bị loại bỏ trong chế độ này. Và nếu trình tạo quá nhanh và tạo vùng đệm nhanh hơn tốc độ tiêu thụ, thì trình tạo sẽ chặn và chờ vùng đệm trống.

Chế độ không chặn – BufferQueue cũng có thể hoạt động ở chế độ không chặn, trong đó nó sẽ tạo lỗi thay vì chờ bộ đệm trong những trường hợp đó. Chế độ này cũng không loại bỏ bất kỳ vùng đệm nào. Điều này rất hữu ích để tránh các tắc nghẽn tiềm ẩn trong phần mềm ứng dụng có thể không hiểu được các phần phụ thuộc phức tạp của khung đồ hoạ.

Chế độ loại bỏ – Cuối cùng, bạn có thể định cấu hình BufferQueue để 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 chế độ xem kết cấu và vẽ nhanh nhất có thể, bạn phải thả vùng đệm.

Để 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í dụ: khi SurfaceFlinger đang chủ động kết hợp một hoặc hai vùng đệm vào vùng đệm thứ ba, thì SurfaceFlinger đang sử dụng OpenGL ES.

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