Triển khai lớp trừu tượng phần cứng (HAL) cho trình soạn phần cứng

Các lớp tổng hợp HAL của Trình tổng hợp phần cứng (HWC) nhận được từ SurfaceFlinger, giúp giảm lượng thành phần OpenGL ES (GLES) và GPU thực hiện.

HWC tóm tắt các đối tượng, chẳng hạn như lớp phủ và bóng 2D thành thành phần tổng hợp bề mặt và giao tiếp bằng phần cứng bố cục cửa sổ chuyên dụng để cửa sổ tổng hợp. Sử dụng HWC cho các cửa sổ tổng hợp thay vì phải Kết hợp SurfaceFlinger với GPU. Hầu hết GPU không được tối ưu hoá cho cấu trúc và khi GPU tạo các lớp từ Với SurfaceFlinger, các ứng dụng không thể sử dụng GPU để kết xuất riêng.

Quá trình triển khai HWC cần hỗ trợ:

  • Ít nhất 4 lớp phủ:
    • Thanh trạng thái
    • Thanh hệ thống
    • Ứng dụng
    • Hình nền/nền
  • Các lớp lớn hơn màn hình (ví dụ: hình nền)
  • Phối alpha đồng thời nhân trước trên mỗi pixel và trên mỗi mặt phẳng trộn alpha
  • Đường dẫn phần cứng để phát video được bảo vệ
  • Thứ tự đóng gói RGBA, định dạng YUV và xếp kề, xoay tròn và sải chân các tài sản

Cách triển khai HWC:

  1. Triển khai HWC không hoạt động và gửi tất cả tác vụ sáng tác tới GLES.
  2. Triển khai một thuật toán để uỷ quyền thành phần kết hợp cho HWC theo cách tăng dần. Ví dụ: chỉ uỷ quyền 3 hoặc 4 nền tảng đầu tiên cho lớp phủ phần cứng của HWC.
  3. Tối ưu hoá HWC. Điều này có thể bao gồm:
    • Chọn các bề mặt có thể tăng tối đa tải trọng lượng giảm đi từ GPU và gửi chúng đến HWC.
    • Phát hiện xem màn hình có đang cập nhật hay không. Nếu không, hãy uỷ quyền thành GLES thay vì HWC để tiết kiệm điện. Khi màn hình các bản cập nhật mới, hãy tiếp tục giảm tải cấu trúc vào HWC.
    • Chuẩn bị cho các trường hợp sử dụng phổ biến như:
      • Màn hình chính, bao gồm thanh trạng thái, thanh hệ thống, ứng dụng cửa sổ và hình nền động
      • Trò chơi chạy ở chế độ toàn màn hình theo hướng dọc và ngang
      • Video toàn màn hình có phụ đề chi tiết và có thể phát âm lượng
      • Phát lại video được bảo vệ
      • Chế độ nhiều cửa sổ chia đôi màn hình

Dữ liệu gốc HWC

HWC cung cấp hai kiểu dữ liệu gốc là lớpmàn hình để thể hiện công việc kết hợp và hoạt động tương tác của nó với phần cứng hiển thị. BCH cũng cung cấp quyền kiểm soát đối với VSYNC và lệnh gọi lại đến SurfaceFlinger để thông báo cho SurfaceFlinger khi xảy ra sự kiện VSYNC.

Giao diện HIDL

Android 8.0 trở lên sử dụng Giao diện HIDL có tên là Composer HAL (Lớp trừu tượng phần cứng) cho IPC liên kết giữa HWC và SurfaceFlinger. HAL (Lớp trừu tượng phần cứng) cho Composer thay thế giao diện hwcomposer2.h cũ. Nếu nhà cung cấp cung cấp một phương thức triển khai Composer HAL của HWC, thì Composer HAL sẽ trực tiếp chấp nhận các lệnh gọi HIDL từ SurfaceFlinger. Nếu nhà cung cấp cung cấp phương thức triển khai cũ của HWC, Composer HAL sẽ tải con trỏ hàm từ hwcomposer2.h, chuyển tiếp các lệnh gọi HIDL vào lệnh gọi con trỏ hàm.

HWC cung cấp các hàm xác định thuộc tính của một màn hình nhất định; đến chuyển đổi giữa các cấu hình hiển thị (chẳng hạn như 4k hoặc 1080p) độ phân giải) và chế độ màu (chẳng hạn như màu gốc hoặc sRGB thực); và để biến màn hình bật, tắt hoặc chuyển sang chế độ tiết kiệm pin nếu được hỗ trợ.

Con trỏ hàm

Nếu nhà cung cấp trực tiếp triển khai HAL (Lớp trừu tượng phần cứng) cho Composer, SurfaceFlinger sẽ gọi các hàm tương ứng thông qua HIDL IPC. Ví dụ: để tạo một lớp, SurfaceFlinger gọi createLayer() trên Composer HAL.

Nếu nhà cung cấp triển khai giao diện hwcomposer2.h, HAL (Lớp trừu tượng phần cứng) cho trình soạn lệnh gọi vào con trỏ hàm hwcomposer2.h. Trong các nhận xét hwcomposer2.h, các hàm giao diện HWC được tham chiếu bằng tên lowerCamelCase không tồn tại trong giao diện dưới dạng các trường được đặt tên. Hầu hết mọi hàm đều được tải bằng cách yêu cầu con trỏ hàm bằng getFunction do hwc2_device_t cung cấp. Ví dụ: hàm createLayer là con trỏ hàm thuộc loại HWC2_PFN_CREATE_LAYER, được trả về khi giá trị được liệt kê HWC2_FUNCTION_CREATE_LAYER được được truyền vào getFunction.

Để biết tài liệu chi tiết về các hàm HAL của trình soạn thảo và truyền qua hàm HWC hãy xem composer. Để biết tài liệu chi tiết về con trỏ hàm HWC, hãy xem hwcomposer2.h.

Xử lý lớp và hiển thị

Các lớp và màn hình được thao tác bằng các tên người dùng do HWC tạo. Các ô điều khiển được làm mờ so với SurfaceFlinger.

Khi tạo một lớp mới, SurfaceFlinger sẽ gọi createLayer, trả về loại Layer cho trực tiếp hoặc hwc2_layer_t để triển khai thông qua. Thời gian SurfaceFlinger sửa đổi thuộc tính của lớp đó, SurfaceFlinger truyền giá trị hwc2_layer_t vào hàm sửa đổi thích hợp cùng với mọi thông tin cần thiết khác để thực hiện sửa đổi. Chiến lược phát hành đĩa đơn Loại hwc2_layer_t đủ lớn để chứa con trỏ hoặc chỉ mục.

Màn hình thực tế được tạo ra bằng cách được cắm nóng. Khi màn hình thực tế được nóng được gắn, HWC tạo một điều khiển và truyền xử lý đến SurfaceFlinger thông qua lệnh gọi lại hot Châu Âu. Màn hình ảo do SurfaceFlinger tạo ra đang gọi createVirtualDisplay() để yêu cầu một màn hình. Nếu HWC hỗ trợ cấu trúc hiển thị ảo, hàm này sẽ trả về một ô điều khiển. Sau đó, SurfaceFlinger sẽ uỷ quyền thành phần hiển thị cho HWC. Nếu HWC không hỗ trợ cấu trúc hiển thị, SurfaceFlinger sẽ tạo tay cầm và kết hợp màn hình.

Hiển thị thao tác kết hợp

Một lần mỗi VSYNC, SurfaceFlinger sẽ đánh thức nếu có nội dung mới tổng hợp. Nội dung mới này có thể là vùng đệm hình ảnh mới từ các ứng dụng hoặc thay đổi về thuộc tính của một hoặc nhiều lớp. Khi SurfaceFlinger đánh thức:

  1. Xử lý giao dịch, nếu có.
  2. Khoá các bộ đệm đồ hoạ mới nếu có.
  3. Thực hiện quá trình kết hợp mới, nếu bước 1 hoặc 2 dẫn đến sự thay đổi vào nội dung hiển thị.

Để thực hiện cấu trúc mới, SurfaceFlinger sẽ tạo và huỷ các lớp hoặc sửa đổi trạng thái của lớp, nếu có. Ứng dụng này cũng cập nhật với nội dung hiện tại của chúng, sử dụng các lệnh gọi như setLayerBuffer hoặc setLayerColor. Sau khi tất cả các lớp đã cập nhật, SurfaceFlinger sẽ gọi validateDisplay để cho biết HWC để kiểm tra trạng thái của các lớp và xác định cách thành phần tiếp tục. Theo mặc định, SurfaceFlinger cố gắng định cấu hình mọi lớp sao cho lớp được kết hợp bởi HWC; mặc dù trong một số trường hợp, SurfaceFlinger kết hợp các lớp thông qua phương thức dự phòng GPU.

Sau lệnh gọi đến validateDisplay, SurfaceFlinger sẽ gọi getChangedCompositionTypes để xem HWC muốn bất kỳ loại thành phần lớp nào thay đổi trước khi thực hiện cấu trúc. Để chấp nhận các thay đổi, SurfaceFlinger sẽ gọi acceptDisplayChanges.

Nếu có lớp nào được đánh dấu cho thành phần SurfaceFlinger, thì SurfaceFlinger sẽ kết hợp các lớp đó vào vùng đệm mục tiêu. Sau đó, SurfaceFlinger gọi setClientTarget để cung cấp vùng đệm cho màn hình để có thể hiển thị trên màn hình hoặc được kết hợp thêm với các lớp chưa được đánh dấu cho cấu trúc SurfaceFlinger. Nếu không lớp nào được đánh dấu Với quá trình kết hợp SurfaceFlinger, SurfaceFlinger bỏ qua bước cấu trúc.

Cuối cùng, SurfaceFlinger gọi presentDisplay để yêu cầu HWC hoàn tất quá trình kết hợp và hiển thị kết quả cuối cùng.

Nhiều màn hình

Android 10 hỗ trợ nhiều màn hình thực. Khi thiết kế cách triển khai HWC để sử dụng trên Android 7.0 và cao hơn, có một số hạn chế không có trong định nghĩa HWC:

  • Giả sử có đúng một màn hình nội bộ. Dữ liệu nội bộ là màn hình mà các báo cáo nóng ban đầu trong khởi động. Sau khi màn hình trong được cắm nóng, bạn không thể ngắt kết nối màn hình này.
  • Ngoài màn hình trong, bất kỳ số lượng màn hình ngoài nào cũng có thể được cắm nóng trong khi thiết bị hoạt động bình thường. Khung này giả định rằng tất cả phích cắm nóng sau màn hình nội bộ đầu tiên là màn hình bên ngoài, vì vậy, nếu có nếu thêm màn hình nội bộ, chúng sẽ bị phân loại không chính xác là Display.TYPE_HDMI thay vì Display.TYPE_BUILT_IN.

Trong khi thực hiện các thao tác SurfaceFlinger mô tả ở trên mỗi hiển thị, chúng được thực hiện tuần tự cho tất cả các màn hình đang hoạt động, ngay cả khi nội dung của chỉ một màn hình được cập nhật.

Ví dụ: nếu màn hình ngoài được cập nhật, trình tự sẽ là:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

Bố cục màn hình ảo

Cấu trúc màn hình ảo tương tự như cấu trúc màn hình bên ngoài. Sự khác biệt giữa thành phần hiển thị ảo và thành phần vật lý cấu trúc hiển thị là các màn hình ảo gửi đầu ra đến vùng đệm Gralloc thay vì vào màn hình. Hardware Composer (Trình tổng hợp phần cứng) (HWC) ghi đầu ra vào một vùng đệm, cung cấp hàng rào hoàn thành và gửi vùng đệm đến đối tượng tiêu dùng (chẳng hạn như bộ mã hoá video, GPU, CPU, v.v.). Màn hình ảo có thể dùng chế độ 2D/công cụ phát sáng hoặc nếu quy trình hiển thị ghi vào bộ nhớ.

Chế độ

Mỗi khung sẽ ở một trong ba chế độ sau khi SurfaceFlinger gọi phương thức Phương thức HWC validateDisplay():

  • GLES – GPU tổng hợp tất cả các lớp, ghi trực tiếp vào bộ đệm đầu ra. HWC không tham gia vào quá trình sáng tác.
  • MIXED – GPU kết hợp một số lớp với vùng đệm khung và HWC kết hợp vùng đệm khung và các lớp còn lại, ghi trực tiếp vào bộ đệm đầu ra.
  • HWC – HWC kết hợp tất cả các lớp và ghi trực tiếp vào vùng đệm đầu ra.

Định dạng đầu ra

Các định dạng đầu ra của vùng đệm hiển thị ảo phụ thuộc vào chế độ tương ứng:

  • Chế độ GLES – Trình điều khiển EGL thiết lập vùng đệm đầu ra ở dequeueBuffer(), thường là RGBA_8888. Người tiêu dùng phải chấp nhận định dạng đầu ra do trình điều khiển đặt hoặc bộ đệm không thể đọc được.
  • Chế độ MIXED và HWC – Nếu người tiêu dùng cần CPU quyền truy cập, người tiêu dùng đặt định dạng. Nếu không, định dạng sẽ là IMPLEMENTATION_DEFINED và Gralloc sẽ đặt định dạng tốt nhất dựa trên cờ sử dụng. Ví dụ: Gralloc đặt định dạng YCbCr nếu người tiêu dùng bộ mã hoá video và HWC có thể ghi định dạng hiệu quả.

Hàng rào đồng bộ hoá

Hàng rào đồng bộ hoá (sync) là một khía cạnh quan trọng của hệ thống đồ hoạ Android. Hàng rào cho phép CPU hoạt động độc lập với hoạt động đồng thời của GPU, chặn chỉ khi có phần phụ thuộc thực sự.

Ví dụ: khi một ứng dụng gửi một vùng đệm đang được tạo GPU cũng gửi một đối tượng hàng rào đồng bộ hoá. Hàng rào này báo hiệu thời điểm GPU hoàn tất quá trình ghi vào vùng đệm.

HWC yêu cầu GPU ghi xong vùng đệm trước khi vùng đệm được được hiển thị. Hàng rào đồng bộ hoá được truyền qua quy trình đồ hoạ bằng các vùng đệm và tín hiệu khi ghi vùng đệm. Trước khi hiển thị một vùng đệm, HWC kiểm tra xem hàng rào đồng bộ hoá đã được báo hiệu chưa và nếu có, hàng rào đồng bộ hoá sẽ hiển thị vùng đệm.

Để biết thêm thông tin về hàng rào đồng bộ hoá, hãy xem bài viết Trình soạn phần cứng Tích hợp.