BufferQueue 類別會將產生圖形資料緩衝區的元件 (生產者) 連結至接受資料以供顯示或進一步處理的元件 (消費者)。幾乎所有透過系統移動圖形資料緩衝區的作業都會使用 BufferQueue。
Gralloc 記憶體配置器會執行緩衝區配置作業,並透過兩個供應商專屬的 HIDL 介面 (請參閱 hardware/interfaces/graphics/allocator/
和 hardware/interfaces/graphics/mapper/
) 實作。allocate()
函式會接受預期的引數 (寬度、高度、像素格式),以及一組用途標記。
BufferQueue 生產者和消費者
消費者會建立並擁有 BufferQueue 資料結構,且可與生產者位於不同的程序中。當產生器需要緩衝區時,會呼叫 dequeueBuffer()
向 BufferQueue 要求空閒緩衝區,並指定緩衝區的寬度、高度、像素格式和用法旗標。接著,生產者會填入緩衝區,並透過呼叫 queueBuffer()
將緩衝區傳回佇列。接著,取用端會使用 acquireBuffer()
取得緩衝區,並使用緩衝區內容。消費者完成後,會呼叫 releaseBuffer()
將緩衝區傳回至佇列。同步處理架構會控制緩衝區如何在 Android 圖形處理管道中移動。
BufferQueue 的部分特性 (例如可容納的緩衝區數量上限) 是由生產者和消費者共同決定。不過,BufferQueue 會視需要分配緩衝區。除非特性發生變更,否則緩衝區會保留在系統中;舉例來說,如果產生器要求不同大小的緩衝區,舊緩衝區會釋放,並視需要分配新的緩衝區。
BufferQueue 一律不會複製緩衝區內容,因為移動這麼多資料效率不彰。而是一律透過句柄傳遞緩衝區。
使用 Systrace 追蹤 BufferQueue
如要瞭解圖形緩衝區的移動方式,請使用 Systrace,這是用於記錄短時間內裝置活動的工具。系統層級的圖形程式碼和大部分的相關應用程式架構程式碼都已做好檢測。
如要使用 Systrace,請啟用 gfx
、view
和 sched
標記。追蹤記錄中會顯示 BufferQueue 物件。舉例來說,如果您在 Grafika 的 Play 影片 (SurfaceView) 執行期間進行追蹤,標示為 SurfaceView 的資料列會顯示在任何特定時間有多少緩衝區排入佇列。
在應用程式處於運作狀態時,這個值會遞增,進而觸發 MediaCodec 解碼器的轉譯作業。當 SurfaceFlinger 運作並使用緩衝區時,這個值會遞減。以 30 fps 顯示影片時,佇列的值會從 0 變為 1,因為約 60 fps 的顯示畫面可以跟上來源。SurfaceFlinger 只會在有工作要執行時喚醒,不會每秒喚醒 60 次。如果沒有任何內容更新螢幕,系統會嘗試避免工作並停用 VSYNC。
如果切換至 Grafika 的 Play 影片 (TextureView),並擷取新的追蹤記錄,您會看到標示為 com.android.grafika
 / com.android.grafika.PlayMovieActivity
的一列。這是主要的 UI 層,也是另一個 BufferQueue。由於 TextureView 會轉譯至 UI 圖層,而非獨立圖層,因此所有由影片驅動的更新都會顯示在此處。
Gralloc
Gralloc 配置器 HAL hardware/libhardware/include/hardware/gralloc.h
會透過用法旗標執行緩衝區配置作業。使用量旗標包括以下屬性:
- 軟體 (CPU) 存取記憶體的頻率
- 硬體 (GPU) 存取記憶體的頻率
- 記憶體是否會用於 OpenGL ES (GLES) 紋理
- 記憶體是否會由影片編碼器使用
舉例來說,如果產生器的緩衝區格式指定 RGBA_8888
像素,且產生器指出會從軟體存取緩衝區 (意即應用程式會觸碰 CPU 上的像素),Gralloc 會以 R-G-B-A 順序建立每個像素 4 個位元組的緩衝區。相反地,如果製作者指定其緩衝區只會透過硬體存取,並以 GLES 紋理形式存取,Gralloc 就能執行 GLES 驅動程式所需的任何操作,例如 BGRA 排序、非線性調色設定的版面配置,以及其他色彩格式。允許硬體使用其偏好的格式,有助於提升效能。
部分值無法在特定平台上合併。舉例來說,影片編碼器旗標可能需要 YUV 像素,因此新增軟體存取權並指定 RGBA_8888
會失敗。
Gralloc 傳回的句柄可透過 Binder 在程序之間傳遞。
受保護的緩衝區
Gralloc 用法旗標 GRALLOC_USAGE_PROTECTED
可讓圖形緩衝區僅透過硬體保護路徑顯示。這些疊加平面是顯示 DRM 內容的唯一方式 (SurfaceFlinger 或 OpenGL ES 驅動程式無法存取受 DRM 保護的緩衝區)。
受 DRM 保護的影片只能在重疊平面上顯示。支援受保護內容的影片播放器必須使用 SurfaceView 實作。在未受保護的硬體上執行的軟體無法讀取或寫入緩衝區;硬體保護路徑必須顯示在硬體合成疊加層上 (也就是說,如果硬體合成器切換為 OpenGL ES 合成,受保護的影片就會從螢幕上消失)。
如要進一步瞭解受保護的內容,請參閱「DRM」。