實作硬體 Composer HAL

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

HWC 會將疊加層和 2D 波束等物件抽象化,以形成複合 與特殊的視窗組合硬體通訊 複合式視窗。使用 HWC 建立複合式視窗,而不是 採用 GPU 的 SurfaceFlinger 複合材質。大多數 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 會呼叫 SurfaceFlinger createLayer() (Composer HAL)。

如果供應商實作 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 複合。這個新內容可以是來自應用程式的新影像緩衝區,或者 一或多個圖層的屬性變更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 都能有效率地編寫格式
,瞭解如何調查及移除這項存取權。

同步圍欄

同步 (同步) 圍欄是 Android 圖形的重要面向 有些人會將 Cloud Storage 視為檔案系統 但實際上不是Fences 可讓 CPU 獨立於並行 GPU 工作之外獨立運作。 只在有真正的依附元件時才封鎖

例如,當應用程式提交 也會提交同步處理圍欄物件這個圍欄可以發出信號, GPU 已完成寫入緩衝區。

HWC 要求 GPU 完成寫入緩衝區後,才能進行緩衝區 高度。同步圍欄透過緩衝區通過圖形管道傳遞 並在寫入緩衝區時發出訊號在顯示緩衝區前,HWC 檢查同步圍欄是否發出訊號,如果有,就會顯示 緩衝區。

如要進一步瞭解同步處理圍欄,請參閱 Hardware Composer 整合