SurfaceFlinger 會接受緩衝區、組合緩衝區,並將緩衝區傳送至螢幕。WindowManager
會提供緩衝區和視窗中繼資料給 SurfaceFlinger,後者會使用這些資料將途徑合成到螢幕上。
SurfaceFlinger
SurfaceFlinger 可以透過兩種方式接受緩衝區:透過 BufferQueue 和 SurfaceControl
,或透過 ASurfaceControl
。
SurfaceFlinger 接受緩衝區的方式之一,是透過 BufferQueue 和 SurfaceControl
。應用程式移至前景時,會向 WindowManager
要求緩衝區。WindowManager
接著會向 SurfaceFlinger 要求圖層。圖層是介面和 SurfaceControl
執行個體的組合,前者包含 BufferQueue,後者包含圖層中繼資料,例如顯示畫面。SurfaceFlinger 會建立圖層並傳送至 WindowManager
。WindowManager
然後將介面傳送至應用程式,但保留 SurfaceControl
例項,以便
操控應用程式在畫面上的外觀。
Android 10 新增了 ASurfaceControl
,這是 SurfaceFlinger 接受緩衝區的另一種方式。ASurfaceControl
會將介面和 SurfaceControl
執行個體合併為一個交易套件,並傳送至 SurfaceFlinger。ASurfaceControl
與圖層相關聯,應用程式會透過 ASurfaceTransaction
例項更新圖層。應用程式隨後會透過回呼取得 ASurfaceTransaction
執行個體的相關資訊,這些回呼會傳遞包含閂鎖時間、擷取時間等資訊的 ASurfaceTransactionStats
。
下表詳細說明 ASurfaceControl
和相關聯的元件:
元件 | 說明 |
---|---|
ASurfaceControl |
封裝 SurfaceControl ,並讓應用程式建立對應於顯示器上圖層的 SurfaceControl 執行個體。可做為 ANativeWindow 的子項建立,或做為其他 ASurfaceControl 執行個體的子項建立。 |
ASurfaceTransaction |
封裝 Transaction ,讓用戶端能夠編輯圖層的描述性屬性 (例如幾何),並將更新後的緩衝區傳送至 SurfaceFlinger。 |
ASurfaceTransactionStats
| 透過預先註冊的回呼,將已顯示交易的相關資訊 (例如閂鎖時間、取得時間和先前的發布柵欄) 傳送至應用程式。 |
雖然應用程式隨時可以提交緩衝區,但 SurfaceFlinger 只會在螢幕重新整理期間喚醒,並接受緩衝區,這可能因裝置而異。這可將記憶體用量降到最低,並避免螢幕上出現明顯的撕裂感 (更新顯示器時可能會發生這種情況)。
顯示器在重新整理之間會將 VSync 訊號傳送至 SurfaceFlinger。VSync 信號表示螢幕可以重新整理,不會出現畫面撕裂問題。SurfaceFlinger 收到 VSync 訊號時,會逐一檢查圖層清單,尋找新的緩衝區。如果 SurfaceFlinger 找到新的緩衝區,就會取得該緩衝區;如果沒有,SurfaceFlinger 會繼續使用先前取得的緩衝區。SurfaceFlinger 一律必須顯示內容,因此會保留一個緩衝區。如果從未在圖層上提交緩衝區,系統會忽略該圖層。
SurfaceFlinger 收集完可見圖層的所有緩衝區後,會詢問硬體合成器 (HWC) 應如何執行合成作業。如果 HWC 將圖層組合類型標示為用戶端組合,SurfaceFlinger 會組合這些圖層。接著,SurfaceFlinger 會將輸出緩衝區傳遞至 HWC。
WindowManager
WindowManager
控制 Window
物件,這些物件是 View
物件的容器。Window
物件一律由 Surface
物件支援。WindowManager
負責監控視窗的生命週期、輸入和焦點事件、螢幕方向、轉場效果、動畫、位置、轉換、Z 順序,以及許多其他方面。WindowManager
會將所有視窗中繼資料傳送至 SurfaceFlinger,以便 SurfaceFlinger 使用該資料在螢幕上合成表面。
預先旋轉
許多硬體重疊畫面不支援旋轉 (即使支援,也會耗用處理能力);解決方法是在緩衝區到達 SurfaceFlinger 前轉換緩衝區。Android 支援 ANativeWindow
中的查詢提示 (NATIVE_WINDOW_TRANSFORM_HINT
),代表 SurfaceFlinger 最有可能套用至緩衝區的轉換。GL 驅動程式可以使用這項提示,在緩衝區到達 SurfaceFlinger 之前預先轉換緩衝區,確保緩衝區到達時已正確轉換。
舉例來說,如果收到旋轉 90 度的提示,請產生並將矩陣套用至緩衝區,避免緩衝區超出頁面結尾。為節省電力,請在旋轉前執行這項操作。詳情請參閱 system/core/include/system/window.h
中定義的 ANativeWindow
介面。