減少圖形記憶體耗用量

在圖形堆疊中,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 預留位置緩衝區控制代碼,以及需要清除的快取緩衝區位置的 slot 編號。

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

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

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

測試無法驗證 HAL 實作是否會清除快取位置。 不過,您可以使用偵錯工具監控圖形緩衝區用量。在監控期間,您可能會發現,在 YouTube 上快速停止及啟動多部不同影片的案例中,記憶體不足錯誤減少了。

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

如需新的 VTS 測試,請參閱下列連結: