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