diff options
author | Jack Palevich <jackpal@google.com> | 2009-11-08 10:55:56 +0800 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-11-08 10:55:56 +0800 |
commit | 32d416518473f3bf5323d660e5910ca5633ffed6 (patch) | |
tree | 91f2387a92133132b0faf49989245c5ca5709291 /opengl | |
parent | a44249500f6c1c7a75b5c420fa2e81c2aa317a10 (diff) | |
download | frameworks_base-32d416518473f3bf5323d660e5910ca5633ffed6.zip frameworks_base-32d416518473f3bf5323d660e5910ca5633ffed6.tar.gz frameworks_base-32d416518473f3bf5323d660e5910ca5633ffed6.tar.bz2 |
Allow a GLThread to release and reacquire the EGL Surface as needed.
We currently only allow one GLThread to have an active EGL Surface at a
time.(This may be lifted in the future, when EGL and GL are reentrant.)
Prior to this change we would enforce this rule by having older GLThreads
quit when a new GLThread started. That had the drawback of leaving the
older GLSurfaceViews in a zombie state -- their GLThreads would be
gone.
We now enforce this rule by just releasing and reacquiring the EGL surface
context as needed.
Specific changes to the code:
created private helper methods - startEgl and stopEgl to help manage
starting and stopping EGL.
Move the calls to sGLThreadManager start and end from the outermost run
method into the startEgl / stopEgl methods.
Reworked the wait loop to handle starting and stopping EGL as needed.
needToWait() gets simpler -- just looks at current status.
sGLThreadManager.shouldQuit was replaced by shouldHaveEgl.
This is another step in fixing bug 2228262.
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/java/android/opengl/GLSurfaceView.java | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index ac27a2d..0330163 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -971,33 +971,41 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback * accesses EGL. */ try { - try { - sGLThreadManager.start(this); - } catch (InterruptedException e) { - return; - } guardedRun(); } catch (InterruptedException e) { // fall thru and exit normally } finally { - try { - sGLThreadManager.end(this); - } finally { - synchronized(this) { - if (LOG_THREADS) { - Log.i("GLThread", "exiting tid=" + getId()); - } - mDone = true; - notifyAll(); + synchronized(this) { + if (LOG_THREADS) { + Log.i("GLThread", "exiting tid=" + getId()); } + mDone = true; + notifyAll(); } } } + private void startEgl() throws InterruptedException { + if (! mHaveEgl) { + mHaveEgl = true; + sGLThreadManager.start(this); + mEglHelper.start(); + } + } + + private void stopEgl() { + if (mHaveEgl) { + mHaveEgl = false; + mEglHelper.destroySurface(); + mEglHelper.finish(); + sGLThreadManager.end(this); + } + } + private void guardedRun() throws InterruptedException { mEglHelper = new EglHelper(); try { - mEglHelper.start(); + startEgl(); GL10 gl = null; boolean tellRendererSurfaceCreated = true; @@ -1021,20 +1029,30 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback r.run(); } if (mPaused) { - mEglHelper.destroySurface(); - mEglHelper.finish(); + stopEgl(); needStart = true; } - while (needToWait()) { - if (LOG_THREADS) { - Log.i("GLThread", "needToWait tid=" + getId()); - } + while(true) { if (!mHasSurface) { if (!mWaitingForSurface) { - mEglHelper.destroySurface(); + stopEgl(); mWaitingForSurface = true; notifyAll(); } + } else { + boolean shouldHaveEgl = sGLThreadManager.shouldHaveEgl(this); + if (mHaveEgl && (!shouldHaveEgl)) { + stopEgl(); + } else if ((!mHaveEgl) && shouldHaveEgl) { + startEgl(); + needStart = true; + } + } + if (!needToWait()) { + break; + } + if (LOG_THREADS) { + Log.i("GLThread", "needToWait tid=" + getId()); } wait(); } @@ -1053,7 +1071,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } if (needStart) { - mEglHelper.start(); + startEgl(); tellRendererSurfaceCreated = true; changed = true; } @@ -1084,21 +1102,16 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback /* * clean-up everything... */ - mEglHelper.destroySurface(); - mEglHelper.finish(); + stopEgl(); } } private boolean needToWait() { - if (sGLThreadManager.shouldQuit(this)) { - mDone = true; - notifyAll(); - } if (mDone) { return false; } - if (mPaused || (! mHasSurface)) { + if (mPaused || (! mHasSurface) || (! mHaveEgl)) { return true; } @@ -1223,6 +1236,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private boolean mPaused; private boolean mHasSurface; private boolean mWaitingForSurface; + private boolean mHaveEgl; private int mWidth; private int mHeight; private int mRenderMode; @@ -1273,9 +1287,9 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } static class GLThreadManager { - public boolean shouldQuit(GLThread thread) { + public boolean shouldHaveEgl(GLThread thread) { synchronized(this) { - return thread != mMostRecentGLThread; + return thread == mMostRecentGLThread || mMostRecentGLThread == null; } } public void start(GLThread thread) throws InterruptedException { |