Surface und SurfaceHolder

Mit Oberflächenobjekten können Apps Bilder rendern, die auf Bildschirmen angezeigt werden. Mit SurfaceHolder-Schnittstellen können Apps Oberflächen bearbeiten und steuern.

Oberfläche

Eine Oberfläche ist eine Schnittstelle für einen Hersteller, um Puffer mit einem Verbraucher auszutauschen.

Die BufferQueue für eine Anzeigeoberfläche ist normalerweise für die Dreifachpufferung konfiguriert. Puffer werden bei Bedarf zugewiesen. Wenn der Produzent also langsam genug Puffer generiert, z. B. bei 30 fps auf einer 60-fps-Anzeige, befinden sich möglicherweise nur zwei zugewiesene Puffer in der Warteschlange. Durch das Zuweisen von Puffern nach Bedarf wird der Speicherverbrauch minimiert. In der Ausgabe von dumpsys SurfaceFlinger sehen Sie eine Zusammenfassung der Puffer, die jeder Ebene dumpsys SurfaceFlinger .

Die meisten Clients rendern mit OpenGL ES oder Vulkan auf Oberflächen. Einige Clients rendern jedoch mithilfe einer Zeichenfläche auf Oberflächen.

Canvas-Rendering

Die Canvas-Implementierung wird von der Skia-Grafikbibliothek bereitgestellt. Wenn Sie ein Rechteck zeichnen möchten, rufen Sie die Canvas-API auf, mit der Bytes in einem Puffer entsprechend festgelegt werden. Um sicherzustellen, dass ein Puffer nicht von zwei Clients gleichzeitig aktualisiert oder während der Anzeige beschrieben wird, sperren Sie den Puffer, um darauf zuzugreifen. Verwenden Sie die folgenden Befehle, um mit Canvas-Sperren zu arbeiten:

  • lockCanvas() sperrt den Puffer zum Rendern auf der CPU und gibt einen Canvas zurück, der zum Zeichnen verwendet werden soll.
  • unlockCanvasAndPost() entsperrt den Puffer und sendet ihn an den Compositor.
  • lockHardwareCanvas() sperrt den Puffer zum Rendern auf der GPU und gibt eine Zeichenfläche zurück, die zum Zeichnen verwendet werden soll.

Wenn der Produzent zum ersten Mal einen Puffer von einer BufferQueue anfordert, wird der Puffer zugewiesen und auf Null initialisiert. Die Initialisierung ist erforderlich, um zu vermeiden, dass versehentlich Daten zwischen Prozessen ausgetauscht werden. Wenn Sie jedoch einen Puffer wiederverwenden, ist der vorherige Inhalt weiterhin vorhanden. Wenn Sie wiederholt lockCanvas() und unlockCanvasAndPost() ohne etwas zu zeichnen, wechselt der Produzent zwischen zuvor gerenderten Frames.

Der Oberflächensperr- / Entsperrcode enthält einen Verweis auf den zuvor gerenderten Puffer. Wenn Sie beim Sperren der Oberfläche einen verschmutzten Bereich angeben, werden die nicht dreißig Pixel aus dem vorherigen Puffer kopiert. SurfaceFlinger oder HWC verarbeiten normalerweise den Puffer. Da wir jedoch nur aus dem Puffer lesen müssen, müssen Sie nicht auf den exklusiven Zugriff warten.

SurfaceHolder

Ein SurfaceHolder ist eine Schnittstelle, über die das System den Besitz von Oberflächen mit Apps teilt. Einige Clients, die mit Oberflächen arbeiten, möchten einen SurfaceHolder, da APIs zum Abrufen und Festlegen von Oberflächenparametern über einen SurfaceHolder implementiert werden. Eine SurfaceView enthält einen SurfaceHolder.

Bei den meisten Komponenten, die mit einer Ansicht interagieren, handelt es sich um einen SurfaceHolder. Einige andere APIs, wie z. B. MediaCodec, arbeiten auf der Oberfläche selbst.