SurfaceFlinger 會接受緩衝區、組合緩衝區,並將緩衝區傳送至螢幕畫面。WindowManager 會為 SurfaceFlinger 提供緩衝區和視窗中繼資料,SurfaceFlinger 會使用這些資料將途徑合成至螢幕。
SurfaceFlinger
SurfaceFlinger 可透過兩種方式接受緩衝區:透過 BufferQueue 和 SurfaceControl,或透過 ASurfaceControl。
SurfaceFlinger 接受緩衝區的方法之一是透過 BufferQueue 和 SurfaceControl。應用程式進入前景時,會向 WindowManager 要求緩衝區。接著,WindowManager 會向 SurfaceFlinger 要求圖層。圖層是 surface 和 SurfaceControl 的組合,前者包含 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
介面。