Android 13 führt eine vom Hersteller konfigurierbare statische Bibliothek namens libtonemap
ein, die Tone-Mapping-Operationen definiert und mit dem SurfaceFlinger-Prozess und Hardware Composer (HWC)-Implementierungen geteilt wird. Mit dieser Funktion können OEMs ihre Display-Ton-Mapping-Algorithmen definieren und zwischen dem Framework und den Anbietern teilen, wodurch eine Nichtübereinstimmung bei der Tone-Mapping verringert wird.
Vor Android 13 wurden anzeigespezifische Tonzuordnungsvorgänge nicht zwischen HWC, SurfaceFlinger und Apps geteilt. Abhängig vom Rendering-Pfad führte dies bei HDR-Inhalten zu Unstimmigkeiten in der Bildqualität, da der HDR-Inhalt auf unterschiedliche Weise farblich einem Ausgaberaum zugeordnet wurde. Dies machte sich in Szenarien wie der Bildschirmrotation bemerkbar, bei denen sich die Kompositionsstrategie zwischen der GPU und der DPU ändert, und in Unterschieden im Renderverhalten zwischen TextureView und SurfaceView.
Auf dieser Seite werden die Schnittstellen-, Anpassungs- und Validierungsdetails der libtonemap
Bibliothek beschrieben.
Schnittstelle zur Tone-Mapping-Bibliothek
Die libtonemap
Bibliothek enthält CPU-gestützte Implementierungen und SkSL-Shader, die von SurfaceFlinger für die GPU-Backend-Komposition und vom HWC zum Generieren einer Tone-Mapping-Lookup-Tabelle (LUT) eingebunden werden können. Der Einstiegspunkt für libtonemap
ist android::tonemap::getToneMapper()
, der ein Objekt zurückgibt, das die ToneMapper
Schnittstelle implementiert.
Die ToneMapper
Schnittstelle unterstützt die folgenden Funktionen:
Generieren Sie eine Tone-Mapping-LUT
Die Schnittstelle
ToneMapper::lookupTonemapGain
ist eine CPU-Implementierung des inlibtonemap_LookupTonemapGain()
definierten Shaders. Dies wird von Unit-Tests im Framework verwendet und kann von Partnern zur Unterstützung bei der Generierung einer Tone-Mapping-LUT innerhalb ihrer Farbpipeline verwendet werden.libtonemap_LookupTonemapGain()
nimmt Farbwerte im absoluten, nicht normalisierten linearen Raum auf, sowohl im linearen RGB als auch in XYZ, und gibt einen Gleitkommawert zurück, der beschreibt, wie viel die Eingabefarben im linearen Raum multipliziert werden sollen.Generieren Sie einen SkSL-Shader
Die Schnittstelle
ToneMapper::generateTonemapGainShaderSkSL()
gibt bei gegebenem Quell- und Zieldatenraum einen SkSL-Shader-String zurück. Der SkSL-Shader ist in die Skia-Implementierung fürRenderEngine
eingebunden, die GPU-beschleunigte Compositing-Komponente für SurfaceFlinger. Der Shader ist auch inlibhwui
eingebunden, sodass die HDR-zu-SDR-Tonzuordnung fürTextureView
effizient durchgeführt werden kann. Da die generierte Zeichenfolge in andere von Skia verwendete SkSL-Shader eingefügt wird, muss der Shader die folgenden Regeln einhalten:- Die Shader-Zeichenfolge muss einen Einstiegspunkt mit der
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)
haben, wobeilinearRGB
der Wert der absoluten Nits der RGB-Pixel im linearen Raum undxyz
der in XYZ konvertiertelinearRGB
Wert ist. - Allen von der Shader-Zeichenfolge verwendeten Hilfsmethoden muss die Zeichenfolge
libtonemap_
vorangestellt werden, damit Framework-Shader-Definitionen nicht in Konflikt geraten. Ebenso muss den Eingabeuniformenin_libtonemap_
vorangestellt werden.
- Die Shader-Zeichenfolge muss einen Einstiegspunkt mit der
Generieren Sie SkSL-Uniformen
Die Schnittstelle
ToneMapper::generateShaderSkSLUniforms()
gibt Folgendes zurück, wenn einestruct
gegeben ist, die Metadaten aus verschiedenen HDR-Standards und Anzeigebedingungen beschreibt:Eine Liste von Uniformen, die durch einen SkSL-Shader gebunden sind.
Die einheitlichen Werte
in_libtonemap_displayMaxLuminance
undin_libtonemap_inputMaxLuminance
. Diese Werte werden von Framework-Shadern verwendet, wenn sie die Eingabe inlibtonemap
skalieren und die Ausgabe gegebenenfalls normalisieren.
Derzeit ist der Prozess der Generierung von Uniformen unabhängig vom Eingabe- und Ausgabedatenraum.
Anpassung
Die Referenzimplementierung der libtonemap
Bibliothek liefert akzeptable Ergebnisse. Da sich der von der GPU-Komposition verwendete Tonzuordnungsalgorithmus jedoch von dem von der DPU-Komposition verwendeten unterscheiden kann, kann die Verwendung der Referenzimplementierung in einigen Szenarios wie der Rotationsanimation zu Flimmern führen. Durch Anpassung können solche herstellerspezifischen Bildqualitätsprobleme behoben werden.
OEMs wird dringend empfohlen, die Implementierung von libtonemap
zu überschreiben, um ihre eigene ToneMapper
Unterklasse zu definieren, die von getToneMapper()
zurückgegeben wird. Bei der Anpassung der Implementierung wird von den Partnern erwartet, dass sie einen der folgenden Schritte ausführen:
- Ändern Sie die Implementierung von
libtonemap
direkt. - Definieren Sie ihre eigene statische Bibliothek, kompilieren Sie die Bibliothek als eigenständige Bibliothek und ersetzen Sie die
.a
Dateilibtonemap
Bibliothek durch die aus ihrer benutzerdefinierten Bibliothek generierte Datei.
Anbieter müssen keinen Kernel-Code ändern, aber mehrere Anbieter müssen Details zu den DPU-Ton-Mapping-Algorithmen für eine ordnungsgemäße Implementierung kommunizieren.
Validierung
Befolgen Sie diese Schritte, um Ihre Implementierung zu validieren:
Spielen Sie HDR-Videos auf dem Bildschirm aller HDR-Standards ab, die Ihr Anzeigesystem unterstützt , z. B. HLG, HDR10, HDR10+ oder DolbyVision.
Schalten Sie die GPU-Zusammensetzung um, um sicherzustellen, dass kein vom Benutzer wahrnehmbares Flimmern auftritt.
Verwenden Sie den folgenden
adb
Befehl, um die GPU-Zusammensetzung umzuschalten:adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition, 1 to force GPU composition>
Häufige Probleme
Bei dieser Implementierung können folgende Probleme auftreten:
Streifenbildung wird verursacht, wenn das von der GPU-Komposition verwendete Renderziel eine geringere Präzision aufweist als der typische Wert für HDR-Inhalte. Beispielsweise kann es zu Streifenbildung kommen, wenn eine HWC-Implementierung undurchsichtige 10-Bit-Formate für HDR wie RGBA1010102 oder P010 unterstützt, aber erfordert, dass die GPU-Komposition in ein 8-Bit-Format wie RGBA8888 schreibt, um Alpha zu unterstützen.
Eine geringfügige Farbverschiebung wird durch Quantisierungsunterschiede verursacht, wenn die DPU mit einer anderen Präzision arbeitet als die GPU.
Jedes dieser Probleme hängt mit den relativen Präzisionsunterschieden der zugrunde liegenden Hardware zusammen. Eine typische Problemumgehung besteht darin, sicherzustellen, dass in den Pfaden mit geringerer Präzision ein Dithering-Schritt vorhanden ist, wodurch Präzisionsunterschiede für den Menschen weniger wahrnehmbar werden.