Hardware Composer HAL implementieren

Der Hardware Composer (HWC) HAL fasst die von SurfaceFlinger empfangenen Ebenen zusammen, wodurch die Menge der Zusammensetzung von OpenGL ES (GLES) und der GPU reduziert wird.

Das HWC abstrahiert Objekte wie Overlays und 2D-Blitters zu zusammengesetzten Objekten. und kommuniziert mit spezieller Schaufensterbau-Hardware, zusammengesetzte Fenster. Verwenden Sie die HWC, um Fenster zu erstellen, SurfaceFlinger-Zusammengesetztes Element mit der GPU. Die meisten GPUs sind nicht für die Komposition optimiert. Wenn die GPU Ebenen aus SurfaceFlinger zusammensetzt, können Apps die GPU nicht für ihr eigenes Rendering verwenden.

HWC-Implementierungen sollten Folgendes unterstützen:

  • Mindestens vier Overlays:
    • Statusleiste
    • Systemleiste
    • App
    • Hintergrund
  • Ebenen, die größer als das Display sind (z. B. ein Hintergrund)
  • Gleichzeitige vormultiplizierte Alphamischung pro Pixel und Alphamischung pro Ebene
  • Hardwarepfad für die Wiedergabe geschützter Videos
  • RGBA-Paketreihenfolge, YUV-Formate sowie Eigenschaften für das Tiling, das Swizzlen und den Schritt

So implementieren Sie die HWC:

  1. Implementieren Sie einen nicht funktionsfähigen HWC und senden Sie alle Zusammenstellungsarbeiten an GLES.
  2. Implementieren Sie einen Algorithmus, um die Komposition schrittweise an die HWC zu delegieren. Delegieren Sie beispielsweise nur die ersten drei oder vier Oberflächen an das Overlay. Hardware der HWC.
  3. HWC optimieren Dazu kann Folgendes gehören:
    • Auswahl von Oberflächen, die die Last von der GPU maximieren und an die HWC senden.
    • Erkennt, ob der Bildschirm aktualisiert wird. Andernfalls delegieren Sie die Komposition an GLES anstelle der HWC, um Strom zu sparen. Wenn sich das Display wieder aktualisiert, lade die Zusammensetzung weiterhin an die HWC aus.
    • Vorbereitung auf gängige Anwendungsfälle wie:
      • Der Startbildschirm, der die Statusleiste, die Systemleiste, die App Fenster- und Live-Hintergründe
      • Spiele im Vollbildmodus im Hoch- und Querformat
      • Vollbildvideo mit Untertiteln und Wiedergabesteuerung
      • Geschützte Videowiedergabe
      • Splitscreen-Multiwindow

HWC-Primitive

HWC bietet zwei Primitive, Layers und Displays, stellen die Kompositionsarbeit und ihre Interaktion mit der Display-Hardware dar. Die HWC bietet auch Kontrolle über VSYNC und einen Callback an SurfaceFlinger. um sie über das Eintreten eines VSYNC-Ereignisses zu informieren.

HIDL-Schnittstelle

Android 8.0 und höher verwenden eine HIDL-Schnittstelle namens Composer HAL für die bindungsorientierte IPC zwischen HWC und SurfaceFlinger. Die Composer HAL ersetzt die bisherige hwcomposer2.h-Benutzeroberfläche. Wenn Anbieter eine Composer HAL-Implementierung der HWC bereitstellen, akzeptiert die Composer HAL HIDL-Aufrufe direkt von SurfaceFlinger. Wenn Anbieter eine ältere Implementierung der HWC bereitstellen, lädt Composer HAL Funktionszeigeter aus hwcomposer2.h und leitet HIDL-Aufrufe an Funktionszeigeraufrufe weiter.

Die HWC bietet Funktionen zum Ermitteln der Eigenschaften eines bestimmten Displays, zum Wechseln zwischen verschiedenen Displaykonfigurationen (z. B. 4K oder 1080p) und Farbmodi (z. B. native Farbe oder echtes sRGB) sowie zum Ein- und Ausschalten des Displays oder zum Aktivieren eines Energiesparmodus, sofern unterstützt.

Funktionszeiger

Wenn Anbieter die Composer HAL direkt implementieren, ruft SurfaceFlinger die Funktionen über HIDL IPC auf. Um eine Ebene zu erstellen, ruft SurfaceFlinger beispielsweise createLayer() in der Composer-HAL.

Wenn Anbieter die hwcomposer2.h-Schnittstelle implementieren, ruft die Composer HAL hwcomposer2.h-Funktionszeigers auf. In hwcomposer2.h Kommentaren, Funktionen der HWC-Schnittstelle sind auf die in CamelCase-Namen verwiesen wird, die in der Oberfläche nicht vorhanden sind, als benannte Felder. Nahezu jede Funktion wird geladen, indem ein Funktionszeiger mit getFunction von hwc2_device_t. Zum Beispiel wird mit der Funktion createLayer ist ein Funktionszeiger vom Typ HWC2_PFN_CREATE_LAYER, der wird zurückgegeben, wenn der Aufzählungswert HWC2_FUNCTION_CREATE_LAYER an getFunction übergeben.

Ausführliche Dokumentation zu Composer-HAL-Funktionen und HWC-Funktionspassthrough finden Sie unter composer. Eine ausführliche Dokumentation zu HWC-Funktionszeigern finden Sie unter hwcomposer2.h.

Ebenen- und Anzeige-Ziehpunkte

Ebenen und Displays werden über vom HWC generierte Handles manipuliert. Die Handles sind für SurfaceFlinger nicht transparent.

Wenn SurfaceFlinger eine neue Ebene erstellt, ruft es createLayer auf, das bei direkten Implementierungen den Typ Layer und bei Passthrough-Implementierungen den Typ hwc2_layer_t zurückgibt. Wann? SurfaceFlinger ändert eine Eigenschaft dieser Ebene, SurfaceFlinger übergibt hwc2_layer_t in die entsprechende Änderungsfunktion ein, sowie alle weiteren Informationen an, die für die Änderung erforderlich sind. Die Der Typ hwc2_layer_t ist groß genug, um einen Zeiger oder einen -Index.

Physische Displays werden durch Hotplugging erstellt. Wenn ein physisches Display Hotplugged erstellt die HWC einen Handle und übergibt ihn an SurfaceFlinger über den Hotplug-Callback. Virtuelle Displays werden von SurfaceFlinger erstellt createVirtualDisplay() wird aufgerufen, um eine Anzeige anzufordern. Wenn die HWC virtuelle Displayzusammensetzung unterstützt, wird ein Handle zurückgegeben. Dann SurfaceFlinger delegiert die Komposition der Bildschirme an HWC. Wenn die HWC die Zusammensetzung des virtuellen Displays nicht unterstützt, erstellt SurfaceFlinger den Handle und stellt das Display zusammen.

Vorgänge zur Displayzusammensetzung

Einmal pro VSYNC wird SurfaceFlinger gestartet, wenn neue Inhalte zusammengesetzt werden müssen. Diese neuen Inhalte können neue Bildpuffer von Apps oder eine Änderung der Eigenschaften einer oder mehrerer Layers. Wenn SurfaceFlinger es aufweckt:

  1. Verwaltet Transaktionen, falls vorhanden.
  2. Öffnet neue Grafikzwischenspeicher, falls vorhanden.
  3. Eine neue Komposition wird durchgeführt, wenn Schritt 1 oder 2 zu einer Änderung geführt hat. zu den Displayinhalten hinzugefügt.

Für eine neue Komposition erstellt SurfaceFlinger zerstört Ebenen oder ändert Ebenenstatus, falls zutreffend. Außerdem werden Ebenen mit ihren aktuellen Inhalten aktualisiert, indem Aufrufe wie setLayerBuffer oder setLayerColor verwendet werden. Nachdem alle Ebenen aktualisiert, ruft SurfaceFlinger validateDisplay auf, der HWC, um den Zustand der Schichten zu untersuchen und zu bestimmen, wie die Zusammensetzung können Sie fortfahren. Standardmäßig versucht SurfaceFlinger, jede Ebene zu konfigurieren. So wird die Schicht aus der HWC zusammengesetzt. aber in einigen SurfaceFlinger erstellt Ebenen über das GPU-Fallback.

Nach dem Aufruf von validateDisplay ruft SurfaceFlinger auf getChangedCompositionTypes, um zu sehen, ob die HWC möchte, dass eine der Ebenenzusammensetzungstypen vor der Durchführung der Zusammensetzung. Um die Änderungen zu akzeptieren, ruft SurfaceFlinger acceptDisplayChanges

Sind Ebenen für die SurfaceFlinger-Zusammensetzung markiert, SurfaceFlinger fügt sie im Zielpuffer zusammen. SurfaceFlinger ruft dann setClientTarget, um den Zwischenspeicher für die Anzeige zu senden, damit der kann auf dem Bildschirm angezeigt oder aus Layern bestehen, nicht für die SurfaceFlinger-Zusammensetzung gekennzeichnet. Wenn keine Ebenen für SurfaceFlinger-Zusammensetzung umgeht SurfaceFlinger.

Schließlich ruft SurfaceFlinger presentDisplay auf, um dem HWC zu signalisieren, dass der Zusammensetzungsprozess abgeschlossen und das Endergebnis angezeigt werden soll.

Mehrere Displays

Android 10 unterstützt mehrere physische Displays. Bei der Entwicklung einer HWC-Implementierung für Android 7.0 und höher gelten einige Einschränkungen, die in der HWC-Definition nicht enthalten sind:

  • Es wird angenommen, dass es genau ein internes Display gibt. Das interne Display ist das Display, das beim Starten vom hotplug-Dienst gemeldet wird. Nachdem das interne Display per Hot-Plug angeschlossen wurde, kann es nicht mehr getrennt werden.
  • Zusätzlich zum internen Display können beliebig viele externe Displays mit Hotplugs verbunden werden während des normalen Betriebs des Geräts. Das Framework geht davon aus, dass alle Hotplugs nach dem ersten internen Display externe Displays sind. Wenn also weitere interne Displays hinzugefügt werden, werden sie fälschlicherweise als Display.TYPE_HDMI statt als Display.TYPE_BUILT_IN kategorisiert.

Während die oben beschriebenen SurfaceFlinger-Operationen werden für alle aktiven Bildschirme nacheinander ausgeführt. auch wenn nur der Inhalt einer Anzeige aktualisiert wird.

Wenn der externe Bildschirm beispielsweise aktualisiert wird, lautet die Reihenfolge:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

Zusammensetzung virtueller Displays

Die Zusammensetzung des virtuellen Displays ähnelt der eines externen Displays. Der Unterschied zwischen der Zusammensetzung virtueller und physischer Bildschirme Displayzusammensetzung besteht darin, dass virtuelle Displays Ausgabe an einen Gralloc-Zwischenspeicher senden. statt auf den Bildschirm. Hardware Composer (HWC) schreibt die Ausgabe in einen Zwischenspeicher. den Abschluss und den Puffer an einen Verbraucher (z. B. Video-Encoder, GPU, CPU usw.). Virtuelle Displays können 2D/Blitter oder Overlays, wenn die Anzeigepipeline in den Arbeitsspeicher schreibt.

Modi

Jeder Frame befindet sich in einem der drei Modi, nachdem SurfaceFlinger die validateDisplay()-HWC-Methode aufgerufen hat:

  • GLES: Die GPU setzt alle Ebenen zusammen und schreibt in den Ausgabepuffer. Der HWC ist nicht an der Komposition beteiligt.
  • MIXED: Die GPU kombiniert einige Ebenen mit dem Framebuffer und HWC kombiniert den Framebuffer mit den verbleibenden Ebenen und schreibt direkt in den Ausgabebuffer.
  • HWC: HWC kombiniert alle Ebenen und schreibt sie direkt in den Ausgabebuffer.

Ausgabeformat

Die Ausgabeformate der virtuellen Anzeigepuffer hängen von ihrem Modus ab:

  • GLES-Modus: Der EGL-Treiber legt das Ausgabebufferformat in dequeueBuffer() fest, normalerweise RGBA_8888. Der Verbraucher muss das vom Treiber festgelegte Ausgabeformat akzeptieren können, da der Puffer sonst nicht gelesen werden kann.
  • MIXED- und HWC-Modi – wenn der Nutzer CPU benötigt legt der Nutzer das Format fest. Andernfalls lautet das Format IMPLEMENTATION_DEFINED und Gralloc legen das beste Format basierend auf Nutzungs-Flags. Beispielsweise legt Gralloc ein YCbCr-Format fest, wenn der Verbraucher ein Videoencoder ist und HWC das Format effizient schreiben kann.

Synchronisierungszäune

Synchronisierungszäune sind ein wichtiger Bestandteil der Android-Grafik System. Mit Fences können CPU-Arbeiten unabhängig von gleichzeitigen GPU-Arbeiten ausgeführt werden. Sie werden nur blockiert, wenn eine echte Abhängigkeit besteht.

Wenn eine Anwendung beispielsweise einen Zwischenspeicher einreicht, an die GPU sendet, sendet sie auch ein Sync-Fence-Objekt. Dieser Zaun signalisiert, GPU hat das Schreiben in den Zwischenspeicher abgeschlossen.

Der HWC erfordert, dass die GPU das Schreiben von Buffers beendet, bevor Buffers angezeigt werden. Synchronisationsschranken werden mit Buffers durch die Grafikpipeline übergeben und signalisieren, wenn Buffers geschrieben werden. Bevor ein Puffer angezeigt wird, prüft der HWC, ob der Synchronisierungs-Fence ein Signal gesendet hat. Ist das der Fall, wird der Puffer angezeigt.

Weitere Informationen zu Synchronisierungszäunen finden Sie unter Hardware Composer. Integration: