Oberfläche und Oberflächenhalter

Mithilfe von Oberflächenobjekten können Apps Bilder rendern, die auf Bildschirmen angezeigt werden sollen. SurfaceHolder-Schnittstellen ermöglichen Apps das Bearbeiten und Steuern von Oberflächen.

Oberfläche

Eine Oberfläche ist eine Schnittstelle für einen Produzenten zum Austausch von Puffern mit einem Verbraucher.

Die BufferQueue für eine Anzeigeoberfläche ist normalerweise für Dreifachpufferung konfiguriert. Puffer werden bei Bedarf zugewiesen. Wenn der Produzent Puffer also langsam genug generiert, beispielsweise mit 30 fps auf einem 60-fps-Display, befinden sich möglicherweise nur zwei zugewiesene Puffer in der Warteschlange. Durch die Zuweisung von Puffern nach Bedarf lässt sich der Speicherverbrauch minimieren. In der dumpsys SurfaceFlinger können Sie eine Zusammenfassung der Puffer sehen, die jeder Ebene zugeordnet sind.

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

Canvas-Rendering

Die Canvas-Implementierung wird von der Skia Graphics Library bereitgestellt. Wenn Sie ein Rechteck zeichnen möchten, rufen Sie die Canvas-API auf, die die Bytes in einem Puffer entsprechend festlegt. 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 für das Rendern auf der CPU und gibt einen Canvas zur Verwendung zum Zeichnen zurück.
  • unlockCanvasAndPost() entsperrt den Puffer und sendet ihn an den Compositor.
  • lockHardwareCanvas() sperrt den Puffer für das Rendern auf der GPU und gibt eine Leinwand zum Zeichnen zurück.

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 verhindern, dass versehentlich Daten zwischen Prozessen ausgetauscht werden. Wenn Sie jedoch einen Puffer wiederverwenden, ist der vorherige Inhalt weiterhin vorhanden. Wenn Sie lockCanvas() und unlockCanvasAndPost() wiederholt aufrufen, ohne etwas zu zeichnen, wechselt der Produzent zwischen zuvor gerenderten Frames.

Der Code zum Sperren/Entsperren der Oberfläche behält einen Verweis auf den zuvor gerenderten Puffer bei. Wenn Sie beim Sperren der Oberfläche einen schmutzigen Bereich angeben, werden die nicht schmutzigen 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 wir nicht auf den exklusiven Zugriff warten.

Oberflächenhalter

Ein SurfaceHolder ist eine Schnittstelle, die das System verwendet, um den Besitz von Oberflächen mit Apps zu teilen. Einige Clients, die mit Oberflächen arbeiten, benötigen einen SurfaceHolder, da APIs zum Abrufen und Festlegen von Oberflächenparametern über einen SurfaceHolder implementiert werden. Ein SurfaceView enthält einen SurfaceHolder.

Die meisten Komponenten, die mit einer Ansicht interagieren, umfassen einen SurfaceHolder. Einige andere APIs, wie etwa MediaCodec, arbeiten auf der Oberfläche selbst.