Nuke WindowState#mShownPosition. Rework mXOffset/mYOffset.

Ignoring Wallpaper Offsets, the WindowStateAnimator is now
always positioned at (0,0), so we don't need to calculate or store this. For
Wallpaper Offsets we can manipulate the position of the WindowStateAnimator surface
directly. This seems to be a nice level to model the concept of scrolling a buffer
larger than the "Window" to which it is assigned.
Everything on top of WSA can ignore the offsets by only interacting with the WS and above.
Seamless rotation may mess with the position so we need to be sure to reset it to 0,0.

Test: Manual. go/wm-smoke
Bug: 72038766
Change-Id: I961d190d1f1ee71faaede095617092a0ad32e16f
This commit is contained in:
Robert Carr
2018-01-31 18:08:39 -08:00
parent 824095856b
commit 217e7cc221
8 changed files with 34 additions and 88 deletions

View File

@@ -295,7 +295,6 @@ message WindowStateProto {
optional bool animating_exit = 14;
repeated WindowStateProto child_windows = 15;
optional .android.graphics.RectProto surface_position = 16;
optional .android.graphics.RectProto shown_position = 17;
optional int32 requested_width = 18;
optional int32 requested_height = 19;
optional int32 view_visibility = 20;

View File

@@ -5642,9 +5642,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final int fl = PolicyControl.getWindowFlags(null,
mTopFullscreenOpaqueWindowState.getAttrs());
if (localLOGV) {
Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
+ " shown position: "
+ mTopFullscreenOpaqueWindowState.getShownPositionLw());
Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw());
Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
+ " lp.flags=0x" + Integer.toHexString(fl));
}

View File

@@ -231,14 +231,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
*/
public Rect getFrameLw();
/**
* Retrieve the current position of the window that is actually shown.
* Must be called with the window manager lock held.
*
* @return Point The point holding the shown window position.
*/
public Point getShownPositionLw();
/**
* Retrieve the frame of the display that this window was last
* laid out in. Must be called with the

View File

@@ -275,6 +275,8 @@ class WallpaperController {
}
boolean updateWallpaperOffset(WindowState wallpaperWin, int dw, int dh, boolean sync) {
int xOffset = 0;
int yOffset = 0;
boolean rawChanged = false;
// Set the default wallpaper x-offset to either edge of the screen (depending on RTL), to
// match the behavior of most Launchers
@@ -286,11 +288,8 @@ class WallpaperController {
if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
offset += mLastWallpaperDisplayOffsetX;
}
boolean changed = wallpaperWin.mXOffset != offset;
if (changed) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " x: " + offset);
wallpaperWin.mXOffset = offset;
}
xOffset = offset;
if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
wallpaperWin.mWallpaperX = wpx;
wallpaperWin.mWallpaperXStep = wpxs;
@@ -304,17 +303,16 @@ class WallpaperController {
if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
offset += mLastWallpaperDisplayOffsetY;
}
if (wallpaperWin.mYOffset != offset) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " y: " + offset);
changed = true;
wallpaperWin.mYOffset = offset;
}
yOffset = offset;
if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
wallpaperWin.mWallpaperY = wpy;
wallpaperWin.mWallpaperYStep = wpys;
rawChanged = true;
}
boolean changed = wallpaperWin.mWinAnimator.setWallpaperOffset(xOffset, yOffset);
if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
try {

View File

@@ -74,10 +74,6 @@ class WallpaperWindowToken extends WindowToken {
for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
final WindowState wallpaper = mChildren.get(wallpaperNdx);
if (wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, sync)) {
final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
winAnimator.computeShownFrameLocked();
// No need to lay out the windows - we can just set the wallpaper position directly.
winAnimator.setWallpaperOffset(wallpaper.mShownPosition);
// We only want to be synchronous with one wallpaper.
sync = false;
}

View File

@@ -138,7 +138,6 @@ import static com.android.server.wm.proto.WindowStateProto.REMOVED;
import static com.android.server.wm.proto.WindowStateProto.REMOVE_ON_EXIT;
import static com.android.server.wm.proto.WindowStateProto.REQUESTED_HEIGHT;
import static com.android.server.wm.proto.WindowStateProto.REQUESTED_WIDTH;
import static com.android.server.wm.proto.WindowStateProto.SHOWN_POSITION;
import static com.android.server.wm.proto.WindowStateProto.STABLE_INSETS;
import static com.android.server.wm.proto.WindowStateProto.STACK_ID;
import static com.android.server.wm.proto.WindowStateProto.SURFACE_INSETS;
@@ -297,12 +296,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
*/
private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration();
/**
* Actual position of the surface shown on-screen (may be modified by animation). These are
* in the screen's coordinate space (WITH the compatibility scale applied).
*/
final Point mShownPosition = new Point();
/**
* Insets that determine the actually visible area. These are in the application's
* coordinate space (without compatibility scale applied).
@@ -462,10 +455,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
int mWallpaperDisplayOffsetX = Integer.MIN_VALUE;
int mWallpaperDisplayOffsetY = Integer.MIN_VALUE;
// Wallpaper windows: pixels offset based on above variables.
int mXOffset;
int mYOffset;
/**
* This is set after IWindowSession.relayout() has been called at
* least once for the window. It allows us to detect the situation
@@ -771,8 +760,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mRequestedHeight = 0;
mLastRequestedWidth = 0;
mLastRequestedHeight = 0;
mXOffset = 0;
mYOffset = 0;
mLayer = 0;
mInputWindowHandle = new InputWindowHandle(
mAppToken != null ? mAppToken.mInputApplicationHandle : null, this, c,
@@ -1137,11 +1124,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mFrame;
}
@Override
public Point getShownPositionLw() {
return mShownPosition;
}
@Override
public Rect getDisplayFrameLw() {
return mDisplayFrame;
@@ -3136,7 +3118,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mContentInsets.writeToProto(proto, CONTENT_INSETS);
mAttrs.surfaceInsets.writeToProto(proto, SURFACE_INSETS);
mSurfacePosition.writeToProto(proto, SURFACE_POSITION);
mShownPosition.writeToProto(proto, SHOWN_POSITION);
mWinAnimator.writeToProto(proto, ANIMATOR);
proto.write(ANIMATING_EXIT, mAnimatingExit);
for (int i = 0; i < mChildren.size(); i++) {
@@ -3252,10 +3233,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
}
if (mXOffset != 0 || mYOffset != 0) {
pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
pw.print(" y="); pw.println(mYOffset);
}
if (dumpAll) {
pw.print(prefix); pw.print("mGivenContentInsets=");
mGivenContentInsets.printShortString(pw);
@@ -3274,7 +3251,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
pw.println(getLastReportedConfiguration());
}
pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
pw.print(" mShownPosition="); mShownPosition.printShortString(pw);
pw.print(" isReadyForDisplay()="); pw.print(isReadyForDisplay());
pw.print(" mWindowRemovalAllowed="); pw.println(mWindowRemovalAllowed);
if (dumpAll) {
@@ -4195,9 +4171,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
final int width = mFrame.width();
final int height = mFrame.height();
// Compute the offset of the window in relation to the decor rect.
final int left = mXOffset + mFrame.left;
final int top = mYOffset + mFrame.top;
final int left = mFrame.left;
final int top = mFrame.top;
// Initialize the decor rect to the entire frame.
if (isDockedResizing()) {
@@ -4391,8 +4366,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
float9[Matrix.MSKEW_Y] = mWinAnimator.mDtDx;
float9[Matrix.MSKEW_X] = mWinAnimator.mDtDy;
float9[Matrix.MSCALE_Y] = mWinAnimator.mDsDy;
int x = mSurfacePosition.x + mShownPosition.x;
int y = mSurfacePosition.y + mShownPosition.y;
int x = mSurfacePosition.x;
int y = mSurfacePosition.y;
// If changed, also adjust transformFrameToSurfacePosition
final WindowContainer parent = getParent();

View File

@@ -209,6 +209,12 @@ class WindowStateAnimator {
float mExtraHScale = (float) 1.0;
float mExtraVScale = (float) 1.0;
// 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;
private final Rect mTmpSize = new Rect();
private final SurfaceControl.Transaction mReparentTransaction = new SurfaceControl.Transaction();
@@ -438,7 +444,7 @@ class WindowStateAnimator {
flags |= SurfaceControl.SECURE;
}
mTmpSize.set(w.mFrame.left + w.mXOffset, w.mFrame.top + w.mYOffset, 0, 0);
mTmpSize.set(0, 0, 0, 0);
calculateSurfaceBounds(w, attrs);
final int width = mTmpSize.width();
final int height = mTmpSize.height();
@@ -679,8 +685,8 @@ class WindowStateAnimator {
// WindowState.prepareSurfaces expands for surface insets (in order they don't get
// clipped by the WindowState surface), so we need to go into the other direction here.
tmpMatrix.postTranslate(mWin.mXOffset + mWin.mAttrs.surfaceInsets.left,
mWin.mYOffset + mWin.mAttrs.surfaceInsets.top);
tmpMatrix.postTranslate(mWin.mAttrs.surfaceInsets.left,
mWin.mAttrs.surfaceInsets.top);
// "convert" it into SurfaceFlinger's format
@@ -695,9 +701,6 @@ class WindowStateAnimator {
mDtDx = tmpFloats[Matrix.MSKEW_Y];
mDtDy = tmpFloats[Matrix.MSKEW_X];
mDsDy = tmpFloats[Matrix.MSCALE_Y];
float x = tmpFloats[Matrix.MTRANS_X];
float y = tmpFloats[Matrix.MTRANS_Y];
mWin.mShownPosition.set(Math.round(x), Math.round(y));
// Now set the alpha... but because our current hardware
// can't do alpha transformation on a non-opaque surface,
@@ -707,8 +710,7 @@ class WindowStateAnimator {
mShownAlpha = mAlpha;
if (!mService.mLimitedAlphaCompositing
|| (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
|| (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)
&& x == frame.left && y == frame.top))) {
|| (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)))) {
//Slog.i(TAG_WM, "Applying alpha transform");
if (screenAnimation) {
mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
@@ -738,10 +740,6 @@ class WindowStateAnimator {
TAG, "computeShownFrameLocked: " + this +
" not attached, mAlpha=" + mAlpha);
// WindowState.prepareSurfaces expands for surface insets (in order they don't get
// clipped by the WindowState surface), so we need to go into the other direction here.
mWin.mShownPosition.set(mWin.mXOffset + mWin.mAttrs.surfaceInsets.left,
mWin.mYOffset + mWin.mAttrs.surfaceInsets.top);
mShownAlpha = mAlpha;
mHaveMatrix = false;
mDsDx = mWin.mGlobalScale;
@@ -792,12 +790,6 @@ class WindowStateAnimator {
if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect
+ " fullscreen=" + fullscreen);
if (isFreeformResizing && !w.isChildWindow()) {
// For freeform resizing non child windows, we are using the big surface positioned
// at 0,0. Thus we must express the crop in that coordinate space.
clipRect.offset(w.mShownPosition.x, w.mShownPosition.y);
}
w.expandForSurfaceInsets(clipRect);
// The clip rect was generated assuming (0,0) as the window origin,
@@ -834,7 +826,7 @@ class WindowStateAnimator {
final LayoutParams attrs = mWin.getAttrs();
final Task task = w.getTask();
mTmpSize.set(w.mShownPosition.x, w.mShownPosition.y, 0, 0);
mTmpSize.set(0, 0, 0, 0);
calculateSurfaceBounds(w, attrs);
mExtraHScale = (float) 1.0;
@@ -970,8 +962,7 @@ class WindowStateAnimator {
mForceScaleUntilResize = true;
} else {
if (!w.mSeamlesslyRotated) {
mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top,
recoveringMemory);
mSurfaceController.setPositionInTransaction(0, 0, recoveringMemory);
}
}
@@ -1139,24 +1130,26 @@ class WindowStateAnimator {
mSurfaceController.setTransparentRegionHint(region);
}
void setWallpaperOffset(Point shownPosition) {
final LayoutParams attrs = mWin.getAttrs();
final int left = shownPosition.x - attrs.surfaceInsets.left;
final int top = shownPosition.y - attrs.surfaceInsets.top;
boolean setWallpaperOffset(int dx, int dy) {
if (mXOffset == dx && mYOffset == dy) {
return false;
}
mXOffset = dx;
mYOffset = dy;
try {
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
mService.openSurfaceTransaction();
mSurfaceController.setPositionInTransaction(mWin.mFrame.left + left,
mWin.mFrame.top + top, false);
mSurfaceController.setPositionInTransaction(dx, dy, false);
applyCrop(null, false);
} catch (RuntimeException e) {
Slog.w(TAG, "Error positioning surface of " + mWin
+ " pos=(" + left + "," + top + ")", e);
+ " pos=(" + dx + "," + dy + ")", e);
} finally {
mService.closeSurfaceTransaction("setWallpaperOffset");
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION setWallpaperOffset");
return true;
}
}

View File

@@ -78,11 +78,6 @@ public class FakeWindowState implements WindowManagerPolicy.WindowState {
return parentFrame;
}
@Override
public Point getShownPositionLw() {
return new Point(parentFrame.left, parentFrame.top);
}
@Override
public Rect getDisplayFrameLw() {
return displayFrame;