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

Commit e0b684f7 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

SurfaceView: Revert SurfaceLock locking changes

This reverts commit 9e3cd053
and commit 74c76039.

Initially we made a change to address a performance issue
in SurfaceView caused by holding the mSurfaceLock whenever
we went though the updateSurfaces loop. This had a side
effects of causing an ANR since the locking order changed.

The followup fix removed the lock but broke some API
contracts around lock and unlock canvas.

Subsequent fixes, which never went into QPR, introduced
new issues. Changing the locking order is too risky
QPR so lets revert and try to rework the locking
mechanism in U.

Test: app in b/234006724 does not ANR
Test: app in b/235188096 does not crash
Test: app in b/239895124 does not ANR
Test: app in b/239142077 does not crash
Test: atest SurfaceViewTest

Bug: 235188096
Change-Id: I99c5bb707ecad7c8d3c1fbd8b4105a77d58c145d
parent 2701e807
Loading
Loading
Loading
Loading
+103 −106
Original line number Diff line number Diff line
@@ -724,9 +724,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall

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

        synchronized (mSurfaceControlLock) {
            mSurface.destroy();
            if (mBlastBufferQueue != null) {
                mBlastBufferQueue.destroy();
                mBlastBufferQueue = null;
@@ -775,6 +775,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
            Transaction surfaceUpdateTransaction) {
        boolean realSizeChanged = false;

        mSurfaceLock.lock();
        try {
            mDrawingStopped = !mVisible;

            if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
@@ -814,6 +816,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                setBufferSize(surfaceUpdateTransaction);
            }
            if (sizeChanged || creating || !isHardwareAccelerated()) {

                // Set a window crop when creating the surface or changing its size to
                // crop the buffer to the surface size since the buffer producer may
                // use SCALING_MODE_SCALE and submit a larger size than the surface
@@ -851,6 +854,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
            }
            applyTransactionOnVriDraw(surfaceUpdateTransaction);
            updateEmbeddedAccessibilityMatrix(false);

            mSurfaceFrame.left = 0;
            mSurfaceFrame.top = 0;
            if (translator == null) {
@@ -867,7 +871,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                    || mLastSurfaceHeight != surfaceHeight;
            mLastSurfaceWidth = surfaceWidth;
            mLastSurfaceHeight = surfaceHeight;

        } finally {
            mSurfaceLock.unlock();
        }
        return realSizeChanged;
    }

@@ -1133,30 +1139,21 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
     *                          Surface for compatibility reasons.
     */
    private void copySurface(boolean surfaceControlCreated, boolean bufferSizeChanged) {
        if (surfaceControlCreated) {
            mSurface.copyFrom(mBlastBufferQueue);
        }

        if (bufferSizeChanged && getContext().getApplicationInfo().targetSdkVersion
                < Build.VERSION_CODES.O) {
            // Some legacy applications use the underlying native {@link Surface} object
            // as a key to whether anything has changed. In these cases, updates to the
            // existing {@link Surface} will be ignored when the size changes.
            // Therefore, we must explicitly recreate the {@link Surface} in these
            // cases.
        boolean needsWorkaround = bufferSizeChanged &&
            getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O;
       if (!surfaceControlCreated && !needsWorkaround) {
           return;
       }
       mSurfaceLock.lock();
       try {
           if (surfaceControlCreated) {
               mSurface.copyFrom(mBlastBufferQueue);
           }

           if (needsWorkaround) {
            if (mBlastBufferQueue != null) {
                mSurface.transferFrom(mBlastBufferQueue.createSurfaceWithHandle());
            }
        }
       } finally {
           mSurfaceLock.unlock();
       }
    }

    private void setBufferSize(Transaction transaction) {