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 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 en libtonemap_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 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 tonos de HDR a SDR se pueda realizar de manera eficiente para TextureView. 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 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.
    • 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 prefijo in_libtonemap_.
  • Genera variables uniformes de SkSL

    La interfaz ToneMapper::generateShaderSkSLUniforms() devuelve lo siguiente, dado un objeto struct 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 y in_libtonemap_inputMaxLuminance. Los sombreadores del framework usan estos valores cuando se ajusta la escala de la entrada a libtonemap 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 biblioteca libtonemap 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:

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

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