Ebenen und Displays

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

Ebenen

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

Attribut Beschreibung
Position Definiert, wo die Ebene auf dem Display angezeigt wird. Enthält Informationen wie die Positionen der Kanten einer Ebene und ihre Z-Reihenfolge im Verhältnis zu anderen Ebenen (ob sie vor oder hinter anderen Ebenen liegen soll).
Inhalt Gibt an, wie Inhalte auf der Ebene innerhalb der durch die Positionseigenschaften festgelegten Grenzen angezeigt werden. Dazu gehören Zuschneiden (um Inhalte so zu erweitern, dass sie die Grenzen der Ebene ausfüllen) und Transformieren (um gedrehte oder gespiegelte Inhalte anzuzeigen).
Komposition Definiert, wie die Ebene mit anderen Ebenen zusammengesetzt werden soll. Enthält Informationen wie den Mischmodus und einen ebenenweiten Alphawert für die Alphakomposition .
Optimierung Bietet Informationen, die für die korrekte Ebenenzusammensetzung nicht unbedingt erforderlich sind, aber vom Hardware Composer (HWC) des Geräts verwendet werden können, um die Leistung der Komposition zu optimieren. Dazu gehören der sichtbare Bereich der Ebene und der Teil, der seit dem vorherigen Frame aktualisiert wurde.

Displays

Ein Display ist eine weitere wichtige Einheit der Komposition. Ein System kann mehrere Displays haben und Displays können während des normalen Systembetriebs hinzugefügt oder entfernt werden. Displays werden auf Anfrage des HWC oder des Frameworks hinzugefügt oder entfernt.

Das HWC-Gerät fordert das Hinzufügen oder Entfernen von Displays an, wenn ein externes Display an das Gerät angeschlossen oder von ihm getrennt wird. Dies wird als Hotplugging bezeichnet. Clients fordern virtuelle Displays an, deren Inhalte in einen Offscreen-Puffer und nicht auf einem physischen Display gerendert werden.

Virtuelle Displays

SurfaceFlinger unterstützt ein internes Display (im Smartphone oder Tablet integriert), externe Displays (z. B. einen über HDMI angeschlossenen Fernseher) und ein oder mehrere virtuelle Displays, die die zusammengesetzte Ausgabe im System verfügbar machen. Virtuelle Displays können verwendet werden, um den Bildschirm aufzuzeichnen 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 (der Ebenenstapel) verwenden oder eigene Ebenen haben. Für ein virtuelles Display gibt es keine VSync. Daher löst die VSync für das interne Display die Komposition für alle Displays aus.

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

Fallstudie: screenrecord

Mit dem screenrecord Befehl kann der Nutzer alles, was auf dem Bildschirm angezeigt wird, als MP4-Datei auf der Festplatte aufzeichnen. Dazu empfängt das System zusammengesetzte Frames von SurfaceFlinger, schreibt sie in den Video-Encoder und schreibt dann die codierten Videodaten in eine Datei. Die Video-Codecs werden von einem separaten Prozess (mediaserver) verwaltet, sodass große Grafikpuffer im System verschoben werden müssen. Erschwerend kommt hinzu, dass das Ziel darin besteht, Videos mit 60 fps in 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 Video-Encoder anfordert, erstellt der Prozess mediaserver eine BufferQueue, stellt eine Verbindung zur Consumer-Seite her und übergibt die Producer-Seite als Oberfläche an screenrecord zurück.

Das Dienstprogramm screenrecord fordert dann SurfaceFlinger auf, ein virtuelles Display zu erstellen, das das Hauptdisplay spiegelt (d. h. alle Ebenen sind identisch), und weist es an, die Ausgabe an die Oberfläche zu senden, die vom Prozess mediaserver stammt. In diesem Fall ist SurfaceFlinger der Producer von Puffern und nicht der Consumer.

Nach Abschluss der Konfiguration wird screenrecord ausgelöst, wenn die codierten Daten angezeigt werden. Wenn Apps zeichnen, werden ihre Puffer an SurfaceFlinger gesendet, das sie zu einem einzigen Puffer zusammensetzt, der direkt an den Video-Encoder im Prozess mediaserver gesendet wird. Die vollständigen Frames werden vom Prozess screenrecord nie gesehen. Intern hat der Prozess mediaserver eine eigene Methode zum Verschieben von Puffern, bei der Daten auch per Handle übergeben werden, wodurch der Overhead minimiert wird.

Fallstudie: Sekundäre Displays simulieren

WindowManager kann SurfaceFlinger auffordern, eine sichtbare Ebene zu erstellen, für die SurfaceFlinger als BufferQueue-Consumer fungiert. Es ist auch möglich, SurfaceFlinger aufzufordern, ein virtuelles Display zu erstellen, für das SurfaceFlinger als BufferQueue-Producer fungiert.

Wenn Sie ein virtuelles Display mit einer sichtbaren Ebene verbinden, wird eine geschlossene Schleife erstellt, in der der zusammengesetzte Bildschirm in einem Fenster angezeigt wird. Dieses Fenster ist jetzt Teil der zusammengesetzten Ausgabe. Bei der nächsten Aktualisierung zeigt das zusammengesetzte Bild im Fenster auch die Fensterinhalte. Um dies in Aktion zu sehen, aktivieren Sie die Entwickleroptionen in den Einstellungen, wählen Sie Sekundäre Displays simulieren aus und aktivieren Sie ein Fenster. Um sekundäre Displays in Aktion zu sehen, verwenden Sie screenrecord, um das Aktivieren des Displays aufzuzeichnen, und spielen Sie es dann Frame für Frame ab.