Android verwendet die OpenGL ES (GLES) API, um Grafiken zu rendern. Zum Erstellen von GLES-Kontexten und zum Bereitstellen eines Fenstersystems für GLES-Renderings verwendet Android die EGL-Bibliothek. GLES-Aufrufe rendern texturierte Polygone, während EGL-Aufrufe Renderings auf Bildschirme bringen.
Bevor Sie mit GLES zeichnen können, müssen Sie einen GL-Kontext erstellen. In EGL bedeutet das, einen EGLContext und einen EGLSurface zu erstellen. GLES-Vorgänge gelten für den aktuellen Kontext, auf den über threadlokalen Speicher zugegriffen wird, anstatt ihn als Argument zu übergeben. Der Rendering-Code sollte in einem aktuellen GLES-Thread ausgeführt werden, nicht im UI-Thread.
EGLSurfaces
Das EGLSurface kann ein von EGL zugewiesener Offscreen-Puffer (pbuffer) oder ein vom Betriebssystem zugewiesenes Fenster sein. Durch den Aufruf der Funktion eglCreateWindowSurface()
werden EGL-Fensteroberflächen erstellt.
eglCreateWindowSurface()
nimmt ein Fensterobjekt als Argument entgegen, das unter Android eine Oberfläche ist. Eine Oberfläche ist die Erstellerseite einer BufferQueue. Nutzer, also SurfaceView, SurfaceTexture, TextureView oder ImageReader, erstellen Oberflächen.
Wenn Sie eglCreateWindowSurface()
aufrufen, erstellt EGL ein neues EGLSurface-Objekt und verbindet es mit der Produzentenschnittstelle der BufferQueue des Fensterobjekts. Ab diesem Zeitpunkt führt das Rendern in dieser EGLSurface dazu, dass ein Puffer aus der Warteschlange entfernt, gerendert und für die Verwendung durch den Verbraucher in die Warteschlange gestellt wird.
EGL bietet keine Anrufe zum Sperren/Entsperren. Geben Sie Zeichenbefehle ein und rufen Sie dann eglSwapBuffers()
auf, um den aktuellen Frame zu senden. Der Name der Methode stammt aus dem traditionellen Austausch von Front- und Back-Buffern, die tatsächliche Implementierung kann jedoch abweichen.
Einem Surface kann jeweils nur ein EGLSurface zugeordnet werden (es kann nur einen Produzenten geben, der mit einer BufferQueue verbunden ist). Wenn Sie das EGLSurface jedoch zerstören, wird die Verbindung zur BufferQueue getrennt und eine andere Verbindung wird zugelassen.
Ein bestimmter Thread kann zwischen mehreren EGLSurfaces wechseln, indem er das aktuelle ändert. Eine EGLSurface darf jeweils nur in einem Thread aktuell sein.
EGL ist kein weiterer Aspekt einer Oberfläche wie SurfaceHolder. EGLSurface ist ein ähnliches, aber unabhängiges Konzept. Sie können auf einer EGLSurface zeichnen, die nicht von einer Surface unterstützt wird, und Sie können eine Surface ohne EGL verwenden. EGLSurface bietet GLES lediglich einen Ort zum Zeichnen.
Die OpenGL ES- und EGL-Anforderungen finden Sie im Compatibility Definition Document (CDD) für Android.
ANativeWindow
Die öffentliche Surface-Klasse wird in der Programmiersprache Java implementiert. Das Äquivalent in C/C++ ist die Klasse „ANativeWindow“, die vom Android NDK teilweise freigegeben wird. Sie können die ANativeWindow-Instanz über den Aufruf ANativeWindow_fromSurface()
von einer Oberfläche abrufen. Genau wie bei der Java-Version können Sie sie sperren, in Software rendern und entsperren und posten. Der grundlegende native Fenstertyp ist die Produzentenseite einer BufferQueue.
Wenn Sie eine EGL-Fensteroberfläche aus nativem Code erstellen möchten, übergeben Sie eglCreateWindowSurface()
eine Instanz von EGLNativeWindowType. EGLNativeWindowType ist ein Synonym für ANativeWindow. Sie können also einen Wert in den anderen umwandeln.