在圖形堆疊中,每個層級的緩衝區快取會位於 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 測試,請前往以下連結: