GLSurfaceView.java revision 82fd4fce16b9bbde25d044acc86ddf7306ebdd10
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.opengl; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.Writer; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.Semaphore; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.egl.EGL10; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.egl.EGL11; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.egl.EGLConfig; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.egl.EGLContext; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.egl.EGLDisplay; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.egl.EGLSurface; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.opengles.GL; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.opengles.GL10; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.SurfaceHolder; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.SurfaceView; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An implementation of SurfaceView that uses the dedicated surface for 40b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * displaying OpenGL rendering. 41b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 42b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * A GLSurfaceView provides the following features: 43b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 44b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <ul> 45b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>Manages a surface, which is a special piece of memory that can be 46b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * composited into the Android view system. 47b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>Manages an EGL display, which enables OpenGL to render into a surface. 48b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>Accepts a user-provided Renderer object that does the actual rendering. 49b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>Renders on a dedicated thread to decouple rendering performance from the 50b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * UI thread. 51b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>Supports both on-demand and continuous rendering. 52b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>Optionally wraps, traces, and/or error-checks the renderer's OpenGL calls. 53b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * </ul> 54b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 55b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h3>Using GLSurfaceView</h3> 56b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 57b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Typically you use GLSurfaceView by subclassing it and overriding one or more of the 58b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * View system input event methods. If your application does not need to override event 59b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * methods then GLSurfaceView can be used as-is. For the most part 60b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * GLSurfaceView behavior is customized by calling "set" methods rather than by subclassing. 61b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * For example, unlike a regular View, drawing is delegated to a separate Renderer object which 62b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * is registered with the GLSurfaceView 63b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * using the {@link #setRenderer(Renderer)} call. 64b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 65b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h3>Initializing GLSurfaceView</h3> 66b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * All you have to do to initialize a GLSurfaceView is call {@link #setRenderer(Renderer)}. 67b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * However, if desired, you can modify the default behavior of GLSurfaceView by calling one or 68b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * more of these methods before calling setRenderer: 69b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <ul> 70b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setDebugFlags(int)} 71b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setEGLConfigChooser(boolean)} 72b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setEGLConfigChooser(EGLConfigChooser)} 73b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setEGLConfigChooser(int, int, int, int, int, int)} 74b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setGLWrapper(GLWrapper)} 75b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * </ul> 76b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 77b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h4>Choosing an EGL Configuration</h4> 78b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * A given Android device may support multiple possible types of drawing surfaces. 79b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The available surfaces may differ in how may channels of data are present, as 80b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * well as how many bits are allocated to each channel. Therefore, the first thing 81b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * GLSurfaceView has to do when starting to render is choose what type of surface to use. 82b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 83b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * By default GLSurfaceView chooses an available surface that's closest to a 16-bit R5G6B5 surface 84b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * with a 16-bit depth buffer and no stencil. If you would prefer a different surface (for example, 85b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * if you do not need a depth buffer) you can override the default behavior by calling one of the 86b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * setEGLConfigChooser methods. 87b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 88b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h4>Debug Behavior</h4> 89b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * You can optionally modify the behavior of GLSurfaceView by calling 90b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * one or more of the debugging methods {@link #setDebugFlags(int)}, 91b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * and {@link #setGLWrapper}. These methods may be called before and/or after setRenderer, but 92b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * typically they are called before setRenderer so that they take effect immediately. 93b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 94b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h4>Setting a Renderer</h4> 95b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Finally, you must call {@link #setRenderer} to register a {@link Renderer}. 96b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The renderer is 97b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * responsible for doing the actual OpenGL rendering. 98b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 99b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h3>Rendering Mode</h3> 100b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Once the renderer is set, you can control whether the renderer draws 101b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * continuously or on-demand by calling 102b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * {@link #setRenderMode}. The default is continuous rendering. 103b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 104b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h3>Activity Life-cycle</h3> 105b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * A GLSurfaceView must be notified when the activity is paused and resumed. GLSurfaceView clients 106b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * are required to call {@link #onPause()} when the activity pauses and 107b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * {@link #onResume()} when the activity resumes. These calls allow GLSurfaceView to 108b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * pause and resume the rendering thread, and also allow GLSurfaceView to release and recreate 109b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * the OpenGL display. 110b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 111b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h3>Handling events</h3> 112b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 113b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * To handle an event you will typically subclass GLSurfaceView and override the 114b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * appropriate method, just as you would with any other View. However, when handling 115b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * the event, you may need to communicate with the Renderer object 116b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * that's running in the rendering thread. You can do this using any 117b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * standard Java cross-thread communication mechanism. In addition, 118b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * one relatively easy way to communicate with your renderer is 119b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * to call 120b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * {@link #queueEvent(Runnable)}. For example: 121b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <pre class="prettyprint"> 122b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * class MyGLSurfaceView extends GLSurfaceView { 123b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 124b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * private MyRenderer mMyRenderer; 125b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 126b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * public void start() { 127b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * mMyRenderer = ...; 128b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * setRenderer(mMyRenderer); 129b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 130b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 131b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * public boolean onKeyDown(int keyCode, KeyEvent event) { 132b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 133b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * queueEvent(new Runnable() { 134b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * // This method will be called on the rendering 135b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * // thread: 136b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * public void run() { 137b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * mMyRenderer.handleDpadCenter(); 138b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * }}); 139b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * return true; 140b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 141b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * return super.onKeyDown(keyCode, event); 142b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 143b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 144b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * </pre> 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { 148b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 149b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The renderer only renders 150b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * when the surface is created, or when {@link #requestRender} is called. 151b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 152b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #getRenderMode() 153b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #setRenderMode(int) 154b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int RENDERMODE_WHEN_DIRTY = 0; 156b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 157b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The renderer is called 158b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * continuously to re-render the scene. 159b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 160b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #getRenderMode() 161b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #setRenderMode(int) 162b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #requestRender() 163b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 1643e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich public final static int RENDERMODE_CONTINUOUSLY = 1; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 167b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Check glError() after every GL call and throw an exception if glError indicates 168b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * that an error has occurred. This can be used to help track down which OpenGL ES call 169b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * is causing an error. 170b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 171b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #getDebugFlags 172b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #setDebugFlags 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DEBUG_CHECK_GL_ERROR = 1; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Log GL calls to the system log at "verbose" level with tag "GLSurfaceView". 178b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 179b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #getDebugFlags 180b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #setDebugFlags 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DEBUG_LOG_GL_CALLS = 2; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 184b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 185b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Standard View constructor. In order to render something, you 186b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * must call {@link #setRenderer} to register a renderer. 187b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GLSurfaceView(Context context) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project init(); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 193b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 194b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Standard View constructor. In order to render something, you 195b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * must call {@link #setRenderer} to register a renderer. 196b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GLSurfaceView(Context context, AttributeSet attrs) { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project init(); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void init() { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Install a SurfaceHolder.Callback so we get notified when the 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // underlying surface is created and destroyed 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SurfaceHolder holder = getHolder(); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project holder.addCallback(this); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 210b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Set the glWrapper. If the glWrapper is not null, its 211b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * {@link GLWrapper#wrap(GL)} method is called 212b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * whenever a surface is created. A GLWrapper can be used to wrap 213b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * the GL object that's passed to the renderer. Wrapping a GL 214b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * object enables examining and modifying the behavior of the 215b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * GL calls made by the renderer. 216b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 217b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Wrapping is typically used for debugging purposes. 218b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 219b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The default value is null. 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param glWrapper the new GLWrapper 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGLWrapper(GLWrapper glWrapper) { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLWrapper = glWrapper; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 227b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Set the debug flags to a new value. The value is 228b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * constructed by OR-together zero or more 229b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * of the DEBUG_CHECK_* constants. The debug flags take effect 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * whenever a surface is created. The default value is zero. 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param debugFlags the new debug flags 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #DEBUG_CHECK_GL_ERROR 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #DEBUG_LOG_GL_CALLS 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDebugFlags(int debugFlags) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugFlags = debugFlags; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 240b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Get the current value of the debug flags. 241b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @return the current value of the debug flags. 242b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getDebugFlags() { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDebugFlags; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 248b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Set the renderer associated with this view. Also starts the thread that 249b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * will call the renderer, which in turn causes the rendering to start. 250b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p>This method should be called once and only once in the life-cycle of 251b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * a GLSurfaceView. 252b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p>The following GLSurfaceView methods can only be called <em>before</em> 253b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * setRenderer is called: 254b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <ul> 255b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setEGLConfigChooser(boolean)} 256b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setEGLConfigChooser(EGLConfigChooser)} 257b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setEGLConfigChooser(int, int, int, int, int, int)} 258b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * </ul> 259b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 260b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The following GLSurfaceView methods can only be called <em>after</em> 261b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * setRenderer is called: 262b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <ul> 263b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #getRenderMode()} 264b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #onPause()} 265b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #onResume()} 266b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #queueEvent(Runnable)} 267b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #requestRender()} 268b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <li>{@link #setRenderMode(int)} 269b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * </ul> 270b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 271b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @param renderer the renderer to use to perform OpenGL drawing. 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setRenderer(Renderer renderer) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGLThread != null) { 275a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich throw new IllegalStateException( 276a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich "setRenderer has already been called for this instance."); 277a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 278a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich if (mEGLConfigChooser == null) { 279a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mEGLConfigChooser = new SimpleEGLConfigChooser(true); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread = new GLThread(renderer); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.start(); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 286b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Install a custom EGLConfigChooser. 287b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p>If this method is 288b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * called, it must be called before {@link #setRenderer(Renderer)} 289a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * is called. 290a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * <p> 291b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * If no setEGLConfigChooser method is called, then by default the 292b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * view will choose a config as close to 16-bit RGB as possible, with 293b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * a depth buffer as close to 16 bits as possible. 294a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * @param configChooser 295a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich */ 296a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public void setEGLConfigChooser(EGLConfigChooser configChooser) { 297a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich if (mGLThread != null) { 298a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich throw new IllegalStateException( 299a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich "setRenderer has already been called for this instance."); 300a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 301a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mEGLConfigChooser = configChooser; 302a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 303a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 304a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich /** 305b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Install a config chooser which will choose a config 306a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * as close to 16-bit RGB as possible, with or without an optional depth 307a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * buffer as close to 16-bits as possible. 308b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p>If this method is 309b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * called, it must be called before {@link #setRenderer(Renderer)} 310b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * is called. 311a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * <p> 312b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * If no setEGLConfigChooser method is called, then by default the 313a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * view will choose a config as close to 16-bit RGB as possible, with 314b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * a depth buffer as close to 16 bits as possible. 315a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * 316a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * @param needDepth 317a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich */ 318a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public void setEGLConfigChooser(boolean needDepth) { 319a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth)); 320a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 321a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 322a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich /** 323b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Install a config chooser which will choose a config 324b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * with at least the specified component sizes, and as close 325b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * to the specified component sizes as possible. 326b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p>If this method is 327a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * called, it must be called before {@link #setRenderer(Renderer)} 328a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * is called. 329a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * <p> 330b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * If no setEGLConfigChooser method is called, then by default the 331b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * view will choose a config as close to 16-bit RGB as possible, with 332b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * a depth buffer as close to 16 bits as possible. 333a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * 334a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich */ 335a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public void setEGLConfigChooser(int redSize, int greenSize, int blueSize, 336a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich int alphaSize, int depthSize, int stencilSize) { 337a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize, 338a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich blueSize, alphaSize, depthSize, stencilSize)); 339a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 340a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich /** 341b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Set the rendering mode. When renderMode is 3423e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich * RENDERMODE_CONTINUOUSLY, the renderer is called 343b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * repeatedly to re-render the scene. When renderMode 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is RENDERMODE_WHEN_DIRTY, the renderer only rendered when the surface 3453e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich * is created, or when {@link #requestRender} is called. Defaults to RENDERMODE_CONTINUOUSLY. 346b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 347b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Using RENDERMODE_WHEN_DIRTY can improve battery life and overall system performance 348b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * by allowing the GPU and CPU to idle when the view does not need to be updated. 349b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 350b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * This method can only be called after {@link #setRenderer(Renderer)} 351b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param renderMode one of the RENDERMODE_X constants 3533e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich * @see #RENDERMODE_CONTINUOUSLY 354b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #RENDERMODE_WHEN_DIRTY 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setRenderMode(int renderMode) { 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.setRenderMode(renderMode); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get the current rendering mode. May be called 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * from any thread. Must not be called before a renderer has been set. 363b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @return the current rendering mode. 3643e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich * @see #RENDERMODE_CONTINUOUSLY 365b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #RENDERMODE_WHEN_DIRTY 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getRenderMode() { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGLThread.getRenderMode(); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 372b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Request that the renderer render a frame. 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This method is typically used when the render mode has been set to 374b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * {@link #RENDERMODE_WHEN_DIRTY}, so that frames are only rendered on demand. 375b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * May be called 376b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * from any thread. Must not be called before a renderer has been set. 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestRender() { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.requestRender(); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 382b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 383b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * This method is part of the SurfaceHolder.Callback interface, and is 384b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * not normally called or subclassed by clients of GLSurfaceView. 385b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void surfaceCreated(SurfaceHolder holder) { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.surfaceCreated(); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 390b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 391b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * This method is part of the SurfaceHolder.Callback interface, and is 392b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * not normally called or subclassed by clients of GLSurfaceView. 393b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void surfaceDestroyed(SurfaceHolder holder) { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Surface will be destroyed when we return 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.surfaceDestroyed(); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 400b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * This method is part of the SurfaceHolder.Callback interface, and is 401b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * not normally called or subclassed by clients of GLSurfaceView. 402b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.onWindowResize(w, h); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inform the view that the activity is paused. The owner of this view must 409b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * call this method when the activity is paused. Calling this method will 410b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * pause the rendering thread. 411b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Must not be called before a renderer has been set. 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onPause() { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.onPause(); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inform the view that the activity is resumed. The owner of this view must 419b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * call this method when the activity is resumed. Calling this method will 420b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * recreate the OpenGL display and resume the rendering 421b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * thread. 422b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Must not be called before a renderer has been set. 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onResume() { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.onResume(); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 429b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Queue a runnable to be run on the GL rendering thread. This can be used 430b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * to communicate with the Renderer on the rendering thread. 431b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Must not be called before a renderer has been set. 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param r the runnable to be run on the GL rendering thread. 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void queueEvent(Runnable r) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.queueEvent(r); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 438b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 439b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * This method is used as part of the View class and is not normally 440b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * called or subclassed by clients of GLSurfaceView. 441b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Must not be called before a renderer has been set. 442b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onDetachedFromWindow() { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onDetachedFromWindow(); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGLThread.requestExitAndWait(); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ---------------------------------------------------------------------- 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 451b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 452b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * An interface used to wrap a GL interface. 453b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p>Typically 454b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * used for implementing debugging and tracing on top of the default 455b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * GL interface. You would typically use this by creating your own class 456b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * that implemented all the GL methods by delegating to another GL instance. 457b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Then you could add your own behavior before or after calling the 458b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * delegate. All the GLWrapper would do was instantiate and return the 459b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * wrapper GL instance: 460b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <pre class="prettyprint"> 461b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * class MyGLWrapper implements GLWrapper { 462b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * GL wrap(GL gl) { 463b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * return new MyGLImplementation(gl); 464b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 465b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * static class MyGLImplementation implements GL,GL10,GL11,... { 466b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * ... 467b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 468b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 469b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * </pre> 470b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #setGLWrapper(GLWrapper) 471b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface GLWrapper { 473b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich /** 474b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Wraps a gl interface in another gl interface. 475b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @param gl a GL interface that is to be wrapped. 476b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @return either the input argument or another GL object that wraps the input argument. 477b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich */ 478b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich GL wrap(GL gl); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A generic renderer interface. 483b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 484b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The renderer is responsible for making OpenGL calls to render a frame. 485b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 486b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * GLSurfaceView clients typically create their own classes that implement 487b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * this interface, and then call {@link GLSurfaceView#setRenderer} to 488b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * register the renderer with the GLSurfaceView. 489b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 490b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h3>Threading</h3> 491b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The renderer will be called on a separate thread, so that rendering 492b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * performance is decoupled from the UI thread. Clients typically need to 493b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * communicate with the renderer from the UI thread, because that's where 494b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * input events are received. Clients can communicate using any of the 495b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * standard Java techniques for cross-thread communication, or they can 496b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * use the {@link GLSurfaceView#queueEvent(Runnable)} convenience method. 497b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 498b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <h3>EGL Context Lost</h3> 499b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * There are situations where the EGL rendering context will be lost. This 500b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * typically happens when device wakes up after going to sleep. When 501b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * the EGL context is lost, all OpenGL resources (such as textures) that are 502b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * associated with that context will be automatically deleted. In order to 503b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * keep rendering correctly, a renderer must recreate any lost resources 504b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * that it still needs. The {@link #onSurfaceCreated(GL10, EGLConfig)} method 505b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * is a convenient place to do this. 506b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 507b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * 508b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * @see #setRenderer(Renderer) 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface Renderer { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 512b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Called when the surface is created or recreated. 513b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 514b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Called when the rendering thread 515b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * starts and whenever the EGL context is lost. The context will typically 516b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * be lost when the Android device awakes after going to sleep. 517b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 518b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Since this method is called at the beginning of rendering, as well as 519b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * every time the EGL context is lost, this method is a convenient place to put 520b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * code to create resources that need to be created when the rendering 521b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * starts, and that need to be recreated when the EGL context is lost. 522b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Textures are an example of a resource that you might want to create 523b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * here. 524b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 525b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Note that when the EGL context is lost, all OpenGL resources associated 526b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * with that context will be automatically deleted. You do not need to call 527b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * the corresponding "glDelete" methods such as glDeleteTextures to 528b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * manually delete these lost resources. 529b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gl the GL interface. Use <code>instanceof</code> to 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * test if the interface supports GL11 or higher interfaces. 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param config the EGLConfig of the created surface. Can be used 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to create matching pbuffers. 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onSurfaceCreated(GL10 gl, EGLConfig config); 536b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 538b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Called when the surface changed size. 539b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called after the surface is created and whenever 541b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * the OpenGL ES surface size changes. 542b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 543b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Typically you will set your viewport here. If your camera 544b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * is fixed then you could also set your projection matrix here: 545b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <pre class="prettyprint"> 546b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * void onSurfaceChanged(GL10 gl, int width, int height) { 547b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * gl.glViewport(0, 0, width, height); 548b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * // for a fixed camera, set the projection too 549b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * float ratio = (float) width / height; 550b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * gl.glMatrixMode(GL10.GL_PROJECTION); 551b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * gl.glLoadIdentity(); 552b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); 553b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 554b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * </pre> 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gl the GL interface. Use <code>instanceof</code> to 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * test if the interface supports GL11 or higher interfaces. 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onSurfaceChanged(GL10 gl, int width, int height); 561b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 563b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * Called to draw the current frame. 564b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 565b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * This method is responsible for drawing the current frame. 566b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 567b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * The implementation of this method typically looks like this: 568b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <pre class="prettyprint"> 569b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * void onDrawFrame(GL10 gl) { 570b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 571b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * //... other gl calls to render the scene ... 572b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * } 573b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * </pre> 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gl the GL interface. Use <code>instanceof</code> to 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * test if the interface supports GL11 or higher interfaces. 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onDrawFrame(GL10 gl); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 581b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * An interface for choosing an EGLConfig configuration from a list of 582a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * potential configurations. 583b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * <p> 584b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * This interface must be implemented by clients wishing to call 585b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * {@link GLSurfaceView#setEGLConfigChooser(EGLConfigChooser)} 586a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich */ 587a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public interface EGLConfigChooser { 588a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich /** 589a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * Choose a configuration from the list. Implementors typically 590a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * implement this method by calling 591b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * {@link EGL10#eglChooseConfig} and iterating through the results. Please consult the 592b47c641fe8330fc68dbed91163ff07015068d0ceJack Palevich * EGL specification available from The Khronos Group to learn how to call eglChooseConfig. 593a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * @param egl the EGL10 for the current display. 594a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * @param display the current display. 595a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * @return the chosen configuration. 596a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich */ 597a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGLConfig chooseConfig(EGL10 egl, EGLDisplay display); 598a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 599a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 600a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich private static abstract class BaseConfigChooser 601a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich implements EGLConfigChooser { 602a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public BaseConfigChooser(int[] configSpec) { 603a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mConfigSpec = configSpec; 604a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 605a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { 606a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich int[] num_config = new int[1]; 607a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich egl.eglChooseConfig(display, mConfigSpec, null, 0, num_config); 608a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 609a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich int numConfigs = num_config[0]; 610a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 611a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich if (numConfigs <= 0) { 612a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich throw new IllegalArgumentException( 613a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich "No configs match configSpec"); 614a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 615a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 616a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGLConfig[] configs = new EGLConfig[numConfigs]; 617a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs, 618a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich num_config); 619a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGLConfig config = chooseConfig(egl, display, configs); 620a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich if (config == null) { 621a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich throw new IllegalArgumentException("No config chosen"); 622a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 623a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich return config; 624a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 625a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 626a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, 627a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGLConfig[] configs); 628a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 629a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich protected int[] mConfigSpec; 630a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 631a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 632a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich private static class ComponentSizeChooser extends BaseConfigChooser { 633a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public ComponentSizeChooser(int redSize, int greenSize, int blueSize, 634a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich int alphaSize, int depthSize, int stencilSize) { 635a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich super(new int[] { 636a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_RED_SIZE, redSize, 637a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_GREEN_SIZE, greenSize, 638a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_BLUE_SIZE, blueSize, 639a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_ALPHA_SIZE, alphaSize, 640a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_DEPTH_SIZE, depthSize, 641a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_STENCIL_SIZE, stencilSize, 642a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_NONE}); 643a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mValue = new int[1]; 644a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mRedSize = redSize; 645a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mGreenSize = greenSize; 646a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mBlueSize = blueSize; 647a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mAlphaSize = alphaSize; 648a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mDepthSize = depthSize; 649a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mStencilSize = stencilSize; 650a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 651a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 652a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich @Override 653a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, 654a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGLConfig[] configs) { 655a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGLConfig closestConfig = null; 656a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich int closestDistance = 1000; 657a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich for(EGLConfig config : configs) { 658a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich int d = findConfigAttrib(egl, display, config, 659a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_DEPTH_SIZE, 0); 660a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich int s = findConfigAttrib(egl, display, config, 661a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGL10.EGL_STENCIL_SIZE, 0); 66282fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian if (d >= mDepthSize && s>= mStencilSize) { 66382fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian int r = findConfigAttrib(egl, display, config, 66482fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian EGL10.EGL_RED_SIZE, 0); 66582fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian int g = findConfigAttrib(egl, display, config, 66682fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian EGL10.EGL_GREEN_SIZE, 0); 66782fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian int b = findConfigAttrib(egl, display, config, 66882fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian EGL10.EGL_BLUE_SIZE, 0); 66982fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian int a = findConfigAttrib(egl, display, config, 67082fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian EGL10.EGL_ALPHA_SIZE, 0); 67182fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian int distance = Math.abs(r - mRedSize) 67282fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian + Math.abs(g - mGreenSize) 67382fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian + Math.abs(b - mBlueSize) 67482fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian + Math.abs(a - mAlphaSize); 67582fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian if (distance < closestDistance) { 67682fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian closestDistance = distance; 67782fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian closestConfig = config; 67882fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian } 679a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 680a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 681a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich return closestConfig; 682a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 683a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 684a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich private int findConfigAttrib(EGL10 egl, EGLDisplay display, 685a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich EGLConfig config, int attribute, int defaultValue) { 686a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 687a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { 688a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich return mValue[0]; 689a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 690a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich return defaultValue; 691a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 692a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 693a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich private int[] mValue; 694a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich // Subclasses can adjust these values: 695a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich protected int mRedSize; 696a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich protected int mGreenSize; 697a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich protected int mBlueSize; 698a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich protected int mAlphaSize; 699a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich protected int mDepthSize; 700a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich protected int mStencilSize; 701a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 702a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 703a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich /** 704a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * This class will choose a supported surface as close to 705a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * RGB565 as possible, with or without a depth buffer. 706a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich * 707a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich */ 708a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich private static class SimpleEGLConfigChooser extends ComponentSizeChooser { 709a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public SimpleEGLConfigChooser(boolean withDepthBuffer) { 710a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich super(4, 4, 4, 0, withDepthBuffer ? 16 : 0, 0); 711a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich // Adjust target values. This way we'll accept a 4444 or 712a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich // 555 buffer if there's no 565 buffer available. 713a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mRedSize = 5; 714a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mGreenSize = 6; 715a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mBlueSize = 5; 716a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 717a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich } 718a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich 719a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich /** 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An EGL helper class. 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class EglHelper { 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public EglHelper() { 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initialize EGL for a given configuration spec. 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param configSpec 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 732a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich public void start(){ 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get an EGL instance 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl = (EGL10) EGLContext.getEGL(); 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get to the default display. 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We can now initialize EGL for that display 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] version = new int[2]; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglInitialize(mEglDisplay, version); 748a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mEglConfig = mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create an OpenGL ES context. This must be done only once, an 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OpenGL context is a somewhat heavy object. 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig, 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_NO_CONTEXT, null); 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglSurface = null; 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * React to the creation of a new surface by creating and returning an 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OpenGL interface that renders to that surface. 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GL createSurface(SurfaceHolder holder) { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The window size has changed, so we need to create a new 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * surface. 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEglSurface != null) { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unbind and destroy the old EGL surface, if 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * there is one. 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create an EGL surface we can render into. 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglConfig, holder, null); 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Before we can issue GL commands, we need to make sure 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the context is current and bound to a surface. 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglContext); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GL gl = mEglContext.getGL(); 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGLWrapper != null) { 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gl = mGLWrapper.wrap(gl); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mDebugFlags & (DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS))!= 0) { 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int configFlags = 0; 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Writer log = null; 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mDebugFlags & DEBUG_CHECK_GL_ERROR) != 0) { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project configFlags |= GLDebugHelper.CONFIG_CHECK_GL_ERROR; 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mDebugFlags & DEBUG_LOG_GL_CALLS) != 0) { 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log = new LogWriter(); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gl = GLDebugHelper.wrap(gl, configFlags, log); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gl; 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Display the current render surface. 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return false if the context has been lost. 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean swap() { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Always check for EGL_CONTEXT_LOST, which means the context 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and all associated data were lost (For instance because 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the device went to sleep). We need to sleep until we 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * get a new surface. 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST; 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void finish() { 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEglSurface != null) { 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_NO_SURFACE, 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_NO_CONTEXT); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglSurface = null; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEglContext != null) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglDestroyContext(mEglDisplay, mEglContext); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglContext = null; 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEglDisplay != null) { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglTerminate(mEglDisplay); 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglDisplay = null; 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10 mEgl; 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGLDisplay mEglDisplay; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGLSurface mEglSurface; 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGLConfig mEglConfig; 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGLContext mEglContext; 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A generic GL Thread. Takes care of initializing EGL and GL. Delegates 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to a Renderer instance to do the actual drawing. Can be configured to 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * render continuously or on request. 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class GLThread extends Thread { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GLThread(Renderer renderer) { 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDone = false; 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = 0; 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = 0; 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestRender = true; 8673e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich mRenderMode = RENDERMODE_CONTINUOUSLY; 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRenderer = renderer; 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setName("GLThread"); 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When the android framework launches a second instance of 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * an activity, the new instance's onCreate() method may be 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called before the first instance returns from onDestroy(). 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This semaphore ensures that only one instance at a time 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accesses EGL. 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sEglSemaphore.acquire(); 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project guardedRun(); 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall thru and exit normally 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sEglSemaphore.release(); 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void guardedRun() throws InterruptedException { 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglHelper = new EglHelper(); 898a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mEglHelper.start(); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GL10 gl = null; 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean tellRendererSurfaceCreated = true; 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean tellRendererSurfaceChanged = true; 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is our main activity thread's loop, we go until 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * asked to quit. 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!mDone) { 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update the asynchronous state (window size) 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int w, h; 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean changed; 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean needStart = false; 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Runnable r; 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((r = getEvent()) != null) { 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.run(); 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPaused) { 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglHelper.finish(); 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project needStart = true; 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (needToWait()) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDone) { 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project changed = mSizeChanged; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project w = mWidth; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h = mHeight; 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSizeChanged = false; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestRender = false; 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (needStart) { 938a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich mEglHelper.start(); 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tellRendererSurfaceCreated = true; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project changed = true; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (changed) { 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gl = (GL10) mEglHelper.createSurface(getHolder()); 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tellRendererSurfaceChanged = true; 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tellRendererSurfaceCreated) { 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tellRendererSurfaceCreated = false; 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tellRendererSurfaceChanged) { 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRenderer.onSurfaceChanged(gl, w, h); 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tellRendererSurfaceChanged = false; 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((w > 0) && (h > 0)) { 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* draw a frame here */ 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRenderer.onDrawFrame(gl); 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Once we're done with GL, we need to call swapBuffers() 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to instruct the system to display the rendered frame 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglHelper.swap(); 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clean-up everything... 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglHelper.finish(); 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean needToWait() { 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDone) { 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPaused || (! mHasSurface)) { 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9813e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich if ((mWidth > 0) && (mHeight > 0) && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY))) { 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setRenderMode(int renderMode) { 9893e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) { 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("renderMode"); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRenderMode = renderMode; 9943e832dbe966c2ca0fde2f4bd87ad9c974a93a7cfJack Palevich if (renderMode == RENDERMODE_CONTINUOUSLY) { 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getRenderMode() { 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRenderMode; 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestRender() { 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestRender = true; 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void surfaceCreated() { 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHasSurface = true; 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void surfaceDestroyed() { 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHasSurface = false; 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onPause() { 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaused = true; 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onResume() { 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaused = false; 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onWindowResize(int w, int h) { 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = w; 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = h; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSizeChanged = true; 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestExitAndWait() { 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't call this from GLThread thread or it is a guaranteed 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // deadlock! 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDone = true; 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project join(); 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException ex) { 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread.currentThread().interrupt(); 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Queue an "event" to be run on the GL rendering thread. 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param r the runnable to be run on the GL rendering thread. 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void queueEvent(Runnable r) { 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventQueue.add(r); 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Runnable getEvent() { 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventQueue.size() > 0) { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEventQueue.remove(0); 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDone; 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mPaused; 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mHasSurface; 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mWidth; 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHeight; 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRenderMode; 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mRequestRender; 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Renderer mRenderer; 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>(); 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private EglHelper mEglHelper; 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class LogWriter extends Writer { 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public void close() { 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flushBuilder(); 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public void flush() { 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flushBuilder(); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public void write(char[] buf, int offset, int count) { 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < count; i++) { 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char c = buf[offset + i]; 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( c == '\n') { 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flushBuilder(); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuilder.append(c); 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void flushBuilder() { 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBuilder.length() > 0) { 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v("GLSurfaceView", mBuilder.toString()); 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuilder.delete(0, mBuilder.length()); 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private StringBuilder mBuilder = new StringBuilder(); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Semaphore sEglSemaphore = new Semaphore(1); 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mSizeChanged = true; 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GLThread mGLThread; 1131a605a51e63de2e7dc99ed085639a6f12b7f85af7Jack Palevich private EGLConfigChooser mEGLConfigChooser; 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GLWrapper mGLWrapper; 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDebugFlags; 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1135