實作硬體 Composer HAL

硬體 Composer (HWC) HAL 複合層 SurfaceFlinger,可降低組合 OpenGL ES (GLES) 和 GPU 效能。

HWC 會將疊加層和 2D 波束等物件抽象化,以形成複合 與特殊的視窗組合硬體通訊 複合式視窗。請使用 HWC 合併視窗,而非讓 SurfaceFlinger 與 GPU 合併。大多數 GPU 都不會針對 以及 GPU 組合層時 SurfaceFlinger,應用程式無法使用 GPU 進行獨立轉譯。

HWC 實作應支援:

  • 至少四個疊加層:
    • 狀態列
    • 系統列
    • 應用程式
    • 桌布/背景
  • 大於螢幕的圖層 (例如桌布)
  • 每個像素並行的 Alpha 混合和每個平面都預先相乘 Alpha 混合
  • 受保護影片播放的硬體路徑
  • RGBA 包裝順序、YUV 格式,以及傾斜、旋轉和步伐 屬性

如何實作 HWC:

  1. 執行非運作的 HWC,並將所有組合工作傳送到 GLES。
  2. 實作演算法,以便逐步將合成作業委派給 HWC。例如,僅將前三個或四個介面委派給疊加層 安裝 HWC 的硬體
  3. 將硬體最佳化。這類資訊可能包括:
    • 選擇能最大化 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. 替換新的圖形緩衝區 (如果有的話)。
  3. 如果步驟 1 或 2 產生變更,則執行新的組合 也不符合顯示內容的方法

如要執行新的合成作業,SurfaceFlinger 會視情況建立及銷毀圖層或修改圖層狀態。同時更新 呼叫圖層,並呼叫 setLayerBuffersetLayerColor。在所有圖層都 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 整合