summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2024-05-06 21:50:10 +0800
committer Riddle Hsu <riddlehsu@google.com> 2024-05-07 20:59:16 +0800
commitadaa572912e29a8d7cc4c94d7af75a8e8915ce90 (patch)
treef0d16864ab148579eed6a6cebe2b5469a0b666ae
parenta8f99519ab3fec77352f506c62c057e480ae90af (diff)
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
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java23
2 files changed, 29 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c25080f9e756..6e6aba13347e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -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(),
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index fbbb9a2e55a7..b152c3e5355f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -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