SurfaceFlinger 和 WindowManager

SurfaceFlinger 接受緩衝區,組合緩衝區,並將緩衝區發送到顯示器。 WindowManager 為 SurfaceFlinger 提供緩衝區和窗口元數據,SurfaceFlinger 使用它們將表面合成到顯示器。

SurfaceFlinger

SurfaceFlinger 可以通過兩種方式接受緩衝區:通過 BufferQueue 和 SurfaceControl,或者通過 ASurfaceControl。

SurfaceFlinger 接受緩衝區的一種方式是通過 BufferQueue 和 SurfaceControl。當應用程序進入前台時,它會從WindowManager請求緩衝區。 WindowManager 然後從 SurfaceFlinger 請求一個層。層是包含 BufferQueue 的表面和包含層元數據(如顯示幀)的SurfaceControl的組合。 SurfaceFlinger 創建圖層並將其發送到 WindowManager。 WindowManager 然後將表面發送到應用程序,但保留 SurfaceControl 以操縱應用程序在屏幕上的外觀。

Android 10 增加了 ASurfaceControl,這是 SurfaceFlinger 可以接受緩衝區的另一種方式。 ASurfaceControl 將一個表面和一個 SurfaceControl 組合成一個事務包,發送到 SurfaceFlinger。一個 ASurfaceControl 與一個層相關聯,應用程序通過 ASurfaceTransactions 更新該層。然後,應用程序通過傳遞包含諸如閂鎖時間、獲取時間等信息的 ASurfaceTransactionStats 的回調來獲取有關 ASurfaceTransactions 的信息。

下表包含有關 ASurfaceControl 及其相關組件的更多詳細信息。

零件描述
A表面控制包裝 SurfaceControl 並使應用能夠創建與顯示屏上的圖層相對應的 SurfaceControl。

可以創建為 ANativeWindow 的子級或另一個 ASurfaceControl 的子級。
A表面事務包裝 Transaction 以使客戶端能夠編輯層的描述性屬性,例如幾何,並將更新的緩衝區發送到 SurfaceFlinger。
ASurfaceTransactionStats通過預先註冊的回調將有關已呈現事務的信息(例如閂鎖時間、獲取時間和先前的發布柵欄)發送到應用程序。

儘管應用程序可以隨時提交緩衝區,但 SurfaceFlinger 只會在顯示刷新之間喚醒以接受緩衝區,這可能因設備而異。這最大限度地減少了內存使用並避免了屏幕上的可見撕裂,這可能在更新顯示中間刷新時發生。

當顯示器處於兩次刷新之間時,顯示器會向 SurfaceFlinger 發送VSYNC信號。 VSYNC 信號表示可以刷新顯示而不撕裂。當 SurfaceFlinger 接收到 VSYNC 信號時,SurfaceFlinger 會遍歷其層列表以尋找新的緩衝區。如果 SurfaceFlinger 找到新的緩衝區,SurfaceFlinger 獲取緩衝區;如果沒有,SurfaceFlinger 繼續使用之前獲取的緩衝區。 SurfaceFlinger 必須始終顯示某些內容,因此它會掛在一個緩衝區上。如果層上沒有提交過緩衝區,則忽略該層。

在 SurfaceFlinger 收集了所有可見層的緩衝區後,它會詢問 Hardware Composer (HWC) 應該如何執行組合。如果 HWC 將層組合類型標記為客戶端組合,SurfaceFlinger 將組合這些層。然後,SurfaceFlinger 將輸出緩衝區傳遞給HWC

窗口管理器

WindowManager 控制窗口對象,它們是視圖對象的容器。窗口對象總是由表面對象支持。 WindowManager 監督生命週期、輸入和焦點事件、屏幕方向、過渡、動畫、位置、變換、z 順序以及窗口的許多其他方面。 WindowManager 將所有窗口元數據發送到 SurfaceFlinger,以便 SurfaceFlinger 可以使用該數據在顯示器上合成表面。

預旋轉

許多硬件覆蓋不支持旋轉(即使支持,也會消耗處理能力);解決方案是在緩衝區到達 SurfaceFlinger 之前對其進行轉換。 Android 支持在ANativeWindow中使用查詢提示 ( NATIVE_WINDOW_TRANSFORM_HINT ) 來表示 SurfaceFlinger 最有可能應用於緩衝區的轉換。 GL 驅動程序可以使用此提示在緩衝區到達 SurfaceFlinger 之前對其進行預轉換,以便在緩衝區到達時正確轉換。

例如,當接收到旋轉 90 度的提示時,生成一個矩陣並將其應用到緩衝區以防止它跑出頁面末尾。為了節省電力,請進行此預旋轉。有關詳細信息,請參閱system/core/include/system/window.h中定義的ANativeWindow接口。