Merge "Fix some issues with updating the offsets of a window." into jb-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
80fea051ba
@@ -935,6 +935,59 @@ class WindowStateAnimator {
|
||||
mDtDy = mWin.mGlobalScale;
|
||||
}
|
||||
|
||||
void updateSurfaceWindowCrop(final boolean recoveringMemory) {
|
||||
final WindowState w = mWin;
|
||||
|
||||
// Need to recompute a new system decor rect each time.
|
||||
if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
|
||||
// Currently can't do this cropping for scaled windows. We'll
|
||||
// just keep the crop rect the same as the source surface.
|
||||
w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
|
||||
} else if (w.mLayer >= mService.mSystemDecorLayer) {
|
||||
// Above the decor layer is easy, just use the entire window.
|
||||
w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
|
||||
w.mCompatFrame.height());
|
||||
} else {
|
||||
final Rect decorRect = mService.mSystemDecorRect;
|
||||
// Compute the offset of the window in relation to the decor rect.
|
||||
final int offX = w.mXOffset + w.mFrame.left;
|
||||
final int offY = w.mYOffset + w.mFrame.top;
|
||||
// Initialize the decor rect to the entire frame.
|
||||
w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
|
||||
// Intersect with the decor rect, offsetted by window position.
|
||||
w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
|
||||
decorRect.right-offX, decorRect.bottom-offY);
|
||||
// If size compatibility is being applied to the window, the
|
||||
// surface is scaled relative to the screen. Also apply this
|
||||
// scaling to the crop rect. We aren't using the standard rect
|
||||
// scale function because we want to round things to make the crop
|
||||
// always round to a larger rect to ensure we don't crop too
|
||||
// much and hide part of the window that should be seen.
|
||||
if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
|
||||
final float scale = w.mInvGlobalScale;
|
||||
w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
|
||||
w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
|
||||
w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
|
||||
w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
|
||||
w.mLastSystemDecorRect.set(w.mSystemDecorRect);
|
||||
try {
|
||||
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
|
||||
"CROP " + w.mSystemDecorRect.toShortString(), null);
|
||||
mSurface.setWindowCrop(w.mSystemDecorRect);
|
||||
} catch (RuntimeException e) {
|
||||
Slog.w(TAG, "Error setting crop surface of " + w
|
||||
+ " crop=" + w.mSystemDecorRect.toShortString(), e);
|
||||
if (!recoveringMemory) {
|
||||
mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setSurfaceBoundaries(final boolean recoveringMemory) {
|
||||
final WindowState w = mWin;
|
||||
int width, height;
|
||||
@@ -1003,54 +1056,7 @@ class WindowStateAnimator {
|
||||
}
|
||||
}
|
||||
|
||||
// Need to recompute a new system decor rect each time.
|
||||
if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
|
||||
// Currently can't do this cropping for scaled windows. We'll
|
||||
// just keep the crop rect the same as the source surface.
|
||||
w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
|
||||
} else if (w.mLayer >= mService.mSystemDecorLayer) {
|
||||
// Above the decor layer is easy, just use the entire window.
|
||||
w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
|
||||
w.mCompatFrame.height());
|
||||
} else {
|
||||
final Rect decorRect = mService.mSystemDecorRect;
|
||||
// Compute the offset of the window in relation to the decor rect.
|
||||
final int offX = w.mXOffset + w.mFrame.left;
|
||||
final int offY = w.mYOffset + w.mFrame.top;
|
||||
// Initialize the decor rect to the entire frame.
|
||||
w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
|
||||
// Intersect with the decor rect, offsetted by window position.
|
||||
w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
|
||||
decorRect.right-offX, decorRect.bottom-offY);
|
||||
// If size compatibility is being applied to the window, the
|
||||
// surface is scaled relative to the screen. Also apply this
|
||||
// scaling to the crop rect. We aren't using the standard rect
|
||||
// scale function because we want to round things to make the crop
|
||||
// always round to a larger rect to ensure we don't crop too
|
||||
// much and hide part of the window that should be seen.
|
||||
if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
|
||||
final float scale = w.mInvGlobalScale;
|
||||
w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
|
||||
w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
|
||||
w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
|
||||
w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
|
||||
w.mLastSystemDecorRect.set(w.mSystemDecorRect);
|
||||
try {
|
||||
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
|
||||
"CROP " + w.mSystemDecorRect.toShortString(), null);
|
||||
mSurface.setWindowCrop(w.mSystemDecorRect);
|
||||
} catch (RuntimeException e) {
|
||||
Slog.w(TAG, "Error setting crop surface of " + w
|
||||
+ " crop=" + w.mSystemDecorRect.toShortString(), e);
|
||||
if (!recoveringMemory) {
|
||||
mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSurfaceWindowCrop(recoveringMemory);
|
||||
}
|
||||
|
||||
public void prepareSurfaceLocked(final boolean recoveringMemory) {
|
||||
@@ -1181,17 +1187,31 @@ class WindowStateAnimator {
|
||||
}
|
||||
|
||||
void setWallpaperOffset(int left, int top) {
|
||||
mSurfaceX = left;
|
||||
mSurfaceY = top;
|
||||
if (mAnimating) {
|
||||
// If this window (or its app token) is animating, then the position
|
||||
// of the surface will be re-computed on the next animation frame.
|
||||
// We can't poke it directly here because it depends on whatever
|
||||
// transformation is being applied by the animation.
|
||||
return;
|
||||
}
|
||||
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
|
||||
">>> OPEN TRANSACTION setWallpaperOffset");
|
||||
Surface.openTransaction();
|
||||
try {
|
||||
mSurfaceX = left;
|
||||
mSurfaceY = top;
|
||||
mSurface.setPosition(left, top);
|
||||
mSurface.setWindowCrop(null);
|
||||
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
|
||||
"POS " + left + ", " + top, null);
|
||||
mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
|
||||
updateSurfaceWindowCrop(false);
|
||||
} catch (RuntimeException e) {
|
||||
Slog.w(TAG, "Error positioning surface of " + mWin
|
||||
+ " pos=(" + left + "," + top + ")", e);
|
||||
} finally {
|
||||
Surface.closeTransaction();
|
||||
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
|
||||
"<<< CLOSE TRANSACTION setWallpaperOffset");
|
||||
}
|
||||
Surface.closeTransaction();
|
||||
}
|
||||
|
||||
// This must be called while inside a transaction.
|
||||
|
||||
Reference in New Issue
Block a user