實現 Hardware Composer HAL

硬件作曲(HWC)HAL複合材料從SurfaceFlinger的接收層,從而降低組合物的量的OpenGL ES(GLES)和GPU執行。

HWC 將對象(例如疊加層和 2D blitters)抽象為複合表面,並與專門的窗口復合硬件通信以復合窗口。使用 HWC 來合成窗口,而不是讓 SurfaceFlinger 與 GPU 合成。大多數 GPU 都沒有針對合成進行優化,當 GPU 從 SurfaceFlinger 合成圖層時,應用程序無法使用 GPU 進行自己的渲染。

HWC 實現應支持:

  • 至少四個疊加層:
    • 狀態欄
    • 系統欄
    • 應用程序
    • 壁紙/背景
  • 比顯示器大的圖層(例如,牆紙)
  • 同時預乘每像素 alpha 混合和每平面 alpha 混合
  • 受保護視頻播放的硬件路徑
  • RGBA 打包順序、YUV 格式以及平鋪、混合和步幅屬性

實施 HWC:

  1. 實施非操作性 HWC 並將所有組合工作發送到 GLES。
  2. 實現一種算法,以增量方式將組合委託給 HWC。例如,僅將前三個或四個表面委派給 HWC 的覆蓋硬件。
  3. 優化 HWC。這可能包括:
    • 選擇最大化 GPU 負載的表面並將它們發送到 HWC。
    • 檢測屏幕是否正在更新。如果不是,請將合成委託給 GLES 而不是 HWC 以節省電量。當屏幕再次更新時,繼續將合成卸載到 HWC。
    • 為常見用例做準備,例如:
      • 主屏幕,包括狀態欄、系統欄、應用程序窗口和動態壁紙
      • 縱向和橫向模式下的全屏遊戲
      • 帶有隱藏式字幕和播放控制的全屏視頻
      • 受保護的視頻播放
      • 分屏多窗口

HWC 原語

所述HWC提供了兩個原語,顯示器,以表示組合物的工作和它的與顯示硬件交互。所述HWC還提供控制VSYNC和回調SurfaceFlinger的當VSYNC事件發生時通知它。

HIDL 接口

的Android 8.0和更高的使用HIDL接口稱為作曲HAL為HWC和SurfaceFlinger的之間binderized IPC。作曲家HAL替代了傳統的hwcomposer2.h接口。如果供應商提供 HWC 的 Composer HAL 實現,則 Composer HAL 直接接受來自 SurfaceFlinger 的 HIDL 調用。如果供應商提供的HWC的遺產執行者,作曲家HAL負荷運作從指針hwcomposer2.h ,轉發HIDL調用到函數指針調用。

HWC 提供了確定給定顯示器屬性的函數;在不同的顯示配置(例如 4k 或 1080p 分辨率)和顏色模式(例如原生顏色或真 sRGB)之間切換;並在支持的情況下打開、關閉或進入低功耗模式。

函數指針

如果供應商直接實現 Composer HAL,SurfaceFlinger 通過 HIDL IPC 調用其功能。例如,創建的層,SurfaceFlinger的調用createLayer()的作曲HAL。

如果供應商實現了hwcomposer2.h接口,作曲家HAL調用到hwcomposer2.h函數指針。在hwcomposer2.h評論,HWC接口功能是由沒有在界面命名字段存在lowerCamelCase名稱簡稱。幾乎每一個功能是通過請求使用函數指針裝載getFunction提供hwc2_device_t 。例如,該功能createLayer是類型的函數指針HWC2_PFN_CREATE_LAYER ,當枚舉值被返回HWC2_FUNCTION_CREATE_LAYER被送入getFunction

有關作曲家HAL功能和HWC功能的詳細文檔直通功能,見composer 。有關HWC函數指針詳細的文檔,請參閱hwcomposer2.h

圖層和顯示手柄

圖層和顯示由 HWC 生成的句柄操作。手柄對 SurfaceFlinger 是不透明的。

當SurfaceFlinger的創建一個新的層時,它調用createLayer ,它返回類型的Layer進行直接的實現或hwc2_layer_t直通實現。當SurfaceFlinger的修改該層的特性,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 實現時,HWC 定義中不存在一些限制:

  • 它假定有完全一個內部顯示。內部顯示是引導期間初始熱插拔報告的顯示。內置顯示器熱插拔後無法斷開。
  • 除了內部顯示器外,在設備正常運行期間,可以熱插拔任意數量的外部顯示器。該框架假定第一個內部顯示器畢竟hotplugs是外部顯示器,因此,如果添加任何更多的內部顯示器,他們錯誤地歸類為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的調用後validateDisplay() HWC方法:

  • GLES - GPU的複合材料的所有層,直接寫入到輸出緩衝器。 HWC 不參與合成。
  • MIXED - GPU的複合材料的一些層,以將幀緩衝和HWC複合幀緩衝器和剩餘的層,直接寫入到輸出緩衝器。
  • HWC - HWC複合材料的所有層,並直接寫入到輸出緩衝器。

輸出格式

虛擬顯示緩衝區輸出格式取決於它們的模式:

  • GLES模式- EGL驅動設置在輸出緩衝器格式dequeueBuffer()典型地RGBA_8888 。消費者必須能夠接受驅動程序設置的輸出格式,否則無法讀取緩衝區。
  • 混合HWC模式-如果消費者需要CPU訪問,消費者設置格式。否則,格式IMPLEMENTATION_DEFINED ,並Gralloc設置基於使用標籤的最佳格式。例如,如果消費者是視頻編碼器並且 HWC 可以有效地寫入格式,則 Gralloc 設置 YCbCr 格式。

同步柵欄

同步 (sync) 柵欄是 Android 圖形系統的一個重要方面。柵欄讓 CPU 工作獨立於並發 GPU 工作進行,僅在存在真正依賴時才阻塞。

例如,當應用程序提交在 GPU 上生成的緩衝區時,它也會提交一個同步柵欄對象。當 GPU 完成寫入緩衝區時,此柵欄會發出信號。

HWC 要求 GPU 在顯示緩衝區之前完成寫入緩衝區。同步柵欄與緩衝區一起通過圖形管道,並在寫入緩衝區時發出信號。在顯示緩衝區之前,HWC 檢查同步柵欄是否已發出信號,如果已發出信號,則顯示緩衝區。

有關同步柵欄更多信息,請參閱硬件合成一體化