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_displayMaxLuminance
和in_libtonemap_inputMaxLuminance
。框架著色器在將輸入縮放到libtonemap
並在適用時對輸出進行標準化時使用這些值。
目前,生成製服的過程與輸入和輸出數據空間無關。
定制
libtonemap
庫的參考實現產生了可接受的結果。但是,由於 GPU 合成使用的色調映射算法可能與 DPU 合成使用的色調映射算法不同,因此在旋轉動畫等某些場景下,使用參考實現可能會導致閃爍。定制可以解決此類特定於供應商的圖像質量問題。
強烈建議 OEM 覆蓋libtonemap
的實現以定義自己的ToneMapper
子類,該子類由getToneMapper()
返回。在自定義實施時,合作夥伴應執行以下操作之一:
- 直接修改
libtonemap
的實現。 - 定義他們自己的靜態庫,將庫編譯為獨立庫,並將
libtonemap
庫的.a
文件替換為從他們的自定義庫生成的文件。
供應商不需要修改任何內核代碼,但多個供應商必須傳達有關 DPU 色調映射算法的詳細信息才能正確實施。
驗證
請按照以下步驟驗證您的實施:
在顯示系統支持的任何 HDR 標準的屏幕上播放 HDR 視頻,例如 HLG、HDR10、HDR10+ 或 DolbyVision。
切換 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 不同的精度運行,則量化差異會導致細微的顏色偏移。
這些問題中的每一個都與底層硬件的相對精度差異有關。一個典型的解決方法是確保在較低精度的路徑中有一個抖動步驟,使任何精度差異都不易被人察覺。