硬體 Composer (HWC) HAL 複合層 SurfaceFlinger,可降低組合 OpenGL ES (GLES) 和 GPU 效能。
HWC 會將疊加層和 2D 波束等物件抽象化,以形成複合 與特殊的視窗組合硬體通訊 複合式視窗。請使用 HWC 合併視窗,而非讓 SurfaceFlinger 與 GPU 合併。大多數 GPU 都不會針對 以及 GPU 組合層時 SurfaceFlinger,應用程式無法使用 GPU 進行獨立轉譯。
HWC 實作應支援:
- 至少四個疊加層:
- 狀態列
- 系統列
- 應用程式
- 桌布/背景
- 大於螢幕的圖層 (例如桌布)
- 每個像素並行的 Alpha 混合和每個平面都預先相乘 Alpha 混合
- 受保護影片播放的硬體路徑
- RGBA 包裝順序、YUV 格式,以及傾斜、旋轉和步伐 屬性
如何實作 HWC:
- 執行非運作的 HWC,並將所有組合工作傳送到 GLES。
- 實作演算法,以便逐步將合成作業委派給 HWC。例如,僅將前三個或四個介面委派給疊加層 安裝 HWC 的硬體
- 將硬體最佳化。這類資訊可能包括:
- 選擇能最大化 GPU 和 GPU 負載的途徑 提供檔案給 HWC
- 偵測螢幕是否正在更新。如果不是,委派代表 轉換為 GLES 而非 HWC,以節省電力。螢幕顯示時 持續更新,繼續將組合卸載至 HWC。
- 為常見用途做好準備,例如:
- 主畫面,包括狀態列、系統列、應用程式視窗和動態桌布
- 直向和橫向模式的全螢幕遊戲
- 全螢幕影片,搭配隱藏式輔助字幕及播放 控制
- 受保護的影片播放
- 分割畫面多視窗
HWC 基本功能
HWC 提供兩種基本元素:圖層和螢幕,用來代表合成作業及其與顯示硬體的互動情形。 HWC 也提供 VSYNC 的控制,以及對 SurfaceFlinger 的回呼。 以在發生 VSYNC 事件時通知通知。
HIDL 介面
Android 8.0 以上版本使用
HIDL 介面,稱為 Composer HAL,用於:
HWC 和 SurfaceFlinger 之間的繫結化處理序間通訊 (IPC)。Composer HAL 取代了
舊版 hwcomposer2.h
介面。如果供應商提供 Composer HAL
HWC 的實作,Composer HAL 可直接接受來自
SurfaceFlinger。如果供應商提供 HWC 的舊版實作項目,Composer HAL 會從 hwcomposer2.h
載入函式指標,並將 HIDL 呼叫轉送至函式指標呼叫。
HWC 提供函式來判斷特定螢幕的屬性;到 切換不同的顯示設定 (例如 4K 或 1080p) 解析度) 和色彩模式 (例如原生色彩或 true sRGB);然後轉向 開啟/關閉螢幕,或在支援的情況下進入低耗電模式。
函式指標
如果廠商直接實作 Composer HAL,SurfaceFlinger 會呼叫其函式
經由 HIDL 處理序間通訊舉例來說,如要建立圖層,SurfaceFlinger 會在 Composer HAL 上呼叫 createLayer()
。
如果廠商實作 hwcomposer2.h
介面,Composer HAL 會呼叫 hwcomposer2.h
函式指標。在 hwcomposer2.h
則留言中,
HWC 介面函式
也就是介面中沒有的小寫 CamelCase 名稱
做為已命名欄位幾乎每個函式都會透過要求
使用 getFunction
提供的函式指標
hwc2_device_t
。例如 createLayer
函式
是 HWC2_PFN_CREATE_LAYER
類型的函式指標,
當列舉值 HWC2_FUNCTION_CREATE_LAYER
完成
傳遞至 getFunction
。
詳細說明文件瞭解 Composer HAL 函式和 HWC 函式直通
函式,請參閱 composer
。如需 HWC 函式指標的詳細說明文件,請參閱 hwcomposer2.h
。
圖層和顯示控點
圖層和顯示方式是由 HWC 產生的控點操控。 控點不適用於 SurfaceFlinger,
當 SurfaceFlinger 建立新圖層時,會呼叫 createLayer
。
這會針對直接交易傳回 Layer
類型
或 hwc2_layer_t
適用於直通式實作。時間
SurfaceFlinger 會修改該圖層的屬性
將 hwc2_layer_t
值填入適當的修改函式中
以及修改所需的任何其他資訊
hwc2_layer_t
類型夠大,足以包含指標或
索引。
實體螢幕是以熱插頭建立。如果實體螢幕
HWC 建立控點,並將控點傳遞至 SurfaceFlinger,
重新傳送。虛擬螢幕是由 SurfaceFlinger 建立
呼叫 createVirtualDisplay()
要求顯示畫面。如果 HWC
可支援虛擬螢幕組合,會傳回一個控制代碼。接著是 SurfaceFlinger
將螢幕的組合委派給 HWC。如果 HWC 不支援
顯示組合,SurfaceFlinger 會建立控點並合成顯示畫面。
顯示組合作業
每個 VSYNC 一次,如果 SurfaceFlinger 有新內容要合成,就會喚醒。這類新內容可以是應用程式中的新圖片緩衝區,或是一或多個圖層屬性的變更。當 SurfaceFlinger 喚醒時:
- 處理交易 (如有)。
- 替換新的圖形緩衝區 (如果有的話)。
- 如果步驟 1 或 2 產生變更,則執行新的組合 也不符合顯示內容的方法
如要執行新的合成作業,SurfaceFlinger 會視情況建立及銷毀圖層或修改圖層狀態。同時更新
呼叫圖層,並呼叫
setLayerBuffer
或 setLayerColor
。在所有圖層都
SurfaceFlinger 會呼叫 validateDisplay
HWC 檢查圖層狀態,並判斷組成方式
繼續。根據預設,SurfaceFlinger 會嘗試設定每個圖層,以便由 HWC 合成圖層;不過在某些情況下,SurfaceFlinger 會透過 GPU 備用方案合成圖層。
呼叫 validateDisplay
後,SurfaceFlinger 會呼叫 getChangedCompositionTypes
,查看 HWC 是否希望在執行合成作業前變更任何圖層合成類型。為了接受變更,SurfaceFlinger 會呼叫
acceptDisplayChanges
。
如果有任何圖層標示為 SurfaceFlinger 組合,SurfaceFlinger
則會合併至目標緩衝區。SurfaceFlinger,然後呼叫
setClientTarget
為螢幕提供緩衝區,以便
緩衝區可以顯示在畫面上,也可以用圖層
沒有加上 SurfaceFlinger 構圖標記如果沒有將任何圖層標示為
SurfaceFlinger 組合,SurfaceFlinger 會繞過組合步驟。
最後,SurfaceFlinger 會呼叫 presentDisplay
告知使用者
HWC 完成組成程序並顯示最終結果。
多螢幕
Android 10 支援多種實體螢幕。 設計適用於 Android 7.0 及 下方則是 HWC 定義中缺少的幾項限制:
- 系統會假設只有一個內部螢幕。內部 螢幕上是顯示初始熱插頭報告的螢幕 啟動。內螢幕耗電後,就無法 已中斷連線。
- 除了內顯示器外,任意數量的外接螢幕也可以受到熱接,
正常運作期間。架構會假設第一個內部螢幕之後的所有熱插拔都是外部螢幕,因此如果新增更多內部螢幕,這些螢幕會被錯誤分類為
Display.TYPE_HDMI
,而非Display.TYPE_BUILT_IN
。
在執行上述 SurfaceFlinger 運算時 每個多媒體廣告都依序放送 即使只有一個螢幕的內容更新也一樣。
舉例來說,如果外部顯示器更新,序列就會是:
// In Android 9 and lower: // Update state for internal display // Update state for external display validateDisplay(<internal display>) validateDisplay(<external display>) presentDisplay(<internal display>) presentDisplay(<external display>) // In Android 10 and higher: // Update state for internal display // Update state for external display validateInternal(<internal display>) presentInternal(<internal display>) validateExternal(<external display>) presentExternal(<external display>)
虛擬螢幕組合
虛擬螢幕組合與外部螢幕類似 樂曲。虛擬螢幕組成和實體畫面之間的差異 螢幕組合是虛擬螢幕將輸出內容傳送至 Gralloc 緩衝區 而不是螢幕Hardware Composer (HWC) 會將輸出內容寫入緩衝區中。 提供完成圍欄,並將緩衝區傳送給取用端 (例如 例如影片編碼器、GPU、CPU 等虛擬螢幕可以使用 2D/Blitter 或 會在顯示管道寫入記憶體時重疊
模式
SurfaceFlinger 呼叫 SurfaceFlinger 後,每個影格都會有三種模式之一
validateDisplay()
HWC 方法:
- GLES:GPU 會將所有圖層合成,並直接寫入輸出緩衝區。HWC 並不會參與組合。
- MIXED - GPU 會將部分圖層結合成 framebuffer 和 HWC 會複合 framebuffer 和其他層, 直接將寫入至輸出緩衝區
- HWC:HWC 會合成所有圖層,並直接寫入輸出緩衝區。
輸出格式
虛擬顯示器緩衝區輸出格式取決於其模式:
- GLES 模式 - EGL 驅動程式會設定輸出緩衝區
格式為
dequeueBuffer()
,通常是RGBA_8888
。 取用端必須能夠接受驅動程式集的輸出格式,或是 否則無法讀取緩衝區 - MIXED 與 HWC 模式 - 如果消費者需要 CPU
存取,取用端會設定格式。否則格式為
IMPLEMENTATION_DEFINED
,而 Gralloc 會根據使用標記設定最佳格式。例如,如果消費者 和 HWC 都能有效率地編寫格式
同步圍欄
同步 (sync) 圍欄是 Android 圖形系統的重要部分。柵欄可讓 CPU 獨立於並行 GPU 工作進行,只有在存在真正的依附元件時才會阻斷。
舉例來說,當應用程式提交在 GPU 上產生的緩衝區時,也會提交同步化圍欄物件。這個圍欄可以發出信號, GPU 已完成寫入緩衝區。
HWC 要求 GPU 完成寫入緩衝區後,才能進行緩衝區 高度。同步圍欄透過緩衝區通過圖形管道傳遞 並在寫入緩衝區時發出訊號在顯示緩衝區前,HWC 檢查同步圍欄是否發出訊號,如果有,就會顯示 緩衝區。
如要進一步瞭解同步處理圍欄,請參閱 Hardware Composer 整合。