在圖形堆疊中,位於 Composer HAL 和 SurfaceFlinger 之間的個別緩衝區快取位置,可降低透過處理序間通訊 (IPC) 傳送檔案描述元所產生的負擔。在 Android 14 之前,當 GraphicBufferProducer
與 SurfaceFlinger GraphicBufferConsumer
中斷連線時,這個緩衝區快取不會清除,例如當 MediaCodec 與 SurfaceView 中斷連線時。從 Android 14 開始,您可以強制清除這個緩衝區快取,以減少圖形記憶體消耗量。
選擇下列任一選項:
- 對於搭載 Android 14 以上版本的裝置,您必須實作新的 Composer HAL API 3.2 版。這個選項預設為啟用,可儲存最多記憶體。升級至 14 以上版本的裝置也可以使用這個選項,充分發揮記憶體效益。
- 不想在升級至 Android 14 且不想實作 Composer HAL 3.2 API 的裝置上,可以啟用回溯相容的選項。這個選項可節省的記憶體數量和前一個選項差不多。
以下兩個章節將說明如何實作每個選項。
實作 Composer HAL 3.2 API
如要充分發揮圖形緩衝區記憶體的效益,您必須:
- 將 Composer HAL 實作項目更新至 3.2 版。
- 處理
LayerCommand::bufferSlotsToClear
,藉由清除清單中所列的緩衝區快取項目。
與圖形緩衝區記憶體相關的 Composer HAL 3.2 API (包括 LayerCommand:bufferSlotsToClear
) 位於 LayerCommand.aidl-
中。
啟用回溯相容的選項
向後相容的記憶體減少選項會將快取插槽中的實際緩衝區替換為 1x1 預留位置緩衝區,進而節省所有清除插槽的記憶體,但目前的有效緩衝區插槽除外。如要節省部分記憶體,請將 surface_flinger.clear_slots_with_set_layer_buffer
sysprop 設為 true
,啟用回溯相容選項。這個 sysprop 位於 property_contexts
檔案中。
設定這個 sysprop 後,您必須使用 Composer HAL 實作,在單一當前週期中正確處理同一層的多個 setLayerBuffer
指令。
啟用回溯相容選項會產生以下影響:
AIDL HAL:SurfaceFlinger 會針對單一圖層傳送多個
LayerCommand
執行個體,每個例項各有一個BufferCommand
。每個BufferCommand
都包含 1x1 預留位置緩衝區句柄,以及需要清除的快取緩衝區的插槽編號。針對 HIDL HAL:SurfaceFlinger 會傳送多個
SELECT_DISPLAY
、SELECT_LAYER
、SET_BUFFER
指令。這些指令包含 1x1 預留位置緩衝區句柄,以及需要清除的快取緩衝區的插槽編號。
回溯相容選項可能會導致 Composer HAL 在某些裝置上異常終止。您或許可以修改 Composer HAL 來解決這個問題。以下程式碼提供控制這項行為的程式碼:
測試圖形緩衝區快取記憶體用量
測試無法驗證快取插槽是否已由 HAL 實作項目清除。不過,您可以使用偵錯工具監控圖形緩衝區的使用情形。在監控期間,您應該會發現,在 YouTube 上快速停止及啟動多部不同影片的情況下,記憶體不足錯誤會減少。
您可以使用 VTS 測試,驗證 HAL 實作功能是否能夠接收新的 API 呼叫 (HAL 3.2 以上版本),或為向後相容實作發出多個 setLayerBuffer
指令。不過,我們不建議這麼做,因為某些裝置已通過這些 VTS 測試,但在實際用途中卻失敗,因此不應視為有效的功能測試。
如要進行新的 VTS 測試,請前往下列連結:
HIDL 相容性:
GraphicsComposerHidlCommandTest::SET_LAYER_BUFFER_multipleTimes
與 AIDL 3.1 相容:
GraphicsComposerAidlCommandTest::SetLayerBufferMultipleTimes
AIDL 3.2:
GraphicsComposerAidlCommandV2Test::SetLayerBufferSlotsToClear