SurfaceFlinger 和 WindowManager

SurfaceFlinger 會接受緩衝區、組合緩衝區,並將緩衝區傳送至螢幕畫面。WindowManager 會為 SurfaceFlinger 提供緩衝區和視窗中繼資料,SurfaceFlinger 會使用這些資料將途徑合成至螢幕。

SurfaceFlinger

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

SurfaceFlinger 接受緩衝區的方法之一是透過 BufferQueue 和 SurfaceControl。應用程式進入前景時,會向 WindowManager 要求緩衝區。接著,WindowManager 會向 SurfaceFlinger 要求圖層。圖層是 surfaceSurfaceControl 的組合,前者包含 BufferQueue,後者則包含顯示框架等圖層中繼資料。SurfaceFlinger 會建立圖層,並將圖層傳送至 WindowManager。接著,WindowManager 會將介面傳送至應用程式,但會保留 SurfaceControl,以便操控應用程式在螢幕上的外觀。

Android 10 新增了 ASurfaceControl,這是 SurfaceFlinger 可接受緩衝區的另一種方式。ASurfaceControl 會將表面和 SurfaceControl 合併為一個交易包,並傳送至 SurfaceFlinger。ASurfaceControl 與圖層相關聯,應用程式會透過 ASurfaceTransactions 更新圖層。接著,應用程式會透過回呼取得 ASurfaceTransactions 相關資訊,這些回呼會傳遞包含資訊的 ASurfaceTransactionStats,例如鎖定時間、取得時間等。

下表詳細說明 ASurfaceControl 及其相關元件。

元件 說明
ASurfaceControl 納入 SurfaceControl,並讓應用程式建立對應至螢幕上圖層的 SurfaceControl。

可建立為 ANativeWindow 子項或另一個 ASurfaceControl 的子項。
ASurfaceTransaction 包裝交易,讓用戶端可以編輯圖層的描述性屬性 (例如幾何圖形),並將更新的緩衝區傳送至 SurfaceFlinger。
ASurfaceTransactionStats 透過預先註冊的回呼,將已提交交易的相關資訊 (例如鎖定時間、取得時間和先前釋放柵欄) 傳送至應用程式。

雖然應用程式隨時可以提交緩衝區,不過 SurfaceFlinger 只會在螢幕重新整理之間喚醒緩衝區,以便接收螢幕重新整理之間的緩衝區,具體情況因裝置而異。這麼做可盡量減少記憶體用量,並避免在更新螢幕畫面時,畫面出現明顯撕裂的情形。

當螢幕處於重新整理之間時,螢幕會將 VSYNC 信號傳送至 SurfaceFlinger。VSYNC 信號表示螢幕可以重新整理,而不會出現撕裂。當 SurfaceFlinger 收到 VSYNC 信號時,SurfaceFlinger 會逐一檢查圖層清單,尋找新的緩衝區。如果 SurfaceFlinger 找到新的緩衝區,SurfaceFlinger 會取得緩衝區;如果不是,SurfaceFlinger 會繼續使用先前取得的緩衝區。SurfaceFlinger 必須一律顯示內容,因此會掛在一個緩衝區。如未在圖層上提交任何緩衝區,系統就會忽略圖層。

SurfaceFlinger 收集可見層的所有緩衝區後,就會詢問 Hardware Composer (HWC) 應如何執行組合。如果 HWC 將圖層組合類型標示為用戶端組合,SurfaceFlinger 就會將這些圖層組合。接著,SurfaceFlinger 會將輸出緩衝區傳遞至 HWC

WindowManager

WindowManager 會控制視窗物件,這是檢視畫面物件的容器。視窗物件一律由表面物件支援。WindowManager 會監督生命週期、輸入和焦點事件、螢幕方向、轉場、動畫、位置、轉換、z 順序,以及視窗的許多其他層面。WindowManager 會將所有視窗中繼資料傳送至 SurfaceFlinger,以便 SurfaceFlinger 在螢幕上使用該項資料建立複合介面。

預先旋轉

許多硬體覆疊層都不支援旋轉 (即使支援,也會消耗處理效能);解決方法是在緩衝區抵達 SurfaceFlinger 之前轉換緩衝區。Android 支援 ANativeWindow 中的查詢提示 (NATIVE_WINDOW_TRANSFORM_HINT),用於代表 SurfaceFlinger 最有可能套用至緩衝區的轉換。GL 驅動程式可以使用這個提示預先轉換緩衝區,然後才到達 SurfaceFlinger,如此一來緩衝區送達時,就能正確轉換。

舉例來說,當您收到旋轉 90 度的提示時,請產生並套用矩陣至緩衝區,以免畫面跑到網頁結尾。為節省電力,請執行預先旋轉。詳情請參閱 system/core/include/system/window.h 中定義的 ANativeWindow 介面。