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 emlibtonemap_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 que descreve 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 paraRenderEngine
, o componente de composição acelerado por GPU para SurfaceFlinger. O shader também está conectado aolibhwui
, para que o mapeamento de tons HDR para SDR possa ser executado com eficiência noTextureView
. 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)
, ondelinearRGB
é o valor dos nits absolutos dos pixels RGB no espaço linear exyz
é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 comin_libtonemap_
.
- A string do shader deve ter um ponto de entrada com a assinatura
Gerar uniformes SkSL
A interface
ToneMapper::generateShaderSkSLUniforms()
retorna o seguinte, dada umastruct
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
ein_libtonemap_inputMaxLuminance
. Esses valores são usados pelos shaders de estrutura ao dimensionar a entrada emlibtonemap
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 bibliotecalibtonemap
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:
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.
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.