BufferQueue 和 Gralloc

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,請啟用gfxviewsched標籤。 BufferQueue 對象顯示在跟踪中。例如,如果您在Grafika 的播放視頻 (SurfaceView)運行時進行跟踪,標有SurfaceView的行會告訴您在任何給定時間排隊的緩衝區數量。

當應用程序處於活動狀態時,該值會增加,這會觸發 MediaCodec 解碼器渲染幀。當 SurfaceFlinger 工作和使用緩衝區時,該值會遞減。當以 30 fps 顯示視頻時,隊列的值從 0 到 1 不等,因為 ~60 fps 顯示可以跟上源。 SurfaceFlinger 僅在有工作要做時才喚醒,而不是每秒 60 次。如果沒有更新屏幕,系統會嘗試避免工作並禁用 VSYNC。

如果您切換到Grafika 的播放視頻 (TextureView)並獲取新的跟踪,您會看到標記為com.android.grafika / com.android.grafika.PlayMovieActivity的行。這是主要的 UI 層,它是另一個 BufferQueue。因為 TextureView 渲染到 UI 層而不是單獨的層,所以所有視頻驅動的更新都顯示在這裡。

格拉洛克

Gralloc 分配器 HAL hardware/libhardware/include/hardware/gralloc.h通過使用標誌執行緩衝區分配。使用標誌包括以下屬性:

  • 從軟件 (CPU) 訪問內存的頻率
  • 從硬件 (GPU) 訪問內存的頻率
  • 內存是否將用作 OpenGL ES (GLES) 紋理
  • 內存是否將被視頻編碼器使用

例如,如果生產者的緩衝區格式指定RGBA_8888像素,並且生產者指示將從軟件訪問緩衝區(意味著應用程序將觸摸 CPU 上的像素),則 Gralloc 會創建一個緩衝區,每個像素按 RGBA 順序排列 4 個字節。如果相反,生產者指定其緩衝區將僅從硬件訪問,並且作為 GLES 紋理,Gralloc 可以執行 GLES 驅動程序想要的任何操作,例如 BGRA 排序、非線性混合佈局和替代顏色格式。允許硬件使用其首選格式可以提高性能。

某些值無法在某些平台上組合。例如,視頻編碼器標誌可能需要 YUV 像素,因此添加軟件訪問和指定RGBA_8888會失敗。

Gralloc 返回的句柄可以通過 Binder 在進程之間傳遞。

受保護的緩衝區

Gralloc 使用標誌GRALLOC_USAGE_PROTECTED允許圖形緩衝區僅通過受硬件保護的路徑顯示。這些覆蓋平面是顯示 DRM 內容的唯一方式(SurfaceFlinger 或 OpenGL ES 驅動程序無法訪問受 DRM 保護的緩衝區)。

受 DRM 保護的視頻只能在覆蓋平面上呈現。支持受保護內容的視頻播放器必須使用 SurfaceView 實現。在未受保護的硬件上運行的軟件無法讀取或寫入緩衝區;受硬件保護的路徑必須出現在 Hardware Composer 疊加層上(即,如果 Hardware Composer 切換到 O​​penGL ES 合成,受保護的視頻將從顯示屏上消失)。

有關受保護內容的詳細信息,請參閱DRM