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

Commit 6bb5bedc authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Skip traversal of invisible visibility change

The typical partial steps of making an existing activity visible:
1. handleAppVisibility: mAppVisible=true
2. performRestart: setWindowStopped(false)
3. performStart: Activity#makeVisible (View.VISIBLE)

A stopped activity has root view visibility=INVISIBLE. So when
changing mAppVisible to true, there will have an intermediate
GONE->INVISIBLE (host visibility is GONE if mAppVisible is false).

For root view, because it doesn't have parent, GONE and INVISIBLE
are no different. It is also the same on window manager side that
only cares about whehther it is visible or not. So the intermediate
change can be skipped to reduce overhead.

In setWindowStopped, change to use mAppVisibilityChanged to reduce
the extra invocation of destroyHardwareResources().

Bug: 205693679
Test: CtsWindowManagerDeviceTestCases
Change-Id: I16ac73e5f5b837e9946114bee73602bf8c8228a2
parent 05c87f76
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -1551,9 +1551,14 @@ public final class ViewRootImpl implements ViewParent,

    void handleAppVisibility(boolean visible) {
        if (mAppVisible != visible) {
            final boolean previousVisible = getHostVisibility() == View.VISIBLE;
            mAppVisible = visible;
            final boolean currentVisible = getHostVisibility() == View.VISIBLE;
            // Root view only cares about whether it is visible or not.
            if (previousVisible != currentVisible) {
                mAppVisibilityChanged = true;
                scheduleTraversals();
            }
            if (!mAppVisible) {
                WindowManagerGlobal.trimForeground();
            }
@@ -1843,8 +1848,13 @@ public final class ViewRootImpl implements ViewParent,
                renderer.setStopped(mStopped);
            }
            if (!mStopped) {
                mNewSurfaceNeeded = true;
                // Unnecessary to traverse if the window is not yet visible.
                if (getHostVisibility() == View.VISIBLE) {
                    // Make sure that relayoutWindow will be called to get valid surface because
                    // the previous surface may have been released.
                    mAppVisibilityChanged = true;
                    scheduleTraversals();
                }
            } else {
                if (renderer != null) {
                    renderer.destroyHardwareResources(mView);
@@ -2025,7 +2035,8 @@ public final class ViewRootImpl implements ViewParent,
    }

    int getHostVisibility() {
        return (mAppVisible || mForceDecorViewVisibility) ? mView.getVisibility() : View.GONE;
        return mView != null && (mAppVisible || mForceDecorViewVisibility)
                ? mView.getVisibility() : View.GONE;
    }

    /**