Android 13 presenta una biblioteca estática configurable por el proveedor llamada libtonemap, que define las operaciones de asignación de tono y se comparte con el proceso SurfaceFlinger y las implementaciones de Hardware Composer (HWC). Esta función permite que los OEMs definan y compartan sus algoritmos de asignación de tono de visualización entre el framework y los proveedores, lo que disminuye la falta de coincidencia en la asignación de tono.
En Android 12 y versiones anteriores, las operaciones de asignación de tono específicas de la pantalla no se compartían entre HWC, SurfaceFlinger y las apps. Según la ruta de renderización, para el contenido HDR, esto generó falta de coincidencia en la calidad de la imagen, en la que el contenido HDR se asignó a un espacio de salida de diferentes maneras. Esto se percibió en situaciones como la rotación de la pantalla, en la que la estrategia de composición cambia entre la GPU y la DPU, y en las diferencias en el comportamiento de renderización entre TextureView y SurfaceView.
En esta página, se describen la interfaz, la personalización y los detalles de validación de la biblioteca libtonemap.
Interfaz a la biblioteca de asignación de tono
La libtonemap
biblioteca contiene implementaciones respaldadas por CPU y sombreadores SkSL, que SurfaceFlinger puede
conectar para la composición de backend de GPU y el HWC para
generar una tabla de búsqueda de asignación de tono (LUT). El punto de entrada a libtonemap
es
android::tonemap::getToneMapper,
que muestra un objeto que implementa la
ToneMapper
interfaz.
La interfaz ToneMapper admite las siguientes capacidades:
Generar una LUT de asignación de tono
La interfaz
ToneMapper::lookupTonemapGaines una implementación de CPU del sombreador definido enlibtonemap_LookupTonemapGain. Las pruebas de unidades en el framework la usan, y los socios pueden usarla para obtener ayuda para generar una LUT de asignación de tono dentro de su canalización de color.libtonemap_LookupTonemapGaintoma valores de color en espacio lineal absoluto y no normalizado, tanto en RGB lineal como en XYZ, y muestra un valor flotante que describe cuánto multiplicar los colores de entrada en el espacio lineal.Generar un sombreador SkSL
La interfaz
ToneMapper::generateTonemapGainShaderSkSLmuestra una cadena de sombreador SkSL, dado un espacio de datos de origen y destino. El sombreador SkSL se conecta a la implementación de Skia paraRenderEngine, el componente de composición acelerado por GPU para SurfaceFlinger. El sombreador también se conecta alibhwui, de modo que la asignación de tono de HDR a SDR se pueda realizar de manera eficiente paraTextureView. Debido a que la cadena generada se inserta en otros sombreadores SkSL que usa Skia, el sombreador debe cumplir con las siguientes reglas:- La cadena de sombreador debe tener un punto de entrada con la firma
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz), en la quelinearRGBes el valor de los nits absolutos de los píxeles RGB en el espacio lineal yxyzeslinearRGBconvertido en XYZ. - Cualquier método auxiliar que use la cadena de sombreador debe tener el prefijo
libtonemap_para que las definiciones de sombreador del framework no entren en conflicto. Del mismo modo, las variables uniformes de entrada deben tener el prefijoin_libtonemap_.
- La cadena de sombreador debe tener un punto de entrada con la firma
Generar variables uniformes de SkSL
La interfaz
ToneMapper::generateShaderSkSLUniformsmuestra lo siguiente, dado unstructque describe los metadatos de diferentes estándares HDR y condiciones de visualización:Una lista de variables uniformes que están vinculadas por un sombreador SkSL
Los valores uniformes
in_libtonemap_displayMaxLuminanceyin_libtonemap_inputMaxLuminanceLos sombreadores del framework usan estos valores cuando se ajusta la entrada alibtonemapy se normaliza la salida según corresponda.El proceso de generación de variables uniformes es independiente del espacio de datos de entrada y salida.
Personalización
La implementación de referencia de la
libtonemap
biblioteca produce resultados aceptables. Sin embargo, debido a que el algoritmo de asignación de tono que usa la composición de GPU puede diferir del que usa la composición de DPU, el uso de la implementación de referencia puede causar parpadeo en algunas situaciones, como la animación de rotación. La personalización puede resolver esos problemas de calidad de imagen específicos del proveedor.
Se recomienda a los OEMs que anulen la implementación de libtonemap para
definir su propia subclase ToneMapper, que muestra getToneMapper.
Cuando personalizan la implementación, se espera que los socios realicen una de las siguientes acciones:
- Modificar la implementación de
libtonemapdirectamente - Definir su propia biblioteca estática, compilar la biblioteca como independiente y reemplazar el archivo
.ade la bibliotecalibtonemappor el que se genera a partir de su biblioteca personalizada
Los proveedores no necesitan modificar ningún código del kernel, pero varios proveedores deben comunicar detalles sobre los algoritmos de asignación de tono de DPU para una implementación adecuada.
Validación
Sigue estos pasos para validar tu implementación:
Reproduce videos HDR en la pantalla de cualquier estándar HDR que admita tu sistema de visualización admite, como HLG, HDR10, HDR10+ o DolbyVision.
Activa la composición de GPU para asegurarte de que no haya parpadeo perceptible para el usuario.
Usa el siguiente comando de
adbpara activar la composición de GPU:adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition, 1 to force GPU composition>
Problemas comunes
Pueden ocurrir los siguientes problemas con esta implementación:
El banding se produce cuando el objetivo de renderización que usa la composición de GPU tiene una precisión menor que el valor típico para el contenido HDR. Por ejemplo, el banding puede ocurrir cuando una implementación de HWC admite formatos opacos de 10 bits para HDR, como RGBA1010102 o P010, pero requiere que la composición de GPU escriba en un formato de 8 bits como RGBA8888 para admitir alfa.
Un cambio de color sutil se debe a las diferencias de cuantización si la DPU opera con una precisión diferente a la de la GPU.
Cada uno de estos problemas está relacionado con las diferencias de precisión relativa del hardware subyacente. Una solución alternativa típica es asegurarse de que haya un paso de tramado en las rutas de menor precisión, lo que hace que las diferencias de precisión sean menos perceptibles para el ser humano.