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 de SurfaceFlinger y las implementaciones de Hardware Composer (HWC).
Esta función permite que los OEM definan y compartan sus algoritmos de asignación de tono de pantalla entre el framework y los proveedores, lo que disminuye la falta de coincidencia en la asignación de tono.
Antes de Android 13, las operaciones de asignación de tono específicas de la pantalla no se compartían entre el HWC, SurfaceFlinger y las apps. Según la ruta de renderización, en el caso del contenido HDR, esto generaba discrepancias en la calidad de la imagen, en las que el contenido HDR se asignaba a un espacio de salida de diferentes maneras. Esto se percibía 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 los detalles de la interfaz, la personalización y la validación de la biblioteca de libtonemap
.
Interfaz para la biblioteca de asignación de tonos
La biblioteca libtonemap
contiene implementaciones respaldadas por la CPU y sombreadores de SkSL, que SurfaceFlinger puede conectar para la composición de backend de GPU y el HWC para generar una tabla de búsqueda (LUT) de asignación de tonos. El punto de entrada a libtonemap
es android::tonemap::getToneMapper()
, que devuelve un objeto que implementa la interfaz ToneMapper
.
La interfaz ToneMapper
admite las siguientes funciones:
Cómo generar una LUT de asignación de tonos
La interfaz
ToneMapper::lookupTonemapGain
es una implementación de CPU del sombreador definido enlibtonemap_LookupTonemapGain()
. Las pruebas de unidades del framework usan este valor, y los socios pueden usarlo para obtener ayuda con la generación de una LUT de asignación de tonos dentro de su canalización de color.libtonemap_LookupTonemapGain()
toma valores de color en un espacio lineal absoluto y sin normalizar, tanto en RGB lineal como en XYZ, y devuelve un número de punto flotante que describe cuánto se deben multiplicar los colores de entrada en el espacio lineal.Genera un sombreador de SkSL
La interfaz
ToneMapper::generateTonemapGainShaderSkSL()
devuelve una cadena de sombreador de SkSL, dado un espacio de datos de origen y destino. El sombreador de 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 tonos de HDR a SDR se pueda realizar de manera eficiente paraTextureView
. Dado que la cadena generada se inserta en otros sombreadores de SkSL que usa Skia, el sombreador debe cumplir con las siguientes reglas:- La cadena del sombreador debe tener un punto de entrada con la firma
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)
, en la quelinearRGB
es el valor de los nits absolutos de los píxeles RGB en el espacio lineal yxyz
eslinearRGB
convertido en XYZ. - Todos los métodos auxiliares que usa la cadena del sombreador deben tener el prefijo
libtonemap_
para que no haya conflictos con las definiciones de sombreadores del framework. Del mismo modo, las variables uniformes de entrada deben tener el prefijoin_libtonemap_
.
- La cadena del sombreador debe tener un punto de entrada con la firma
Genera variables uniformes de SkSL
La interfaz
ToneMapper::generateShaderSkSLUniforms()
devuelve lo siguiente, dado un objetostruct
de metadatos que describe los metadatos de diferentes estándares de HDR y condiciones de visualización:Es una lista de variables uniformes vinculadas por un sombreador de SkSL.
Los valores uniformes
in_libtonemap_displayMaxLuminance
yin_libtonemap_inputMaxLuminance
. Los sombreadores del framework usan estos valores cuando se ajusta la escala de la entrada alibtonemap
y se normaliza la salida según corresponda.
Actualmente, el proceso de generación de uniformes es independiente del espacio de datos de entrada y salida.
Personalización
La implementación de referencia de la biblioteca libtonemap
produce resultados aceptables. Sin embargo, debido a que el algoritmo de asignación de tonos que usa la composición de la GPU puede diferir del que usa la composición de la DPU, usar la implementación de referencia puede causar parpadeos en algunas situaciones, como la animación de rotación. La personalización puede resolver este tipo de problemas de calidad de imagen específicos del proveedor.
Se recomienda encarecidamente a los OEM que anulen la implementación de libtonemap
para definir su propia subclase ToneMapper
, que devuelve getToneMapper()
.
Cuando personalizan la implementación, se espera que los socios realicen una de las siguientes acciones:
- Modifica la implementación de
libtonemap
directamente. - Definir su propia biblioteca estática, compilar la biblioteca de forma independiente y reemplazar el archivo
.a
de la bibliotecalibtonemap
por el que se generó 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 tonos de la DPU para una implementación adecuada.
Validación
Sigue estos pasos para validar tu implementación:
Reproduce videos HDR en la pantalla con cualquiera de los estándares HDR que admita tu sistema de visualización, como HLG, HDR10, HDR10+ o Dolby Vision.
Activa o desactiva la composición de la GPU para asegurarte de que no haya parpadeos perceptibles para el usuario.
Usa el siguiente comando de
adb
para activar o desactivar la composición de la GPU:adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition, 1 to force GPU composition>
Problemas comunes
Con esta implementación, pueden ocurrir los siguientes problemas:
El banding se produce cuando el destino de renderización que usa la composición de la GPU tiene una precisión menor que el valor típico del contenido HDR. Por ejemplo, la formación de bandas 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 la GPU escriba en un formato de 8 bits, como RGBA8888, para admitir alfa.
Las diferencias de cuantificación provocan un cambio de color sutil si la DPU opera con una precisión diferente a la de la GPU.
Cada uno de estos problemas se relaciona 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.