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:
- Implementieren Sie einen nicht funktionsfähigen HWC und senden Sie alle Zusammenstellungsarbeiten an GLES.
- 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.
- 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:
- Verwaltet Transaktionen, falls vorhanden.
- Öffnet neue Grafikzwischenspeicher, falls vorhanden.
- 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 alsDisplay.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, normalerweiseRGBA_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: