Home | History | Annotate | Download | only in graphics
      1 <html devsite>
      2   <head>
      3     <title>EGLSurfaces and OpenGL ES</title>
      4     <meta name="project_path" value="/_project.yaml" />
      5     <meta name="book_path" value="/_book.yaml" />
      6   </head>
      7   <body>
      8   <!--
      9       Copyright 2017 The Android Open Source Project
     10 
     11       Licensed under the Apache License, Version 2.0 (the "License");
     12       you may not use this file except in compliance with the License.
     13       You may obtain a copy of the License at
     14 
     15           http://www.apache.org/licenses/LICENSE-2.0
     16 
     17       Unless required by applicable law or agreed to in writing, software
     18       distributed under the License is distributed on an "AS IS" BASIS,
     19       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     20       See the License for the specific language governing permissions and
     21       limitations under the License.
     22   -->
     23 
     24 
     25 
     26 <p>OpenGL ES defines an API for rendering graphics.  It does not define a windowing
     27 system.  To allow GLES to work on a variety of platforms, it is designed to be
     28 combined with a library that knows how to create and access windows through the
     29 operating system.  The library used for Android is called EGL.  If you want to
     30 draw textured polygons, you use GLES calls; if you want to put your rendering on
     31 the screen, you use EGL calls.</p>
     32 
     33 <p>Before you can do anything with GLES, you need to create a GL context.  In EGL,
     34 this means creating an EGLContext and an EGLSurface.  GLES operations apply to
     35 the current context, which is accessed through thread-local storage rather than
     36 passed around as an argument.  This means you have to be careful about which
     37 thread your rendering code executes on, and which context is current on that
     38 thread.</p>
     39 
     40  <h2 id=egl_surface>EGLSurfaces</h2>
     41 
     42 <p>The EGLSurface can be an off-screen buffer allocated by EGL (called a "pbuffer")
     43 or a window allocated by the operating system.  EGL window surfaces are created
     44 with the <code>eglCreateWindowSurface()</code> call.  It takes a "window object" as an
     45 argument, which on Android can be a SurfaceView, a SurfaceTexture, a
     46 SurfaceHolder, or a Surface -- all of which have a BufferQueue underneath.  When
     47 you make this call, EGL creates a new EGLSurface object, and connects it to the
     48 producer interface of the window object's BufferQueue.  From that point onward,
     49 rendering to that EGLSurface results in a buffer being dequeued, rendered into,
     50 and queued for use by the consumer.  (The term "window" is indicative of the
     51 expected use, but bear in mind the output might not be destined to appear
     52 on the display.)</p>
     53 
     54 <p>EGL does not provide lock/unlock calls.  Instead, you issue drawing commands and
     55 then call <code>eglSwapBuffers()</code> to submit the current frame.  The
     56 method name comes from the traditional swap of front and back buffers, but the actual
     57 implementation may be very different.</p>
     58 
     59 <p>Only one EGLSurface can be associated with a Surface at a time -- you can have
     60 only one producer connected to a BufferQueue -- but if you destroy the
     61 EGLSurface it will disconnect from the BufferQueue and allow something else to
     62 connect.</p>
     63 
     64 <p>A given thread can switch between multiple EGLSurfaces by changing what's
     65 "current."  An EGLSurface must be current on only one thread at a time.</p>
     66 
     67 <p>The most common mistake when thinking about EGLSurface is assuming that it is
     68 just another aspect of Surface (like SurfaceHolder).  It's a related but
     69 independent concept.  You can draw on an EGLSurface that isn't backed by a
     70 Surface, and you can use a Surface without EGL.  EGLSurface just gives GLES a
     71 place to draw.</p>
     72 
     73 <h2 id="anativewindow">ANativeWindow</h2>
     74 
     75 <p>The public Surface class is implemented in the Java programming language.  The
     76 equivalent in C/C++ is the ANativeWindow class, semi-exposed by the <a
     77 href="https://developer.android.com/ndk/index.html">Android NDK</a>.  You
     78 can get the ANativeWindow from a Surface with the <code>ANativeWindow_fromSurface()</code>
     79 call.  Just like its Java-language cousin, you can lock it, render in software,
     80 and unlock-and-post.</p>
     81 
     82 <p>To create an EGL window surface from native code, you pass an instance of
     83 EGLNativeWindowType to <code>eglCreateWindowSurface()</code>.  EGLNativeWindowType is just
     84 a synonym for ANativeWindow, so you can freely cast one to the other.</p>
     85 
     86 <p>The fact that the basic "native window" type just wraps the producer side of a
     87 BufferQueue should not come as a surprise.</p>
     88 
     89   </body>
     90 </html>
     91