SurfaceFlinger 和 WindowManager

SurfaceFlinger 接受緩衝區、組合緩衝區並將緩衝區傳送到顯示器。 WindowManager 為 SurfaceFlinger 提供緩衝區和視窗元數據,SurfaceFlinger 使用這些緩衝區和視窗元資料將表面合成到顯示器。

SurfaceFlinger

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

SurfaceFlinger 接受緩衝區的一種方式是透過 BufferQueue 和 SurfaceControl。當應用程式進入前台時,它會向WindowManager請求緩衝區。然後 WindowManager 向 SurfaceFlinger 要求一個圖層。圖層是包含 BufferQueue 的Surface和包含圖層元資料(如顯示幀)的SurfaceControl的組合。 SurfaceFlinger 建立層並將其傳送至 WindowManager。然後,WindowManager 將表面發送到應用程序,但保留 SurfaceControl 來操縱應用程式在螢幕上的外觀。

Android 10 新增了 ASurfaceControl,這是 SurfaceFlinger 接受緩衝區的另一種方式。 ASurfaceControl 將 Surface 和 SurfaceControl 組合到一個發送到 SurfaceFlinger 的事務包中。 ASurfaceControl 與圖層關聯,應用程式透過 ASurfaceTransactions 更新該圖層。然後,應用程式透過傳遞包含鎖定時間、取得時間等資訊的 ASurfaceTransactionStats 的回呼來取得有關 ASurfaceTransactions 的資訊。

下表包含有關 ASurfaceControl 及其關聯元件的更多詳細資訊。

成分描述
表面控制包裝 SurfaceControl 並使應用程式能夠建立與顯示器上的圖層相對應的 SurfaceControl。

可以建立為 ANativeWindow 的子級或另一個 ASurfaceControl 的子級。
ASurface交易包裝事務以使用戶端能夠編輯圖層的描述性屬性(例如幾何圖形),並將更新的緩衝區傳送至 SurfaceFlinger。
ASurface交易統計透過預先註冊的回調將有關已呈現交易的資訊(例如鎖定時間、取得時間和先前的釋放柵欄)傳送至應用程式。

儘管應用程式可以隨時提交緩衝區,但 SurfaceFlinger 僅在顯示刷新之間喚醒以接受緩衝區,這可能因裝置而異。這可以最大程度地減少記憶體使用量並避免螢幕上出現明顯的撕裂(這種情況在刷新顯示過程中更新時可能會發生)。

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

SurfaceFlinger 收集了可見層的所有緩衝區後,它會詢問硬體合成器 (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介面。