減少圖形記憶體耗用量

在圖形堆疊中,每層緩衝區快取位於 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

如要充分發揮圖形緩衝區記憶體效益,請務必:

  1. 將 Composer HAL 實作項目更新至 3.2 版。
  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 檔案中。

設定這項系統屬性時,Composer HAL 實作必須在單一顯示週期內,正確處理同一圖層的多個 setLayerBuffer 指令。

啟用回溯相容選項會產生下列影響:

  • 對於 AIDL HAL:SurfaceFlinger 會為單一層傳送多個 LayerCommand 執行個體,每個執行個體都有單一 BufferCommand。每個 BufferCommand 都包含 1x1 預留位置緩衝區控制代碼,以及需要清除的快取緩衝區時段的時段編號。

  • 對於 HIDL HAL:SurfaceFlinger 會傳送多個 SELECT_DISPLAYSELECT_LAYERSET_BUFFER 指令。這些指令包含 1x1 預留位置緩衝區控制代碼,以及需要清除的快取緩衝區位置的 slot 編號。

回溯相容選項可能會導致部分裝置上的 Composer HAL 損毀。您或許可以修改 Composer HAL 來解決這個問題。控管這項行為的程式碼位於下列位置:

測試圖像緩衝區快取記憶體用量

測試無法驗證 HAL 實作是否清除快取時段。不過,您可以使用偵錯工具監控圖像緩衝區用量。監控時,您應該會發現,在 YouTube 上快速連續停止及啟動多部不同影片的情況下,記憶體不足錯誤減少了。

VTS 測試可驗證 HAL 實作項目是否能接收新的 API 呼叫 (HAL 版本 3.2 以上),或接收多個 setLayerBuffer 指令,以用於向後相容的實作項目。不過,這不應視為功能是否正常的充分測試,因為有些裝置通過這些 VTS 測試,但在實際使用案例中卻失敗。

如要進行新的 VTS 測試,請前往下列連結: