將 HDR 亮度色調映射到 SDR 兼容範圍

Android 13 引入了一個名為libtonemap的供應商可配置靜態庫,它定義色調映射操作並與 SurfaceFlinger 進程和硬體編輯器 (HWC) 實作共用。此功能使 OEM 能夠在框架和供應商之間定義和共享其顯示色調映射演算法,從而減少色調映射的不匹配。

在 Android 13 之前,HWC、SurfaceFlinger 和應用程式之間不會共用特定顯示器的色調映射操作。根據渲染路徑,對於 HDR 內容,這會導致影像品質不匹配,其中 HDR 內容以不同方式色調對應到輸出空間。這在螢幕旋轉等場景中很明顯,其中 GPU 和 DPU 之間的合成策略發生變化,以及 TextureView 和 SurfaceView 之間的渲染行為存在差異。

本頁介紹了libtonemap庫的介面、自訂和驗證詳細資訊。

色調映射庫的接口

libtonemap庫包含 CPU 支援的實作和 SkSL 著色器,它們可以由 SurfaceFlinger 插入以進行 GPU 後端組合,也可以由 HWC 插入以產生色調映射查找表 (LUT)。 libtonemap的入口點是android::tonemap::getToneMapper() ,它傳回一個實作ToneMapper介面的物件。

ToneMapper介面支援以下功能:

  • 生成色調映射 LUT

    介面ToneMapper::lookupTonemapGainlibtonemap_LookupTonemapGain()中定義的著色器的 CPU 實作。這由框架中的單元測試使用,並且合作夥伴可以使用它來幫助在其顏色管道內生成色調映射 LUT。

    libtonemap_LookupTonemapGain()接受絕對、非標準化線性空間(線性 RGB 和 XYZ)中的顏色值,並傳回一個浮點數,描述在線性空間中與輸入顏色相乘的量。

  • 產生 SkSL 著色器

    給定來源和目標資料空間,介面ToneMapper::generateTonemapGainShaderSkSL()傳回 SkSL 著色器字串。 SkSL 著色器插入到RenderEngine的 Skia 實作中,RenderEngine 是 SurfaceFlinger 的 GPU 加速合成元件。該著色器也插入到libhwui中,以便可以為TextureView有效地執行 HDR 到 SDR 色調映射。由於產生的字串內聯到 Skia 使用的其他 SkSL 著色器中,因此著色器必須遵守以下規則:

    • 著色器字串必須具有帶有float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)簽名的入口點,其中linearRGB是線性空間中 RGB 像素的絕對尼特值, xyzlinearRGB轉換為 XYZ 的值。
    • 著色器字串使用的任何輔助方法都必須以字串libtonemap_為前綴,以便框架著色器定義不會發生衝突。同樣,輸入製服必須以in_libtonemap_為前綴。
  • 生成 SkSL 制服

    給定描述來自不同 HDR 標準和顯示條件的元資料的元資料struct ,介面ToneMapper::generateShaderSkSLUniforms()傳回以下內容:

    • 由 SkSL 著色器綁定的製服清單。

    • 統一值in_libtonemap_displayMaxLuminancein_libtonemap_inputMaxLuminance 。當輸入縮放到libtonemap並根據需要標準化輸出時,框架著色器將使用這些值。

    目前,生成製服的過程與輸入和輸出資料空間無關。

客製化

libtonemap函式庫的參考實作產生了可接受的結果。但是,由於 GPU 組合使用的色調映射演算法可能與 DPU 組合使用的色調映射演算法不同,因此使用參考實作可能會在某些場景(例如旋轉動畫)中導致閃爍。客製化可以解決此類特定於供應商的影像品質問題。

強烈建議 OEM 重寫libtonemap的實作來定義自己的ToneMapper子類,該子類別由getToneMapper()傳回。在客製化實施時,合作夥伴應執行以下操作之一:

  • 直接修改libtonemap的實作。
  • 定義自己的靜態函式庫,將函式庫編譯為獨立函式庫,並將libtonemap函式庫的.a檔替換為從自訂函式庫產生的檔。

供應商不需要修改任何核心程式碼,但多個供應商必須傳達有關 DPU 色調映射演算法的詳細資訊才能正確實施。

驗證

請依照以下步驟驗證您的實作:

  1. 在您的顯示系統支援的任何 HDR 標準的螢幕上播放 HDR 視頻,例如 HLG、HDR10、HDR10+ 或 DolbyVision。

  2. 切換 GPU 組成以確保使用者不會感覺到閃爍。

    使用以下adb指令切換 GPU 組成:

    adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
    1 to force GPU composition>
    
    

常見問題

此實施可能會出現以下問題:

  • 當 GPU 組合所使用的渲染目標的精確度低於 HDR 內容的典型值時,會導致出現條帶。例如,當 HWC 實作支援 HDR 的不透明 10 位元格式(例如 RGBA1010102 或 P010),但要求 GPU 組合寫入 RGBA8888 等 8 位元格式以支援 Alpha 時,可能會出現條帶。

  • 如果 DPU 的運作精度與 GPU 不同,則量化差異會導致細微的顏色偏移。

這些問題中的每一個都與底層硬體的相對精度差異有關。典型的解決方法是確保較低精度路徑中存在抖動步驟,使人類不易察覺任何精確度差異。