Mapeamento de tom de luminância HDR para uma faixa compatível com SDR

O Android 13 introduz uma biblioteca estática configurável pelo fornecedor chamada libtonemap , que define operações de mapeamento de tons e é compartilhada com o processo SurfaceFlinger e implementações do Hardware Composer (HWC). Esse recurso permite que os OEMs definam e compartilhem seus algoritmos de mapeamento de tons de exibição entre a estrutura e os fornecedores, diminuindo a incompatibilidade no mapeamento de tons.

Antes do Android 13, as operações de mapeamento de tons específicas da tela não eram compartilhadas entre HWC, SurfaceFlinger e aplicativos. Dependendo do caminho de renderização, para conteúdo HDR, isso levava a incompatibilidades na qualidade da imagem, onde o conteúdo HDR era mapeado em tons para um espaço de saída de maneiras diferentes. Isso foi perceptível em cenários como a rotação da tela, onde a estratégia de composição muda entre a GPU e a DPU, e nas diferenças no comportamento de renderização entre o TextureView e o SurfaceView.

Esta página descreve a interface, personalização e detalhes de validação da biblioteca libtonemap .

Interface para a biblioteca de mapeamento de tons

A biblioteca libtonemap contém implementações apoiadas por CPU e shaders SkSL, que podem ser conectados pelo SurfaceFlinger para composição de back-end de GPU e pelo HWC para gerar uma tabela de consulta de mapeamento de tons (LUT). O ponto de entrada para libtonemap é android::tonemap::getToneMapper() , que retorna um objeto que implementa a interface ToneMapper .

A interface ToneMapper oferece suporte aos seguintes recursos:

  • Gere uma LUT de mapeamento de tons

    A interface ToneMapper::lookupTonemapGain é uma implementação de CPU do shader definido em libtonemap_LookupTonemapGain() . Isso é usado por testes de unidade na estrutura e pode ser usado por parceiros para assistência na geração de uma LUT de mapeamento de tons dentro de seu pipeline de cores.

    libtonemap_LookupTonemapGain() recebe valores de cores em espaço linear absoluto e não normalizado, tanto em RGB linear quanto em XYZ, e retorna um ponto flutuante descrevendo quanto multiplicar as cores de entrada no espaço linear.

  • Gere um shader SkSL

    A interface ToneMapper::generateTonemapGainShaderSkSL() retorna uma string de shader SkSL, dado um espaço de dados de origem e destino. O shader SkSL está conectado à implementação Skia para RenderEngine , o componente de composição acelerado por GPU para SurfaceFlinger. O shader também está conectado ao libhwui , para que o mapeamento de tons HDR para SDR possa ser executado com eficiência no TextureView . Como a string gerada está alinhada com outros shaders SkSL usados ​​pelo Skia, o shader deve aderir às seguintes regras:

    • A string do shader deve ter um ponto de entrada com a assinatura float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz) , onde linearRGB é o valor dos nits absolutos dos pixels RGB no espaço linear e xyz é linearRGB convertido em XYZ.
    • Quaisquer métodos auxiliares usados ​​pela string do shader devem ser prefixados com a string libtonemap_ para que as definições do shader da estrutura não entrem em conflito. Da mesma forma, os uniformes de entrada devem ser prefixados com in_libtonemap_ .
  • Gerar uniformes SkSL

    A interface ToneMapper::generateShaderSkSLUniforms() retorna o seguinte, dada uma struct de metadados que descreve metadados de diferentes padrões HDR e condições de exibição:

    • Uma lista de uniformes vinculados a um shader SkSL.

    • Os valores uniformes in_libtonemap_displayMaxLuminance e in_libtonemap_inputMaxLuminance . Esses valores são usados ​​pelos shaders de estrutura ao dimensionar a entrada em libtonemap e normalizar a saída conforme aplicável.

    Atualmente o processo de geração de uniformes é independente do espaço de dados de entrada e saída.

Costumização

A implementação de referência da biblioteca libtonemap produz resultados aceitáveis. No entanto, como o algoritmo de mapeamento de tom usado pela composição da GPU pode ser diferente daquele usado pela composição da DPU, o uso da implementação de referência pode causar oscilações em alguns cenários, como na animação de rotação. A personalização pode resolver esses problemas de qualidade de imagem específicos do fornecedor.

Os OEMs são fortemente encorajados a substituir a implementação de libtonemap para definir sua própria subclasse ToneMapper , que é retornada por getToneMapper() . Ao personalizar a implementação, espera-se que os parceiros façam um dos seguintes:

  • Modifique a implementação do libtonemap diretamente.
  • Defina sua própria biblioteca estática, compile a biblioteca como independente e substitua o arquivo .a da biblioteca libtonemap pelo gerado a partir de sua biblioteca personalizada.

Os fornecedores não precisam modificar nenhum código do kernel, mas vários fornecedores devem comunicar detalhes sobre os algoritmos de mapeamento de tons DPU para uma implementação adequada.

Validação

Siga estas etapas para validar sua implementação:

  1. Reproduza vídeos HDR na tela de qualquer padrão HDR compatível com seu sistema de exibição , como HLG, HDR10, HDR10+ ou DolbyVision.

  2. Alterne a composição da GPU para garantir que não haja oscilações perceptíveis pelo usuário.

    Use o seguinte comando adb para alternar a composição da GPU:

    adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
    1 to force GPU composition>
    
    

Problemas comuns

Os seguintes problemas podem ocorrer com esta implementação:

  • As faixas são causadas quando o alvo de renderização usado pela composição da GPU tem precisão inferior ao valor típico do conteúdo HDR. Por exemplo, faixas podem ocorrer quando uma implementação HWC suporta formatos opacos de 10 bits para HDR, como RGBA1010102 ou P010, mas exige que a composição da GPU grave em um formato de 8 bits, como RGBA8888, para suportar alfa.

  • Uma mudança sutil de cor é causada por diferenças de quantização se a DPU operar com uma precisão diferente da GPU.

Cada um desses problemas está relacionado às diferenças relativas de precisão do hardware subjacente. Uma solução alternativa típica é garantir que haja uma etapa de pontilhamento nos caminhos de menor precisão, tornando quaisquer diferenças de precisão menos perceptíveis por humanos.