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

Commit 3ef46b57 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Optimize screen decor insets calculation

This stores the computed decor insets and frame excluding insets.
So it can save 99% time of recomputing the insets every time during
starting an activity. E.g. dozen times of "prepare display info/frame,
compute window layout of insets source windows, calculate insets"
becomes "get result from array".

The saved decor insets will be updated when:
- Display metrics is changed (DC#updateBaseDisplayMetrics).
- Insets provider is added/removed/changed.

Also
- Use DisplayCutout rather than WmDisplayCutout to simplify
  passing the cutout between methods.
- Optimize getSourceProvider to avoid unnecessary object allocation.

This also fixes an issue that the display doesn't compute the latest
configuration when navigation mode is changed. Now it is fixed by
checking if the insets provider has layout changes and then recompute
screen configuration.

Bug: 238399969
Bug: 159103089
Test: atest DisplayPolicyInsetsTests DisplayPolicyLayoutTests
      DisplayPolicyTests#testUpdateDisplayConfigurationByDecor
Test: Change navigation mode or display size (density) in Settings.
      And then swipe-up or press home key, there won't be a
      frozen effect (display configuration change).

Change-Id: If6c28a89939372e6362b92f469ef7d793e8ec215
parent bde7caf8
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -349,20 +349,6 @@ public class InsetsState implements Parcelable {
        return insets;
    }

    // TODO: Remove this once the task bar is treated as navigation bar.
    public Insets calculateInsetsWithInternalTypes(Rect frame, @InternalInsetsType int[] types,
            boolean ignoreVisibility) {
        Insets insets = Insets.NONE;
        for (int i = types.length - 1; i >= 0; i--) {
            InsetsSource source = mSources[types[i]];
            if (source == null) {
                continue;
            }
            insets = Insets.max(source.calculateInsets(frame, ignoreVisibility), insets);
        }
        return insets;
    }

    public Insets calculateInsets(Rect frame, @InsetsType int types,
            InsetsVisibilities overrideVisibilities) {
        Insets insets = Insets.NONE;
+9 −9
Original line number Diff line number Diff line
@@ -357,7 +357,6 @@ import com.android.server.wm.ActivityMetricsLogger.TransitionInfoSnapshot;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.WindowManagerService.H;
import com.android.server.wm.utils.InsetUtils;
import com.android.server.wm.utils.WmDisplayCutout;

import dalvik.annotation.optimization.NeverCompile;

@@ -918,7 +917,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     */
    private final Configuration mTmpConfig = new Configuration();
    private final Rect mTmpBounds = new Rect();
    private final Rect mTmpOutNonDecorBounds = new Rect();

    // Token for targeting this activity for assist purposes.
    final Binder assistToken = new Binder();
@@ -8152,10 +8150,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final int orientation = parentBounds.height() >= parentBounds.width()
                ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
        // Compute orientation from stable parent bounds (= parent bounds with insets applied)
        final DisplayInfo di = isFixedRotationTransforming()
                ? getFixedRotationTransformDisplayInfo()
                : mDisplayContent.getDisplayInfo();
        final Task task = getTask();
        task.calculateInsetFrames(mTmpOutNonDecorBounds /* outNonDecorBounds */,
                outStableBounds /* outStableBounds */, parentBounds /* bounds */,
                mDisplayContent.getDisplayInfo());
        task.calculateInsetFrames(mTmpBounds /* outNonDecorBounds */,
                outStableBounds /* outStableBounds */, parentBounds /* bounds */, di);
        final int orientationWithInsets = outStableBounds.height() >= outStableBounds.width()
                ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
        // If orientation does not match the orientation with insets applied, then a
@@ -9718,10 +9718,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
                final int dw = rotated ? display.mBaseDisplayHeight : display.mBaseDisplayWidth;
                final int dh = rotated ? display.mBaseDisplayWidth : display.mBaseDisplayHeight;
                final WmDisplayCutout cutout = display.calculateDisplayCutoutForRotation(rotation);
                policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]);
                mStableInsets[rotation].set(mNonDecorInsets[rotation]);
                policy.convertNonDecorInsetsToStableInsets(mStableInsets[rotation], rotation);
                final DisplayPolicy.DecorInsets.Info decorInfo =
                        policy.getDecorInsetsInfo(rotation, dw, dh);
                mNonDecorInsets[rotation].set(decorInfo.mNonDecorInsets);
                mStableInsets[rotation].set(decorInfo.mConfigInsets);

                if (unfilledContainerBounds == null) {
                    continue;
+45 −47
Original line number Diff line number Diff line
@@ -1080,7 +1080,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
        isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
        mInsetsStateController = new InsetsStateController(this);
        mDisplayFrames = new DisplayFrames(mDisplayId, mInsetsStateController.getRawInsetsState(),
        mDisplayFrames = new DisplayFrames(mInsetsStateController.getRawInsetsState(),
                mDisplayInfo, calculateDisplayCutoutForRotation(mDisplayInfo.rotation),
                calculateRoundedCornersForRotation(mDisplayInfo.rotation),
                calculatePrivacyIndicatorBoundsForRotation(mDisplayInfo.rotation));
@@ -1936,11 +1936,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    private void startFixedRotationTransform(WindowToken token, int rotation) {
        mTmpConfiguration.unset();
        final DisplayInfo info = computeScreenConfiguration(mTmpConfiguration, rotation);
        final WmDisplayCutout cutout = calculateDisplayCutoutForRotation(rotation);
        final DisplayCutout cutout = calculateDisplayCutoutForRotation(rotation);
        final RoundedCorners roundedCorners = calculateRoundedCornersForRotation(rotation);
        final PrivacyIndicatorBounds indicatorBounds =
                calculatePrivacyIndicatorBoundsForRotation(rotation);
        final DisplayFrames displayFrames = new DisplayFrames(mDisplayId, new InsetsState(), info,
        final DisplayFrames displayFrames = new DisplayFrames(new InsetsState(), info,
                cutout, roundedCorners, indicatorBounds);
        token.applyFixedRotationTransform(info, displayFrames, mTmpConfiguration);
    }
@@ -2147,12 +2147,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;

        // Update application display metrics.
        final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);
        final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout();
        final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation);
        final RoundedCorners roundedCorners = calculateRoundedCornersForRotation(rotation);

        final Rect appFrame = mDisplayPolicy.getNonDecorDisplayFrame(dw, dh, rotation,
                wmDisplayCutout);
        final Rect appFrame = mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh).mNonDecorFrame;
        mDisplayInfo.rotation = rotation;
        mDisplayInfo.logicalWidth = dw;
        mDisplayInfo.logicalHeight = dh;
@@ -2190,9 +2188,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return mDisplayInfo;
    }

    WmDisplayCutout calculateDisplayCutoutForRotation(int rotation) {
    DisplayCutout calculateDisplayCutoutForRotation(int rotation) {
        return mDisplayCutoutCache.getOrCompute(
                mIsSizeForced ? mBaseDisplayCutout : mInitialDisplayCutout, rotation);
                mIsSizeForced ? mBaseDisplayCutout : mInitialDisplayCutout, rotation)
                        .getDisplayCutout();
    }

    static WmDisplayCutout calculateDisplayCutoutForRotationAndDisplaySizeUncached(
@@ -2263,9 +2262,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
        outConfig.windowConfiguration.setMaxBounds(0, 0, dw, dh);
        outConfig.windowConfiguration.setBounds(outConfig.windowConfiguration.getMaxBounds());

        final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);
        computeScreenAppConfiguration(outConfig, dw, dh, rotation, wmDisplayCutout);
        computeScreenAppConfiguration(outConfig, dw, dh, rotation);

        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
        displayInfo.rotation = rotation;
@@ -2274,7 +2271,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        final Rect appBounds = outConfig.windowConfiguration.getAppBounds();
        displayInfo.appWidth = appBounds.width();
        displayInfo.appHeight = appBounds.height();
        final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout();
        final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation);
        displayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout;
        computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh,
                mDisplayMetrics.density, outConfig);
@@ -2283,21 +2280,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    /** Compute configuration related to application without changing current display. */
    private void computeScreenAppConfiguration(Configuration outConfig, int dw, int dh,
            int rotation, WmDisplayCutout wmDisplayCutout) {
        final DisplayFrames displayFrames =
                mDisplayPolicy.getSimulatedDisplayFrames(rotation, dw, dh, wmDisplayCutout);
        final Rect appFrame =
                mDisplayPolicy.getNonDecorDisplayFrameWithSimulatedFrame(displayFrames);
            int rotation) {
        final DisplayPolicy.DecorInsets.Info info =
                mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh);
        // AppBounds at the root level should mirror the app screen size.
        outConfig.windowConfiguration.setAppBounds(appFrame);
        outConfig.windowConfiguration.setAppBounds(info.mNonDecorFrame);
        outConfig.windowConfiguration.setRotation(rotation);
        outConfig.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;

        final float density = mDisplayMetrics.density;
        final Point configSize =
                mDisplayPolicy.getConfigDisplaySizeWithSimulatedFrame(displayFrames);
        outConfig.screenWidthDp = (int) (configSize.x / density + 0.5f);
        outConfig.screenHeightDp = (int) (configSize.y / density + 0.5f);
        outConfig.screenWidthDp = (int) (info.mConfigFrame.width() / density + 0.5f);
        outConfig.screenHeightDp = (int) (info.mConfigFrame.height() / density + 0.5f);
        outConfig.compatScreenWidthDp = (int) (outConfig.screenWidthDp / mCompatibleScreenScale);
        outConfig.compatScreenHeightDp = (int) (outConfig.screenHeightDp / mCompatibleScreenScale);

@@ -2320,8 +2313,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        config.windowConfiguration.setWindowingMode(getWindowingMode());
        config.windowConfiguration.setDisplayWindowingMode(getWindowingMode());

        computeScreenAppConfiguration(config, dw, dh, displayInfo.rotation,
                calculateDisplayCutoutForRotation(getRotation()));
        computeScreenAppConfiguration(config, dw, dh, displayInfo.rotation);

        config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
                | ((displayInfo.flags & Display.FLAG_ROUND) != 0
@@ -2430,9 +2422,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    private int reduceCompatConfigWidthSize(int curSize, int rotation,
            DisplayMetrics dm, int dw, int dh) {
        final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);
        final Rect nonDecorSize = mDisplayPolicy.getNonDecorDisplayFrame(dw, dh, rotation,
                wmDisplayCutout);
        final Rect nonDecorSize =
                mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh).mNonDecorFrame;
        dm.noncompatWidthPixels = nonDecorSize.width();
        dm.noncompatHeightPixels = nonDecorSize.height();
        float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
@@ -2481,11 +2472,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh) {
        // Get the display cutout at this rotation.
        final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);

        // Get the app screen size at this rotation.
        final Rect size = mDisplayPolicy.getNonDecorDisplayFrame(dw, dh, rotation, wmDisplayCutout);
        final Rect size = mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh).mNonDecorFrame;

        // Compute the screen layout size class for this rotation.
        int longSize = size.width();
@@ -2501,19 +2489,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
        final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);
        final Point size = mDisplayPolicy.getConfigDisplaySize(dw, dh, rotation, wmDisplayCutout);
        if (size.x < displayInfo.smallestNominalAppWidth) {
            displayInfo.smallestNominalAppWidth = size.x;
        final DisplayPolicy.DecorInsets.Info info = mDisplayPolicy.getDecorInsetsInfo(
                rotation, dw, dh);
        final int w = info.mConfigFrame.width();
        final int h = info.mConfigFrame.height();
        if (w < displayInfo.smallestNominalAppWidth) {
            displayInfo.smallestNominalAppWidth = w;
        }
        if (size.x > displayInfo.largestNominalAppWidth) {
            displayInfo.largestNominalAppWidth = size.x;
        if (w > displayInfo.largestNominalAppWidth) {
            displayInfo.largestNominalAppWidth = w;
        }
        if (size.y < displayInfo.smallestNominalAppHeight) {
            displayInfo.smallestNominalAppHeight = size.y;
        if (h < displayInfo.smallestNominalAppHeight) {
            displayInfo.smallestNominalAppHeight = h;
        }
        if (size.y > displayInfo.largestNominalAppHeight) {
            displayInfo.largestNominalAppHeight = size.y;
        if (h > displayInfo.largestNominalAppHeight) {
            displayInfo.largestNominalAppHeight = h;
        }
    }

@@ -2773,14 +2763,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    private void updateDisplayFrames(boolean notifyInsetsChange) {
        if (mDisplayFrames.update(mDisplayInfo,
                calculateDisplayCutoutForRotation(mDisplayInfo.rotation),
                calculateRoundedCornersForRotation(mDisplayInfo.rotation),
                calculatePrivacyIndicatorBoundsForRotation(mDisplayInfo.rotation))) {
        if (updateDisplayFrames(mDisplayFrames, mDisplayInfo.rotation,
                mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight)) {
            mInsetsStateController.onDisplayFramesUpdated(notifyInsetsChange);
        }
    }

    boolean updateDisplayFrames(DisplayFrames displayFrames, int rotation, int w, int h) {
        return displayFrames.update(rotation, w, h,
                calculateDisplayCutoutForRotation(rotation),
                calculateRoundedCornersForRotation(rotation),
                calculatePrivacyIndicatorBoundsForRotation(rotation));
    }

    @Override
    void onDisplayChanged(DisplayContent dc) {
        super.onDisplayChanged(dc);
@@ -2943,6 +2938,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                        + mBaseDisplayHeight + " on display:" + getDisplayId());
            }
        }
        if (mDisplayReady) {
            mDisplayPolicy.mDecorInsets.invalidate();
        }
    }

    /**
@@ -5584,7 +5582,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            outExclusionUnrestricted.setEmpty();
        }
        final Region unhandled = Region.obtain();
        unhandled.set(0, 0, mDisplayFrames.mDisplayWidth, mDisplayFrames.mDisplayHeight);
        unhandled.set(0, 0, mDisplayFrames.mWidth, mDisplayFrames.mHeight);

        final Rect leftEdge = mInsetsStateController.getSourceProvider(ITYPE_LEFT_GESTURES)
                .getSource().getFrame();
+20 −28
Original line number Diff line number Diff line
@@ -30,8 +30,6 @@ import android.view.InsetsState;
import android.view.PrivacyIndicatorBounds;
import android.view.RoundedCorners;

import com.android.server.wm.utils.WmDisplayCutout;

import java.io.PrintWriter;

/**
@@ -39,8 +37,6 @@ import java.io.PrintWriter;
 * @hide
 */
public class DisplayFrames {
    public final int mDisplayId;

    public final InsetsState mInsetsState;

    /**
@@ -54,48 +50,45 @@ public class DisplayFrames {
     */
    public final Rect mDisplayCutoutSafe = new Rect();

    public int mDisplayWidth;
    public int mDisplayHeight;
    public int mWidth;
    public int mHeight;

    public int mRotation;

    public DisplayFrames(int displayId, InsetsState insetsState, DisplayInfo info,
            WmDisplayCutout displayCutout, RoundedCorners roundedCorners,
            PrivacyIndicatorBounds indicatorBounds) {
        mDisplayId = displayId;
    public DisplayFrames(InsetsState insetsState, DisplayInfo info, DisplayCutout cutout,
            RoundedCorners roundedCorners, PrivacyIndicatorBounds indicatorBounds) {
        mInsetsState = insetsState;
        update(info, displayCutout, roundedCorners, indicatorBounds);
        update(info.rotation, info.logicalWidth, info.logicalHeight, cutout, roundedCorners,
                indicatorBounds);
    }

    DisplayFrames() {
        mInsetsState = new InsetsState();
    }

    /**
     * This is called when {@link DisplayInfo} or {@link PrivacyIndicatorBounds} is updated.
     * This is called if the display info may be changed, e.g. rotation, size, insets.
     *
     * @param info the updated {@link DisplayInfo}.
     * @param displayCutout the updated {@link DisplayCutout}.
     * @param roundedCorners the updated {@link RoundedCorners}.
     * @param indicatorBounds the updated {@link PrivacyIndicatorBounds}.
     * @return {@code true} if anything has been changed; {@code false} otherwise.
     */
    public boolean update(DisplayInfo info, @NonNull WmDisplayCutout displayCutout,
    public boolean update(int rotation, int w, int h, @NonNull DisplayCutout displayCutout,
            @NonNull RoundedCorners roundedCorners,
            @NonNull PrivacyIndicatorBounds indicatorBounds) {
        final InsetsState state = mInsetsState;
        final Rect safe = mDisplayCutoutSafe;
        final DisplayCutout cutout = displayCutout.getDisplayCutout();
        if (mDisplayWidth == info.logicalWidth && mDisplayHeight == info.logicalHeight
                && mRotation == info.rotation
                && state.getDisplayCutout().equals(cutout)
        if (mRotation == rotation && mWidth == w && mHeight == h
                && mInsetsState.getDisplayCutout().equals(displayCutout)
                && state.getRoundedCorners().equals(roundedCorners)
                && state.getPrivacyIndicatorBounds().equals(indicatorBounds)) {
            return false;
        }
        mDisplayWidth = info.logicalWidth;
        mDisplayHeight = info.logicalHeight;
        mRotation = info.rotation;
        mRotation = rotation;
        mWidth = w;
        mHeight = h;
        final Rect unrestricted = mUnrestricted;
        unrestricted.set(0, 0, mDisplayWidth, mDisplayHeight);
        unrestricted.set(0, 0, w, h);
        state.setDisplayFrame(unrestricted);
        state.setDisplayCutout(cutout);
        state.setDisplayCutout(displayCutout);
        state.setRoundedCorners(roundedCorners);
        state.setPrivacyIndicatorBounds(indicatorBounds);
        state.getDisplayCutoutSafe(safe);
@@ -132,7 +125,6 @@ public class DisplayFrames {
    }

    public void dump(String prefix, PrintWriter pw) {
        pw.println(prefix + "DisplayFrames w=" + mDisplayWidth + " h=" + mDisplayHeight
                + " r=" + mRotation);
        pw.println(prefix + "DisplayFrames w=" + mWidth + " h=" + mHeight + " r=" + mRotation);
    }
}
+150 −163

File changed.

Preview size limit exceeded, changes collapsed.

Loading