Ebenen und Anzeigen

Ebenen und Anzeigen sind zwei Grundelemente, die Kompositionsarbeiten und Interaktionen mit der Anzeigehardware darstellen.

Lagen

Eine Ebene ist die wichtigste Kompositionseinheit. Eine Ebene ist eine Kombination aus einer Oberfläche und einer Instanz von SurfaceControl . Jede Ebene verfügt über eine Reihe von Eigenschaften, die definieren, wie sie mit anderen Ebenen interagiert. Die Ebeneneigenschaften werden in der folgenden Tabelle beschrieben.

Eigentum Beschreibung
Positionsbezogen Definiert, wo die Ebene auf ihrer Anzeige erscheint. 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).
Inhalt Definiert, wie der auf der Ebene angezeigte Inhalt innerhalb der durch die Positionseigenschaften definierten Grenzen dargestellt werden soll. Enthält Informationen wie Zuschneiden (um einen Teil des Inhalts zu erweitern, um die Grenzen der Ebene auszufüllen) und Transformieren (um gedrehten oder gespiegelten Inhalt anzuzeigen).
Komposition Definiert, wie die Ebene mit anderen Ebenen zusammengesetzt werden soll. Enthält Informationen wie den Mischmodus und einen ebenenweiten Alpha-Wert für Alpha-Compositing .
Optimierung Stellt Informationen bereit, die für die korrekte Zusammensetzung der Ebene nicht unbedingt erforderlich sind, die jedoch vom Hardware Composer (HWC)-Gerät zur Optimierung der Zusammensetzung verwendet werden können. Enthält Informationen wie den sichtbaren Bereich der Ebene und den Teil der Ebene, der seit dem vorherigen Frame aktualisiert wurde.

Zeigt an

Ein Display ist eine weitere wichtige Kompositionseinheit. Ein System kann über mehrere Displays verfügen und Displays können während des normalen Systembetriebs hinzugefügt oder entfernt werden. Anzeigen werden auf Anfrage des HWC oder auf Anfrage des Rahmenwerks hinzugefügt/entfernt. Das HWC-Gerät fordert das Hinzufügen oder Entfernen von Displays an, wenn ein externes Display an das Gerät angeschlossen oder davon getrennt wird, was als Hotplugging bezeichnet wird. Clients fordern virtuelle Displays an, deren Inhalte in einem Off-Screen-Puffer statt auf einem physischen Display gerendert werden.

Virtuelle Displays

SurfaceFlinger unterstützt ein internes Display (im Telefon oder Tablet integriert), externe Displays (z. B. einen über HDMI angeschlossenen Fernseher) und ein oder mehrere virtuelle Displays, die die zusammengesetzte Ausgabe innerhalb des Systems verfügbar machen. Virtuelle Displays können verwendet werden, um den Bildschirm aufzuzeichnen oder über ein Netzwerk zu senden. Für eine virtuelle Anzeige generierte Frames werden in eine BufferQueue geschrieben.

Virtuelle Displays können denselben Ebenensatz wie das Hauptdisplay (den Ebenenstapel) verwenden oder über einen eigenen Satz verfügen. Für ein virtuelles Display gibt es kein VSYNC, daher löst das VSYNC für das interne Display die Komposition für alle Displays aus.

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

Fallstudie: Screenrecord

Mit dem Befehl screenrecord kann der Benutzer alles, was auf dem Bildschirm erscheint, als .mp4 Datei auf der Festplatte aufzeichnen. Um dies zu implementieren, 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, daher müssen große Grafikpuffer im System verschoben werden. Um es anspruchsvoller zu machen, besteht das Ziel darin, Videos mit 60 Bildern pro Sekunde und voller Auflösung aufzunehmen. Der Schlüssel für eine effiziente Arbeit ist BufferQueue.

Mit der MediaCodec Klasse kann eine App Daten als Rohbytes in Puffern oder über eine Oberfläche bereitstellen. Wenn screenrecord Zugriff auf einen Video-Encoder anfordert, erstellt der mediaserver Prozess eine BufferQueue, verbindet sich mit der Verbraucherseite und übergibt die Produzentenseite dann als Oberfläche an screenrecord zurück.

Das screenrecord Dienstprogramm fordert SurfaceFlinger dann auf, eine virtuelle Anzeige zu erstellen, die die Hauptanzeige widerspiegelt (d. h. alle Ebenen sind identisch), und weist es an, Ausgaben an die Oberfläche zu senden, die vom mediaserver Prozess stammen. In diesem Fall ist SurfaceFlinger der Pufferproduzent und nicht der Konsument.

Nachdem die Konfiguration abgeschlossen ist, wird screenrecord ausgelöst, wenn die codierten Daten angezeigt werden. Während Apps zeichnen, werden ihre Puffer an SurfaceFlinger weitergeleitet, der sie zu einem einzigen Puffer zusammenfügt, der im mediaserver Prozess direkt an den Video-Encoder gesendet wird. Die Vollbilder werden beim screenrecord Prozess nie gesehen. Intern verfügt der mediaserver Prozess über eine eigene Methode zum Verschieben von Puffern, die auch Daten per Handle weitergibt, wodurch der Overhead minimiert wird.

Fallstudie: Sekundäranzeigen simulieren

Der WindowManager kann SurfaceFlinger auffordern, eine sichtbare Ebene zu erstellen, für die SurfaceFlinger als BufferQueue-Consumer fungiert. Es ist auch möglich, SurfaceFlinger zu bitten, eine virtuelle Anzeige zu erstellen, für die SurfaceFlinger als BufferQueue-Produzent fungiert.

Wenn Sie eine virtuelle Anzeige mit einer sichtbaren Ebene verbinden, entsteht eine geschlossene Schleife, in der der zusammengesetzte Bildschirm in einem Fenster erscheint. Dieses Fenster ist jetzt Teil der zusammengesetzten Ausgabe, sodass bei der nächsten Aktualisierung auch das zusammengesetzte Bild im Fenster den Fensterinhalt anzeigt. Um dies in Aktion zu sehen, aktivieren Sie die Entwickleroptionen in den Einstellungen , wählen Sie Sekundäranzeigen simulieren und aktivieren Sie ein Fenster. Um sekundäre Displays in Aktion zu sehen, verwenden Sie screenrecord , um den Vorgang der Aktivierung des Displays aufzuzeichnen und ihn dann Bild für Bild wiederzugeben.