Android 13 introduit une bibliothèque statique configurable par le fournisseur, appelée libtonemap
, qui définit les opérations de mappage de tonalités. Elle est partagée avec les implémentations de 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, ce qui réduit les différences de mappage des tons.
Avant Android 13, les opérations de mappage des tons spécifiques à l'écran n'étaient pas partagées entre le HWC, SurfaceFlinger et les applications. Selon le chemin de rendu, pour le contenu HDR, cela a entraîné des différences de qualité d'image, où le contenu HDR a été 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 vers la bibliothèque de mappage des tonalités
La bibliothèque libtonemap
contient des implémentations reposant sur 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 de mappage des tonalités (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
est compatible avec les fonctionnalités suivantes :
Générer une table de correspondance des tons
L'interface
ToneMapper::lookupTonemapGain
est une implémentation du processeur du nuanceur défini danslibtonemap_LookupTonemapGain()
. Cette fonctionnalité est utilisée par les tests unitaires du framework et peut être utilisée par les partenaires pour générer une table de correspondance des tons dans leur pipeline de couleurs.libtonemap_LookupTonemapGain()
prend des valeurs de couleur dans un espace linéaire non normalisé et absolu, à la fois en RVB linéaire et dans XYZ, et renvoie une valeur flottante décrivant la 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, en fonction d'un espace de données source et de destination. Le nuanceur SkSL est branché dans l'implémentation Skia pourRenderEngine
, le composant de composition accéléré par GPU pour SurfaceFlinger. Le nuanceur est également branché àlibhwui
, afin que le mappage des tons HDR/SDR puisse être effectué efficacement 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
est la valeur des nits absolus 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 nuanceur doivent être précédées de la chaîne
libtonemap_
pour que les définitions du nuanceur de framework n'entrent pas en conflit. De même, les uniformes d'entrée doivent être précédés du préfixein_libtonemap_
.
- La chaîne de nuanceur doit comporter un point d'entrée avec la signature
Générer des variables uniformes SkSL
L'interface
ToneMapper::generateShaderSkSLUniforms()
renvoie ce qui suit, en fonction d'unstruct
de métadonnées décrivant les métadonnées de différentes normes HDR et conditions d'affichage:Liste de variables uniformes liées par un nuanceur SkSL.
Les valeurs uniformes
in_libtonemap_displayMaxLuminance
etin_libtonemap_inputMaxLuminance
. Ces valeurs sont utilisées par les nuanceurs de framework lors du scaling de l'entrée danslibtonemap
et de la normalisation de la sortie, le cas échéant.
Actuellement, le processus de génération des variables 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 des 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 entraîner 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 vivement encouragés à remplacer l'implémentation de libtonemap
pour définir leur propre sous-classe ToneMapper
, qui est renvoyée par getToneMapper()
.
Lorsqu'ils personnalisent l'implémentation, les partenaires doivent effectuer l'une des actions suivantes:
- Modifiez directement l'implémentation de
libtonemap
. - Définir sa propre bibliothèque statique, compiler la bibliothèque en tant que autonome et remplacer le fichier
.a
de la bibliothèquelibtonemap
par celui généré à partir de sa 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 tonalités DPU pour une implémentation correcte.
Validation
Pour valider votre implémentation, procédez comme suit :
Lisez des vidéos HDR sur un écran compatible avec n'importe quelle norme HDR compatible avec votre système d'affichage, comme HLG, HDR10, HDR10+ ou DolbyVision.
Activez/Désactivez la composition GPU pour vous assurer qu'il n'y a pas de scepticulation perceptible par l'utilisateur.
Utilisez la commande
adb
suivante pour activer/désactiver la composition GPU:adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition, 1 to force GPU composition>
Problèmes courants
Cette implémentation peut présenter les problèmes suivants:
L'apparition de bandes survient lorsque la cible de rendu utilisée par la composition GPU est moins précise que la valeur typique pour le contenu HDR. Par exemple, l'apparition de bandes peut se produire lorsqu'une mise en œuvre HWC est compatible avec les formats 10 bits opaques pour HDR, tels que RGBA1010102 ou P010, mais nécessite que la composition GPU écrit dans un format 8 bits comme RGBA8888 pour prendre en charge la version alpha.
Un léger décalage 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 à 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'humain.