Hardware Composer-HAL implementieren

Die HWC-HAL-Zusammengesetzten Schichten aus dem Hardware Composer (HWC), die von SurfaceFlinger, wodurch die Menge der Zusammensetzung von OpenGL ES (GLES) und der GPU-Leistung reduziert wird.

Das HWC abstrahiert Objekte wie Overlays und 2D-Blitters zu zusammengesetzten Elementen. 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 und wenn die GPU Schichten aus SurfaceFlinger, können Anwendungen 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 vorabmultiplizierte Alpha-Blending-Funktion pro Pixel und pro Ebene Alpha-Überblendung
  • Hardwarepfad für die geschützte Videowiedergabe
  • RGBA-Paketreihenfolge, YUV-Formate sowie Eigenschaften für das Tiling, das Swizzlen und den Schritt

So implementieren Sie die HWC:

  1. Eine nicht betriebsbereite HWC implementieren und alle Kompositionsarbeiten senden an GLES
  2. Implementieren Sie einen Algorithmus, um die Zusammensetzung inkrementell 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:
    • Auswählen von Oberflächen, die die von der GPU entlastete Last maximieren an das HWC senden.
    • Erkennen, ob der Bildschirm aktualisiert wird Falls nicht, delegieren Sie in GLES statt in HWC, um Energie zu sparen. Wenn das Display mit der Zusammensetzung an die HWC.
    • Vorbereitung auf gängige Anwendungsfälle wie:
      • Der Startbildschirm mit der Statusleiste, der Systemleiste, der App Fenster- und Live-Hintergründe
      • Spiele im Vollbildmodus im Hoch- und Querformat
      • Vollbildvideo mit Untertiteln und Wiedergabe Kontrollgruppe
      • Wiedergabe geschützter Videos
      • Splitscreen-Mehrfenstermodus

HWC-Primitive

HWC bietet zwei Primitive, Layers und Displays, stellen die Kompositionsarbeit und ihre Interaktion mit der Display-Hardware dar. Der HWC bietet auch eine Steuerung für VSYNC und einen Rückruf an SurfaceFlinger, um ihn über ein VSYNC-Ereignis zu benachrichtigen.

HIDL-Schnittstelle

Android 8.0 und höher verwenden eine HIDL-Schnittstelle namens Composer HAL für die bindungsbasierte IPC zwischen HWC und SurfaceFlinger. Der Composer-HAL ersetzt die alte hwcomposer2.h-Oberfläche. Wenn Anbieter einen Composer-HAL bereitstellen HWC-Implementierung von Composer HAL akzeptiert, nimmt Composer HAL direkt HIDL-Aufrufe von SurfaceFlinger. Wenn Anbieter eine Legacy-Implementierung der HWC bereitstellen, HAL lädt Funktionszeiger aus hwcomposer2.h, Weiterleitung von HIDL-Aufrufen an Funktionszeigeraufrufe.

HWC bietet Funktionen zum Ermitteln der Eigenschaften einer bestimmten Anzeige. bis zwischen verschiedenen Displaykonfigurationen wie 4K oder 1080p wechseln Auflösung) und Farbmodi (z. B. native Farbe oder echtes sRGB) und um das Display ein- oder ausschalten oder in einen Energiesparmodus wechseln, falls dies unterstützt wird.

Funktionszeiger

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

Wenn Anbieter die hwcomposer2.h-Schnittstelle implementieren, stellt Composer HAL in hwcomposer2.h-Funktionszeiger umgewandelt. 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. So kann z. B. die 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 HWC-Funktionszeiger, siehe hwcomposer2.h

Ebenen- und Anzeige-Ziehpunkte

Ebenen und Darstellungen werden mithilfe von Ziehpunkten bearbeitet, die von der HWC generiert werden. Die Ziehpunkte sind für SurfaceFlinger undurchsichtig.

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 anderen Informationen, die für die Änderung erforderlich sind. Der Typ hwc2_layer_t ist groß genug, um entweder einen Verweis oder einen Index zu enthalten.

Physische Bildschirme werden durch Hotplugting 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. Anschließend delegiert SurfaceFlinger die Zusammensetzung der Displays an die HWC. Wenn die HWC keine virtuellen Displayzusammensetzung erstellt SurfaceFlinger den Handle und setzt 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 aktiviert den Ruhemodus:

  1. Verarbeitet 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 wird sie aktualisiert Layern mit ihrem aktuellen Inhalt, indem sie Aufrufe wie setLayerBuffer oder setLayerColor. Nachdem alle Ebenen aktualisiert wurden, ruft SurfaceFlinger validateDisplay auf, wodurch die HWC aufgefordert wird, den Status der Ebenen zu prüfen und zu bestimmen, wie die Zusammensetzung fortgesetzt wird. 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. Beim Entwerfen einer HWC-Implementierung, die für die Verwendung unter Android 7.0 und gibt es einige Einschränkungen, die in der HWC-Definition nicht enthalten sind:

  • Es wird angenommen, dass es genau ein internes Display gibt. Das interne ist die Anzeige, die der erste Hotplug während starten. Wenn das interne Display mit einem Hotplug verbunden wurde, kann es nicht verbunden 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, Die Hotplugs nach dem ersten internen Display sind externe Displays. internen Displays hinzugefügt wurden, wurden sie fälschlicherweise Display.TYPE_HDMI statt Display.TYPE_BUILT_IN.

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 der virtuellen Anzeige

Zusammensetzung des virtuellen Displays ähnelt der Zusammensetzung des externen Displays Zusammensetzung. 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 verwenden, wenn die Displaypipeline in den Arbeitsspeicher schreibt.

Modi

Jeder Frame befindet sich in einem von drei Modi, nachdem SurfaceFlinger den validateDisplay() HWC-Methode:

  • GLES: Die GPU kombiniert alle Ebenen und schreibt direkt in den Ausgabebuffer. Die 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 den Ausgabepuffer fest. Format dequeueBuffer(), normalerweise RGBA_8888. Der Nutzer muss das Ausgabeformat akzeptieren können, das vom Treiber festgelegt oder vom Zwischenspeicher kann nicht gelesen werden.
  • 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. Beispiel: Gralloc legt ein YCbCr-Format fest, wenn der Nutzer Video-Encoder und HWC können das Format effizient schreiben.

Synchronisierungszäune

Synchronisierungszäune sind ein wichtiger Bestandteil der Android-Grafik System. Durch Zäune funktioniert die CPU unabhängig von der gleichzeitigen GPU-Arbeit. 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.

Die HWC erfordert, dass die GPU den Schreibpuffer beendet, bevor die Zwischenspeicher verarbeitet werden. angezeigt. Synchronisierungszäune werden mit Puffern durch die Grafikpipeline geleitet und signalisieren, wenn Puffer geschrieben werden. Bevor ein Puffer angezeigt wird, überprüft, ob der Synchronisierungszaun signalisiert hat. Ist dies der Fall, wird der Puffer.

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