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 收集可見圖層的所有緩衝區後,會詢問硬體合成器 (HWC) 應如何執行合成作業。如果 HWC 將圖層組合類型標示為用戶端組合,SurfaceFlinger 就會將這些圖層組合。接著,SurfaceFlinger 會將輸出緩衝區傳遞至 HWC。
WindowManager
WindowManager 會控制視窗物件,這是 View 物件的容器。視窗物件一律由表面物件支援。WindowManager 會監督視窗的生命週期、輸入和焦點事件、螢幕方向、轉場、動畫、位置、轉換、z 順序和其他多項相關事項。WindowManager 會將所有視窗中繼資料傳送至 SurfaceFlinger,讓 SurfaceFlinger 可使用該資料在螢幕上合成介面。
預先旋轉
許多硬體覆疊層都不支援旋轉 (即使支援,也會消耗處理效能);解決方法是在緩衝區到達 SurfaceFlinger 之前轉換緩衝區。Android 支援 ANativeWindow
中的查詢提示 (NATIVE_WINDOW_TRANSFORM_HINT
),用於代表 SurfaceFlinger 最有可能套用至緩衝區的轉換。GL 驅動程式可使用這項提示,在緩衝區抵達 SurfaceFlinger 之前預先轉換緩衝區,以便在緩衝區抵達時正確轉換。
舉例來說,當您收到旋轉 90 度的提示時,請產生並套用矩陣至緩衝區,以免畫面跑到網頁結尾。為節省電力,請執行這項預先旋轉作業。詳情請參閱 system/core/include/system/window.h
中定義的 ANativeWindow
介面。