am 79447b20: resolved conflicts for merge of 84872738 to eclair-mr2

Merge commit '79447b2087c8c820d742185dda7305101f9656f0' into eclair-mr2-plus-aosp

* commit '79447b2087c8c820d742185dda7305101f9656f0':
  Improve GLSurfaceView to avoid deadlocks and race conditions.
This commit is contained in:
Jack Palevich
2009-11-06 00:25:44 -08:00
committed by Android Git Automerger

View File

@@ -146,6 +146,7 @@ import android.view.SurfaceView;
* *
*/ */
public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private final static boolean LOG_THREADS = false;
/** /**
* The renderer only renders * The renderer only renders
* when the surface is created, or when {@link #requestRender} is called. * when the surface is created, or when {@link #requestRender} is called.
@@ -964,11 +965,15 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
mRequestRender = true; mRequestRender = true;
mRenderMode = RENDERMODE_CONTINUOUSLY; mRenderMode = RENDERMODE_CONTINUOUSLY;
mRenderer = renderer; mRenderer = renderer;
setName("GLThread");
} }
@Override @Override
public void run() { public void run() {
setName("GLThread " + getId());
if (LOG_THREADS) {
Log.i("GLThread", "starting tid=" + getId());
}
/* /*
* When the android framework launches a second instance of * When the android framework launches a second instance of
* an activity, the new instance's onCreate() method may be * an activity, the new instance's onCreate() method may be
@@ -978,12 +983,26 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
* accesses EGL. * accesses EGL.
*/ */
try { try {
sGLAccessLock.acquire(); try {
sGLThreadManager.start(this);
} catch (InterruptedException e) {
return;
}
guardedRun(); guardedRun();
} catch (InterruptedException e) { } catch (InterruptedException e) {
// fall thru and exit normally // fall thru and exit normally
} finally { } finally {
sGLAccessLock.release(); try {
sGLThreadManager.end(this);
} finally {
synchronized(this) {
if (LOG_THREADS) {
Log.i("GLThread", "exiting tid=" + getId());
}
mDone = true;
notifyAll();
}
}
} }
} }
@@ -1019,11 +1038,14 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
needStart = true; needStart = true;
} }
while (needToWait()) { while (needToWait()) {
if (LOG_THREADS) {
Log.i("GLThread", "needToWait tid=" + getId());
}
if (!mHasSurface) { if (!mHasSurface) {
if (!mWaitingForSurface) { if (!mWaitingForSurface) {
mEglHelper.destroySurface(); mEglHelper.destroySurface();
mWaitingForSurface = true; mWaitingForSurface = true;
notify(); notifyAll();
} }
} }
wait(); wait();
@@ -1039,6 +1061,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
if (mHasSurface && mWaitingForSurface) { if (mHasSurface && mWaitingForSurface) {
changed = true; changed = true;
mWaitingForSurface = false; mWaitingForSurface = false;
notifyAll();
} }
} }
if (needStart) { if (needStart) {
@@ -1048,7 +1071,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
} }
if (changed) { if (changed) {
gl = (GL10) mEglHelper.createSurface(getHolder()); gl = (GL10) mEglHelper.createSurface(getHolder());
sGLAccessLock.checkGLDriver(gl); sGLThreadManager.checkGLDriver(gl);
tellRendererSurfaceChanged = true; tellRendererSurfaceChanged = true;
} }
if (tellRendererSurfaceCreated) { if (tellRendererSurfaceCreated) {
@@ -1080,6 +1103,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
} }
private boolean needToWait() { private boolean needToWait() {
if (sGLThreadManager.shouldQuit(this)) {
mDone = true;
notifyAll();
}
if (mDone) { if (mDone) {
return false; return false;
} }
@@ -1102,7 +1129,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
synchronized(this) { synchronized(this) {
mRenderMode = renderMode; mRenderMode = renderMode;
if (renderMode == RENDERMODE_CONTINUOUSLY) { if (renderMode == RENDERMODE_CONTINUOUSLY) {
notify(); notifyAll();
} }
} }
} }
@@ -1116,22 +1143,28 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
public void requestRender() { public void requestRender() {
synchronized(this) { synchronized(this) {
mRequestRender = true; mRequestRender = true;
notify(); notifyAll();
} }
} }
public void surfaceCreated() { public void surfaceCreated() {
synchronized(this) { synchronized(this) {
if (LOG_THREADS) {
Log.i("GLThread", "surfaceCreated tid=" + getId());
}
mHasSurface = true; mHasSurface = true;
notify(); notifyAll();
} }
} }
public void surfaceDestroyed() { public void surfaceDestroyed() {
synchronized(this) { synchronized(this) {
if (LOG_THREADS) {
Log.i("GLThread", "surfaceDestroyed tid=" + getId());
}
mHasSurface = false; mHasSurface = false;
notify(); notifyAll();
while(!mWaitingForSurface && isAlive()) { while(!mWaitingForSurface && isAlive() && ! mDone) {
try { try {
wait(); wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -1144,13 +1177,15 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
public void onPause() { public void onPause() {
synchronized (this) { synchronized (this) {
mPaused = true; mPaused = true;
notifyAll();
} }
} }
public void onResume() { public void onResume() {
synchronized (this) { synchronized (this) {
mPaused = false; mPaused = false;
notify(); mRequestRender = true;
notifyAll();
} }
} }
@@ -1159,7 +1194,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
mWidth = w; mWidth = w;
mHeight = h; mHeight = h;
mSizeChanged = true; mSizeChanged = true;
notify(); notifyAll();
} }
} }
@@ -1168,7 +1203,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
// deadlock! // deadlock!
synchronized(this) { synchronized(this) {
mDone = true; mDone = true;
notify(); notifyAll();
} }
try { try {
join(); join();
@@ -1250,9 +1285,9 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
} }
} }
private static class GLAccessLock { private static class GLThreadManager {
public synchronized void acquire() throws InterruptedException { public void start(GLThread thread) throws InterruptedException {
if (! mGLESVersionCheckComplete) { if (! mGLESVersionCheckComplete) {
mGLESVersion = SystemProperties.getInt( mGLESVersion = SystemProperties.getInt(
"ro.opengles.version", "ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED); ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
@@ -1262,18 +1297,32 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
mGLESVersionCheckComplete = true; mGLESVersionCheckComplete = true;
} }
while ((! mMultipleGLESContextsAllowed) GLThread oldThread = null;
&& mGLContextCount > 0) { synchronized(this) {
wait(); mMostRecentGLThread = thread;
oldThread = mMostRecentGLThread;
while ((! mMultipleGLESContextsAllowed)
&& mGLContextCount > 0) {
wait();
}
mGLContextCount++;
} }
mGLContextCount++; if (oldThread != null && ! mMultipleGLESContextsAllowed) {
synchronized(oldThread) {
oldThread.notifyAll();
}
}
} }
public synchronized void release() { public synchronized void end(GLThread thread) {
mGLContextCount--; mGLContextCount--;
notifyAll(); notifyAll();
if (mMostRecentGLThread == thread) {
mMostRecentGLThread = null;
}
} }
public synchronized void checkGLDriver(GL10 gl) { public synchronized void checkGLDriver(GL10 gl) {
@@ -1288,8 +1337,15 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
} }
} }
public boolean shouldQuit(GLThread thread) {
synchronized(this) {
return thread != mMostRecentGLThread;
}
}
private boolean mGLESVersionCheckComplete; private boolean mGLESVersionCheckComplete;
private int mGLESVersion; private int mGLESVersion;
private GLThread mMostRecentGLThread;
private boolean mGLESDriverCheckComplete; private boolean mGLESDriverCheckComplete;
private boolean mMultipleGLESContextsAllowed; private boolean mMultipleGLESContextsAllowed;
private int mGLContextCount; private int mGLContextCount;
@@ -1298,8 +1354,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
"Q3Dimension MSM7500 "; "Q3Dimension MSM7500 ";
}; };
private static GLAccessLock sGLAccessLock = new GLAccessLock(); private static final GLThreadManager sGLThreadManager = new GLThreadManager();
private boolean mSizeChanged = true; private boolean mSizeChanged = true;
private GLThread mGLThread; private GLThread mGLThread;