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