Mapeo de tonos HDR Luminance a un rango compatible con SDR

Android 13 presenta una biblioteca estática configurable por el proveedor llamada libtonemap , que define las operaciones de mapeo de tonos y se comparte con el proceso SurfaceFlinger y las implementaciones de Hardware Composer (HWC). Esta función permite a los OEM definir y compartir sus algoritmos de mapeo de tonos de pantalla entre el marco y los proveedores, lo que reduce la falta de coincidencia en el mapeo de tonos.

Antes de Android 13, las operaciones de asignación de tonos específicas de la pantalla no se compartían entre HWC, SurfaceFlinger y las aplicaciones. Dependiendo de la ruta de renderizado, para el contenido HDR, esto provocó discrepancias en la calidad de la imagen, donde el contenido HDR se asignó a un espacio de salida de diferentes maneras. Esto fue perceptible en escenarios como la rotación de la pantalla, donde la estrategia de composición cambia entre la GPU y la DPU, y en las diferencias en el comportamiento de representación entre TextureView y SurfaceView.

Esta página describe la interfaz, la personalización y los detalles de validación de la biblioteca libtonemap .

Interfaz a la biblioteca de mapeo de tonos

La biblioteca libtonemap contiene implementaciones respaldadas por CPU y sombreadores SkSL, que SurfaceFlinger puede conectar para la composición de back-end de GPU y HWC para generar una tabla de búsqueda de asignación de tonos (LUT). 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 capacidades:

  • Generar una LUT de mapeo de tonos

    La interfaz ToneMapper::lookupTonemapGain es una implementación de CPU del shader definido en libtonemap_LookupTonemapGain() . Esto lo usan las pruebas unitarias en el marco, y los socios pueden usarlo como ayuda para generar una LUT de mapeo de tonos dentro de su tubería de color.

    libtonemap_LookupTonemapGain() toma valores de color en un espacio lineal no normalizado absoluto, tanto en RGB lineal como en XYZ, y devuelve un flotante que describe cuánto multiplicar los colores de entrada en el espacio lineal.

  • Generar un sombreador SkSL

    La interfaz ToneMapper::generateTonemapGainShaderSkSL() devuelve una cadena de sombreado SkSL, dado un espacio de datos de origen y destino. El sombreador SkSL está conectado a la implementación de Skia para RenderEngine , el componente de composición acelerado por GPU para SurfaceFlinger. El sombreador también está conectado a libhwui , de modo que el mapeo de tonos de HDR a SDR se puede realizar de manera eficiente para TextureView . Debido a que la cadena generada está integrada en otros sombreadores SkSL utilizados por Skia, el sombreador debe cumplir con las siguientes reglas:

    • La cadena de sombreado debe tener un punto de entrada con la firma float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz) , donde 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 utilizado por la cadena de sombreado debe tener como prefijo la cadena libtonemap_ para que las definiciones de sombreado del marco no entren en conflicto. Del mismo modo, los uniformes de entrada deben tener el prefijo in_libtonemap_ .
  • Generar uniformes SkSL

    La interfaz ToneMapper::generateShaderSkSLUniforms() devuelve lo siguiente, dada una struct de metadatos que describe metadatos de diferentes estándares HDR y condiciones de visualización:

    • Una lista de uniformes que están vinculados por un shader SkSL.

    • Los valores uniformes in_libtonemap_displayMaxLuminance e in_libtonemap_inputMaxLuminance . Estos valores son utilizados por los sombreadores de framework al escalar la entrada en libtonemap y normalizar 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 utilizado por la composición de GPU puede diferir del utilizado por la composición de DPU, el uso de la implementación de referencia puede causar parpadeo en algunos escenarios, como la animación de rotación. La personalización puede resolver estos problemas de calidad de imagen específicos del proveedor.

Se recomienda enfáticamente a los OEM que anulen la implementación de libtonemap para definir su propia subclase ToneMapper , que es devuelta por getToneMapper() . Al personalizar la implementación, se espera que los socios realicen una de las siguientes acciones:

  • Modifique la implementación de libtonemap directamente.
  • Defina su propia biblioteca estática, compile la biblioteca como independiente y reemplace el archivo .a de la biblioteca libtonemap con el generado a partir de su biblioteca personalizada.

Los proveedores no necesitan modificar ningún código del kernel, pero varios proveedores deben comunicar los detalles sobre los algoritmos de mapeo de tonos de la DPU para una implementación adecuada.

Validación

Siga estos pasos para validar su implementación:

  1. Reproduzca videos HDR en la pantalla de cualquier estándar HDR compatible con su sistema de visualización , como HLG, HDR10, HDR10+ o DolbyVision.

  2. Alterne la composición de GPU para asegurarse de que no haya parpadeo perceptible por el usuario.

    Utilice el siguiente comando adb para alternar 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

Los siguientes problemas pueden ocurrir con esta implementación:

  • La formación de bandas se produce cuando el objetivo de representación utilizado por la composición de la GPU tiene una precisión inferior al valor típico del contenido HDR. Por ejemplo, las bandas pueden 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.

  • Las diferencias de cuantización provocan un sutil cambio de color si la DPU funciona 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 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 los humanos.