Android 13 introduit une bibliothèque statique configurable par le fournisseur appelée libtonemap
, qui définit les opérations de mappage de tons et est partagée avec les implémentations du processus SurfaceFlinger et de Hardware Composer (HWC). Cette fonctionnalité permet aux OEM de définir et de partager leurs algorithmes de mappage des tons d'affichage entre le framework et les fournisseurs, réduisant ainsi les écarts de mappage des tons.
Avant Android 13, les opérations de mappage de tons spécifiques à l'affichage n'étaient pas partagées entre HWC, SurfaceFlinger et les applications. En fonction du chemin de rendu, pour le contenu HDR, cela entraînait des différences de qualité d'image, le contenu HDR étant mappé de différentes manières sur un espace de sortie. Cela était perceptible dans des scénarios tels que la rotation de l'écran, où la stratégie de composition change entre le GPU et le DPU, et dans les différences de comportement de rendu entre TextureView et SurfaceView.
Cette page décrit les détails de l'interface, de la personnalisation et de la validation de la bibliothèque libtonemap
.
Interface vers la bibliothèque de mappage de tons
La bibliothèque libtonemap
contient des implémentations soutenues par le CPU et des shaders SkSL, qui peuvent être branchés par SurfaceFlinger pour la composition GPU-backend et par le HWC pour générer une table de recherche de mappage de tons (LUT). Le point d'entrée de libtonemap
est android::tonemap::getToneMapper()
, qui renvoie un objet qui implémente l'interface ToneMapper
.
L'interface ToneMapper
prend en charge les fonctionnalités suivantes :
Générer une LUT de mappage de tons
L'interface
ToneMapper::lookupTonemapGain
est une implémentation CPU du shader défini danslibtonemap_LookupTonemapGain()
. Ceci est utilisé par les tests unitaires dans le cadre et peut être utilisé par les partenaires pour les aider à générer une LUT de mappage de tons dans leur pipeline de couleurs.libtonemap_LookupTonemapGain()
prend les valeurs de couleur dans un espace linéaire absolu et non normalisé, à la fois en RVB linéaire et en XYZ, et renvoie un flottant décrivant combien multiplier les couleurs d'entrée dans l'espace linéaire.Générer un shader SkSL
L'interface
ToneMapper::generateTonemapGainShaderSkSL()
renvoie une chaîne de shader SkSL, étant donné un espace de données source et destination. Le shader SkSL est connecté à l'implémentation Skia pourRenderEngine
, le composant de composition accéléré par GPU pour SurfaceFlinger. Le shader est également connecté àlibhwui
, afin que le mappage de tons HDR vers SDR puisse être effectué efficacement pourTextureView
. Étant donné que la chaîne générée est intégrée à d'autres shaders SkSL utilisés par Skia, le shader doit respecter les règles suivantes :- La chaîne de shader doit avoir un point d'entrée avec la signature
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)
, oùlinearRGB
est la valeur des lentes absolues des pixels RVB dans l'espace linéaire etxyz
estlinearRGB
converti en XYZ. - Toutes les méthodes d'assistance utilisées par la chaîne du shader doivent être préfixées par la chaîne
libtonemap_
afin que les définitions du shader du framework n'entrent pas en conflit. De même, les uniformes d'entrée doivent être préfixés parin_libtonemap_
.
- La chaîne de shader doit avoir un point d'entrée avec la signature
Générer des uniformes SkSL
L'interface
ToneMapper::generateShaderSkSLUniforms()
renvoie ce qui suit, étant donné unestruct
de métadonnées décrivant les métadonnées de différentes normes HDR et conditions d'affichage :Une liste d'uniformes liés par un shader SkSL.
Les valeurs uniformes
in_libtonemap_displayMaxLuminance
etin_libtonemap_inputMaxLuminance
. Ces valeurs sont utilisées par les shaders du framework lors de la mise à l'échelle de l'entrée danslibtonemap
et de la normalisation de la sortie, le cas échéant.
Actuellement, le processus de génération d'uniformes est indépendant de l'espace de données d'entrée et de sortie.
Personnalisation
L'implémentation de référence de la bibliothèque libtonemap
produit des résultats acceptables. Cependant, étant donné que l'algorithme de mappage de tons utilisé par la composition GPU peut différer de celui utilisé par la composition DPU, l'utilisation de l'implémentation de référence peut provoquer un scintillement dans certains scénarios tels que l'animation de rotation. La personnalisation peut résoudre ces problèmes de qualité d’image spécifiques au fournisseur.
Les OEM sont fortement encouragés à remplacer l'implémentation de libtonemap
pour définir leur propre sous-classe ToneMapper
, qui est renvoyée par getToneMapper()
. Lors de la personnalisation de la mise en œuvre, les partenaires doivent effectuer l'une des opérations suivantes :
- Modifiez directement l'implémentation de
libtonemap
. - Définissez leur propre bibliothèque statique, compilez la bibliothèque de manière autonome et remplacez le fichier
.a
de la bibliothèquelibtonemap
par celui généré à partir de leur bibliothèque personnalisée.
Les fournisseurs n'ont pas besoin de modifier le code du noyau, mais plusieurs fournisseurs doivent communiquer des détails sur les algorithmes de mappage de tons DPU pour une mise en œuvre correcte.
Validation
Suivez ces étapes pour valider votre implémentation :
Lisez des vidéos HDR sur un écran selon toutes les normes HDR prises en charge par votre système d'affichage , telles que HLG, HDR10, HDR10+ ou DolbyVision.
Basculez la composition du GPU pour garantir qu'il n'y a pas de scintillement perceptible par l'utilisateur.
Utilisez la commande
adb
suivante pour modifier la composition du GPU :adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition, 1 to force GPU composition>
Problèmes courants
Les problèmes suivants peuvent survenir avec cette implémentation :
Le banding se produit lorsque la cible de rendu utilisée par la composition GPU est d'une précision inférieure à la valeur typique du contenu HDR. Par exemple, des bandes peuvent se produire lorsqu'une implémentation HWC prend en charge les formats opaques 10 bits pour HDR tels que RGBA1010102 ou P010, mais nécessite que la composition GPU écrive dans un format 8 bits comme RGBA8888 pour prendre en charge l'alpha.
Un subtil changement de couleur est causé par des différences de quantification si le DPU fonctionne avec une précision différente de celle du GPU.
Chacun de ces problèmes est lié aux différences de précision relative du matériel sous-jacent. Une solution de contournement typique consiste à garantir qu'il existe une étape de tramage dans les chemins de précision inférieure, rendant les différences de précision moins perceptibles par l'homme.