diff options
author | Jack Palevich <jackpal@google.com> | 2009-09-21 15:59:17 -0700 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-09-21 15:59:17 -0700 |
commit | 1bd888ba2e0976a179258cfa65ef07be31602a0a (patch) | |
tree | 5d1d9ef76fd5f1c29e029f1ead80e0116548ade1 /opengl | |
parent | a953ed4bc08cf5fc98f17a399adbd8afdd8293d5 (diff) | |
download | frameworks_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.java | 27 |
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; |