Oberflächenobjekte ermöglichen es Apps, Bilder zu rendern, die auf Bildschirmen präsentiert werden sollen. SurfaceHolder-Schnittstellen ermöglichen es Apps, Oberflächen zu bearbeiten und zu steuern.
Auftauchen
Eine Oberfläche ist eine Schnittstelle für einen Erzeuger, um Puffer mit einem Verbraucher auszutauschen.
Die BufferQueue für eine Anzeigeoberfläche ist typischerweise für Triple-Buffering konfiguriert. Puffer werden bei Bedarf zugewiesen. Wenn der Produzent also Puffer langsam genug generiert, z. B. bei 30 fps auf einem 60-fps-Display, befinden sich möglicherweise nur zwei zugewiesene Puffer in der Warteschlange. Die Zuweisung von Puffern nach Bedarf trägt dazu bei, den Speicherverbrauch zu minimieren. Sie können eine Zusammenfassung der jedem Layer zugeordneten Puffer in der dumpsys SurfaceFlinger
.
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 Bytes in einem Puffer entsprechend setzt. Um sicherzustellen, dass ein Puffer nicht gleichzeitig von zwei Clients aktualisiert oder während der Anzeige beschrieben wird, sperren Sie den Puffer für den Zugriff. 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 wird. -
unlockCanvasAndPost()
entsperrt den Puffer und sendet ihn an den Compositor. -
lockHardwareCanvas()
sperrt den Puffer für das Rendern auf der GPU und gibt eine Zeichenfläche zurück, die zum Zeichnen verwendet werden soll.
Wenn der Erzeuger 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 Daten versehentlich zwischen Prozessen ausgetauscht werden. Wenn Sie jedoch einen Puffer wiederverwenden, ist der vorherige Inhalt immer noch vorhanden. Wenn Sie lockCanvas()
und unlockCanvasAndPost()
wiederholt aufrufen, ohne etwas zu zeichnen, wechselt der Producer zwischen zuvor gerenderten Frames.
Der Code zum Sperren/Entsperren der Oberfläche behält einen Verweis auf den zuvor gerenderten Puffer. Wenn Sie beim Sperren der Oberfläche einen schmutzigen Bereich angeben, werden die nicht schmutzigen Pixel aus dem vorherigen Puffer kopiert. SurfaceFlinger oder HWC handhaben 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, möchten einen SurfaceHolder, da APIs zum Abrufen und Festlegen von Oberflächenparametern über einen SurfaceHolder implementiert werden. Eine SurfaceView enthält einen SurfaceHolder.
Die meisten Komponenten, die mit einer Ansicht interagieren, beinhalten einen SurfaceHolder. Einige andere APIs wie MediaCodec arbeiten auf der Oberfläche selbst.