Lớp BufferQueue kết nối các thành phần tạo bộ đệm dữ liệu đồ họa ( nhà sản xuất ) với các thành phần chấp nhận dữ liệu để hiển thị hoặc xử lý thêm ( người tiêu dùng ). Gần như mọi thứ di chuyển vùng đệm dữ liệu đồ họa trong hệ thống đều dựa vào BufferQueue.
Bộ cấp phát bộ nhớ Gralloc thực hiện phân bổ bộ đệm và được triển khai thông qua hai giao diện HIDL dành riêng cho nhà cung cấp (xem hardware/interfaces/graphics/allocator/
và hardware/interfaces/graphics/mapper/
). Hàm allocate()
nhận các đối số dự kiến (chiều rộng, chiều cao, định dạng pixel) cũng như một tập hợp các cờ sử dụng.
Người sản xuất và người tiêu dùng BufferQueue
Người tiêu dùng tạo và sở hữu cấu trúc dữ liệu BufferQueue và có thể tồn tại trong các quy trình khác với quy trình sản xuất của họ. Khi nhà sản xuất cần bộ đệm, họ sẽ yêu cầu bộ đệm miễn phí từ BufferQueue bằng cách gọi dequeueBuffer()
, chỉ định chiều rộng, chiều cao, định dạng pixel và cờ sử dụng của bộ đệm. Sau đó, nhà sản xuất sẽ điền vào bộ đệm và trả bộ đệm về hàng đợi bằng cách gọi queueBuffer()
. Tiếp theo, người tiêu dùng lấy bộ đệm bằng acquireBuffer()
và sử dụng nội dung bộ đệm. Khi người tiêu dùng hoàn tất, nó sẽ trả bộ đệm về hàng đợi bằng cách gọi releaseBuffer()
. Khung đồng bộ hóa kiểm soát cách bộ đệm di chuyển qua đường dẫn đồ họa Android.
Một số đặc điểm của BufferQueue, chẳng hạn như số lượng bộ đệm tối đa mà nó có thể chứa, được xác định chung bởi nhà sản xuất và người tiêu dùng. Tuy nhiên, BufferQueue phân bổ bộ đệm khi cần. Bộ đệm được giữ lại trừ khi các đặc tính thay đổi; ví dụ: nếu nhà sản xuất yêu cầu bộ đệm có kích thước khác, bộ đệm cũ sẽ được giải phóng và bộ đệm mới sẽ được phân bổ theo yêu cầu.
Nội dung bộ đệm không bao giờ được BufferQueue sao chép vì việc di chuyển nhiều dữ liệu như vậy là không hiệu quả. Thay vào đó, bộ đệm luôn được chuyển qua một bộ điều khiển.
Theo dõi BufferQueue bằng Systrace
Để hiểu cách bộ đệm đồ họa di chuyển xung quanh, hãy sử dụng Systrace , một công cụ ghi lại hoạt động của thiết bị trong một khoảng thời gian ngắn. Mã đồ họa cấp hệ thống được trang bị tốt, cũng như phần lớn mã khung ứng dụng có liên quan.
Để sử dụng Systrace, hãy bật thẻ gfx
, view
và sched
. Các đối tượng BufferQueue được hiển thị trong dấu vết. Ví dụ: nếu bạn theo dõi trong khi video Grafika's Play (SurfaceView) đang chạy, hàng có nhãn SurfaceView sẽ cho bạn biết có bao nhiêu bộ đệm được xếp hàng đợi tại bất kỳ thời điểm nào.
Giá trị sẽ tăng lên khi ứng dụng đang hoạt động, điều này sẽ kích hoạt quá trình hiển thị khung bằng bộ giải mã MediaCodec. Giá trị giảm trong khi SurfaceFlinger đang hoạt động và sử dụng bộ đệm. Khi hiển thị video ở tốc độ 30 khung hình/giây, giá trị của hàng đợi thay đổi từ 0 đến 1 vì màn hình ~60 khung hình/giây có thể theo kịp nguồn. SurfaceFlinger chỉ thức dậy khi có việc phải làm chứ không phải 60 lần mỗi giây. Hệ thống cố gắng tránh hoạt động và tắt VSYNC nếu không có gì cập nhật màn hình.
Nếu bạn chuyển sang video Play của Grafika (TextureView) và lấy một dấu vết mới, bạn sẽ thấy một hàng có nhãn com.android.grafika
/ com.android.grafika.PlayMovieActivity
. Đây là lớp giao diện người dùng chính, là một BufferQueue khác. Vì TextView hiển thị trong lớp giao diện người dùng chứ không phải một lớp riêng biệt nên tất cả các cập nhật dựa trên video đều được hiển thị ở đây.
Gralloc
Bộ cấp phát Gralloc HAL hardware/libhardware/include/hardware/gralloc.h
thực hiện phân bổ bộ đệm thông qua các cờ sử dụng. Cờ sử dụng bao gồm các thuộc tính như:
- Tần suất bộ nhớ sẽ được truy cập từ phần mềm (CPU)
- Tần suất bộ nhớ sẽ được truy cập từ phần cứng (GPU)
- Liệu bộ nhớ có được sử dụng làm kết cấu OpenGL ES (GLES) hay không
- Liệu bộ nhớ có được bộ mã hóa video sử dụng hay không
Ví dụ: nếu định dạng bộ đệm của nhà sản xuất chỉ định RGBA_8888
pixel và nhà sản xuất chỉ ra rằng bộ đệm sẽ được truy cập từ phần mềm (nghĩa là ứng dụng sẽ chạm vào các pixel trên CPU), Gralloc sẽ tạo bộ đệm có 4 byte cho mỗi pixel theo thứ tự RGBA. Thay vào đó, nếu nhà sản xuất chỉ định bộ đệm của họ sẽ chỉ được truy cập từ phần cứng và dưới dạng kết cấu GLES, Gralloc có thể làm bất cứ điều gì mà trình điều khiển GLES muốn, chẳng hạn như thứ tự BGRA, bố cục lệch phi tuyến tính và các định dạng màu thay thế. Cho phép phần cứng sử dụng định dạng ưa thích có thể cải thiện hiệu suất.
Một số giá trị không thể được kết hợp trên một số nền tảng nhất định. Ví dụ: cờ bộ mã hóa video có thể yêu cầu pixel YUV, do đó việc thêm quyền truy cập phần mềm và chỉ định RGBA_8888
không thành công.
Handle do Gralloc trả về có thể được chuyển giữa các tiến trình thông qua Binder.
Bộ đệm được bảo vệ
Cờ sử dụng Gralloc GRALLOC_USAGE_PROTECTED
cho phép bộ đệm đồ họa chỉ được hiển thị thông qua đường dẫn được bảo vệ bằng phần cứng. Các mặt phẳng lớp phủ này là cách duy nhất để hiển thị nội dung DRM (SurfaceFlinger hoặc trình điều khiển OpenGL ES không thể truy cập bộ đệm được bảo vệ DRM).
Video được bảo vệ bằng DRM chỉ có thể được trình bày trên mặt phẳng lớp phủ. Trình phát video hỗ trợ nội dung được bảo vệ phải được triển khai bằng SurfaceView. Phần mềm chạy trên phần cứng không được bảo vệ không thể đọc hoặc ghi bộ đệm; đường dẫn được bảo vệ bằng phần cứng phải xuất hiện trên lớp phủ của Trình soạn thảo phần cứng (nghĩa là các video được bảo vệ sẽ biến mất khỏi màn hình nếu Trình soạn thảo phần cứng chuyển sang bố cục OpenGL ES).
Để biết chi tiết về nội dung được bảo vệ, hãy xem DRM .