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 de EGL. Las llamadas de GLES renderizan polígonos con textura, mientras que las llamadas de EGL colocan renderizaciones en 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 pasarlo como argumento. El código de renderización debe ejecutarse en un subproceso GLES actual, no en el subproceso de IU.
EGLSurfaces
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 un BufferQueue. Los consumidores, que son SurfaceView, SurfaceTexture, TextureView o ImageReader, crean superficies.
Cuando llamas a eglCreateWindowSurface()
, EGL crea un objeto EGLSurface nuevo y lo conecta a la interfaz de productor del BufferQueue del objeto de ventana. A partir de ese momento, la renderización en ese EGLSurface genera un búfer que se quita de la cola, se renderiza y se pone en cola para que el consumidor lo use.
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 con una superficie a la vez (puedes tener solo un productor conectado a un BufferQueue), pero si destruyes el EGLSurface, se desconecta del BufferQueue y permite que se conecte algo más.
Un subproceso determinado puede cambiar entre varios 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 SurfaceHolder). EGLSurface es un concepto relacionado, pero independiente. Puedes dibujar en una EGLSurface que no esté respaldada por una superficie y puedes usar una superficie sin EGL. EGLSurface solo le 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 de forma semicompleta. Puedes obtener el ANativeWindow de una superficie con la llamada a ANativeWindow_fromSurface()
. Al igual que su primo en lenguaje Java, puedes bloquearlo, renderizarlo en software, desbloquearlo y publicarlo. El tipo básico de ventana nativa es el lado del productor de un BufferQueue.
Para crear una superficie de ventana EGL a partir de código nativo, pasa una instancia de EGLNativeWindowType a eglCreateWindowSurface()
. EGLNativeWindowType es un sinónimo de ANativeWindow, por lo que puedes transmitir uno al otro.