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::lookupTonemapGain
是libtonemap_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 像素的絕對尼特值,xyz
是linearRGB
轉換為 XYZ 的值。 - 著色器字串使用的任何輔助方法都必須以字串
libtonemap_
為前綴,以便框架著色器定義不會發生衝突。同樣,輸入製服必須以in_libtonemap_
為前綴。
- 著色器字串必須具有帶有
生成 SkSL 制服
給定描述來自不同 HDR 標準和顯示條件的元資料的元資料
struct
,介面ToneMapper::generateShaderSkSLUniforms()
傳回以下內容:由 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 不同,則量化差異會導致細微的顏色偏移。
這些問題中的每一個都與底層硬體的相對精度差異有關。典型的解決方法是確保較低精度路徑中存在抖動步驟,使人類不易察覺任何精確度差異。