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