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

Commit 77cbb960 authored by Vishnu Nair's avatar Vishnu Nair Committed by Robert Carr
Browse files

SurfaceView: Synchronize add/remove SurfacePackage with VRI draw

Apply the SurfacePackage reparent transactions with the next
ViewRootImpl draw so the caller can optionally synchronize attaching
SurfacePackages with contents on the main window.

Test: atest CtsWindowManagerDeviceTestCases:SurfaceControlViewHostTests
Bug: 217973491
Change-Id: I87f77cb6a5a2505592f6e9431d2964517fe497cd
parent c5c0a60b
Loading
Loading
Loading
Loading
+37 −59
Original line number Diff line number Diff line
@@ -527,20 +527,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        mRequestedVisible = false;

        updateSurface();
        tryReleaseSurfaces();

        // We don't release this as part of releaseSurfaces as
        // that is also called on transient visibility changes. We can't
        // recreate this Surface, so only release it when we are fully
        // detached.
        if (mSurfacePackage != null) {
            final SurfaceControl sc = mSurfacePackage.getSurfaceControl();
            if (sc != null && sc.isValid()) {
                mTmpTransaction.reparent(sc, null).apply();
            }
            mSurfacePackage.release();
            mSurfacePackage = null;
        }
        tryReleaseSurfaces(true /* releaseSurfacePackage*/);

        mHaveFrame = false;
        super.onDetachedFromWindow();
@@ -871,7 +863,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        return t;
    }

    private void tryReleaseSurfaces() {
    private void tryReleaseSurfaces(boolean releaseSurfacePackage) {
        mSurfaceAlpha = 1f;

        synchronized (mSurfaceControlLock) {
@@ -881,18 +873,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                mBlastBufferQueue = null;
            }

            ViewRootImpl viewRoot = getViewRootImpl();
            Transaction transaction = new Transaction();
            releaseSurfaces(transaction);
            if (viewRoot != null) {
                viewRoot.applyTransactionOnDraw(transaction);
            } else {
                transaction.apply();
            }
        }
    }

    private void releaseSurfaces(Transaction transaction) {
            if (mSurfaceControl != null) {
                transaction.remove(mSurfaceControl);
                mSurfaceControl = null;
@@ -905,8 +886,24 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                transaction.remove(mBlastSurfaceControl);
                mBlastSurfaceControl = null;
            }

            if (releaseSurfacePackage && mSurfacePackage != null) {
                final SurfaceControl sc = mSurfacePackage.getSurfaceControl();
                if (sc != null && sc.isValid()) {
                    transaction.reparent(sc, null).apply();
                }
                mSurfacePackage.release();
                mSurfacePackage = null;
            }

            ViewRootImpl viewRoot = getViewRootImpl();
            if (viewRoot != null) {
                viewRoot.applyTransactionOnDraw(transaction);
            } else {
                transaction.apply();
            }
        }
    }

    // The position update listener is used to safely share the surface size between render thread
    // workers and the UI thread. Both threads need to know the surface size to determine the scale.
@@ -1048,7 +1045,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall

        if (viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
            notifySurfaceDestroyed();
            tryReleaseSurfaces();
            tryReleaseSurfaces(false /* releaseSurfacePackage*/);
            return;
        }

@@ -1189,7 +1186,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                } finally {
                    mIsCreating = false;
                    if (mSurfaceControl != null && !mSurfaceCreated) {
                        tryReleaseSurfaces();
                        tryReleaseSurfaces(false /* releaseSurfacePackage*/);
                    }
                }
            } catch (Exception ex) {
@@ -1835,44 +1832,25 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
     * @param p The SurfacePackage to embed.
     */
    public void setChildSurfacePackage(@NonNull SurfaceControlViewHost.SurfacePackage p) {
        setChildSurfacePackage(p, false /* applyTransactionOnDraw */);
    }

    /**
     * Similar to setChildSurfacePackage, but using the BLAST queue so the transaction can be
     * synchronized with the ViewRootImpl frame.
     * @hide
     */
    public void setChildSurfacePackageOnDraw(
            @NonNull SurfaceControlViewHost.SurfacePackage p) {
        setChildSurfacePackage(p, true /* applyTransactionOnDraw */);
    }

    /**
     * @param applyTransactionOnDraw Whether to apply transaction at onDraw or immediately.
     */
    private void setChildSurfacePackage(
            @NonNull SurfaceControlViewHost.SurfacePackage p, boolean applyTransactionOnDraw) {
        final SurfaceControl lastSc = mSurfacePackage != null ?
                mSurfacePackage.getSurfaceControl() : null;
        final SurfaceControl.Transaction transaction = new Transaction();
        if (mSurfaceControl != null) {
            if (lastSc != null) {
                mTmpTransaction.reparent(lastSc, null);
                transaction.reparent(lastSc, null);
                mSurfacePackage.release();
            }
            reparentSurfacePackage(mTmpTransaction, p);
            applyTransaction(applyTransactionOnDraw);
        }
        mSurfacePackage = p;
    }

    private void applyTransaction(boolean applyTransactionOnDraw) {
        if (applyTransactionOnDraw) {
            getViewRootImpl().applyTransactionOnDraw(mTmpTransaction);
            reparentSurfacePackage(transaction, p);
            final ViewRootImpl viewRoot = getViewRootImpl();
            if (viewRoot != null) {
                viewRoot.applyTransactionOnDraw(transaction);
            } else {
            mTmpTransaction.apply();
                transaction.apply();
            }
        }
        mSurfacePackage = p;
        invalidate();
    }

    private void reparentSurfacePackage(SurfaceControl.Transaction t,
            SurfaceControlViewHost.SurfacePackage p) {
+1 −1
Original line number Diff line number Diff line
@@ -493,7 +493,7 @@ public final class SplashScreenView extends FrameLayout {
            Log.d(TAG, "Transferring surface " + mSurfaceView.toString());
        }

        mSurfaceView.setChildSurfacePackageOnDraw(mSurfacePackage);
        mSurfaceView.setChildSurfacePackage(mSurfacePackage);
    }

    void initIconAnimation(Drawable iconDrawable, long duration) {