Tone Mapping HDR-Helligkeit in einem SDR-kompatiblen Bereich

In Android 13 wird eine vom Anbieter konfigurierbare statische Bibliothek namens libtonemap eingeführt, die Tonzuordnungsvorgänge definiert und für den SurfaceFlinger-Prozess und Hardware Composer-Implementierungen (HWC) freigegeben ist. Mit dieser Funktion können OEMs ihre Algorithmen für das Tone-Mapping von Displays zwischen dem Framework und den Anbietern definieren und freigeben, wodurch eine Diskrepanz beim Tone-Mapping verringert wird.

Vor Android 13 wurden anzeigespezifische Tone-Mapping-Vorgänge nicht zwischen HWC, SurfaceFlinger und Apps geteilt. Je nach Rendering-Pfad führte dies bei HDR-Inhalten zu Abweichungen bei der Bildqualität, da die HDR-Inhalte auf unterschiedliche Weise in einen Ausgabebereich umgewandelt wurden. Dies war in Szenarien wie der Bildschirmrotation spürbar, bei denen sich die Kompositionsstrategie zwischen GPU und DPU ändert, sowie bei Unterschieden im Rendering-Verhalten zwischen TextureView und SurfaceView.

Auf dieser Seite werden die Schnittstelle, die Anpassung und die Validierungsdetails der libtonemap-Bibliothek beschrieben.

Schnittstelle zur Tone-Mapping-Bibliothek

Die Bibliothek libtonemap enthält CPU-basierte Implementierungen und SkSL-Shader, die von SurfaceFlinger für die GPU-basierte Komposition und vom HWC zum Generieren einer LUT (Look-up-Table) für das Tone Mapping verwendet werden können. Der Einstiegspunkt für libtonemap ist android::tonemap::getToneMapper(). Diese Funktion gibt ein Objekt zurück, das die ToneMapper-Schnittstelle implementiert.

Die ToneMapper-Schnittstelle unterstützt die folgenden Funktionen:

  • LUT für Tonzuordnung generieren

    Die Schnittstelle ToneMapper::lookupTonemapGain ist eine CPU-Implementierung des in libtonemap_LookupTonemapGain() definierten Shaders. Sie wird von Unittests im Framework verwendet und kann von Partnern genutzt werden, um eine LUT für das Tone-Mapping in ihrer Farb-Pipeline zu generieren.

    libtonemap_LookupTonemapGain() akzeptiert Farbwerte im absoluten, nicht normalisierten linearen Raum, sowohl in linearem RGB als auch in XYZ, und gibt einen Gleitkommawert zurück, der angibt, um wie viel die Eingabefarben im linearen Raum multipliziert werden sollen.

  • SkSL-Shader generieren

    Die Schnittstelle ToneMapper::generateTonemapGainShaderSkSL() gibt einen SkSL-Shader-String zurück, der auf einem Quell- und einem Ziel-Datenraum basiert. Der SkSL-Shader wird in die Skia-Implementierung für RenderEngine, die GPU-beschleunigte Compositing-Komponente für SurfaceFlinger, eingebunden. Der Shader ist auch mit libhwui verbunden, sodass das HDR-zu-SDR-Tone-Mapping effizient für TextureView durchgeführt werden kann. Da der generierte String in andere SkSL-Shader eingebunden wird, die von Skia verwendet werden, muss der Shader die folgenden Regeln einhalten:

    • Der Shader-String muss einen Einstiegspunkt mit der Signatur float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz) haben, wobei linearRGB der Wert der absoluten Nits der RGB-Pixel im linearen Raum und xyz linearRGB in XYZ umgewandelt ist.
    • Alle Hilfsmethoden, die vom Shader-String verwendet werden, müssen mit dem String libtonemap_ beginnen, damit keine Konflikte mit Framework-Shader-Definitionen entstehen. Eingabe-Uniforms müssen ebenfalls das Präfix in_libtonemap_ haben.
  • SkSL-Uniformen generieren

    Die Schnittstelle ToneMapper::generateShaderSkSLUniforms() gibt Folgendes zurück, wenn ein Metadaten-struct angegeben wird, das Metadaten aus verschiedenen HDR-Standards und Anzeigebedingungen beschreibt:

    • Eine Liste von Uniformen, die an einen SkSL-Shader gebunden sind.

    • Die einheitlichen Werte in_libtonemap_displayMaxLuminance und in_libtonemap_inputMaxLuminance. Diese Werte werden von Framework-Shadern verwendet, wenn die Eingabe in libtonemap skaliert und die Ausgabe normalisiert wird.

    Derzeit ist der Prozess zum Generieren von Uniformen unabhängig vom Ein- und Ausgabedatenraum.

Personalisierung

Die Referenzimplementierung der libtonemap-Bibliothek liefert akzeptable Ergebnisse. Da sich der vom GPU-Compositing verwendete Tone-Mapping-Algorithmus jedoch von dem unterscheiden kann, der vom DPU-Compositing verwendet wird, kann die Verwendung der Referenzimplementierung in einigen Szenarien wie der Rotationsanimation zu Flimmern führen. Durch die Anpassung können solche anbieterspezifischen Probleme mit der Bildqualität behoben werden.

OEMs wird dringend empfohlen, die Implementierung von libtonemap zu überschreiben, um eine eigene ToneMapper-Unterklasse zu definieren, die von getToneMapper() zurückgegeben wird. Bei der Anpassung der Implementierung müssen Partner einen der folgenden Schritte ausführen:

  • Die Implementierung von libtonemap direkt ändern
  • Sie definieren ihre eigene statische Bibliothek, kompilieren die Bibliothek als eigenständige Bibliothek und ersetzen die .a-Datei der libtonemap-Bibliothek durch die Datei, die aus ihrer benutzerdefinierten Bibliothek generiert wurde.

Anbieter müssen keinen Kernel-Code ändern, aber mehrere Anbieter müssen Details zu den DPU-Tone-Mapping-Algorithmen für die richtige Implementierung kommunizieren.

Zertifizierungsstufe

So prüfen Sie Ihre Implementierung:

  1. HDR-Videos werden auf dem Bildschirm in allen HDR-Standards wiedergegeben, die von deinem Anzeigesystem unterstützt werden, z. B. HLG, HDR10, HDR10+ oder Dolby Vision.

  2. Aktivieren oder deaktivieren Sie die GPU-Zusammensetzung, um sicherzustellen, dass kein für den Nutzer wahrnehmbares Flimmern auftritt.

    Verwenden Sie den folgenden adb-Befehl, um die GPU-Zusammensetzung zu aktivieren oder zu deaktivieren:

    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 die folgenden Probleme auftreten:

  • Banding wird verursacht, wenn das von der GPU-Zusammensetzung verwendete Renderziel eine geringere Präzision als der typische Wert für HDR-Inhalte hat. Banding kann beispielsweise auftreten, wenn eine HWC-Implementierung undurchsichtige 10-Bit-Formate für HDR wie RGBA1010102 oder P010 unterstützt, aber für die GPU-Zusammensetzung ein 8-Bit-Format wie RGBA8888 erforderlich ist, um Alpha zu unterstützen.

  • Ein geringfügiger Farbwechsel wird durch Quantisierungsunterschiede verursacht, wenn die DPU mit einer anderen Genauigkeit als die GPU arbeitet.

Jedes dieser Probleme hängt mit den relativen Präzisionsunterschieden der zugrunde liegenden Hardware zusammen. Eine typische Problemumgehung besteht darin, dafür zu sorgen, dass in den Pfaden mit niedrigerer Präzision ein Dithering-Schritt erfolgt, sodass Präzisionsunterschiede für den Menschen weniger wahrnehmbar sind.