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

Commit 1f76f88c authored by Jack Palevich's avatar Jack Palevich Committed by Android Git Automerger
Browse files

am 43429036: am 91216a7e: Merge "Fix deadlock when switching between two...

am 43429036: am 91216a7e: Merge "Fix deadlock when switching between two GLSurfaceViews" into gingerbread

Merge commit '43429036'

* commit '43429036':
  Fix deadlock when switching between two GLSurfaceViews
parents 2388ad9e 43429036
Loading
Loading
Loading
Loading
+74 −18
Original line number Original line Diff line number Diff line
@@ -222,6 +222,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
        // underlying surface is created and destroyed
        // underlying surface is created and destroyed
        SurfaceHolder holder = getHolder();
        SurfaceHolder holder = getHolder();
        holder.addCallback(this);
        holder.addCallback(this);
        // setFormat is done by SurfaceView in SDK 2.3 and newer. Uncomment
        // this statement if back-porting to 2.2 or older:
        // holder.setFormat(PixelFormat.RGB_565);
        //
        // setType is not needed for SDK 2.0 or newer. Uncomment this
        // setType is not needed for SDK 2.0 or newer. Uncomment this
        // statement if back-porting this code to older SDKs.
        // statement if back-porting this code to older SDKs.
        // holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
        // holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
@@ -1103,7 +1107,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
            mRenderer = renderer;
            mRenderer = renderer;
        }
        }



        @Override
        @Override
        public void run() {
        public void run() {
            setName("GLThread " + getId());
            setName("GLThread " + getId());
@@ -1154,6 +1157,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                boolean sizeChanged = false;
                boolean sizeChanged = false;
                boolean wantRenderNotification = false;
                boolean wantRenderNotification = false;
                boolean doRenderNotification = false;
                boolean doRenderNotification = false;
                boolean askedToReleaseEglContext = false;
                int w = 0;
                int w = 0;
                int h = 0;
                int h = 0;
                Runnable event = null;
                Runnable event = null;
@@ -1179,6 +1183,17 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                                }
                                }
                            }
                            }


                            // Do we need to give up the EGL context?
                            if (mShouldReleaseEglContext) {
                                if (LOG_SURFACE) {
                                    Log.i("GLThread", "releasing EGL context because asked to tid=" + getId());
                                }
                                stopEglSurfaceLocked();
                                stopEglContextLocked();
                                mShouldReleaseEglContext = false;
                                askedToReleaseEglContext = true;
                            }

                            // Have we lost the EGL context?
                            // Have we lost the EGL context?
                            if (lostEglContext) {
                            if (lostEglContext) {
                                stopEglSurfaceLocked();
                                stopEglSurfaceLocked();
@@ -1228,6 +1243,9 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                            }
                            }


                            if (doRenderNotification) {
                            if (doRenderNotification) {
                                if (LOG_SURFACE) {
                                    Log.i("GLThread", "sending render notification tid=" + getId());
                                }
                                wantRenderNotification = false;
                                wantRenderNotification = false;
                                doRenderNotification = false;
                                doRenderNotification = false;
                                mRenderComplete = true;
                                mRenderComplete = true;
@@ -1235,12 +1253,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                            }
                            }


                            // Ready to draw?
                            // Ready to draw?
                            if ((!mPaused) && mHasSurface
                            if (readyToDraw()) {
                                && (mWidth > 0) && (mHeight > 0)
                                && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY))) {


                                // If we don't have an EGL context, try to acquire one.
                                // If we don't have an EGL context, try to acquire one.
                                if ((! mHaveEglContext) && sGLThreadManager.tryAcquireEglContextLocked(this)) {
                                if (! mHaveEglContext) {
                                    if (askedToReleaseEglContext) {
                                        askedToReleaseEglContext = false;
                                    } else if (sGLThreadManager.tryAcquireEglContextLocked(this)) {
                                        try {
                                        try {
                                            mEglHelper.start();
                                            mEglHelper.start();
                                        } catch (RuntimeException t) {
                                        } catch (RuntimeException t) {
@@ -1252,6 +1271,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback


                                        sGLThreadManager.notifyAll();
                                        sGLThreadManager.notifyAll();
                                    }
                                    }
                                }


                                if (mHaveEglContext && !mHaveEglSurface) {
                                if (mHaveEglContext && !mHaveEglSurface) {
                                    mHaveEglSurface = true;
                                    mHaveEglSurface = true;
@@ -1265,6 +1285,9 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                                        w = mWidth;
                                        w = mWidth;
                                        h = mHeight;
                                        h = mHeight;
                                        wantRenderNotification = true;
                                        wantRenderNotification = true;
                                        if (LOG_SURFACE) {
                                            Log.i("GLThread", "noticing that we want render notification tid=" + getId());
                                        }


                                        if (DRAW_TWICE_AFTER_SIZE_CHANGED) {
                                        if (DRAW_TWICE_AFTER_SIZE_CHANGED) {
                                            // We keep mRequestRender true so that we draw twice after the size changes.
                                            // We keep mRequestRender true so that we draw twice after the size changes.
@@ -1284,7 +1307,16 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback


                            // By design, this is the only place in a GLThread thread where we wait().
                            // By design, this is the only place in a GLThread thread where we wait().
                            if (LOG_THREADS) {
                            if (LOG_THREADS) {
                                Log.i("GLThread", "waiting tid=" + getId());
                                Log.i("GLThread", "waiting tid=" + getId()
                                    + " mHaveEglContext: " + mHaveEglContext
                                    + " mHaveEglSurface: " + mHaveEglSurface
                                    + " mPaused: " + mPaused
                                    + " mHasSurface: " + mHasSurface
                                    + " mWaitingForSurface: " + mWaitingForSurface
                                    + " mWidth: " + mWidth
                                    + " mHeight: " + mHeight
                                    + " mRequestRender: " + mRequestRender
                                    + " mRenderMode: " + mRenderMode);
                            }
                            }
                            sGLThreadManager.wait();
                            sGLThreadManager.wait();
                        }
                        }
@@ -1326,7 +1358,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                    }
                    }


                    if (LOG_RENDERER_DRAW_FRAME) {
                    if (LOG_RENDERER_DRAW_FRAME) {
                        Log.w("GLThread", "onDrawFrame");
                        Log.w("GLThread", "onDrawFrame tid=" + getId());
                    }
                    }
                    mRenderer.onDrawFrame(gl);
                    mRenderer.onDrawFrame(gl);
                    if (!mEglHelper.swap()) {
                    if (!mEglHelper.swap()) {
@@ -1352,6 +1384,16 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
            }
            }
        }
        }


        public boolean ableToDraw() {
            return mHaveEglContext && mHaveEglSurface && readyToDraw();
        }

        private boolean readyToDraw() {
            return (!mPaused) && mHasSurface
                && (mWidth > 0) && (mHeight > 0)
                && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY));
        }

        public void setRenderMode(int renderMode) {
        public void setRenderMode(int renderMode) {
            if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) {
            if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) {
                throw new IllegalArgumentException("renderMode");
                throw new IllegalArgumentException("renderMode");
@@ -1461,9 +1503,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                sGLThreadManager.notifyAll();
                sGLThreadManager.notifyAll();


                // Wait for thread to react to resize and render a frame
                // Wait for thread to react to resize and render a frame
                while (! mExited && !mPaused && !mRenderComplete ) {
                while (! mExited && !mPaused && !mRenderComplete
                        && (mGLThread != null && mGLThread.ableToDraw())) {
                    if (LOG_SURFACE) {
                    if (LOG_SURFACE) {
                        Log.i("Main thread", "onWindowResize waiting for render complete.");
                        Log.i("Main thread", "onWindowResize waiting for render complete from tid=" + mGLThread.getId());
                    }
                    }
                    try {
                    try {
                        sGLThreadManager.wait();
                        sGLThreadManager.wait();
@@ -1490,6 +1533,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
            }
            }
        }
        }


        public void requestReleaseEglContextLocked() {
            mShouldReleaseEglContext = true;
            sGLThreadManager.notifyAll();
        }

        /**
        /**
         * Queue an "event" to be run on the GL rendering thread.
         * Queue an "event" to be run on the GL rendering thread.
         * @param r the runnable to be run on the GL rendering thread.
         * @param r the runnable to be run on the GL rendering thread.
@@ -1514,6 +1562,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
        private boolean mWaitingForSurface;
        private boolean mWaitingForSurface;
        private boolean mHaveEglContext;
        private boolean mHaveEglContext;
        private boolean mHaveEglSurface;
        private boolean mHaveEglSurface;
        private boolean mShouldReleaseEglContext;
        private int mWidth;
        private int mWidth;
        private int mHeight;
        private int mHeight;
        private int mRenderMode;
        private int mRenderMode;
@@ -1598,6 +1647,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
            if (mMultipleGLESContextsAllowed) {
            if (mMultipleGLESContextsAllowed) {
                return true;
                return true;
            }
            }
            // Notify the owning thread that it should release the context.
            // TODO: implement a fairness policy. Currently
            // if the owning thread is drawing continuously it will just
            // reacquire the EGL context.
            if (mEglOwner != null) {
                mEglOwner.requestReleaseEglContextLocked();
            }
            return false;
            return false;
        }
        }