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

Commit 68004771 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Use separated display transaction

Since new transition system is enabled in U, the display will
use its own transaction to play animation. So it is no longer
appropriate to use a global transaction to update all displays.

Otherwise the order of transaction may apply old state, e.g.
Display1 is rotating and Display2 is resizing, the transaction
T1 may contain the new rotation for D1 and old size for D2. And
the transaction T2 contains new size for D2. If T2 is applied
before T1, the Display2 will still show with old projection.

Also removed the traversal when updating rotation because
RWC#applySurfaceChangesTransaction will always be called
before starting the transition. Then only need to keep one
centralized invocation entry.

Bug: 322121097
Test: CtsWindowManagerDeviceDisplay
Change-Id: Icefa9e9810996a3e5fbe95bfea2a2aebc044cdce
parent a9d2c1f1
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -202,8 +202,11 @@ public abstract class DisplayManagerInternal {
    /**
     * Called by the window manager to perform traversals while holding a
     * surface flinger transaction.
     * @param t The default transaction.
     * @param displayTransactions The transactions mapped by display id.
     */
    public abstract void performTraversal(Transaction t);
    public abstract void performTraversal(Transaction t,
            SparseArray<SurfaceControl.Transaction> displayTransactions);

    /**
     * Tells the display manager about properties of the display that depend on the windows on it.
+12 −7
Original line number Diff line number Diff line
@@ -872,14 +872,15 @@ public final class DisplayManagerService extends SystemService {
    }

    @VisibleForTesting
    void performTraversalInternal(SurfaceControl.Transaction t) {
    void performTraversalInternal(SurfaceControl.Transaction t,
            SparseArray<SurfaceControl.Transaction> displayTransactions) {
        synchronized (mSyncRoot) {
            if (!mPendingTraversal) {
                return;
            }
            mPendingTraversal = false;

            performTraversalLocked(t);
            performTraversalLocked(t, displayTransactions);
        }

        // List is self-synchronized copy-on-write.
@@ -2591,7 +2592,8 @@ public final class DisplayManagerService extends SystemService {
        }
    }

    private void performTraversalLocked(SurfaceControl.Transaction t) {
    private void performTraversalLocked(SurfaceControl.Transaction t,
            SparseArray<SurfaceControl.Transaction> displayTransactions) {
        // Clear all viewports before configuring displays so that we can keep
        // track of which ones we have configured.
        clearViewportsLocked();
@@ -2599,9 +2601,11 @@ public final class DisplayManagerService extends SystemService {
        // Configure each display device.
        mLogicalDisplayMapper.forEachLocked((LogicalDisplay display) -> {
            final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
            final SurfaceControl.Transaction displayTransaction =
                    displayTransactions.get(display.getDisplayIdLocked(), t);
            if (device != null) {
                configureDisplayLocked(t, device);
                device.performTraversalLocked(t);
                configureDisplayLocked(displayTransaction, device);
                device.performTraversalLocked(displayTransaction);
            }
        });

@@ -4678,8 +4682,9 @@ public final class DisplayManagerService extends SystemService {
        }

        @Override
        public void performTraversal(SurfaceControl.Transaction t) {
            performTraversalInternal(t);
        public void performTraversal(SurfaceControl.Transaction t,
                SparseArray<SurfaceControl.Transaction> displayTransactions) {
            performTraversalInternal(t, displayTransactions);
        }

        @Override
+0 −1
Original line number Diff line number Diff line
@@ -2250,7 +2250,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            }
        }

        mWmService.mDisplayManagerInternal.performTraversal(transaction);
        if (shellTransitions) {
            // Before setDisplayProjection is applied by the start transaction of transition,
            // set the transform hint to avoid using surface in old rotation.
+5 −1
Original line number Diff line number Diff line
@@ -249,6 +249,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
    /** Reference to default display so we can quickly look it up. */
    private DisplayContent mDefaultDisplay;
    private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
    private final SparseArray<SurfaceControl.Transaction> mDisplayTransactions =
            new SparseArray<>();

    /** The current user */
    int mCurrentUser;
@@ -991,11 +993,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        for (int j = 0; j < count; ++j) {
            final DisplayContent dc = mChildren.get(j);
            dc.applySurfaceChangesTransaction();
            mDisplayTransactions.append(dc.mDisplayId, dc.getSyncTransaction());
        }

        // Give the display manager a chance to adjust properties like display rotation if it needs
        // to.
        mWmService.mDisplayManagerInternal.performTraversal(t);
        mWmService.mDisplayManagerInternal.performTraversal(t, mDisplayTransactions);
        mDisplayTransactions.clear();
    }

    /**
+17 −11
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.SparseArray;
import android.view.ContentRecordingSession;
import android.view.Display;
import android.view.DisplayAdjustments;
@@ -431,7 +432,7 @@ public class DisplayManagerServiceTest {
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));

        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
@@ -506,7 +507,7 @@ public class DisplayManagerServiceTest {
            assertTrue(expectedDisplayTypeToViewPortTypeMapping.keySet().contains(info.type));
        }

        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
@@ -558,7 +559,7 @@ public class DisplayManagerServiceTest {
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));

        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
@@ -593,7 +594,7 @@ public class DisplayManagerServiceTest {
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));

        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0);
@@ -631,7 +632,7 @@ public class DisplayManagerServiceTest {
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));

        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0);
@@ -666,7 +667,7 @@ public class DisplayManagerServiceTest {
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));

        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0);
@@ -946,7 +947,7 @@ public class DisplayManagerServiceTest {
                PACKAGE_NAME);
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));
        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
@@ -1438,7 +1439,7 @@ public class DisplayManagerServiceTest {
                PACKAGE_NAME);
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));
        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
@@ -1693,7 +1694,7 @@ public class DisplayManagerServiceTest {
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));

        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);

        // flush the handler
        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
@@ -1727,7 +1728,7 @@ public class DisplayManagerServiceTest {
                null /* projection */, PACKAGE_NAME);
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));
        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);
        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
        DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
        assertNotNull(ddi);
@@ -1796,7 +1797,7 @@ public class DisplayManagerServiceTest {
                mock(DisplayWindowPolicyController.class), PACKAGE_NAME);
        verify(mMockProjectionService, never()).setContentRecordingSession(any(),
                nullable(IMediaProjection.class));
        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
        performTraversalInternal(displayManager);
        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
        DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
        assertNotNull(ddi);
@@ -2911,6 +2912,11 @@ public class DisplayManagerServiceTest {
        assertEquals(expectedMode, displayInfo.getMode());
    }

    private void performTraversalInternal(DisplayManagerService displayManager) {
        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class),
                new SparseArray<>());
    }

    private int getDisplayIdForDisplayDevice(
            DisplayManagerService displayManager,
            DisplayManagerService.BinderService displayManagerBinderService,