Android utilizza l'API OpenGL ES (GLES) per il rendering della grafica. Per creare contesti GLES e fornire un sistema di finestre per i rendering GLES, Android utilizza la libreria EGL. Le chiamate GLES eseguono il rendering di poligoni con texture, mentre le chiamate EGL inseriscono i rendering sugli schermi.
Prima di disegnare con GLES, devi creare un contesto GL. In EGL, ciò significa creare un EGLContext e un EGLSurface. Le operazioni GLES vengono applicate al contesto corrente, a cui si accede tramite l'archiviazione locale del thread anziché tramite un argomento. Il codice di rendering deve essere eseguito su un thread GLES, non sul thread UI.
EGLSurfaces
EGLSurface può essere un buffer off-screen allocato da EGL, chiamato
pbuffer, o una finestra allocata dal sistema operativo. La chiamata alla funzione
eglCreateWindowSurface()
crea superfici della finestra EGL.
eglCreateWindowSurface()
accetta un oggetto finestra come
argomento, che su Android è una superficie. Una superficie è il lato producer
di una BufferQueue. I consumer, ovvero SurfaceView,
SurfaceTexture, TextureView o ImageReader, creano superfici.
Quando chiami eglCreateWindowSurface()
, EGL crea un nuovo oggetto EGLSurface e lo connette all'interfaccia del produttore di BufferQueue dell'oggetto finestra. Da questo momento in poi, il rendering su EGLSurface
estrae un buffer, esegue il rendering al suo interno e lo mette in coda per l'utilizzo da parte del consumer.
EGL non fornisce chiamate di apertura/chiusura. Emetti comandi di disegno e
poi chiama eglSwapBuffers()
per inviare il frame corrente. Il nome del metodo deriva dallo scambio tradizionale dei buffer anteriore e posteriore, ma l'implementazione effettiva potrebbe essere diversa.
A una superficie può essere associata una sola EGLSurface alla volta (puoi avere un solo producer connesso a una BufferQueue), ma se distruggi EGLSurface, questa si disconnette da BufferQueue e consente a un altro producer di connettersi.
Un determinato thread può passare da una EGLSurface all'altra modificando l'elemento corrente. Una EGLSurface deve essere attuale su un solo thread alla volta.
EGL non è un altro aspetto di una superficie, come un SurfaceHolder. EGLSurface è un concetto correlato ma indipendente. Puoi disegnare su una EGLSurface non supportata da una superficie e puoi utilizzare una superficie senza EGL. EGLSurface fornisce a GLES un punto in cui disegnare.
Consulta il Compatibility Definition Document di Android per i requisiti di OpenGL ES ed EGL.
ANativeWindow
La classe di superficie pubblica è implementata nel linguaggio di programmazione Java. L'equivalente in C/C++ è la classe ANativeWindow, semi-esposta dall'Android NDK. Puoi
ottenere ANativeWindow da una superficie con la chiamata ANativeWindow_fromSurface()
. Proprio come la sua controparte in linguaggio Java, puoi bloccarlo, eseguirne il rendering nel software
e sbloccarlo e pubblicarlo. Il tipo di finestra nativa di base è il lato produttore di una
BufferQueue.
Per creare una superficie della finestra EGL dal codice nativo, passa un'istanza di
EGLNativeWindowType a eglCreateWindowSurface()
. EGLNativeWindowType è
un sinonimo di ANativeWindow, quindi puoi eseguire il cast di uno nell'altro.