summaryrefslogtreecommitdiffstats
path: root/opengl/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'opengl/java/android')
-rw-r--r--opengl/java/android/opengl/GLSurfaceView.java98
-rw-r--r--opengl/java/android/opengl/GLUtils.java13
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();
}