Ebenen und Displays

Ebenen und Displays sind zwei Primitive, die die Zusammensetzung und Interaktionen mit der Displayhardware darstellen.

Ebenen

Eine Ebene ist die wichtigste Einheit der Komposition. Eine Ebene ist eine Kombination aus einer Fläche und einer Instanz von SurfaceControl. Jede Ebene hat eine Reihe von Eigenschaften, die definieren, wie sie mit anderen Ebenen interagiert. Die Ebeneneigenschaften werden in der folgenden Tabelle beschrieben.

Attribut Beschreibung
Positionsbezogen Definiert, wo die Ebene auf ihrer Anzeige angezeigt wird. Enthält Informationen wie die Positionen der Kanten einer Ebene und ihre Z-Reihenfolge relativ zu anderen Ebenen (ob sie vor oder hinter anderen Ebenen liegen soll).
Content Hiermit wird festgelegt, wie die auf der Ebene angezeigten Inhalte innerhalb der durch die Positionierungseigenschaften definierten Grenzen dargestellt werden sollen. Enthält Informationen wie „Zuschneiden“ (um einen Teil des Inhalts so zu vergrößern, dass er die Grenzen der Ebene füllt) und „Transformieren“ (um gedrehte oder gespiegelte Inhalte anzuzeigen).
Komposition Hier wird festgelegt, wie die Ebene mit anderen Ebenen kombiniert werden soll. Enthält Informationen wie den Mischmodus und einen schichtweiten Alphawert für die Alphakomposition.
Optimierung Bietet Informationen, die nicht unbedingt für die korrekte Zusammensetzung der Ebene erforderlich sind, aber vom Hardware Composer (HWC) verwendet werden können, um die Zusammensetzung zu optimieren. Enthält Informationen wie den sichtbaren Bereich der Ebene und welcher Teil der Ebene seit dem vorherigen Frame aktualisiert wurde.

Displays

Display ist eine weitere wichtige Zusammensetzung. Ein System kann mehrere Bildschirme haben und Bildschirme können während des normalen Systembetriebs hinzugefügt oder entfernt werden. Bildschirme werden auf Anfrage der HWC oder auf Anfrage des Frameworks hinzugefügt bzw. entfernt. Das HWC-Gerät fordert das Hinzufügen oder Entfernen von Displays an, wenn ein externes Display mit dem Gerät verbunden oder getrennt wird. Dies wird als Hotplugging bezeichnet. Clients fordern virtuelle Displays an, deren Inhalte in einem Zwischenspeicher außerhalb des Bildschirms und nicht auf einem physischen Bildschirm gerendert werden.

Virtuelle Displays

SurfaceFlinger unterstützt einen internen Bildschirm (in das Smartphone oder Tablet integriert), externe Bildschirme (z. B. einen über HDMI verbundenen Fernseher) und einen oder mehrere virtuelle Bildschirme, die eine zusammengesetzte Ausgabe ermöglichen. Virtuelle Displays können verwendet werden, um den Bildschirm aufzunehmen oder über ein Netzwerk zu senden. Für ein virtuelles Display generierte Frames werden in eine BufferQueue geschrieben.

Virtuelle Displays können dieselben Ebenen wie das Hauptdisplay (Ebenenstapel) verwenden oder eigene Ebenen haben. Für ein virtuelles Display gibt es keine VSYNC-Funktion. Daher löst die VSYNC-Funktion für das interne Display die Zusammensetzung für alle Displays aus.

In HWC-Implementierungen, die diese unterstützen, können virtuelle Displays mit OpenGL ES (GLES), HWC oder sowohl GLES als auch HWC erstellt werden. Bei nicht unterstützten Implementierungen werden virtuelle Displays immer mit GLES zusammengesetzt.

Fallstudie: screenrecord

Mit dem Befehl screenrecord kann der Nutzer alles auf dem Bildschirm als .mp4-Datei auf dem Laufwerk aufzeichnen. Dazu empfängt das System zusammengesetzte Frames von SurfaceFlinger, schreibt sie in den Videoencoder und dann die codierten Videodaten in eine Datei. Die Videocodecs werden von einem separaten Prozess (mediaserver) verwaltet, sodass große Grafik-Buffer im System bewegt werden müssen. Das Ziel ist es, Videos mit 60 fps bei voller Auflösung aufzunehmen. Der Schlüssel für eine effiziente Umsetzung ist BufferQueue.

Mit der Klasse MediaCodec kann eine App Daten als Rohbytes in Puffern oder über eine Oberfläche bereitstellen. Wenn screenrecord Zugriff auf einen Videoencoder anfordert, erstellt der mediaserver-Prozess eine BufferQueue, stellt eine Verbindung zur Verbraucherseite her und gibt die Produzentenseite dann als Oberfläche an screenrecord zurück.

Das screenrecord-Dienstprogramm bittet dann SurfaceFlinger, ein virtuelles Display zu erstellen, das das Hauptdisplay spiegelt (d. h. es hat alle gleichen Ebenen) und es anzuweisen, die Ausgabe an die Oberfläche zu senden, die aus dem mediaserver-Prozess stammt. In diesem Fall ist SurfaceFlinger der Ersteller von Puffern und nicht der Nutzer.

Nach Abschluss der Konfiguration wird screenrecord ausgelöst, wenn die codierten Daten angezeigt werden. Während Apps gezeichnet werden, werden ihre Buffers an SurfaceFlinger gesendet, der sie zu einem einzigen Buffer zusammensetzt, der im mediaserver-Prozess direkt an den Videoencoder gesendet wird. Die vollständigen Frames werden vom screenrecord-Prozess nie gesehen. Intern hat der mediaserver-Prozess eine eigene Methode zum Verschieben von Puffern, die auch Daten per Handle übergibt, wodurch der Overhead minimiert wird.

Fallstudie: Sekundäre Displays simulieren

Der WindowManager kann SurfaceFlinger bitten, eine sichtbare Ebene zu erstellen, für die SurfaceFlinger als BufferQueue-Konsument fungiert. Es ist auch möglich, SurfaceFlinger zu bitten, ein virtuelles Display zu erstellen, für das SurfaceFlinger als BufferQueue-Produzent fungiert.

Wenn Sie ein virtuelles Display mit einer sichtbaren Ebene verbinden, wird ein geschlossener Loop erstellt, in dem der zusammengesetzte Bildschirm in einem Fenster angezeigt wird. Dieses Fenster ist jetzt Teil der zusammengesetzten Ausgabe. Bei der nächsten Aktualisierung enthält das zusammengesetzte Bild im Fenster also auch den Fensterinhalt. Wenn Sie sich das ansehen möchten, aktivieren Sie in den Einstellungen die Entwickleroptionen, wählen Sie Sekundäre Displays simulieren aus und aktivieren Sie ein Fenster. Wenn Sie sekundäre Bildschirme in Aktion sehen möchten, erfassen Sie mit screenrecord den Vorgang der Aktivierung des Bildschirms und spielen ihn dann Frame für Frame ab.