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

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

Reduce unnecessary sync redraw without changes

If a window was drawn and its parent container's prepareSync is called,
the window will always redraw even if there is nothing change to it.

For example, when cold launching an activity in a different orientation,
the app window and starting window can be drawn first and then display
updates. The prepareSync from display will request the 2 windows redraw
but the windows already have the latest state.

In general, prepareSync is usually called before knowing whether there
will be a change. Then updateResizingWindowIfNeeded can give a chance
to filter necessary redraw request.

Bug: 231435331
Bug: 297493149
Test: atest WindowStateTests#testRequestResizeForBlastSync
Change-Id: Id9134e7c71d37357d39d864b3d502ba5bdaebdc2
parent a8f99519
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -1443,14 +1443,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                    + " last=" + mWindowFrames.mLastFrame + " frame=" + mWindowFrames.mFrame);
        }

        final boolean contentChanged = didFrameInsetsChange || configChanged
                || dragResizingChanged || attachedFrameChanged;
        // Cancel unchanged non-sync-buffer redraw request to avoid unnecessary reportResized().
        if (!contentChanged && !mRedrawForSyncReported && mPrepareSyncSeqId <= 0
                && mDrawHandlers.isEmpty()) {
            mRedrawForSyncReported = true;
        }

        // Add a window that is using blastSync to the resizing list if it hasn't been reported
        // already. This because the window is waiting on a finishDrawing from the client.
        if (didFrameInsetsChange
                || configChanged
                || insetsChanged
                || dragResizingChanged
                || shouldSendRedrawForSync()
                || attachedFrameChanged) {
        if (contentChanged || insetsChanged || shouldSendRedrawForSync()) {
            ProtoLog.v(WM_DEBUG_RESIZE,
                        "Resize reasons for w=%s:  %s configChanged=%b didFrameInsetsChange=%b",
                        this, mWindowFrames.getInsetsChangedInfo(),
+20 −3
Original line number Diff line number Diff line
@@ -819,17 +819,20 @@ public class WindowStateTests extends WindowTestsBase {
        assertFalse(win.getOrientationChanging());
    }

    @SetupWindows(addWindows = W_ABOVE_ACTIVITY)
    @Test
    public void testRequestResizeForBlastSync() {
        final WindowState win = mChildAppWindowAbove;
        makeWindowVisible(win, win.getParentWindow());
        final WindowState win = createWindow(null, TYPE_APPLICATION, "window");
        makeWindowVisible(win);
        makeLastConfigReportedToClient(win, true /* visible */);
        win.mLayoutSeq = win.getDisplayContent().mLayoutSeq;
        win.reportResized();
        win.updateResizingWindowIfNeeded();
        assertThat(mWm.mResizingWindows).doesNotContain(win);

        // Check that the window is in resizing if using blast sync.
        final BLASTSyncEngine.SyncGroup syncGroup = mock(BLASTSyncEngine.SyncGroup.class);
        syncGroup.mSyncMethod = BLASTSyncEngine.METHOD_BLAST;
        win.mSyncGroup = syncGroup;
        win.reportResized();
        win.prepareSync();
        assertEquals(SYNC_STATE_WAITING_FOR_DRAW, win.mSyncState);
@@ -842,6 +845,20 @@ public class WindowStateTests extends WindowTestsBase {
        mWm.mResizingWindows.remove(win);
        win.updateResizingWindowIfNeeded();
        assertThat(mWm.mResizingWindows).doesNotContain(win);

        // Non blast sync doesn't require to force resizing, because it won't use syncSeqId.
        // And if the window is already drawn, it can report sync finish immediately so that the
        // sync group won't be blocked.
        win.finishSync(mTransaction, syncGroup, false /* cancel */);
        syncGroup.mSyncMethod = BLASTSyncEngine.METHOD_NONE;
        win.mSyncGroup = syncGroup;
        win.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
        win.prepareSync();
        assertEquals(SYNC_STATE_WAITING_FOR_DRAW, win.mSyncState);
        win.updateResizingWindowIfNeeded();
        assertThat(mWm.mResizingWindows).doesNotContain(win);
        assertTrue(win.isSyncFinished(syncGroup));
        assertEquals(WindowContainer.SYNC_STATE_READY, win.mSyncState);
    }

    @Test