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

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

Android 13 引入了一個名為libtonemap的供應商可配置靜態庫,它定義色調映射操作並與 SurfaceFlinger 進程和 Hardware Composer (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::lookupTonemapGain接口是libtonemap_LookupTonemapGain()中定義的著色器的 CPU 實現。這由框架中的單元測試使用,合作夥伴可以使用它來幫助在其顏色管道中生成色調映射 LUT。

    libtonemap_LookupTonemapGain()在線性 RGB 和 XYZ 中獲取絕對、非歸一化線性空間中的顏色值,並返回一個浮點數,描述在線性空間中與輸入顏色相乘的程度。

  • 生成 SkSL 著色器

    接口ToneMapper::generateTonemapGainShaderSkSL()返回一個 SkSL 著色器字符串,給定源和目標數據空間。 SkSL 著色器插入到RenderEngine的 Skia 實現中,這是 SurfaceFlinger 的 GPU 加速合成組件。著色器也插入到libhwui中,因此可以為TextureView高效地執行 HDR 到 SDR 色調映射。因為生成的字符串內嵌到 Skia 使用的其他 SkSL 著色器中,所以著色器必須遵守以下規則:

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

    接口ToneMapper::generateShaderSkSLUniforms()返回以下內容,給定描述來自不同 HDR 標準和顯示條件的元數據的元數據struct

    • 由 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 不同的精度運行,則量化差異會導致細微的顏色偏移。

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