客戶端幀緩衝管理

從 Android 13 開始,只要顯示解析度發生變化,就會分配在用戶端組合期間使用的新幀緩衝區。此分配由 SurfaceFlinger 在解析度變更後的下一個無效週期執行。

解析度切換期間的幀緩衝區管理

由於以下兩種情況之一,會發生解析度變更:

  • 由 Hardware Composer (HWC) 發起的熱插拔事件,當從一個外部顯示器交換到具有不同預設解析度的另一個外部顯示器時會發生該事件。

    在熱插拔事件期間,當舊的顯示資料被釋放時,舊的幀緩衝區的句柄被釋放。

  • 由 SurfaceFlinger 發起的顯示模式切換,當使用者使用user settings變更分辨率,或應用程式使用preferredDisplayModeId變更解析度時,會發生這種切換。

    在顯示模式切換期間,SurfaceFlinger 在呼叫setActiveConfigsetActiveConfigWithConstraints之前釋放現有客戶端幀緩衝區的句柄。

為了避免在沒有為新舊幀緩衝區保留足夠記憶體的裝置上出現災難性問題(例如記憶體碎片),HWC 停止使用舊幀緩衝區並釋放這些幀緩衝區的任何句柄至關重要,如下例所示:

釋放句柄允許在 SurfaceFlinger 在下一個無效週期期間執行的新幀緩衝區分配之前完全釋放幀緩衝區記憶體。

幀緩衝區管理建議

如果 HWC 沒有及時釋放舊幀緩衝區的句柄,則新幀緩衝區分配將在舊幀緩衝區釋放之前進行。當新的分配由於碎片或其他問題而失敗時,這可能會導致災難性的問題。更糟糕的是,如果 HWC 根本不釋放這些句柄,則可能會發生記憶體洩漏。

為了避免災難性的分配失敗,請遵循以下建議:

  • 如果HWC 需要繼續使用舊的用戶端幀緩衝區,直到提供新的用戶端幀緩衝區,則為新舊幀緩衝區保留足夠的記憶體至關重要,並且可能在幀緩衝區記憶體空間上運行碎片整理演算法。

  • 為幀緩衝區分配一個與圖形緩衝區記憶體的其餘部分分開的專用記憶體池。這很重要,因為在幀緩衝區的釋放和重新分配之間,第三方進程可以嘗試分配圖形記憶體。如果幀緩衝區使用相同的圖形記憶體池,且圖形記憶體已滿,則第三方進程可能會佔用幀緩衝區先前分配的圖形內存,從而導致幀緩衝區重新分配的內存不足,或者可能導致內存空間碎片化。

測試幀緩衝區管理

建議 OEM 測試其裝置的跨解析度切換是否正確的客戶端幀緩衝區記憶體管理,如下所述:

  • 對於熱插拔事件,只需拔下並重新連接具有不同解析度的兩個不同顯示器即可。

  • 對於模式切換,請使用ModeSwitchingTestActivity CTS Verifier 測試啟動模式切換以測試幀緩衝區記憶體行為。該測試可以直觀地識別難以透過程式檢測到的問題。