Android usa la API de OpenGL ES (GLES) para renderizar gráficos. Para crear contextos de GLES y proporcionar un sistema de ventanas para las renderizaciones de GLES, Android usa la biblioteca EGL. Las llamadas a GLES renderizan polígonos texturizados, mientras que las llamadas a EGL colocan renderizaciones en las pantallas.
Antes de dibujar con GLES, debes crear un contexto de GL. En EGL, esto significa crear un EGLContext y un EGLSurface. Las operaciones de GLES se aplican al contexto actual, al que se accede a través del almacenamiento local de subprocesos en lugar de pasarse como argumento. El código de renderización debe ejecutarse en un subproceso de GLES, no en el subproceso de IU.
EGLSurfaces
La EGLSurface puede ser un búfer fuera de la pantalla asignado por EGL, llamado pbuffer, o una ventana asignada por el sistema operativo. Llamar a la función eglCreateWindowSurface()
crea superficies de ventana de EGL.
eglCreateWindowSurface()
toma un objeto de ventana como argumento, que en Android es una superficie. Una superficie es el lado del productor de una BufferQueue. Los consumidores, que son SurfaceView, SurfaceTexture, TextureView o ImageReader, crean superficies.
Cuando llamas a eglCreateWindowSurface()
, EGL crea un nuevo objeto EGLSurface y lo conecta a la interfaz de productor de BufferQueue del objeto de ventana. A partir de ese momento, la renderización en ese EGLSurface quita un búfer de la cola, renderiza en él y lo pone en cola para que lo use el consumidor.
EGL no proporciona llamadas de bloqueo o desbloqueo. Emite comandos de dibujo y, luego, llama a eglSwapBuffers()
para enviar el fotograma actual. El nombre del método proviene del intercambio tradicional de búferes frontal y posterior, pero la implementación real puede ser diferente.
Solo se puede asociar un EGLSurface a una superficie a la vez (solo puedes tener un productor conectado a un BufferQueue), pero si destruyes el EGLSurface, se desconecta del BufferQueue y permite que se conecte otro elemento.
Un subproceso determinado puede cambiar entre varias EGLSurfaces cambiando lo que es actual. Un EGLSurface debe ser actual en un solo subproceso a la vez.
EGL no es otro aspecto de una superficie, como un SurfaceHolder. EGLSurface es un concepto relacionado, pero independiente. Puedes dibujar en un EGLSurface que no esté respaldado por una superficie y puedes usar una superficie sin EGL. EGLSurface proporciona a GLES un lugar para dibujar.
Consulta el Documento de Definición de Compatibilidad de Android para conocer los requisitos de OpenGL ES y EGL.
ANativeWindow
La clase de superficie pública se implementa en el lenguaje de programación Java. El equivalente en C/C++ es la clase ANativeWindow, que el NDK de Android expone parcialmente. Puedes obtener el ANativeWindow de una superficie con la llamada ANativeWindow_fromSurface()
. Al igual que su primo en lenguaje Java, puedes bloquearlo, renderizarlo en software y desbloquearlo y publicarlo. El tipo básico de ventana nativa es el lado del productor de una BufferQueue.
Para crear una superficie de ventana EGL a partir de código nativo, pasa una instancia de EGLNativeWindowType a eglCreateWindowSurface()
. EGLNativeWindowType es sinónimo de ANativeWindow, por lo que puedes convertir uno en el otro.