Asignación de tono de la luminancia HDR a un rango compatible con SDR

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::lookupTonemapGain es una implementación de CPU del sombreador definido en libtonemap_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_LookupTonemapGain toma 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::generateTonemapGainShaderSkSL muestra 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 para RenderEngine, el componente de composición acelerado por GPU para SurfaceFlinger. El sombreador también se conecta a libhwui, de modo que la asignación de tono de HDR a SDR se pueda realizar de manera eficiente para TextureView. 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 que linearRGB es el valor de los nits absolutos de los píxeles RGB en el espacio lineal y xyz es linearRGB convertido 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 prefijo in_libtonemap_.
  • Generar variables uniformes de SkSL

    La interfaz ToneMapper::generateShaderSkSLUniforms muestra lo siguiente, dado un struct que 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_displayMaxLuminance y in_libtonemap_inputMaxLuminance Los sombreadores del framework usan estos valores cuando se ajusta la entrada a libtonemap y 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 libtonemap directamente
  • Definir su propia biblioteca estática, compilar la biblioteca como independiente y reemplazar el archivo .a de la biblioteca libtonemap por 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:

  1. 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.

  2. Activa la composición de GPU para asegurarte de que no haya parpadeo perceptible para el usuario.

    Usa el siguiente comando de adb para 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.