Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49c9a3a3 authored by Jack Palevich's avatar Jack Palevich
Browse files

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.
parent 11b97c50
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -999,6 +999,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;
@@ -1044,6 +1046,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)
@@ -1063,6 +1072,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.)
@@ -1119,6 +1130,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                            Log.i("GLThread", "egl surface lost tid=" + getId());
                        }
                    }

                    if (wantRenderNotification) {
                        doRenderNotification = true;
                    }
                }
            } finally {
                /*
@@ -1201,7 +1216,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();
                    }
                }
            }
        }

@@ -1247,6 +1275,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.