From 2cc2c57db32301b80cb5de1d5ea97e6b45f2a42c Mon Sep 17 00:00:00 2001 From: Aurélien Pomini Date: Wed, 28 Feb 2024 14:39:39 +0000 Subject: Correctly compute diffWidth and diffHeight. The previous calculation was wrong and lead to less parallax than expected in some cases. This is the OP part of the CL. Also, this CL makes sure we scale by width if the crop is proportionally taller than the screen: this way, the window will always be filled with content (and could support vertical parallax). Note that given our implementation of WallpaperCropper, the wallpaper is always wide enough for the screen, so we always scale by height (make the wallpaper match the screen height) and only have horizontal parallax. A honest alternative would be to remove (under flag) the whole logic for vertical parallax. Flag: aconfig com.android.window.flags.multi_crop DEVELOPMENT Test: atest WallpaperControllerTest Bug: 327042053 Change-Id: I8aac1b0d4b85fed0a446aed794fdb525b21d8e3a --- .../com/android/server/wm/WallpaperController.java | 42 ++++++++++++++-------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 594043d380c9..9b19a707d7be 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -349,7 +349,7 @@ class WallpaperController { final Rect lastWallpaperBounds = wallpaperWin.getParentFrame(); int screenWidth = lastWallpaperBounds.width(); int screenHeight = lastWallpaperBounds.height(); - float screenRatio = ((float) screenWidth) / screenHeight; + float screenRatio = (float) screenWidth / screenHeight; Point screenSize = new Point(screenWidth, screenHeight); WallpaperWindowToken token = wallpaperWin.mToken.asWallpaperToken(); @@ -399,20 +399,32 @@ class WallpaperController { Point bitmapSize = new Point( wallpaperWin.mRequestedWidth, wallpaperWin.mRequestedHeight); SparseArray cropHints = token.getCropHints(); - wallpaperFrame = mWallpaperCropUtils.getCrop( - screenSize, bitmapSize, cropHints, wallpaperWin.isRtl()); - - cropZoom = wallpaperFrame.isEmpty() ? 1f - : ((float) screenHeight) / wallpaperFrame.height() / wallpaperWin.mVScale; - - // A positive x / y offset shifts the wallpaper to the right / bottom respectively. - cropOffsetX = -wallpaperFrame.left - + (int) ((cropZoom - 1f) * wallpaperFrame.height() * screenRatio / 2f); - cropOffsetY = -wallpaperFrame.top - + (int) ((cropZoom - 1f) * wallpaperFrame.height() / 2f); - - diffWidth = (int) (wallpaperFrame.width() * wallpaperWin.mHScale) - screenWidth; - diffHeight = (int) (wallpaperFrame.height() * wallpaperWin.mVScale) - screenHeight; + wallpaperFrame = bitmapSize.x <= 0 || bitmapSize.y <= 0 ? wallpaperWin.getFrame() + : mWallpaperCropUtils.getCrop(screenSize, bitmapSize, cropHints, + wallpaperWin.isRtl()); + int frameWidth = wallpaperFrame.width(); + int frameHeight = wallpaperFrame.height(); + float frameRatio = (float) frameWidth / frameHeight; + + // If the crop is proportionally wider/taller than the screen, scale it so that its + // height/width matches the screen height/width, and use the additional width/height + // for parallax (respectively). + boolean scaleHeight = frameRatio >= screenRatio; + cropZoom = wallpaperFrame.isEmpty() ? 1f : scaleHeight + ? (float) screenHeight / frameHeight / wallpaperWin.mVScale + : (float) screenWidth / frameWidth / wallpaperWin.mHScale; + + // The dimensions of the frame, without the additional width or height for parallax. + float w = scaleHeight ? frameHeight * screenRatio : frameWidth; + float h = scaleHeight ? frameHeight : frameWidth / screenRatio; + + // Note: a positive x/y offset shifts the wallpaper to the right/bottom respectively. + cropOffsetX = -wallpaperFrame.left + (int) ((cropZoom - 1f) * w / 2f); + cropOffsetY = -wallpaperFrame.top + (int) ((cropZoom - 1f) * h / 2f); + + // Available width or height for parallax + diffWidth = (int) ((frameWidth - w) * wallpaperWin.mHScale); + diffHeight = (int) ((frameHeight - h) * wallpaperWin.mVScale); } else { wallpaperFrame = wallpaperWin.getFrame(); cropZoom = 1f; -- cgit v1.2.3-59-g8ed1b