將 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 不同,則量化差異會導致細微的顏色偏移。

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