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

Commit 494ad7de authored by Robert Carr's avatar Robert Carr
Browse files

WindowState/WindowStateAnimator: Remove cropping

Cropping is all handled by higher levels of the hierarchy and
we don't need this code anymore. We can examine it bit by bit.

First we see lots of code cropping to screen boundaries, this will
be handled by DisplayContent/Area or the physical construction of
the screen.

In a few other cases we crop to the CompatFrame, this is the same
as the SurfaceSIze and so crop doesn't do anything.

In split-screen resize mode we crop to the display size, but this
doesm't do anything.

Cropping to the window frame wont have any effect since its the surface
frame before scaling, but we scale the crop rect after using it.

The only case we have to examine is calculateSystemDecorRect, but in new
inset mode, this only produces a crop for windows which don't draw
behind the nav bar. This is now limited to pre N (or earlier?) apps
and shouldn't have any effect.

Bug: 161937501
Test: Existing tests pass
Change-Id: I3c8edef0bb0d0482487184071902f366ed1f4ebb
parent 55d882cf
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7864,7 +7864,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        InsetUtils.addInsets(insets, getLetterboxInsets());
        return new RemoteAnimationTarget(task.mTaskId, record.getMode(),
                record.mAdapter.mCapturedLeash, !fillsParent(),
                mainWindow.mWinAnimator.mLastClipRect, insets,
                new Rect(), insets,
                getPrefixOrderIndex(), record.mAdapter.mPosition, record.mAdapter.mLocalBounds,
                record.mAdapter.mStackBounds, task.getWindowConfiguration(),
                false /*isNotInRecents*/,
+1 −1
Original line number Diff line number Diff line
@@ -929,7 +929,7 @@ public class RecentsAnimationController implements DeathRecipient {
                    ? MODE_OPENING
                    : MODE_CLOSING;
            mTarget = new RemoteAnimationTarget(mTask.mTaskId, mode, mCapturedLeash,
                    !topApp.fillsParent(), mainWindow.mWinAnimator.mLastClipRect,
                    !topApp.fillsParent(), new Rect(),
                    insets, mTask.getPrefixOrderIndex(), new Point(mBounds.left, mBounds.top),
                    mLocalBounds, mBounds, mTask.getWindowConfiguration(),
                    mIsRecentTaskInvisible, null, null);
+0 −87
Original line number Diff line number Diff line
@@ -4952,93 +4952,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return mToken.canLayerAboveSystemBars();
    }

    /**
     * Calculate the window crop according to system decor policy. In general this is
     * the system decor rect (see #calculateSystemDecorRect), but we also have some
     * special cases. This rectangle is in screen space.
     */
    void calculatePolicyCrop(Rect policyCrop) {
        final DisplayContent displayContent = getDisplayContent();

        if (!displayContent.isDefaultDisplay && !displayContent.supportsSystemDecorations()) {
            // On a different display there is no system decor. Crop the window
            // by the screen boundaries.
            final DisplayInfo displayInfo = getDisplayInfo();
            policyCrop.set(0, 0, mWindowFrames.mCompatFrame.width(),
                    mWindowFrames.mCompatFrame.height());
            policyCrop.intersect(-mWindowFrames.mCompatFrame.left, -mWindowFrames.mCompatFrame.top,
                    displayInfo.logicalWidth - mWindowFrames.mCompatFrame.left,
                    displayInfo.logicalHeight - mWindowFrames.mCompatFrame.top);
        } else if (skipDecorCrop()) {
            // Windows without policy decor aren't cropped.
            policyCrop.set(0, 0, mWindowFrames.mCompatFrame.width(),
                    mWindowFrames.mCompatFrame.height());
        } else {
            // Crop to the system decor specified by policy.
            calculateSystemDecorRect(policyCrop);
        }
    }

    /**
     * The system decor rect is the region of the window which is not covered
     * by system decorations.
     */
    private void calculateSystemDecorRect(Rect systemDecorRect) {
        final Rect decorRect = mWindowFrames.mDecorFrame;
        final int width = mWindowFrames.mFrame.width();
        final int height = mWindowFrames.mFrame.height();

        final int left = mWindowFrames.mFrame.left;
        final int top = mWindowFrames.mFrame.top;

        // Initialize the decor rect to the entire frame.
        if (isDockedResizing()) {
            // If we are resizing with the divider, the task bounds might be smaller than the
            // stack bounds. The system decor is used to clip to the task bounds, which we don't
            // want in this case in order to avoid holes.
            //
            // We take care to not shrink the width, for surfaces which are larger than
            // the display region. Of course this area will not eventually be visible
            // but if we truncate the width now, we will calculate incorrectly
            // when adjusting to the stack bounds.
            final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo();
            systemDecorRect.set(0, 0,
                    Math.max(width, displayInfo.logicalWidth),
                    Math.max(height, displayInfo.logicalHeight));
        } else {
            systemDecorRect.set(0, 0, width, height);
        }

        // If a freeform window is animating from a position where it would be cutoff, it would be
        // cutoff during the animation. We don't want that, so for the duration of the animation
        // we ignore the decor cropping and depend on layering to position windows correctly.

        // We also ignore cropping when the window is currently being drag resized in split screen
        // to prevent issues with the crop for screenshot.
        final boolean cropToDecor =
                !(inFreeformWindowingMode() && isAnimatingLw()) && !isDockedResizing();
        if (cropToDecor) {
            // Intersect with the decor rect, offsetted by window position.
            systemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
                    decorRect.right - left, decorRect.bottom - top);
        }

        // If size compatibility is being applied to the window, the
        // surface is scaled relative to the screen.  Also apply this
        // scaling to the crop rect.  We aren't using the standard rect
        // scale function because we want to round things to make the crop
        // always round to a larger rect to ensure we don't crop too
        // much and hide part of the window that should be seen.
        if (mInvGlobalScale != 1.0f && inSizeCompatMode()) {
            final float scale = mInvGlobalScale;
            systemDecorRect.left = (int) (systemDecorRect.left * scale - 0.5f);
            systemDecorRect.top = (int) (systemDecorRect.top * scale - 0.5f);
            systemDecorRect.right = (int) ((systemDecorRect.right + 1) * scale - 0.5f);
            systemDecorRect.bottom = (int) ((systemDecorRect.bottom + 1) * scale - 0.5f);
        }

    }

    /**
     * Expand the given rectangle by this windows surface insets. This
     * takes you from the 'window size' to the 'surface size'.
+0 −99
Original line number Diff line number Diff line
@@ -135,9 +135,6 @@ class WindowStateAnimator {
    float mAlpha = 0;
    float mLastAlpha = 0;

    Rect mTmpClipRect = new Rect();
    Rect mLastClipRect = new Rect();
    Rect mLastFinalClipRect = new Rect();
    Rect mTmpStackBounds = new Rect();
    private Rect mTmpAnimatingBounds = new Rect();
    private Rect mTmpSourceBounds = new Rect();
@@ -469,9 +466,6 @@ class WindowStateAnimator {
                    + " format=" + attrs.format + " flags=" + flags);
        }

        // We may abort, so initialize to defaults.
        mLastClipRect.set(0, 0, 0, 0);

        // Set up surface control with initial size.
        try {

@@ -641,77 +635,6 @@ class WindowStateAnimator {
        mDsDy = mWin.mGlobalScale;
    }

    /**
     * Calculate the window-space crop rect and fill clipRect.
     * @return true if clipRect has been filled otherwise, no window space crop should be applied.
     */
    private boolean calculateCrop(Rect clipRect) {
        final WindowState w = mWin;
        final DisplayContent displayContent = w.getDisplayContent();
        clipRect.setEmpty();

        if (displayContent == null) {
            return false;
        }

        if (w.getWindowConfiguration().tasksAreFloating()
                || WindowConfiguration.isSplitScreenWindowingMode(w.getWindowingMode())) {
            return false;
        }

        // During forced seamless rotation, the surface bounds get updated with the crop in the
        // new rotation, which is not compatible with showing the surface in the old rotation.
        // To work around that we disable cropping for such windows, as it is not necessary anyways.
        if (w.mForceSeamlesslyRotate) {
            return false;
        }

        // If we're animating, the wallpaper should only
        // be updated at the end of the animation.
        if (w.mAttrs.type == TYPE_WALLPAPER) {
            return false;
        }

        if (DEBUG_WINDOW_CROP) Slog.d(TAG,
                "Updating crop win=" + w + " mLastCrop=" + mLastClipRect);

        w.calculatePolicyCrop(mSystemDecorRect);

        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
                + w.getDecorFrame() + " mSystemDecorRect=" + mSystemDecorRect);

        // We use the clip rect as provided by the tranformation for non-fullscreen windows to
        // avoid premature clipping with the system decor rect.
        clipRect.set(mSystemDecorRect);
        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect);

        w.expandForSurfaceInsets(clipRect);

        // The clip rect was generated assuming (0,0) as the window origin,
        // so we need to translate to match the actual surface coordinates.
        clipRect.offset(w.mAttrs.surfaceInsets.left, w.mAttrs.surfaceInsets.top);

        if (DEBUG_WINDOW_CROP) Slog.d(TAG,
                "win=" + w + " Clip rect after stack adjustment=" + clipRect);

        w.transformClipRectFromScreenToSurfaceSpace(clipRect);

        return true;
    }

    private void applyCrop(Rect clipRect, boolean recoveringMemory) {
        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "applyCrop: win=" + mWin
                + " clipRect=" + clipRect);
        if (clipRect != null) {
            if (!clipRect.equals(mLastClipRect)) {
                mLastClipRect.set(clipRect);
                mSurfaceController.setCropInTransaction(clipRect, recoveringMemory);
            }
        } else {
            mSurfaceController.clearCropInTransaction(recoveringMemory);
        }
    }

    private boolean shouldConsumeMainWindowSizeTransaction() {
      // We only consume the transaction when the client is calling relayout
      // because this is the only time we know the frameNumber will be valid
@@ -738,15 +661,6 @@ class WindowStateAnimator {
        final LayoutParams attrs = mWin.getAttrs();
        final Task task = w.getTask();

        // If we are undergoing seamless rotation, the surface has already
        // been set up to persist at it's old location. We need to freeze
        // updates until a resize occurs.

        Rect clipRect = null;
        if (calculateCrop(mTmpClipRect)) {
            clipRect = mTmpClipRect;
        }

        if (shouldConsumeMainWindowSizeTransaction()) {
            task.getMainWindowSizeChangeTask().getSurfaceControl().deferTransactionUntil(
                    mWin.getClientViewRootSurface(), mWin.getFrameNumber());
@@ -788,12 +702,6 @@ class WindowStateAnimator {
                    }
                     xOffset = -mTmpPos.x;
                    yOffset = -mTmpPos.y;
                     // Crop also needs to be extended so the bottom isn't cut off when the WSA
                    // position is moved.
                    if (clipRect != null) {
                        clipRect.right += mTmpPos.x;
                        clipRect.bottom += mTmpPos.y;
                    }
                }
            }
            if (!mIsWallpaper) {
@@ -808,7 +716,6 @@ class WindowStateAnimator {
            // Wallpaper is already updated above when calling setWallpaperPositionAndScale so
            // we only need to consider the non-wallpaper case here.
            if (!mIsWallpaper) {
                applyCrop(clipRect, recoveringMemory);
                mSurfaceController.setMatrixInTransaction(
                    mDsDx * w.mHScale,
                    mDtDx * w.mVScale,
@@ -1010,7 +917,6 @@ class WindowStateAnimator {
                mDtDy * mWin.mTmpMatrixArray[MSKEW_X] * mWin.mHScale,
                mDsDy * mWin.mTmpMatrixArray[MSCALE_Y] * mWin.mVScale,
                recoveringMemory);
        applyCrop(null, recoveringMemory);
    }

    /**
@@ -1201,7 +1107,6 @@ class WindowStateAnimator {

    void dumpDebug(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);
        mLastClipRect.dumpDebug(proto, LAST_CLIP_RECT);
        if (mSurfaceController != null) {
            mSurfaceController.dumpDebug(proto, SURFACE);
        }
@@ -1222,11 +1127,7 @@ class WindowStateAnimator {
            pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
            pw.print(prefix); pw.print("mEnterAnimationPending=" + mEnterAnimationPending);
            pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
            pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);

            if (!mLastFinalClipRect.isEmpty()) {
                pw.print(" mLastFinalClipRect="); mLastFinalClipRect.printShortString(pw);
            }
            pw.println();
        }

+0 −3
Original line number Diff line number Diff line
@@ -117,7 +117,6 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
            assertEquals(win.mActivityRecord.getPrefixOrderIndex(), app.prefixOrderIndex);
            assertEquals(win.mActivityRecord.getTask().mTaskId, app.taskId);
            assertEquals(mMockLeash, app.leash);
            assertEquals(win.mWinAnimator.mLastClipRect, app.clipRect);
            assertEquals(false, app.isTranslucent);
            verify(mMockTransaction).setPosition(mMockLeash, app.position.x, app.position.y);
            verify(mMockTransaction).setWindowCrop(mMockLeash, 100, 50);
@@ -274,7 +273,6 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
            assertEquals(new Rect(0, 0, 200, 200), app.startBounds);
            assertEquals(mMockLeash, app.leash);
            assertEquals(mMockThumbnailLeash, app.startLeash);
            assertEquals(win.mWinAnimator.mLastClipRect, app.clipRect);
            assertEquals(false, app.isTranslucent);
            verify(mMockTransaction).setPosition(
                    mMockLeash, app.startBounds.left, app.startBounds.top);
@@ -325,7 +323,6 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
            assertEquals(new Rect(50, 100, 150, 150), app.startBounds);
            assertEquals(mMockLeash, app.leash);
            assertEquals(mMockThumbnailLeash, app.startLeash);
            assertEquals(win.mWinAnimator.mLastClipRect, app.clipRect);
            assertEquals(false, app.isTranslucent);
            verify(mMockTransaction).setPosition(
                    mMockLeash, app.startBounds.left, app.startBounds.top);
Loading