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

Commit 48cda45f authored by chaviw's avatar chaviw Committed by Robert Carr
Browse files

Replace VRI and SV sync logic with SurfaceSyncer

Instead of using the count to keep track of sync information in VRI, use
the SurfaceSyncer to handle this. This also means changing SV since SV
would also increment the VRI counter. This cleans up the logic since
code that's used for the SurfaceSyncer can be re-used in VRI.

Test: seamless rotation, launching apps
Bug: 200284684
Fixes: 225776224
Change-Id: Idb505b35eef9f99b2f76e9d1f1b26f5c50ed9a90
parent 5c687a51
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -401,7 +401,7 @@ public class SurfaceControlViewHost {
    public void relayout(WindowManager.LayoutParams attrs,
            WindowlessWindowManager.ResizeCompleteCallback callback) {
        mViewRoot.setLayoutParams(attrs, false);
        mViewRoot.setReportNextDraw();
        mViewRoot.setReportNextDraw(true /* syncBuffer */);
        mWm.setCompletionCallback(mViewRoot.mWindow.asBinder(), callback);
    }

+77 −68
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.view.accessibility.IAccessibilityEmbeddedConnection;
import com.android.internal.view.SurfaceCallbackHelper;

import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;

@@ -203,19 +204,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall

    private int mSurfaceFlags = SurfaceControl.HIDDEN;

    private int mPendingReportDraws;

    /**
     * Transaction that should be used from the render thread. This transaction is only thread safe
     * with other calls directly from the render thread.
     */
    private final SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction();

    /**
     * Used on the main thread to set the transaction that will be synced with the main window.
     */
    private final Transaction mSyncTransaction = new Transaction();

    /**
     * Transaction that should be used whe
     * {@link HardwareRenderer.FrameDrawingCallback#onFrameDraw} is invoked. All
@@ -391,31 +385,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        }
    }

    private void performDrawFinished(@Nullable Transaction t) {
        if (t != null) {
            mSyncTransaction.merge(t);
        }

        if (mPendingReportDraws > 0) {
    private void performDrawFinished() {
        mDrawFinished = true;
        if (mAttachedToWindow) {
            mParent.requestTransparentRegion(SurfaceView.this);
                notifyDrawFinished();
            invalidate();
        }
        } else {
            Log.e(TAG, System.identityHashCode(this) + "finished drawing"
                    + " but no pending report draw (extra call"
                    + " to draw completion runnable?)");
        }
    }

    void notifyDrawFinished() {
        ViewRootImpl viewRoot = getViewRootImpl();
        if (viewRoot != null) {
            viewRoot.pendingDrawFinished(mSyncTransaction);
        }
        mPendingReportDraws--;
    }

    @Override
@@ -438,10 +413,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
            mGlobalListenersAdded = false;
        }

        while (mPendingReportDraws > 0) {
            notifyDrawFinished();
        }

        mRequestedVisible = false;

        updateSurface();
@@ -993,10 +964,17 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                    return;
                }

                final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
                        translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
                final boolean redrawNeeded = sizeChanged || creating || hintChanged
                        || (mVisible && !mDrawFinished);
                final TransactionCallback transactionCallback =
                        redrawNeeded ? new TransactionCallback() : null;
                if (redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInSync()) {
                    mBlastBufferQueue.syncNextTransaction(
                            false /* acquireSingleBuffer */,
                            transactionCallback::onTransactionReady);
                }
                final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
                        translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);

                try {
                    SurfaceHolder.Callback[] callbacks = null;
@@ -1015,9 +993,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                            mIsCreating = true;
                            if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                                    + "visibleChanged -- surfaceCreated");
                            if (callbacks == null) {
                            callbacks = getSurfaceCallbacks();
                            }
                            for (SurfaceHolder.Callback c : callbacks) {
                                c.surfaceCreated(mSurfaceHolder);
                            }
@@ -1035,32 +1011,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                            }
                        }
                        if (redrawNeeded) {
                            if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                                    + "surfaceRedrawNeeded");
                            if (callbacks == null) {
                                callbacks = getSurfaceCallbacks();
                            }

                            final boolean wasRelayoutRequested = viewRoot.wasRelayoutRequested();
                            if (wasRelayoutRequested && (mBlastBufferQueue != null)) {
                                mBlastBufferQueue.syncNextTransaction(
                                        false /* acquireSingleBuffer */,
                                        this::onDrawFinished);
                            }
                            mPendingReportDraws++;
                            viewRoot.drawPending();
                            SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
                                if (mBlastBufferQueue != null) {
                                    mBlastBufferQueue.stopContinuousSyncTransaction();
                                }
                                // If relayout was requested, then a callback from BBQ will
                                // be invoked with the sync transaction. onDrawFinished will be
                                // called in there
                                if (!wasRelayoutRequested) {
                                    onDrawFinished(null);
                                }
                            });
                            sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
                            redrawNeeded(callbacks, transactionCallback);
                        }
                    }
                } finally {
@@ -1079,6 +1030,64 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        }
    }

    private void redrawNeeded(SurfaceHolder.Callback[] callbacks,
            @Nullable TransactionCallback transactionCallback) {
        if (DEBUG) {
            Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
        }
        final SurfaceHolder.Callback[] capturedCallbacks =
                callbacks == null ? getSurfaceCallbacks() : callbacks;

        ViewRootImpl viewRoot = getViewRootImpl();
        boolean isVriSync = viewRoot.addToSync(syncBufferCallback ->
                redrawNeededAsync(capturedCallbacks, () -> {
                    if (mBlastBufferQueue != null) {
                        mBlastBufferQueue.stopContinuousSyncTransaction();
                    }

                    Transaction t = null;
                    if (transactionCallback != null && mBlastBufferQueue != null) {
                        t = transactionCallback.waitForTransaction();
                    }
                    // If relayout was requested, then a callback from BBQ will
                    // be invoked with the sync transaction. onDrawFinished will be
                    // called in there
                    syncBufferCallback.onBufferReady(t);
                    onDrawFinished();
                }));

        // If isVriSync, then everything was setup in the addToSync.
        if (isVriSync) {
            return;
        }

        redrawNeededAsync(capturedCallbacks, this::onDrawFinished);
    }

    private void redrawNeededAsync(SurfaceHolder.Callback[] callbacks,
            Runnable callbacksCollected) {
        SurfaceCallbackHelper sch = new SurfaceCallbackHelper(callbacksCollected);
        sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
    }

    private static class TransactionCallback {
        private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
        private Transaction mTransaction;

        Transaction waitForTransaction() {
            try {
                mCountDownLatch.await();
            } catch (InterruptedException e) {
            }
            return mTransaction;
        }

        void onTransactionReady(Transaction t) {
            mTransaction = t;
            mCountDownLatch.countDown();
        }
    }

    /**
     * Copy the Surface from the SurfaceControl or the blast adapter.
     *
@@ -1189,13 +1198,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
    }

    private void onDrawFinished(@Nullable Transaction t) {
    private void onDrawFinished() {
        if (DEBUG) {
            Log.i(TAG, System.identityHashCode(this) + " "
                    + "finishedDrawing");
        }

        runOnUiThread(() -> performDrawFinished(t));
        runOnUiThread(this::performDrawFinished);
    }

    /**
+164 −245

File changed.

Preview size limit exceeded, changes collapsed.

+2 −1
Original line number Diff line number Diff line
@@ -2373,7 +2373,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
                // Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
                // the next draw from here, so we don't have to wait for window manager to signal
                // this to our ViewRootImpl.
                mKeyguardViewControllerLazy.get().getViewRootImpl().setReportNextDraw();
                mKeyguardViewControllerLazy.get().getViewRootImpl().setReportNextDraw(
                        false /* syncBuffer */);
                mScreenOnCoordinator.setWakeAndUnlocking(false);
            }