summaryrefslogtreecommitdiffstats
path: root/opengl
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2009-09-21 15:59:17 -0700
committerJack Palevich <jackpal@google.com>2009-09-21 15:59:17 -0700
commit1bd888ba2e0976a179258cfa65ef07be31602a0a (patch)
tree5d1d9ef76fd5f1c29e029f1ead80e0116548ade1 /opengl
parenta953ed4bc08cf5fc98f17a399adbd8afdd8293d5 (diff)
downloadframeworks_base-1bd888ba2e0976a179258cfa65ef07be31602a0a.zip
frameworks_base-1bd888ba2e0976a179258cfa65ef07be31602a0a.tar.gz
frameworks_base-1bd888ba2e0976a179258cfa65ef07be31602a0a.tar.bz2
Fix GLSurfaceView to sync surfaceDestroyed with GL rendering thread
Until now we had a race condition where the GL rendering thread could continue rendering a frame after we have returned from the SurfaceHolder.Callback.surfaceDestroyed notification.
Diffstat (limited to 'opengl')
-rw-r--r--opengl/java/android/opengl/GLSurfaceView.java27
1 files changed, 26 insertions, 1 deletions
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 022da0c..07c19b4 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -826,7 +826,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST;
}
- public void finish() {
+ public void destroySurface() {
if (mEglSurface != null) {
mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE,
@@ -834,6 +834,9 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
mEglSurface = null;
}
+ }
+
+ public void finish() {
if (mEglContext != null) {
mEgl.eglDestroyContext(mEglDisplay, mEglContext);
mEglContext = null;
@@ -919,10 +922,18 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
r.run();
}
if (mPaused) {
+ mEglHelper.destroySurface();
mEglHelper.finish();
needStart = true;
}
while (needToWait()) {
+ if (!mHasSurface) {
+ if (!mWaitingForSurface) {
+ mEglHelper.destroySurface();
+ mWaitingForSurface = true;
+ notify();
+ }
+ }
wait();
}
if (mDone) {
@@ -933,6 +944,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
h = mHeight;
mSizeChanged = false;
mRequestRender = false;
+ if (mHasSurface && mWaitingForSurface) {
+ changed = true;
+ mWaitingForSurface = false;
+ mRequestRender = true; // Forces a redraw for RENDERMODE_RENDER_WHEN_DIRTY
+ }
}
if (needStart) {
mEglHelper.start();
@@ -966,6 +982,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
/*
* clean-up everything...
*/
+ mEglHelper.destroySurface();
mEglHelper.finish();
}
@@ -1021,6 +1038,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
synchronized(this) {
mHasSurface = false;
notify();
+ while(!mWaitingForSurface) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
}
}
@@ -1083,6 +1107,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
private boolean mDone;
private boolean mPaused;
private boolean mHasSurface;
+ private boolean mWaitingForSurface;
private int mWidth;
private int mHeight;
private int mRenderMode;