summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2009-12-21 14:47:35 +0800
committerJack Palevich <jackpal@google.com>2009-12-21 14:47:35 +0800
commit21799450ec751fd3c41c7e66e69fefb094b3050b (patch)
tree97bb8d957e78bd77c97cc7547aa16a9ac26d0882
parent0f10c2bd328da35ab8aeb534af2d3f51416b3e2c (diff)
downloadframeworks_base-21799450ec751fd3c41c7e66e69fefb094b3050b.zip
frameworks_base-21799450ec751fd3c41c7e66e69fefb094b3050b.tar.gz
frameworks_base-21799450ec751fd3c41c7e66e69fefb094b3050b.tar.bz2
Fix bug 2325244 screen turns black for a brief period of time
The problem was a black first frame when creating a surface, or a garbage frame when the surface was resized. The cause was lack of synchronization between the render thread and the UI thread. The UI thread would typically return before the render thread had a chance to draw its first frame. The fix was to make the UI thread wait until at least one frame had been rendered by the rendering thread. The waiting is done in the surfaceChanged method because we know that surfaceChanged will be called in both the surface created and surface changed cases.
-rw-r--r--opengl/java/android/opengl/GLSurfaceView.java29
1 files changed, 29 insertions, 0 deletions
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 185398b..28b10ec 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -1066,6 +1066,8 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
GL10 gl = null;
boolean createEglSurface = false;
boolean sizeChanged = false;
+ boolean wantRenderNotification = false;
+ boolean doRenderNotification = false;
int w = 0;
int h = 0;
Runnable event = null;
@@ -1111,6 +1113,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
sGLThreadManager.notifyAll();
}
+ if (doRenderNotification) {
+ wantRenderNotification = false;
+ doRenderNotification = false;
+ mRenderComplete = true;
+ sGLThreadManager.notifyAll();
+ }
+
// Ready to draw?
if ((!mPaused) && mHasSurface
&& (mWidth > 0) && (mHeight > 0)
@@ -1130,6 +1139,8 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
sizeChanged = true;
w = mWidth;
h = mHeight;
+ wantRenderNotification = true;
+
if (DRAW_TWICE_AFTER_SIZE_CHANGED) {
// We keep mRequestRender true so that we draw twice after the size changes.
// (Once because of mSizeChanged, the second time because of mRequestRender.)
@@ -1187,6 +1198,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
Log.i("GLThread", "egl surface lost tid=" + getId());
}
}
+
+ if (wantRenderNotification) {
+ doRenderNotification = true;
+ }
}
} finally {
/*
@@ -1269,7 +1284,20 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
mHeight = h;
mSizeChanged = true;
mRequestRender = true;
+ mRenderComplete = false;
sGLThreadManager.notifyAll();
+
+ // Wait for thread to react to resize and render a frame
+ while (! mExited && !mPaused && !mRenderComplete ) {
+ if (LOG_SURFACE) {
+ Log.i("Main thread", "onWindowResize waiting for render complete.");
+ }
+ try {
+ sGLThreadManager.wait();
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
}
}
@@ -1315,6 +1343,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
private int mHeight;
private int mRenderMode;
private boolean mRequestRender;
+ private boolean mRenderComplete;
private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>();
// End of member variables protected by the sGLThreadManager monitor.