EGLSurfaces and OpenGL ES

Android uses the OpenGL ES (GLES) API to render graphics. To create GLES contexts and provide a windowing system for GLES renderings, Android uses the EGL library. GLES calls render textured polygons, while EGL calls put renderings on screens.

Before you draw with GLES, you need to create a GL context. In EGL, this means creating an EGLContext and an EGLSurface. GLES operations apply to the current context, which is accessed through thread-local storage rather than passed as an argument. Rendering code should execute on a current GLES thread, not the UI thread.


The EGLSurface can be an off-screen buffer allocated by EGL, called a pbuffer, or a window allocated by the operating system. Calling the eglCreateWindowSurface() function creates EGL window surfaces. eglCreateWindowSurface() takes a window object as an argument, which on Android is a surface. A surface is the producer side of a BufferQueue. Consumers, which are SurfaceView, SurfaceTexture, TextureView, or ImageReader, create surfaces. When you call eglCreateWindowSurface(), EGL creates a new EGLSurface object and connects it to the producer interface of the window object's BufferQueue. From that point onward, rendering to that EGLSurface results in a buffer being dequeued, rendered into, and queued for use by the consumer.

EGL doesn't provide lock/unlock calls. Issue drawing commands and then call eglSwapBuffers() to submit the current frame. The method name comes from the traditional swap of front and back buffers, but the actual implementation may be different.

Only one EGLSurface can be associated with a surface at a time (you can have only one producer connected to a BufferQueue), but if you destroy the EGLSurface it disconnects from the BufferQueue and lets something else connect.

A given thread can switch between multiple EGLSurfaces by changing what's current. An EGLSurface must be current on only one thread at a time.

EGL isn't another aspect of a surface (like SurfaceHolder). EGLSurface is a related but independent concept. You can draw on an EGLSurface that isn't backed by a surface, and you can use a surface without EGL. EGLSurface just provides GLES with a place to draw.

Refer to the Android Compatibility Definition Document for OpenGL ES and EGL requirements.


The public surface class is implemented in the Java programming language. The equivalent in C/C++ is the ANativeWindow class, semi-exposed by the Android NDK. You can get the ANativeWindow from a surface with the ANativeWindow_fromSurface() call. Just like its Java-language cousin, you can lock it, render in software, and unlock-and-post. The basic native window type is the producer side of a BufferQueue.

To create an EGL window surface from native code, pass an instance of EGLNativeWindowType to eglCreateWindowSurface(). EGLNativeWindowType is a synonym for ANativeWindow, so you can cast one to the other.