diff --git a/app/build.gradle b/app/build.gradle index 86d81d400..e3d3a2031 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -68,6 +68,7 @@ dependencies { compile 'com.github.seven332:refreshlayout:0.1.0' compile 'com.github.seven332:ripple:0.1.1' compile 'com.github.seven332:streampipe:0.1.0' + compile 'com.github.seven332:tuxiang:0.1.0' compile 'com.github.seven332:unifile:0.1.3' compile 'com.github.seven332:yorozuya-collect:0.1.2' compile 'com.github.seven332:yorozuya-thread:0.1.0' diff --git a/app/src/main/java/com/hippo/gl/view/EGLError.java b/app/src/main/java/com/hippo/gl/view/EGLError.java deleted file mode 100644 index ddb348673..000000000 --- a/app/src/main/java/com/hippo/gl/view/EGLError.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.gl.view; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGL11; - -final class EGLError { - private EGLError() {} - - private static String getHex(int value) { - return "0x" + Integer.toHexString(value); - } - - public static String getErrorString(int error) { - switch (error) { - case EGL10.EGL_SUCCESS: - return "EGL_SUCCESS"; - case EGL10.EGL_NOT_INITIALIZED: - return "EGL_NOT_INITIALIZED"; - case EGL10.EGL_BAD_ACCESS: - return "EGL_BAD_ACCESS"; - case EGL10.EGL_BAD_ALLOC: - return "EGL_BAD_ALLOC"; - case EGL10.EGL_BAD_ATTRIBUTE: - return "EGL_BAD_ATTRIBUTE"; - case EGL10.EGL_BAD_CONFIG: - return "EGL_BAD_CONFIG"; - case EGL10.EGL_BAD_CONTEXT: - return "EGL_BAD_CONTEXT"; - case EGL10.EGL_BAD_CURRENT_SURFACE: - return "EGL_BAD_CURRENT_SURFACE"; - case EGL10.EGL_BAD_DISPLAY: - return "EGL_BAD_DISPLAY"; - case EGL10.EGL_BAD_MATCH: - return "EGL_BAD_MATCH"; - case EGL10.EGL_BAD_NATIVE_PIXMAP: - return "EGL_BAD_NATIVE_PIXMAP"; - case EGL10.EGL_BAD_NATIVE_WINDOW: - return "EGL_BAD_NATIVE_WINDOW"; - case EGL10.EGL_BAD_PARAMETER: - return "EGL_BAD_PARAMETER"; - case EGL10.EGL_BAD_SURFACE: - return "EGL_BAD_SURFACE"; - case EGL11.EGL_CONTEXT_LOST: - return "EGL_CONTEXT_LOST"; - default: - return getHex(error); - } - } -} diff --git a/app/src/main/java/com/hippo/gl/view/GLRootView.java b/app/src/main/java/com/hippo/gl/view/GLRootView.java index 0f0344d7a..aae5fe1b4 100644 --- a/app/src/main/java/com/hippo/gl/view/GLRootView.java +++ b/app/src/main/java/com/hippo/gl/view/GLRootView.java @@ -39,6 +39,9 @@ import com.hippo.gl.glrenderer.UploadedTexture; import com.hippo.gl.util.ApiHelper; import com.hippo.gl.util.GalleryUtils; import com.hippo.gl.util.MotionEventHelper; +import com.hippo.tuxiang.BestConfigChooser; +import com.hippo.tuxiang.GLSurfaceView; +import com.hippo.tuxiang.Renderer; import com.hippo.yorozuya.AssertUtils; import java.util.ArrayDeque; @@ -46,9 +49,7 @@ import java.util.ArrayList; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; -import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.opengles.GL10; import javax.microedition.khronos.opengles.GL11; @@ -62,7 +63,7 @@ import javax.microedition.khronos.opengles.GL11; // (2) The public methods of CameraHeadUpDisplay // (3) The overridden methods in GLRootView. public class GLRootView extends GLSurfaceView - implements GLSurfaceView.Renderer, GLRoot { + implements Renderer, GLRoot { private static final String TAG = "GLRootView"; private static final boolean DEBUG_FPS = false; @@ -630,111 +631,4 @@ public class GLRootView extends GLSurfaceView super.finalize(); } } - - private static abstract class BaseConfigChooser implements EGLConfigChooser { - - public BaseConfigChooser(int[] configSpec) { - mConfigSpec = filterConfigSpec(configSpec); - } - - @Override - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { - int[] num_config = new int[1]; - if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, - num_config)) { - throw new IllegalArgumentException("eglChooseConfig failed"); - } - - int numConfigs = num_config[0]; - - if (numConfigs <= 0) { - throw new IllegalArgumentException( - "No configs match configSpec"); - } - - EGLConfig[] configs = new EGLConfig[numConfigs]; - if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs, - num_config)) { - throw new IllegalArgumentException("eglChooseConfig#2 failed"); - } - EGLConfig config = chooseConfig(egl, display, configs); - if (config == null) { - throw new IllegalArgumentException("No config chosen"); - } - return config; - } - - abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, - EGLConfig[] configs); - - protected int[] mConfigSpec; - - private int[] filterConfigSpec(int[] configSpec) { - /* We know none of the subclasses define EGL_RENDERABLE_TYPE. - * And we know the configSpec is well formed. - */ - int len = configSpec.length; - int[] newConfigSpec = new int[len + 2]; - System.arraycopy(configSpec, 0, newConfigSpec, 0, len-1); - newConfigSpec[len-1] = EGL10.EGL_RENDERABLE_TYPE; - newConfigSpec[len] = 4; // EGL14.EGL_OPENGL_ES2_BIT; /* EGL_OPENGL_ES2_BIT */ - newConfigSpec[len+1] = EGL10.EGL_NONE; - return newConfigSpec; - } - } - - private static class BestConfigChooser extends BaseConfigChooser { - - private final int[] mValue = new int[1]; - - public BestConfigChooser() { - super(new int[] { - EGL10.EGL_DEPTH_SIZE, 0, - EGL10.EGL_STENCIL_SIZE, 0, - EGL10.EGL_NONE}); - } - - @Override - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, - EGLConfig[] configs) { - // Use score to avoid "No config chosen" - int configIndex = 0; - int maxScore = 0; - - for (int i = 0, n = configs.length; i < n; i++) { - EGLConfig config = configs[i]; - int redSize = findConfigAttrib(egl, display, config, - EGL10.EGL_RED_SIZE, 0); - int greenSize = findConfigAttrib(egl, display, config, - EGL10.EGL_GREEN_SIZE, 0); - int blueSize = findConfigAttrib(egl, display, config, - EGL10.EGL_BLUE_SIZE, 0); - int alphaSize = findConfigAttrib(egl, display, config, - EGL10.EGL_ALPHA_SIZE, 0); - int sampleBuffers = findConfigAttrib(egl, display, config, - EGL10.EGL_SAMPLE_BUFFERS, 0); - int samples = findConfigAttrib(egl, display, config, - EGL10.EGL_SAMPLES, 0); - - int score = redSize + greenSize + blueSize + alphaSize + - sampleBuffers + samples; - - if (score > maxScore) { - maxScore = score; - configIndex = i; - } - } - - return configs[configIndex]; - } - - private int findConfigAttrib(EGL10 egl, EGLDisplay display, - EGLConfig config, int attribute, int defaultValue) { - - if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { - return mValue[0]; - } - return defaultValue; - } - } } diff --git a/app/src/main/java/com/hippo/gl/view/GLSurfaceView.java b/app/src/main/java/com/hippo/gl/view/GLSurfaceView.java deleted file mode 100644 index 863a01d2a..000000000 --- a/app/src/main/java/com/hippo/gl/view/GLSurfaceView.java +++ /dev/null @@ -1,1794 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.gl.view; - -import android.content.Context; -import android.content.pm.ConfigurationInfo; -import android.opengl.GLDebugHelper; -import android.util.AttributeSet; -import android.util.Log; -import android.view.SurfaceHolder; -import android.view.SurfaceView; - -import java.io.Writer; -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGL11; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; -import javax.microedition.khronos.opengles.GL; -import javax.microedition.khronos.opengles.GL10; - -// android-6.0.1_r31 -/** - * An implementation of SurfaceView that uses the dedicated surface for - * displaying OpenGL rendering. - *
- * A GLSurfaceView provides the following features: - *
- *
For more information about how to use OpenGL, read the - * OpenGL developer guide.
- *- * Typically you use GLSurfaceView by subclassing it and overriding one or more of the - * View system input event methods. If your application does not need to override event - * methods then GLSurfaceView can be used as-is. For the most part - * GLSurfaceView behavior is customized by calling "set" methods rather than by subclassing. - * For example, unlike a regular View, drawing is delegated to a separate Renderer object which - * is registered with the GLSurfaceView - * using the {@link #setRenderer(Renderer)} call. - *
- *
- *
- *
- * By default GLSurfaceView chooses a EGLConfig that has an RGB_888 pixel format, - * with at least a 16-bit depth buffer and no stencil. - *
- * If you would prefer a different EGLConfig - * you can override the default behavior by calling one of the - * setEGLConfigChooser methods. - *
- *
- *
- *
- *
- *
- * To handle an event you will typically subclass GLSurfaceView and override the - * appropriate method, just as you would with any other View. However, when handling - * the event, you may need to communicate with the Renderer object - * that's running in the rendering thread. You can do this using any - * standard Java cross-thread communication mechanism. In addition, - * one relatively easy way to communicate with your renderer is - * to call - * {@link #queueEvent(Runnable)}. For example: - *
- * class MyGLSurfaceView extends GLSurfaceView {
- *
- * private MyRenderer mMyRenderer;
- *
- * public void start() {
- * mMyRenderer = ...;
- * setRenderer(mMyRenderer);
- * }
- *
- * public boolean onKeyDown(int keyCode, KeyEvent event) {
- * if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- * queueEvent(new Runnable() {
- * // This method will be called on the rendering
- * // thread:
- * public void run() {
- * mMyRenderer.handleDpadCenter();
- * }});
- * return true;
- * }
- * return super.onKeyDown(keyCode, event);
- * }
- * }
- *
- *
- */
-public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
- private final static String TAG = "GLSurfaceView";
- private final static boolean LOG_ATTACH_DETACH = false;
- private final static boolean LOG_THREADS = false;
- private final static boolean LOG_PAUSE_RESUME = false;
- private final static boolean LOG_SURFACE = false;
- private final static boolean LOG_RENDERER = false;
- private final static boolean LOG_RENDERER_DRAW_FRAME = false;
- private final static boolean LOG_EGL = false;
- /**
- * The renderer only renders
- * when the surface is created, or when {@link #requestRender} is called.
- *
- * @see #getRenderMode()
- * @see #setRenderMode(int)
- * @see #requestRender()
- */
- public final static int RENDERMODE_WHEN_DIRTY = 0;
- /**
- * The renderer is called
- * continuously to re-render the scene.
- *
- * @see #getRenderMode()
- * @see #setRenderMode(int)
- */
- public final static int RENDERMODE_CONTINUOUSLY = 1;
-
- /**
- * Check glError() after every GL call and throw an exception if glError indicates
- * that an error has occurred. This can be used to help track down which OpenGL ES call
- * is causing an error.
- *
- * @see #getDebugFlags
- * @see #setDebugFlags
- */
- public final static int DEBUG_CHECK_GL_ERROR = 1;
-
- /**
- * Log GL calls to the system log at "verbose" level with tag "GLSurfaceView".
- *
- * @see #getDebugFlags
- * @see #setDebugFlags
- */
- public final static int DEBUG_LOG_GL_CALLS = 2;
-
- /**
- * Standard View constructor. In order to render something, you
- * must call {@link #setRenderer} to register a renderer.
- */
- public GLSurfaceView(Context context) {
- super(context);
- init();
- }
-
- /**
- * Standard View constructor. In order to render something, you
- * must call {@link #setRenderer} to register a renderer.
- */
- public GLSurfaceView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mGLThread != null) {
- // GLThread may still be running if this view was never
- // attached to a window.
- mGLThread.requestExitAndWait();
- }
- } finally {
- super.finalize();
- }
- }
-
- private void init() {
- // Install a SurfaceHolder.Callback so we get notified when the
- // underlying surface is created and destroyed
- SurfaceHolder holder = getHolder();
- holder.addCallback(this);
- // setFormat is done by SurfaceView in SDK 2.3 and newer. Uncomment
- // this statement if back-porting to 2.2 or older:
- // holder.setFormat(PixelFormat.RGB_565);
- //
- // setType is not needed for SDK 2.0 or newer. Uncomment this
- // statement if back-porting this code to older SDKs.
- // holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
- }
-
- /**
- * Set the glWrapper. If the glWrapper is not null, its
- * {@link GLWrapper#wrap(GL)} method is called
- * whenever a surface is created. A GLWrapper can be used to wrap
- * the GL object that's passed to the renderer. Wrapping a GL
- * object enables examining and modifying the behavior of the
- * GL calls made by the renderer.
- * - * Wrapping is typically used for debugging purposes. - *
- * The default value is null. - * @param glWrapper the new GLWrapper - */ - public void setGLWrapper(GLWrapper glWrapper) { - mGLWrapper = glWrapper; - } - - /** - * Set the debug flags to a new value. The value is - * constructed by OR-together zero or more - * of the DEBUG_CHECK_* constants. The debug flags take effect - * whenever a surface is created. The default value is zero. - * @param debugFlags the new debug flags - * @see #DEBUG_CHECK_GL_ERROR - * @see #DEBUG_LOG_GL_CALLS - */ - public void setDebugFlags(int debugFlags) { - mDebugFlags = debugFlags; - } - - /** - * Get the current value of the debug flags. - * @return the current value of the debug flags. - */ - public int getDebugFlags() { - return mDebugFlags; - } - - /** - * Control whether the EGL context is preserved when the GLSurfaceView is paused and - * resumed. - *
- * If set to true, then the EGL context may be preserved when the GLSurfaceView is paused. - * Whether the EGL context is actually preserved or not depends upon whether the - * Android device that the program is running on can support an arbitrary number of EGL - * contexts or not. Devices that can only support a limited number of EGL contexts must - * release the EGL context in order to allow multiple applications to share the GPU. - *
- * If set to false, the EGL context will be released when the GLSurfaceView is paused, - * and recreated when the GLSurfaceView is resumed. - *
- * - * The default is false. - * - * @param preserveOnPause preserve the EGL context when paused - */ - public void setPreserveEGLContextOnPause(boolean preserveOnPause) { - mPreserveEGLContextOnPause = preserveOnPause; - } - - /** - * @return true if the EGL context will be preserved when paused - */ - public boolean getPreserveEGLContextOnPause() { - return mPreserveEGLContextOnPause; - } - - /** - * Set the renderer associated with this view. Also starts the thread that - * will call the renderer, which in turn causes the rendering to start. - *
This method should be called once and only once in the life-cycle of - * a GLSurfaceView. - *
The following GLSurfaceView methods can only be called before - * setRenderer is called: - *
- * The following GLSurfaceView methods can only be called after - * setRenderer is called: - *
If this method is - * called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *
- * If this method is not called, then by default - * a context will be created with no shared context and - * with a null attribute list. - */ - public void setEGLContextFactory(EGLContextFactory factory) { - checkRenderThreadState(); - mEGLContextFactory = factory; - } - - /** - * Install a custom EGLWindowSurfaceFactory. - *
If this method is - * called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *
- * If this method is not called, then by default - * a window surface will be created with a null attribute list. - */ - public void setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory factory) { - checkRenderThreadState(); - mEGLWindowSurfaceFactory = factory; - } - - /** - * Install a custom EGLConfigChooser. - *
If this method is - * called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *
- * If no setEGLConfigChooser method is called, then by default the - * view will choose an EGLConfig that is compatible with the current - * android.view.Surface, with a depth buffer depth of - * at least 16 bits. - * @param configChooser - */ - public void setEGLConfigChooser(EGLConfigChooser configChooser) { - checkRenderThreadState(); - mEGLConfigChooser = configChooser; - } - - /** - * Inform the default EGLContextFactory and default EGLConfigChooser - * which EGLContext client version to pick. - *
Use this method to create an OpenGL ES 2.0-compatible context. - * Example: - *
- * public MyView(Context context) {
- * super(context);
- * setEGLContextClientVersion(2); // Pick an OpenGL ES 2.0 context.
- * setRenderer(new MyRenderer());
- * }
- *
- * Note: Activities which require OpenGL ES 2.0 should indicate this by - * setting @lt;uses-feature android:glEsVersion="0x00020000" /> in the activity's - * AndroidManifest.xml file. - *
If this method is called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *
This method only affects the behavior of the default EGLContexFactory and the - * default EGLConfigChooser. If - * {@link #setEGLContextFactory(EGLContextFactory)} has been called, then the supplied - * EGLContextFactory is responsible for creating an OpenGL ES 2.0-compatible context. - * If - * {@link #setEGLConfigChooser(EGLConfigChooser)} has been called, then the supplied - * EGLConfigChooser is responsible for choosing an OpenGL ES 2.0-compatible config. - * @param version The EGLContext client version to choose. Use 2 for OpenGL ES 2.0 - */ - public void setEGLContextClientVersion(int version) { - checkRenderThreadState(); - mEGLContextClientVersion = version; - } - - /** - * Set the rendering mode. When renderMode is - * RENDERMODE_CONTINUOUSLY, the renderer is called - * repeatedly to re-render the scene. When renderMode - * is RENDERMODE_WHEN_DIRTY, the renderer only rendered when the surface - * is created, or when {@link #requestRender} is called. Defaults to RENDERMODE_CONTINUOUSLY. - *
- * Using RENDERMODE_WHEN_DIRTY can improve battery life and overall system performance - * by allowing the GPU and CPU to idle when the view does not need to be updated. - *
- * This method can only be called after {@link #setRenderer(Renderer)} - * - * @param renderMode one of the RENDERMODE_X constants - * @see #RENDERMODE_CONTINUOUSLY - * @see #RENDERMODE_WHEN_DIRTY - */ - public void setRenderMode(int renderMode) { - mGLThread.setRenderMode(renderMode); - } - - /** - * Get the current rendering mode. May be called - * from any thread. Must not be called before a renderer has been set. - * @return the current rendering mode. - * @see #RENDERMODE_CONTINUOUSLY - * @see #RENDERMODE_WHEN_DIRTY - */ - public int getRenderMode() { - return mGLThread.getRenderMode(); - } - - /** - * Request that the renderer render a frame. - * This method is typically used when the render mode has been set to - * {@link #RENDERMODE_WHEN_DIRTY}, so that frames are only rendered on demand. - * May be called - * from any thread. Must not be called before a renderer has been set. - */ - public void requestRender() { - mGLThread.requestRender(); - } - - /** - * This method is part of the SurfaceHolder.Callback interface, and is - * not normally called or subclassed by clients of GLSurfaceView. - */ - @Override - public void surfaceCreated(SurfaceHolder holder) { - mGLThread.surfaceCreated(); - } - - /** - * This method is part of the SurfaceHolder.Callback interface, and is - * not normally called or subclassed by clients of GLSurfaceView. - */ - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - // Surface will be destroyed when we return - mGLThread.surfaceDestroyed(); - } - - /** - * This method is part of the SurfaceHolder.Callback interface, and is - * not normally called or subclassed by clients of GLSurfaceView. - */ - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { - mGLThread.onWindowResize(w, h); - } - - /** - * Inform the view that the activity is paused. The owner of this view must - * call this method when the activity is paused. Calling this method will - * pause the rendering thread. - * Must not be called before a renderer has been set. - */ - public void onPause() { - mGLThread.onPause(); - } - - /** - * Inform the view that the activity is resumed. The owner of this view must - * call this method when the activity is resumed. Calling this method will - * recreate the OpenGL display and resume the rendering - * thread. - * Must not be called before a renderer has been set. - */ - public void onResume() { - mGLThread.onResume(); - } - - /** - * Queue a runnable to be run on the GL rendering thread. This can be used - * to communicate with the Renderer on the rendering thread. - * Must not be called before a renderer has been set. - * @param r the runnable to be run on the GL rendering thread. - */ - public void queueEvent(Runnable r) { - mGLThread.queueEvent(r); - } - - /** - * This method is used as part of the View class and is not normally - * called or subclassed by clients of GLSurfaceView. - */ - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (LOG_ATTACH_DETACH) { - Log.d(TAG, "onAttachedToWindow reattach =" + mDetached); - } - if (mDetached && (mRenderer != null)) { - int renderMode = RENDERMODE_CONTINUOUSLY; - if (mGLThread != null) { - renderMode = mGLThread.getRenderMode(); - } - mGLThread = new GLThread(mThisWeakRef); - if (renderMode != RENDERMODE_CONTINUOUSLY) { - mGLThread.setRenderMode(renderMode); - } - mGLThread.start(); - } - mDetached = false; - } - - @Override - protected void onDetachedFromWindow() { - if (LOG_ATTACH_DETACH) { - Log.d(TAG, "onDetachedFromWindow"); - } - if (mGLThread != null) { - mGLThread.requestExitAndWait(); - } - mDetached = true; - super.onDetachedFromWindow(); - } - - // ---------------------------------------------------------------------- - - /** - * An interface used to wrap a GL interface. - *
Typically - * used for implementing debugging and tracing on top of the default - * GL interface. You would typically use this by creating your own class - * that implemented all the GL methods by delegating to another GL instance. - * Then you could add your own behavior before or after calling the - * delegate. All the GLWrapper would do was instantiate and return the - * wrapper GL instance: - *
- * class MyGLWrapper implements GLWrapper {
- * GL wrap(GL gl) {
- * return new MyGLImplementation(gl);
- * }
- * static class MyGLImplementation implements GL,GL10,GL11,... {
- * ...
- * }
- * }
- *
- * @see #setGLWrapper(GLWrapper)
- */
- public interface GLWrapper {
- /**
- * Wraps a gl interface in another gl interface.
- * @param gl a GL interface that is to be wrapped.
- * @return either the input argument or another GL object that wraps the input argument.
- */
- GL wrap(GL gl);
- }
-
- /**
- * A generic renderer interface.
- * - * The renderer is responsible for making OpenGL calls to render a frame. - *
- * GLSurfaceView clients typically create their own classes that implement - * this interface, and then call {@link GLSurfaceView#setRenderer} to - * register the renderer with the GLSurfaceView. - *
- * - *
For more information about how to use OpenGL, read the - * OpenGL developer guide.
- *- *
- * Called when the rendering thread - * starts and whenever the EGL context is lost. The EGL context will typically - * be lost when the Android device awakes after going to sleep. - *
- * Since this method is called at the beginning of rendering, as well as - * every time the EGL context is lost, this method is a convenient place to put - * code to create resources that need to be created when the rendering - * starts, and that need to be recreated when the EGL context is lost. - * Textures are an example of a resource that you might want to create - * here. - *
- * Note that when the EGL context is lost, all OpenGL resources associated - * with that context will be automatically deleted. You do not need to call - * the corresponding "glDelete" methods such as glDeleteTextures to - * manually delete these lost resources. - *
- * @param gl the GL interface. Use instanceof to
- * test if the interface supports GL11 or higher interfaces.
- * @param config the EGLConfig of the created surface. Can be used
- * to create matching pbuffers.
- */
- void onSurfaceCreated(GL10 gl, EGLConfig config);
-
- /**
- * Called when the surface changed size.
- *
- * Called after the surface is created and whenever - * the OpenGL ES surface size changes. - *
- * Typically you will set your viewport here. If your camera - * is fixed then you could also set your projection matrix here: - *
- * void onSurfaceChanged(GL10 gl, int width, int height) {
- * gl.glViewport(0, 0, width, height);
- * // for a fixed camera, set the projection too
- * float ratio = (float) width / height;
- * gl.glMatrixMode(GL10.GL_PROJECTION);
- * gl.glLoadIdentity();
- * gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
- * }
- *
- * @param gl the GL interface. Use instanceof to
- * test if the interface supports GL11 or higher interfaces.
- * @param width
- * @param height
- */
- void onSurfaceChanged(GL10 gl, int width, int height);
-
- /**
- * Called to draw the current frame.
- * - * This method is responsible for drawing the current frame. - *
- * The implementation of this method typically looks like this: - *
- * void onDrawFrame(GL10 gl) {
- * gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
- * //... other gl calls to render the scene ...
- * }
- *
- * @param gl the GL interface. Use instanceof to
- * test if the interface supports GL11 or higher interfaces.
- */
- void onDrawFrame(GL10 gl);
-
- void onSurfaceDestroyed();
- }
-
- /**
- * An interface for customizing the eglCreateContext and eglDestroyContext calls.
- * - * This interface must be implemented by clients wishing to call - * {@link GLSurfaceView#setEGLContextFactory(EGLContextFactory)} - */ - public interface EGLContextFactory { - EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig); - void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context); - } - - private class DefaultContextFactory implements EGLContextFactory { - private int EGL_CONTEXT_CLIENT_VERSION = 0x3098; - - @Override - public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) { - int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, mEGLContextClientVersion, - EGL10.EGL_NONE }; - - return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, - mEGLContextClientVersion != 0 ? attrib_list : null); - } - - @Override - public void destroyContext(EGL10 egl, EGLDisplay display, - EGLContext context) { - if (!egl.eglDestroyContext(display, context)) { - Log.e("DefaultContextFactory", "display:" + display + " context: " + context); - if (LOG_THREADS) { - Log.i("DefaultContextFactory", "tid=" + Thread.currentThread().getId()); - } - EglHelper.throwEglException("eglDestroyContex", egl.eglGetError()); - } - } - } - - /** - * An interface for customizing the eglCreateWindowSurface and eglDestroySurface calls. - *
- * This interface must be implemented by clients wishing to call - * {@link GLSurfaceView#setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory)} - */ - public interface EGLWindowSurfaceFactory { - /** - * @return null if the surface cannot be constructed. - */ - EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, EGLConfig config, - Object nativeWindow); - void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface); - } - - private static class DefaultWindowSurfaceFactory implements EGLWindowSurfaceFactory { - - @Override - public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, - EGLConfig config, Object nativeWindow) { - EGLSurface result = null; - try { - result = egl.eglCreateWindowSurface(display, config, nativeWindow, null); - } catch (IllegalArgumentException e) { - // This exception indicates that the surface flinger surface - // is not valid. This can happen if the surface flinger surface has - // been torn down, but the application has not yet been - // notified via SurfaceHolder.Callback.surfaceDestroyed. - // In theory the application should be notified first, - // but in practice sometimes it is not. See b/4588890 - Log.e(TAG, "eglCreateWindowSurface", e); - } - return result; - } - - @Override - public void destroySurface(EGL10 egl, EGLDisplay display, - EGLSurface surface) { - egl.eglDestroySurface(display, surface); - } - } - - /** - * An interface for choosing an EGLConfig configuration from a list of - * potential configurations. - *
- * This interface must be implemented by clients wishing to call
- * {@link GLSurfaceView#setEGLConfigChooser(EGLConfigChooser)}
- */
- public interface EGLConfigChooser {
- /**
- * Choose a configuration from the list. Implementors typically
- * implement this method by calling
- * {@link EGL10#eglChooseConfig} and iterating through the results. Please consult the
- * EGL specification available from The Khronos Group to learn how to call eglChooseConfig.
- * @param egl the EGL10 for the current display.
- * @param display the current display.
- * @return the chosen configuration.
- */
- EGLConfig chooseConfig(EGL10 egl, EGLDisplay display);
- }
-
- /**
- * An EGL helper class.
- */
-
- private static class EglHelper {
- public EglHelper(WeakReference