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

Commit ed6794ec authored by Tiger Huang's avatar Tiger Huang
Browse files

Fix a bug about the z-order of layers caused by merging transactions

Each WindowContainer has its own pending transaction. These transactions
may be merged to the global one within WindowContainer.prepareSurfaces()
in a hierarchy-based order, not in a time-based order. It may cause
that a later surface operation overwritten by an earlier surface
operation. For example, atokenA.setLayer(t1, 0) was called earlier, and
then atokenA.setLayer(t2, 1) was called later. However, the layer of
atokenA might eventually be 0 because t1 could be merged into the
global transaction later.

This CL uses a single transaction per display to solve this problem.

Fix: 120282809
Test: atest SurfaceAnimatorTest
Test: Manual test with the steps in the issue.
Change-Id: Idca57d01d8be884369510642c2d9345b6ee4e3b1
parent 4d5b76d3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2660,6 +2660,9 @@ public final class SurfaceControl implements Parcelable {
         */
        @NonNull
        public Transaction merge(@NonNull Transaction other) {
            if (this == other) {
                return this;
            }
            mResizedSurfaces.putAll(other.mResizedSurfaces);
            other.mResizedSurfaces.clear();
            nativeMergeTransaction(mNativeObject, other.mNativeObject);
+6 −6
Original line number Diff line number Diff line
@@ -2005,7 +2005,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
        }
        layoutLetterbox(winHint);
        if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
            mLetterbox.applySurfaceChanges(mPendingTransaction);
            mLetterbox.applySurfaceChanges(getPendingTransaction());
        }
    }

@@ -3059,13 +3059,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

        if (mSurfaceControl != null) {
            if (show && !mLastSurfaceShowing) {
                mPendingTransaction.show(mSurfaceControl);
                getPendingTransaction().show(mSurfaceControl);
            } else if (!show && mLastSurfaceShowing) {
                mPendingTransaction.hide(mSurfaceControl);
                getPendingTransaction().hide(mSurfaceControl);
            }
        }
        if (mThumbnail != null) {
            mThumbnail.setShowing(mPendingTransaction, show);
            mThumbnail.setShowing(getPendingTransaction(), show);
        }
        mLastSurfaceShowing = show;
        super.prepareSurfaces();
@@ -3225,8 +3225,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree

    private void updateColorTransform() {
        if (mSurfaceControl != null && mLastAppSaturationInfo != null) {
            mPendingTransaction.setColorTransform(mSurfaceControl, mLastAppSaturationInfo.mMatrix,
                    mLastAppSaturationInfo.mTranslation);
            getPendingTransaction().setColorTransform(mSurfaceControl,
                    mLastAppSaturationInfo.mMatrix, mLastAppSaturationInfo.mTranslation);
            mWmService.scheduleAnimationLocked();
        }
    }
+12 −6
Original line number Diff line number Diff line
@@ -3340,7 +3340,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        final SurfaceControl newParent =
                shouldAttachToDisplay ? mWindowingLayer : computeImeParent();
        if (newParent != null) {
            mPendingTransaction.reparent(mImeWindowsContainers.mSurfaceControl, newParent);
            getPendingTransaction().reparent(mImeWindowsContainers.mSurfaceControl, newParent);
            scheduleAnimation();
        }
    }
@@ -3747,7 +3747,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            mPortalWindowHandle.touchableRegion.getBounds(mTmpRect);
            if (!mTmpBounds.equals(mTmpRect)) {
                mPortalWindowHandle.touchableRegion.set(mTmpBounds);
                mPendingTransaction.setInputWindowInfo(mParentSurfaceControl, mPortalWindowHandle);
                getPendingTransaction().setInputWindowInfo(
                        mParentSurfaceControl, mPortalWindowHandle);
            }
        }
    }
@@ -4846,18 +4847,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        try {
            final ScreenRotationAnimation screenRotationAnimation =
                    mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
            final Transaction transaction = getPendingTransaction();
            if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
                screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats);
                mPendingTransaction.setMatrix(mWindowingLayer,
                transaction.setMatrix(mWindowingLayer,
                        mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
                        mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
                mPendingTransaction.setPosition(mWindowingLayer,
                transaction.setPosition(mWindowingLayer,
                        mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
                mPendingTransaction.setAlpha(mWindowingLayer,
                transaction.setAlpha(mWindowingLayer,
                        screenRotationAnimation.getEnterTransformation().getAlpha());
            }

            super.prepareSurfaces();

            // TODO: Once we totally eliminate global transaction we will pass transaction in here
            //       rather than merging to global.
            SurfaceControl.mergeToGlobalTransaction(transaction);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
@@ -5013,7 +5019,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (mPortalWindowHandle == null) {
            mPortalWindowHandle = createPortalWindowHandle(sc.toString());
        }
        mPendingTransaction.setInputWindowInfo(sc, mPortalWindowHandle)
        getPendingTransaction().setInputWindowInfo(sc, mPortalWindowHandle)
                .reparent(mWindowingLayer, sc).reparent(mOverlayLayer, sc);
    }

+1 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta
        setOrientation(SCREEN_ORIENTATION_UNSET);
    }

    @Override
    DisplayContent getDisplayContent() {
        return mStack != null ? mStack.getDisplayContent() : null;
    }
+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable {

    @Override
    public SurfaceControl.Transaction getPendingTransaction() {
        return mTask.mPendingTransaction;
        return mTask.getPendingTransaction();
    }

    @Override
Loading