Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80fea051 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Fix some issues with updating the offsets of a window." into jb-dev

parents 79f5777d 3e52fc25
Loading
Loading
Loading
Loading
+73 −53
Original line number Diff line number Diff line
@@ -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) {
        Surface.openTransaction();
        try {
        mSurfaceX = left;
        mSurfaceY = top;
            mSurface.setPosition(left, top);
            mSurface.setWindowCrop(null);
        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 {
            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");
        }
    }

    // This must be called while inside a transaction.