Android utilizza l'API OpenGL ES (GLES) per eseguire 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, questo significa creare un EGLContext e un EGLSurface. Le operazioni GLES si applicano al contesto corrente, a cui si accede tramite lo spazio di archiviazione locale del thread anziché passarlo come argomento. Il codice di rendering deve essere eseguito su un thread GLES corrente, non sul thread dell'interfaccia utente.
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 di finestre EGL.
eglCreateWindowSurface()
accetta come argomento un oggetto finestra, che su Android è una superficie. Una superficie è il lato produttore di una BufferQueue. I consumatori, ovvero SurfaceView,
SurfaceTexture, TextureView o ImageReader, creano le superfici.
Quando chiami eglCreateWindowSurface()
, EGL crea un nuovo oggetto EGLSurface e lo connette all'interfaccia di produzione della BufferQueue dell'oggetto finestra. Da quel momento in poi, il rendering in EGLSurface
comporta l'estrazione di un buffer, il rendering in un buffer e l'inserimento in coda per l'utilizzo da parte del
consumatore.
EGL non fornisce chiamate di blocco/sblocco. Esegui i 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 associato un solo EGLSurface alla volta (puoi avere un solo produttore collegato a una BufferQueue), ma se distruggi EGLSurface, la connessione alla BufferQueue viene disconnessa e consente a qualcos'altro di connettersi.
Un determinato thread può passare da un'EGLSurface all'altra modificando quella corrente. Un EGLSurface deve essere corrente in un solo thread alla volta.
EGL non è un altro aspetto di una superficie (come SurfaceHolder). EGLSurface è un concetto correlato, ma indipendente. Puoi disegnare su un'EGLSurface non supportata da una surface e puoi utilizzare una surface senza EGL. EGLSurface fornisce solo a GLES un luogo in cui disegnare.
Per i requisiti di OpenGL ES e EGL, consulta il Compatibility Definition Document (Documento di definizione della compatibilità) di Android.
ANativeWindow
La classe di interfaccia pubblica è implementata nel linguaggio di programmazione Java. L'equivalente in C/C++ è la classe ANativeWindow, semi-esposta dall'Android NDK. Puoi recuperare ANativeWindow da una superficie con la chiamata ANativeWindow_fromSurface()
. Proprio come il suo cugino in linguaggio Java, puoi bloccarlo, eseguire il rendering in software e sbloccare e pubblicare. Il tipo di finestra nativa di base è il lato produttore di un
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 trasmetterli l'uno all'altro.