WM Wallpaper: Set offset and scale on WindowState level

When we set it on the WindowStateAnimator we are potentially
coming in to disagreement with scaling applied via the BLASTBufferQueue.

Bug: 188504567
Test: Repro from bug. Existing tests pass.
Change-Id: I7843fa12e52812a5cd3a3dd34114e0c6d58aecd3
This commit is contained in:
Robert Carr
2021-06-02 14:40:22 -07:00
parent 327a271617
commit 47307ac8f0
5 changed files with 35 additions and 85 deletions

View File

@@ -340,7 +340,7 @@ class WallpaperController {
rawChanged = true;
}
boolean changed = wallpaperWin.mWinAnimator.setWallpaperOffset(xOffset, yOffset,
boolean changed = wallpaperWin.setWallpaperOffset(xOffset, yOffset,
wallpaperWin.mShouldScaleWallpaper
? zoomOutToScale(wallpaperWin.mWallpaperZoomOut) : 1);

View File

@@ -444,6 +444,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
float mOverrideScale = 1;
float mHScale=1, mVScale=1;
float mLastHScale=1, mLastVScale=1;
// An offset in pixel of the surface contents from the window position. Used for Wallpaper
// to provide the effect of scrolling within a large surface. We just use these values as
// a cache.
int mXOffset = 0;
int mYOffset = 0;
// A scale factor for the surface contents, that will be applied from the center of the visible
// region.
float mWallpaperScale = 1f;
final Matrix mTmpMatrix = new Matrix();
final float[] mTmpMatrixArray = new float[9];
@@ -5422,10 +5433,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
private void updateScaleIfNeeded() {
if (mLastGlobalScale != mGlobalScale || mLastHScale != mHScale ||
mLastVScale != mVScale ) {
float newHScale = mHScale * mGlobalScale * mWallpaperScale;
float newVScale = mVScale * mGlobalScale * mWallpaperScale;
if (mLastHScale != newHScale ||
mLastVScale != newVScale ) {
getPendingTransaction().setMatrix(getSurfaceControl(),
mGlobalScale*mHScale, 0, 0, mGlobalScale*mVScale);
newHScale, 0, 0, newVScale);
mLastGlobalScale = mGlobalScale;
mLastHScale = mHScale;
mLastVScale = mVScale;
@@ -5463,6 +5476,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mSurfacePlacementNeeded = false;
transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
mSurfacePosition);
mSurfacePosition.offset(mXOffset, mYOffset);
// Freeze position while we're unrotated, so the surface remains at the position it was
// prior to the rotation.
@@ -6071,4 +6085,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
void markRedrawForSyncReported() {
mRedrawForSyncReported = true;
}
boolean setWallpaperOffset(int dx, int dy, float scale) {
if (mXOffset == dx && mYOffset == dy && Float.compare(mWallpaperScale, scale) == 0) {
return false;
}
mXOffset = dx;
mYOffset = dy;
mWallpaperScale = scale;
scheduleAnimation();
return true;
}
}

View File

@@ -169,16 +169,6 @@ class WindowStateAnimator {
int mAttrType;
// An offset in pixel of the surface contents from the window position. Used for Wallpaper
// to provide the effect of scrolling within a large surface. We just use these values as
// a cache.
int mXOffset = 0;
int mYOffset = 0;
// A scale factor for the surface contents, that will be applied from the center of the visible
// region.
float mWallpaperScale = 1f;
private final Rect mTmpSize = new Rect();
/**
@@ -502,18 +492,6 @@ class WindowStateAnimator {
}
final WindowState w = mWin;
if (!w.mSeamlesslyRotated) {
// Used to offset the WSA when stack position changes before a resize.
int xOffset = mXOffset;
int yOffset = mYOffset;
if (!mIsWallpaper) {
mSurfaceController.setPosition(t, xOffset, yOffset);
} else {
setWallpaperPositionAndScale(t, xOffset, yOffset, mWallpaperScale);
}
}
final Task task = w.getTask();
if (shouldConsumeMainWindowSizeTransaction()) {
if (isInBlastSync()) {
@@ -575,14 +553,8 @@ class WindowStateAnimator {
"SURFACE controller=%s alpha=%f HScale=%f, VScale=%f: %s",
mSurfaceController, mShownAlpha, w.mHScale, w.mVScale, w);
boolean prepared = true;
if (mIsWallpaper) {
setWallpaperPositionAndScale(t, mXOffset, mYOffset, mWallpaperScale);
} else {
prepared =
mSurfaceController.prepareToShowInTransaction(t, mShownAlpha);
}
boolean prepared =
mSurfaceController.prepareToShowInTransaction(t, mShownAlpha);
if (prepared && mDrawState == HAS_DRAWN) {
if (mLastHidden) {
@@ -635,53 +607,6 @@ class WindowStateAnimator {
}
}
boolean setWallpaperOffset(int dx, int dy, float scale) {
if (mXOffset == dx && mYOffset == dy && Float.compare(mWallpaperScale, scale) == 0) {
return false;
}
mXOffset = dx;
mYOffset = dy;
mWallpaperScale = scale;
if (mSurfaceController != null) {
try {
if (SHOW_LIGHT_TRANSACTIONS) {
Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
}
mService.openSurfaceTransaction();
setWallpaperPositionAndScale(SurfaceControl.getGlobalTransaction(), dx, dy, scale);
} catch (RuntimeException e) {
Slog.w(TAG, "Error positioning surface of " + mWin
+ " pos=(" + dx + "," + dy + ")", e);
} finally {
mService.closeSurfaceTransaction("setWallpaperOffset");
if (SHOW_LIGHT_TRANSACTIONS) {
Slog.i(TAG, "<<< CLOSE TRANSACTION setWallpaperOffset");
}
}
}
return true;
}
private void setWallpaperPositionAndScale(SurfaceControl.Transaction t, int dx, int dy,
float scale) {
DisplayInfo displayInfo = mWin.getDisplayInfo();
Matrix matrix = mWin.mTmpMatrix;
matrix.setTranslate(dx, dy);
matrix.postScale(scale, scale, displayInfo.logicalWidth / 2f,
displayInfo.logicalHeight / 2f);
matrix.getValues(mWin.mTmpMatrixArray);
matrix.reset();
mSurfaceController.setPosition(t,mWin.mTmpMatrixArray[MTRANS_X],
mWin.mTmpMatrixArray[MTRANS_Y]);
mSurfaceController.setMatrix(t, mWin.mTmpMatrixArray[MSCALE_X],
mWin.mTmpMatrixArray[MSKEW_Y],
mWin.mTmpMatrixArray[MSKEW_X],
mWin.mTmpMatrixArray[MSCALE_Y]);
}
/**
* Try to change the pixel format without recreating the surface. This
* will be common in the case of changing from PixelFormat.OPAQUE to

View File

@@ -1386,11 +1386,11 @@ public class DisplayContentTests extends WindowTestsBase {
performLayout(mDisplayContent);
// Force the negative offset to verify it can be updated.
mWallpaperWindow.mWinAnimator.mXOffset = mWallpaperWindow.mWinAnimator.mYOffset = -1;
mWallpaperWindow.mXOffset = mWallpaperWindow.mYOffset = -1;
assertTrue(mDisplayContent.mWallpaperController.updateWallpaperOffset(mWallpaperWindow,
false /* sync */));
assertThat(mWallpaperWindow.mWinAnimator.mXOffset).isGreaterThan(-1);
assertThat(mWallpaperWindow.mWinAnimator.mYOffset).isGreaterThan(-1);
assertThat(mWallpaperWindow.mXOffset).isGreaterThan(-1);
assertThat(mWallpaperWindow.mYOffset).isGreaterThan(-1);
// The wallpaper need to animate with transformed position, so its surface position should
// not be reset.

View File

@@ -212,7 +212,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
// value did, and we do dispatch the zoom to the wallpaper service
dc.mWallpaperController.setWallpaperZoomOut(homeWindow, newZoom);
assertEquals(newZoom, wallpaperWindow.mWallpaperZoomOut, .01f);
assertEquals(1f, wallpaperWindow.mWinAnimator.mWallpaperScale, .01f);
assertEquals(1f, wallpaperWindow.mWallpaperScale, .01f);
verify(wallpaperWindow.mClient).dispatchWallpaperOffsets(anyFloat(), anyFloat(), anyFloat(),
anyFloat(), eq(newZoom), anyBoolean());
}