Tonzuordnung der HDR-Luminanz zu einem SDR-kompatiblen Bereich

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 in libtonemap_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ür RenderEngine eingebunden, die GPU-beschleunigte Compositing-Komponente für SurfaceFlinger. Der Shader ist auch in libhwui eingebunden, sodass die HDR-zu-SDR-Tonzuordnung für TextureView 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, wobei linearRGB der Wert der absoluten Nits der RGB-Pixel im linearen Raum und xyz der in XYZ konvertierte linearRGB 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 Eingabeuniformen in_libtonemap_ vorangestellt werden.
  • Generieren Sie SkSL-Uniformen

    Die Schnittstelle ToneMapper::generateShaderSkSLUniforms() gibt Folgendes zurück, wenn eine struct 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 und in_libtonemap_inputMaxLuminance . Diese Werte werden von Framework-Shadern verwendet, wenn sie die Eingabe in libtonemap 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 Datei libtonemap 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:

  1. Spielen Sie HDR-Videos auf dem Bildschirm aller HDR-Standards ab, die Ihr Anzeigesystem unterstützt , z. B. HLG, HDR10, HDR10+ oder DolbyVision.

  2. 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.