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.