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

Commit c402520f authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Coalesce layout traversal when resizing stacks

When resizing the docked stack, the other stacks are also resized,
leading to multiple layout traversals. Coalesce these by
introducing the concept of layout traversal coalscing.

In addition, don't cause layout refreshs for the stacks that are
currently not visible.

Bug: 25015474
Change-Id: I5692d00c044572a1bbb3ea218b0c31572585f5bd
parent 8ccdf3ac
Loading
Loading
Loading
Loading
+69 −66
Original line number Original line Diff line number Diff line
@@ -2992,7 +2992,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
        }
        }


        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);

        mWindowManager.deferSurfaceLayout();
        try {
            ActivityRecord r = stack.topRunningActivityLocked();
            ActivityRecord r = stack.topRunningActivityLocked();


            mTmpBounds.clear();
            mTmpBounds.clear();
@@ -3068,9 +3069,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
                    resumeTopActivitiesLocked(stack, null, null);
                    resumeTopActivitiesLocked(stack, null, null);
                }
                }
            }
            }

        } finally {
            mWindowManager.continueSurfaceLayout();
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
        }
    }


    void resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow) {
    void resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow) {
        if (!task.mResizeable) {
        if (!task.mResizeable) {
+21 −1
Original line number Original line Diff line number Diff line
@@ -4679,7 +4679,7 @@ public class WindowManagerService extends IWindowManager.Stub
                throw new IllegalArgumentException("resizeStack: stackId " + stackId
                throw new IllegalArgumentException("resizeStack: stackId " + stackId
                        + " not found.");
                        + " not found.");
            }
            }
            if (stack.setBounds(bounds, configs, taskBounds)) {
            if (stack.setBounds(bounds, configs, taskBounds) && stack.isVisibleLocked()) {
                stack.resizeWindows();
                stack.resizeWindows();
                stack.getDisplayContent().layoutNeeded = true;
                stack.getDisplayContent().layoutNeeded = true;
                mWindowPlacerLocked.performSurfacePlacement();
                mWindowPlacerLocked.performSurfacePlacement();
@@ -4732,6 +4732,26 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        }
    }
    }


    /**
     * Starts deferring layout passes. Useful when doing multiple changes but to optimize
     * performance, only one layout pass should be done. This can be called multiple times, and
     * layouting will be resumed once the last caller has called {@link #continueSurfaceLayout}
     */
    public void deferSurfaceLayout() {
        synchronized (mWindowMap) {
            mWindowPlacerLocked.deferLayout();
        }
    }

    /**
     * Resumes layout passes after deferring them. See {@link #deferSurfaceLayout()}
     */
    public void continueSurfaceLayout() {
        synchronized (mWindowMap) {
            mWindowPlacerLocked.continueLayout();
        }
    }

    public void getTaskBounds(int taskId, Rect bounds) {
    public void getTaskBounds(int taskId, Rect bounds) {
        synchronized (mWindowMap) {
        synchronized (mWindowMap) {
            Task task = mTaskIdToTask.get(taskId);
            Task task = mTaskIdToTask.get(taskId);
+21 −0
Original line number Original line Diff line number Diff line
@@ -112,13 +112,34 @@ class WindowSurfacePlacer {
    private int mPreferredModeId = 0;
    private int mPreferredModeId = 0;


    private boolean mTraversalScheduled;
    private boolean mTraversalScheduled;
    private int mDeferDepth = 0;


    public WindowSurfacePlacer(WindowManagerService service) {
    public WindowSurfacePlacer(WindowManagerService service) {
        mService = service;
        mService = service;
        mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
        mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
    }
    }


    /**
     * See {@link WindowManagerService#deferSurfaceLayout()}
     */
    void deferLayout() {
        mDeferDepth++;
    }

    /**
     * See {@link WindowManagerService#continueSurfaceLayout()}
     */
    void continueLayout() {
        mDeferDepth--;
        if (mDeferDepth <= 0) {
            performSurfacePlacement();
        }
    }

    final void performSurfacePlacement() {
    final void performSurfacePlacement() {
        if (mDeferDepth > 0) {
            return;
        }
        int loopCount = 6;
        int loopCount = 6;
        do {
        do {
            mTraversalScheduled = false;
            mTraversalScheduled = false;