減少圖形記憶體耗用量

在圖形堆疊中,每個層級的緩衝區快取會位於 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 檔案中。

設定這個 sysprop 需要 Composer HAL 實作項目,才能在單一呈現週期中正確處理相同層級的多個 setLayerBuffer 指令。

啟用向下相容選項會產生以下影響:

  • 針對 AIDL HAL:SurfaceFlinger 會為單一圖層傳送多個 LayerCommand 例項,每個例項都有一個 BufferCommand。每個 BufferCommand 都包含 1x1 預留位置緩衝區句柄,以及需要清除的快取緩衝區的插槽編號。

  • 針對 HIDL HAL:SurfaceFlinger 會傳送多個 SELECT_DISPLAYSELECT_LAYERSET_BUFFER 指令。這些指令包含 1x1 預留位置緩衝區句柄,以及需要清除的快取緩衝區的插槽編號。

回溯相容選項可能會導致 Composer HAL 在某些裝置上當機。您或許可以修改 Composer HAL 來解決這個問題。控制這項行為的程式碼如下:

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

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

您可以使用 VTS 測試,驗證 HAL 實作功能是否能夠接收新的 API 呼叫 (HAL 3.2 以上版本),或是多個 setLayerBuffer 指令,以便實作向後相容性。不過,這不應視為測試功能是否正常運作的充分依據,因為有些裝置會通過這些 VTS 測試,但在實際使用情境中失敗。

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