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

Commit 0b2d6d53 authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge "SurfaceView: Ensure the Surface remains valid with SurfaceHolder#lockCanvas"

parents 6707d97e 38876847
Loading
Loading
Loading
Loading
+31 −11
Original line number Diff line number Diff line
@@ -119,6 +119,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
    final int[] mLocation = new int[2];

    @UnsupportedAppUsage
    // Used to ensure the Surface remains valid between SurfaceHolder#lockCanvas and
    // SurfaceHolder#unlockCanvasAndPost calls. This prevents SurfaceView from destroying or
    // invalidating the Surface. This means this lock should be acquired when destroying the
    // BlastBufferQueue.
    final ReentrantLock mSurfaceLock = new ReentrantLock();
    @UnsupportedAppUsage
    final Surface mSurface = new Surface();       // Current surface in use
@@ -724,14 +728,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall

    private void releaseSurfaces(boolean releaseSurfacePackage) {
        mSurfaceAlpha = 1f;
        try {
            mSurfaceLock.lock();
            mSurface.destroy();

        synchronized (mSurfaceControlLock) {
            if (mBlastBufferQueue != null) {
                mBlastBufferQueue.destroy();
                mBlastBufferQueue = null;
            }
        } finally {
            mSurfaceLock.unlock();
        }

        synchronized (mSurfaceControlLock) {
            final Transaction transaction = new Transaction();
            if (mSurfaceControl != null) {
                transaction.remove(mSurfaceControl);
@@ -1232,16 +1240,21 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                    .build();
        }

        mTransformHint = viewRoot.getBufferTransformHint();
        mBlastSurfaceControl.setTransformHint(mTransformHint);

        // Always recreate the IGBP for compatibility. This can be optimized in the future but
        // the behavior change will need to be gated by SDK version.
        try {
            mSurfaceLock.lock();
            if (mBlastBufferQueue != null) {
                mBlastBufferQueue.destroy();
            }
        mTransformHint = viewRoot.getBufferTransformHint();
        mBlastSurfaceControl.setTransformHint(mTransformHint);

            mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
            mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
        } finally {
            mSurfaceLock.unlock();
        }
        mBlastBufferQueue.setTransactionHangCallback(ViewRootImpl.sTransactionHangCallback);
    }

@@ -1814,7 +1827,14 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
            // so the next connect will always work if we end up reusing
            // the surface.
            if (mSurface.isValid()) {
                // We need to grab this lock since mSurface.forceScopedDisconnect
                // will free buffers from the queue.
                try {
                    mSurfaceLock.lock();
                    mSurface.forceScopedDisconnect();
                } finally {
                    mSurfaceLock.unlock();
                }
            }
        }
    }