From c084015e237058c7f3b1550820f7a73ff1fb371a Mon Sep 17 00:00:00 2001 From: Jorge Gil Date: Wed, 31 May 2023 20:48:27 +0000 Subject: Reland: Crop surface to the content size during drag-resizing During drag-resizing, a fullscreen-sized surface is reused to optimize reallocations, which can leave outdated app content on the surface when resizing to a smaller size. This outdated app content can then be briefly exposed to the user when drag-resizing to a larger size until the app draws again and fills the new size. To "clear" this garbage content, this change crops the content directly from the client side during drag-resizing. The "gap" between the cropped app content and the larger task that's in sync with the drag-gesture is now the solid background color of the task surface instead of the former garbage app content. Bug: 270202228 Test: quickly drag-resize a freeform task to a smaller and then a larger size, verify that the "gap" exposed while the app draw catches up to the resize gesture is now a solid color instead of artifacts from a previous app draw. Test: atest AutoEnterPipFromSplitScreenOnGoToHomeTest - no regressions Change-Id: Ibc3ca2a8f5b83b3fef2fe4832f93ca52d3b156a8 (cherry picked from commit 52530935ec5bde9455179833f0db438413fdee40) --- core/java/android/view/ViewRootImpl.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 543c1efa1104..bfe5cfb12c8d 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -8432,10 +8432,20 @@ public final class ViewRootImpl implements ViewParent, } } - if (mSurfaceControl.isValid() && !HardwareRenderer.isDrawingEnabled()) { - // When drawing is disabled the window layer won't have a valid buffer. - // Set a window crop so input can get delivered to the window. - mTransaction.setWindowCrop(mSurfaceControl, mSurfaceSize.x, mSurfaceSize.y).apply(); + if (mSurfaceControl.isValid()) { + if (mPendingDragResizing && !mSurfaceSize.equals( + mWinFrameInScreen.width(), mWinFrameInScreen.height())) { + // During drag-resize, a single fullscreen-sized surface is reused for optimization. + // Crop to the content size instead of the surface size to avoid exposing garbage + // content that is still on the surface from previous re-layouts (e.g. when + // resizing to a larger size). + mTransaction.setWindowCrop(mSurfaceControl, + mWinFrameInScreen.width(), mWinFrameInScreen.height()); + } else if (!HardwareRenderer.isDrawingEnabled()) { + // When drawing is disabled the window layer won't have a valid buffer. + // Set a window crop so input can get delivered to the window. + mTransaction.setWindowCrop(mSurfaceControl, mSurfaceSize.x, mSurfaceSize.y).apply(); + } } mLastTransformHint = transformHint; -- cgit v1.2.3-59-g8ed1b