Android 13 introduit une bibliothèque statique configurable par le fournisseur appelée libtonemap
, qui définit les opérations de mappage de tonalité et est partagée avec le processus SurfaceFlinger et les implémentations Hardware Composer (HWC).
Cette fonctionnalité permet aux OEM de définir et de partager leurs algorithmes de mappage de tonalité d'écran entre le framework et les fournisseurs, ce qui réduit les incohérences de mappage de tonalité.
Avant Android 13, les opérations de mappage de tonalité spécifiques à l'écran n'étaient pas partagées entre HWC, SurfaceFlinger et les applications. En fonction du chemin de rendu, cela entraînait des différences de qualité d'image pour le contenu HDR, où le contenu HDR était mappé sur un espace de sortie de différentes manières. 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 l'interface, la personnalisation et les détails de validation de la bibliothèque libtonemap
.
Interface de la bibliothèque de mappage de tonalités
La bibliothèque libtonemap
contient des implémentations soutenues par le processeur et des nuanceurs SkSL, qui peuvent être branchés par SurfaceFlinger pour la composition du backend GPU et par le HWC pour générer une table de recherche (LUT) de mappage de tonalité. Le point d'entrée de libtonemap
est android::tonemap::getToneMapper()
, qui renvoie un objet implémentant l'interface ToneMapper
.
L'interface ToneMapper
est compatible avec les fonctionnalités suivantes :
Générer un LUT de mappage de tonalité
L'interface
ToneMapper::lookupTonemapGain
est une implémentation CPU du nuanceur défini danslibtonemap_LookupTonemapGain()
. Il est utilisé par les tests unitaires du framework et peut être utilisé par les partenaires pour obtenir de l'aide concernant la génération d'une LUT de mappage de tonalité dans leur pipeline de couleurs.libtonemap_LookupTonemapGain()
accepte 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 float décrivant le facteur de multiplication des couleurs d'entrée dans l'espace linéaire.Générer un nuanceur SkSL
L'interface
ToneMapper::generateTonemapGainShaderSkSL()
renvoie une chaîne de nuanceur SkSL, étant donné un espace de données source et de destination. Le nuanceur SkSL est intégré à l'implémentation Skia pourRenderEngine
, le composant de composition accéléré par GPU pour SurfaceFlinger. Le nuanceur est également branché surlibhwui
, ce qui permet d'effectuer efficacement le mappage des tons HDR vers SDR pourTextureView
. Étant donné que la chaîne générée est intégrée à d'autres nuanceurs SkSL utilisés par Skia, le nuanceur doit respecter les règles suivantes :- La chaîne de nuanceur doit comporter un point d'entrée avec la signature
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)
, oùlinearRGB
correspond à la valeur des nits absolus des pixels RVB dans l'espace linéaire etxyz
correspond àlinearRGB
converti en XYZ. - Toutes les méthodes d'assistance utilisées par la chaîne de nuanceur doivent être précédées de la chaîne
libtonemap_
afin que les définitions de nuanceur du framework ne soient pas en conflit. De même, les uniformes d'entrée doivent être précédés dein_libtonemap_
.
- La chaîne de nuanceur doit comporter un point d'entrée avec la signature
Générer des uniformes SkSL
L'interface
ToneMapper::generateShaderSkSLUniforms()
renvoie les éléments suivants, étant donné unstruct
de métadonnées décrivant les métadonnées de différentes normes HDR et conditions d'affichage :Liste des uniforms liés par un nuanceur SkSL.
Les valeurs uniformes
in_libtonemap_displayMaxLuminance
etin_libtonemap_inputMaxLuminance
. Ces valeurs sont utilisées par les nuanceurs de 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. Toutefois, comme l'algorithme de mappage de tonalité 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 entraîner un scintillement dans certains scénarios, comme l'animation de rotation. La personnalisation peut résoudre ces problèmes de qualité d'image spécifiques aux fournisseurs.
Nous encourageons vivement les OEM à 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 l'implémentation, 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 en tant que bibliothèque 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 informations sur les algorithmes de mappage de tonalités DPU pour une implémentation correcte.
Validation
Pour valider votre implémentation, procédez comme suit :
Regardez des vidéos HDR sur un écran compatible avec les normes HDR de votre système d'affichage, comme HLG, HDR10, HDR10+ ou Dolby Vision.
Activez la composition GPU pour vous assurer qu'il n'y a pas de scintillement perceptible par l'utilisateur.
Utilisez la commande
adb
suivante pour activer ou désactiver 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 :
Les bandes sont dues au fait que la cible de rendu utilisée par la composition du GPU est de précision inférieure à la valeur typique pour le contenu HDR. Par exemple, des bandes peuvent apparaître lorsqu'une implémentation HWC prend en charge les formats HDR opaques 10 bits tels que RGBA1010102 ou P010, mais exige que la composition GPU écrive dans un format 8 bits tel que RGBA8888 pour prendre en charge le canal alpha.
Un léger changement de couleur est dû à des différences de quantification si la 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 classique consiste à s'assurer qu'il existe une étape de tramage dans les chemins de précision inférieure, ce qui rend les différences de précision moins perceptibles par l'homme.