Skip to content

Commit 80fea05

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Fix some issues with updating the offsets of a window." into jb-dev
2 parents 79f5777 + 3e52fc2 commit 80fea05

File tree

1 file changed

+73
-53
lines changed

1 file changed

+73
-53
lines changed

services/java/com/android/server/wm/WindowStateAnimator.java

Lines changed: 73 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,59 @@ void computeShownFrameLocked() {
935935
mDtDy = mWin.mGlobalScale;
936936
}
937937

938+
void updateSurfaceWindowCrop(final boolean recoveringMemory) {
939+
final WindowState w = mWin;
940+
941+
// Need to recompute a new system decor rect each time.
942+
if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
943+
// Currently can't do this cropping for scaled windows. We'll
944+
// just keep the crop rect the same as the source surface.
945+
w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
946+
} else if (w.mLayer >= mService.mSystemDecorLayer) {
947+
// Above the decor layer is easy, just use the entire window.
948+
w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
949+
w.mCompatFrame.height());
950+
} else {
951+
final Rect decorRect = mService.mSystemDecorRect;
952+
// Compute the offset of the window in relation to the decor rect.
953+
final int offX = w.mXOffset + w.mFrame.left;
954+
final int offY = w.mYOffset + w.mFrame.top;
955+
// Initialize the decor rect to the entire frame.
956+
w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
957+
// Intersect with the decor rect, offsetted by window position.
958+
w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
959+
decorRect.right-offX, decorRect.bottom-offY);
960+
// If size compatibility is being applied to the window, the
961+
// surface is scaled relative to the screen. Also apply this
962+
// scaling to the crop rect. We aren't using the standard rect
963+
// scale function because we want to round things to make the crop
964+
// always round to a larger rect to ensure we don't crop too
965+
// much and hide part of the window that should be seen.
966+
if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
967+
final float scale = w.mInvGlobalScale;
968+
w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
969+
w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
970+
w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
971+
w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
972+
}
973+
}
974+
975+
if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
976+
w.mLastSystemDecorRect.set(w.mSystemDecorRect);
977+
try {
978+
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
979+
"CROP " + w.mSystemDecorRect.toShortString(), null);
980+
mSurface.setWindowCrop(w.mSystemDecorRect);
981+
} catch (RuntimeException e) {
982+
Slog.w(TAG, "Error setting crop surface of " + w
983+
+ " crop=" + w.mSystemDecorRect.toShortString(), e);
984+
if (!recoveringMemory) {
985+
mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
986+
}
987+
}
988+
}
989+
}
990+
938991
void setSurfaceBoundaries(final boolean recoveringMemory) {
939992
final WindowState w = mWin;
940993
int width, height;
@@ -1003,54 +1056,7 @@ void setSurfaceBoundaries(final boolean recoveringMemory) {
10031056
}
10041057
}
10051058

1006-
// Need to recompute a new system decor rect each time.
1007-
if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1008-
// Currently can't do this cropping for scaled windows. We'll
1009-
// just keep the crop rect the same as the source surface.
1010-
w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
1011-
} else if (w.mLayer >= mService.mSystemDecorLayer) {
1012-
// Above the decor layer is easy, just use the entire window.
1013-
w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
1014-
w.mCompatFrame.height());
1015-
} else {
1016-
final Rect decorRect = mService.mSystemDecorRect;
1017-
// Compute the offset of the window in relation to the decor rect.
1018-
final int offX = w.mXOffset + w.mFrame.left;
1019-
final int offY = w.mYOffset + w.mFrame.top;
1020-
// Initialize the decor rect to the entire frame.
1021-
w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
1022-
// Intersect with the decor rect, offsetted by window position.
1023-
w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
1024-
decorRect.right-offX, decorRect.bottom-offY);
1025-
// If size compatibility is being applied to the window, the
1026-
// surface is scaled relative to the screen. Also apply this
1027-
// scaling to the crop rect. We aren't using the standard rect
1028-
// scale function because we want to round things to make the crop
1029-
// always round to a larger rect to ensure we don't crop too
1030-
// much and hide part of the window that should be seen.
1031-
if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
1032-
final float scale = w.mInvGlobalScale;
1033-
w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
1034-
w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
1035-
w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
1036-
w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
1037-
}
1038-
}
1039-
1040-
if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
1041-
w.mLastSystemDecorRect.set(w.mSystemDecorRect);
1042-
try {
1043-
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1044-
"CROP " + w.mSystemDecorRect.toShortString(), null);
1045-
mSurface.setWindowCrop(w.mSystemDecorRect);
1046-
} catch (RuntimeException e) {
1047-
Slog.w(TAG, "Error setting crop surface of " + w
1048-
+ " crop=" + w.mSystemDecorRect.toShortString(), e);
1049-
if (!recoveringMemory) {
1050-
mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
1051-
}
1052-
}
1053-
}
1059+
updateSurfaceWindowCrop(recoveringMemory);
10541060
}
10551061

10561062
public void prepareSurfaceLocked(final boolean recoveringMemory) {
@@ -1181,17 +1187,31 @@ void setTransparentRegionHint(final Region region) {
11811187
}
11821188

11831189
void setWallpaperOffset(int left, int top) {
1190+
mSurfaceX = left;
1191+
mSurfaceY = top;
1192+
if (mAnimating) {
1193+
// If this window (or its app token) is animating, then the position
1194+
// of the surface will be re-computed on the next animation frame.
1195+
// We can't poke it directly here because it depends on whatever
1196+
// transformation is being applied by the animation.
1197+
return;
1198+
}
1199+
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1200+
">>> OPEN TRANSACTION setWallpaperOffset");
11841201
Surface.openTransaction();
11851202
try {
1186-
mSurfaceX = left;
1187-
mSurfaceY = top;
1188-
mSurface.setPosition(left, top);
1189-
mSurface.setWindowCrop(null);
1203+
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1204+
"POS " + left + ", " + top, null);
1205+
mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
1206+
updateSurfaceWindowCrop(false);
11901207
} catch (RuntimeException e) {
11911208
Slog.w(TAG, "Error positioning surface of " + mWin
11921209
+ " pos=(" + left + "," + top + ")", e);
1210+
} finally {
1211+
Surface.closeTransaction();
1212+
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1213+
"<<< CLOSE TRANSACTION setWallpaperOffset");
11931214
}
1194-
Surface.closeTransaction();
11951215
}
11961216

11971217
// This must be called while inside a transaction.

0 commit comments

Comments
 (0)