diff options
Diffstat (limited to 'opengl/java/android')
| -rw-r--r-- | opengl/java/android/opengl/GLSurfaceView.java | 98 | ||||
| -rw-r--r-- | opengl/java/android/opengl/GLUtils.java | 13 |
2 files changed, 68 insertions, 43 deletions
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index 8e2294c..c937a09 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -779,8 +779,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (LOG_THREADS) { Log.i("DefaultContextFactory", "tid=" + Thread.currentThread().getId()); } - throw new RuntimeException("eglDestroyContext failed: " - + EGLLogWrapper.getErrorString(egl.eglGetError())); + EglHelper.throwEglException("eglDestroyContex", egl.eglGetError()); } } } @@ -1094,7 +1093,12 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback * the context is current and bound to a surface. */ if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { - throwEglException("eglMakeCurrent"); + /* + * Could not make the context current, probably because the underlying + * SurfaceView surface has been destroyed. + */ + logEglErrorAsWarning("EGLHelper", "eglMakeCurrent", mEgl.eglGetError()); + return false; } return true; @@ -1130,32 +1134,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback /** * Display the current render surface. - * @return false if the context has been lost. + * @return the EGL error code from eglSwapBuffers. */ - public boolean swap() { + public int swap() { if (! mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { - - /* - * Check for EGL_CONTEXT_LOST, which means the context - * and all associated data were lost (For instance because - * the device went to sleep). We need to sleep until we - * get a new surface. - */ - int error = mEgl.eglGetError(); - switch(error) { - case EGL11.EGL_CONTEXT_LOST: - return false; - case EGL10.EGL_BAD_NATIVE_WINDOW: - // The native window is bad, probably because the - // window manager has closed it. Ignore this error, - // on the expectation that the application will be closed soon. - Log.e("EglHelper", "eglSwapBuffers returned EGL_BAD_NATIVE_WINDOW. tid=" + Thread.currentThread().getId()); - break; - default: - throwEglException("eglSwapBuffers", error); - } + return mEgl.eglGetError(); } - return true; + return EGL10.EGL_SUCCESS; } public void destroySurface() { @@ -1199,14 +1184,23 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback throwEglException(function, mEgl.eglGetError()); } - private void throwEglException(String function, int error) { - String message = function + " failed: " + EGLLogWrapper.getErrorString(error); + public static void throwEglException(String function, int error) { + String message = formatEglError(function, error); if (LOG_THREADS) { - Log.e("EglHelper", "throwEglException tid=" + Thread.currentThread().getId() + " " + message); + Log.e("EglHelper", "throwEglException tid=" + Thread.currentThread().getId() + " " + + message); } throw new RuntimeException(message); } + public static void logEglErrorAsWarning(String tag, String function, int error) { + Log.w(tag, formatEglError(function, error)); + } + + public static String formatEglError(String function, int error) { + return function + " failed: " + EGLLogWrapper.getErrorString(error); + } + private WeakReference<GLSurfaceView> mGLSurfaceViewWeakRef; EGL10 mEgl; EGLDisplay mEglDisplay; @@ -1353,7 +1347,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } - // Have we lost the surface view surface? + // Have we lost the SurfaceView surface? if ((! mHasSurface) && (! mWaitingForSurface)) { if (LOG_SURFACE) { Log.i("GLThread", "noticed surfaceView surface lost tid=" + getId()); @@ -1362,6 +1356,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback stopEglSurfaceLocked(); } mWaitingForSurface = true; + mSurfaceIsBad = false; sGLThreadManager.notifyAll(); } @@ -1419,7 +1414,9 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback h = mHeight; wantRenderNotification = true; if (LOG_SURFACE) { - Log.i("GLThread", "noticing that we want render notification tid=" + getId()); + Log.i("GLThread", + "noticing that we want render notification tid=" + + getId()); } // Destroy and recreate the EGL surface. @@ -1440,6 +1437,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback + " mHaveEglSurface: " + mHaveEglSurface + " mPaused: " + mPaused + " mHasSurface: " + mHasSurface + + " mSurfaceIsBad: " + mSurfaceIsBad + " mWaitingForSurface: " + mWaitingForSurface + " mWidth: " + mWidth + " mHeight: " + mHeight @@ -1461,8 +1459,8 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback Log.w("GLThread", "egl createSurface"); } if (!mEglHelper.createSurface()) { - // Couldn't create a surface. Quit quietly. - break; + mSurfaceIsBad = true; + continue; } createEglSurface = false; } @@ -1505,11 +1503,24 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback view.mRenderer.onDrawFrame(gl); } } - if (!mEglHelper.swap()) { - if (LOG_SURFACE) { - Log.i("GLThread", "egl context lost tid=" + getId()); - } - lostEglContext = true; + int swapError = mEglHelper.swap(); + switch (swapError) { + case EGL10.EGL_SUCCESS: + break; + case EGL11.EGL_CONTEXT_LOST: + if (LOG_SURFACE) { + Log.i("GLThread", "egl context lost tid=" + getId()); + } + lostEglContext = true; + break; + default: + // Other errors typically mean that the current surface is bad, + // probably because the SurfaceView surface has been destroyed, + // but we haven't been notified yet. + // Log the error to help developers understand why rendering stopped. + EglHelper.logEglErrorAsWarning("GLThread", "eglSwapBuffers", swapError); + mSurfaceIsBad = true; + break; } if (wantRenderNotification) { @@ -1533,7 +1544,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } private boolean readyToDraw() { - return (!mPaused) && mHasSurface + return (!mPaused) && mHasSurface && (!mSurfaceIsBad) && (mWidth > 0) && (mHeight > 0) && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY)); } @@ -1703,6 +1714,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private boolean mRequestPaused; private boolean mPaused; private boolean mHasSurface; + private boolean mSurfaceIsBad; private boolean mWaitingForSurface; private boolean mHaveEglContext; private boolean mHaveEglSurface; @@ -1841,7 +1853,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback ! renderer.startsWith(kMSM7K_RENDERER_PREFIX); notifyAll(); } - mLimitedGLESContexts = !mMultipleGLESContextsAllowed || renderer.startsWith(kADRENO); + mLimitedGLESContexts = !mMultipleGLESContextsAllowed; if (LOG_SURFACE) { Log.w(TAG, "checkGLDriver renderer = \"" + renderer + "\" multipleContextsAllowed = " + mMultipleGLESContextsAllowed @@ -1867,6 +1879,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } + /** + * This check was required for some pre-Android-3.0 hardware. Android 3.0 provides + * support for hardware-accelerated views, therefore multiple EGL contexts are + * supported on all Android 3.0+ EGL drivers. + */ private boolean mGLESVersionCheckComplete; private int mGLESVersion; private boolean mGLESDriverCheckComplete; @@ -1875,7 +1892,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private static final int kGLES_20 = 0x20000; private static final String kMSM7K_RENDERER_PREFIX = "Q3Dimension MSM7500 "; - private static final String kADRENO = "Adreno"; private GLThread mEglOwner; } diff --git a/opengl/java/android/opengl/GLUtils.java b/opengl/java/android/opengl/GLUtils.java index 125c56e..1527f22 100644 --- a/opengl/java/android/opengl/GLUtils.java +++ b/opengl/java/android/opengl/GLUtils.java @@ -227,9 +227,9 @@ public final class GLUtils { /** * Return a string for the EGL error code, or the hex representation * if the error is unknown. - * + * * @param error The EGL error to convert into a String. - * + * * @return An error string corresponding to the EGL error code. */ public static String getEGLErrorString(int error) { @@ -269,6 +269,14 @@ public final class GLUtils { } } + /** + * Enable tracing of OpenGL functions for this application. + * @hide + */ + public static void enableTracing() { + native_enableTracing(); + } + native private static void nativeClassInit(); native private static int native_getInternalFormat(Bitmap bitmap); @@ -277,4 +285,5 @@ public final class GLUtils { Bitmap bitmap, int type, int border); native private static int native_texSubImage2D(int target, int level, int xoffset, int yoffset, Bitmap bitmap, int format, int type); + native private static void native_enableTracing(); } |
