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

Commit 7d8df390 authored by Craig Mautner's avatar Craig Mautner
Browse files

Animate from Choreographer only.

Animation steps are now executed on a Thread launched from the
Choreographer rather than being called at the end of the WindowManager
layout process. Animations and layout are still tightly coupled in
that they share considerable state information and neither can be
executed without holding a lock on WindowServiceManager.mWindowMap.

Change-Id: Ie17d693706971507b50aa473da1b7258e9e67764
parent 9688fea7
Loading
Loading
Loading
Loading
+156 −127
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.wm;

import java.io.PrintWriter;

import static com.android.server.wm.WindowStateAnimator.SurfaceTrace;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
@@ -208,14 +210,20 @@ class ScreenRotationAnimation {

        try {
            try {
                mSurface = new Surface(session, 0, "FreezeSurface",
                        -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
                if (WindowManagerService.DEBUG_SURFACE_TRACE) {
                    mSurface = new SurfaceTrace(session, 0, "FreezeSurface", -1, mWidth, mHeight,
                        PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
                } else {
                    mSurface = new Surface(session, 0, "FreezeSurface", -1, mWidth, mHeight,
                        PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
                }
                if (!mSurface.isValid()) {
                    // Screenshot failed, punt.
                    mSurface = null;
                    return;
                }
                mSurface.setLayer(FREEZE_LAYER + 1);
                mSurface.setAlpha(0);
                mSurface.show();
            } catch (Surface.OutOfResourcesException e) {
                Slog.w(TAG, "Unable to allocate freeze surface", e);
@@ -308,11 +316,11 @@ class ScreenRotationAnimation {
        if (TWO_PHASE_ANIMATION) {
            return startAnimation(session, maxAnimationDuration, animationScale,
                    finalWidth, finalHeight, false);
        } else {
        }

        // Don't start animation yet.
        return false;
    }
    }

    /**
     * Returns true if animating.
@@ -590,6 +598,7 @@ class ScreenRotationAnimation {
            mEnteringBlackFrame.kill();
            mEnteringBlackFrame = null;
        }
        if (TWO_PHASE_ANIMATION) {
            if (mStartExitAnimation != null) {
                mStartExitAnimation.cancel();
                mStartExitAnimation = null;
@@ -598,10 +607,6 @@ class ScreenRotationAnimation {
                mStartEnterAnimation.cancel();
                mStartEnterAnimation = null;
            }
        if (mStartFrameAnimation != null) {
            mStartFrameAnimation.cancel();
            mStartFrameAnimation = null;
        }
            if (mFinishExitAnimation != null) {
                mFinishExitAnimation.cancel();
                mFinishExitAnimation = null;
@@ -610,10 +615,21 @@ class ScreenRotationAnimation {
                mFinishEnterAnimation.cancel();
                mFinishEnterAnimation = null;
            }
        }
        if (USE_CUSTOM_BLACK_FRAME) {
            if (mStartFrameAnimation != null) {
                mStartFrameAnimation.cancel();
                mStartFrameAnimation = null;
            }
            if (mRotateFrameAnimation != null) {
                mRotateFrameAnimation.cancel();
                mRotateFrameAnimation = null;
            }
            if (mFinishFrameAnimation != null) {
                mFinishFrameAnimation.cancel();
                mFinishFrameAnimation = null;
            }
        }
        if (mRotateExitAnimation != null) {
            mRotateExitAnimation.cancel();
            mRotateExitAnimation = null;
@@ -622,27 +638,20 @@ class ScreenRotationAnimation {
            mRotateEnterAnimation.cancel();
            mRotateEnterAnimation = null;
        }
        if (mRotateFrameAnimation != null) {
            mRotateFrameAnimation.cancel();
            mRotateFrameAnimation = null;
        }
    }

    public boolean isAnimating() {
        if (TWO_PHASE_ANIMATION) {
            return hasAnimations() || mFinishAnimReady;
        } else {
            return hasAnimations();
        }
        return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
    }

    private boolean hasAnimations() {
        return mStartEnterAnimation != null || mStartExitAnimation != null
                || mStartFrameAnimation != null
                || mFinishEnterAnimation != null || mFinishExitAnimation != null
                || mFinishFrameAnimation != null
                || mRotateEnterAnimation != null || mRotateExitAnimation != null
                || mRotateFrameAnimation != null;
        return (TWO_PHASE_ANIMATION &&
                    (mStartEnterAnimation != null || mStartExitAnimation != null
                    || mFinishEnterAnimation != null || mFinishExitAnimation != null))
                || (USE_CUSTOM_BLACK_FRAME &&
                        (mStartFrameAnimation != null || mRotateFrameAnimation != null
                        || mFinishFrameAnimation != null))
                || mRotateEnterAnimation != null || mRotateExitAnimation != null;
    }

    private boolean stepAnimation(long now) {
@@ -651,6 +660,7 @@ class ScreenRotationAnimation {
            mFinishAnimStartTime = now;
        }

        if (TWO_PHASE_ANIMATION) {
            mMoreStartExit = false;
            if (mStartExitAnimation != null) {
                mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
@@ -662,16 +672,19 @@ class ScreenRotationAnimation {
                mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
            }

        }
        if (USE_CUSTOM_BLACK_FRAME) {
            mMoreStartFrame = false;
            if (mStartFrameAnimation != null) {
                mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
            }
        }

        long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
        if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);

        if (TWO_PHASE_ANIMATION) {
            mMoreFinishExit = false;
            if (mFinishExitAnimation != null) {
                mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
@@ -683,12 +696,14 @@ class ScreenRotationAnimation {
                mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
            }

        }
        if (USE_CUSTOM_BLACK_FRAME) {
            mMoreFinishFrame = false;
            if (mFinishFrameAnimation != null) {
                mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
            }
        }

        mMoreRotateExit = false;
        if (mRotateExitAnimation != null) {
@@ -702,13 +717,16 @@ class ScreenRotationAnimation {
            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
        }

        if (USE_CUSTOM_BLACK_FRAME) {
            mMoreRotateFrame = false;
            if (mRotateFrameAnimation != null) {
                mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
            }
        }

        if (!mMoreStartExit && !mMoreRotateExit && !mMoreFinishExit) {
        if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
            if (TWO_PHASE_ANIMATION) {
                if (mStartExitAnimation != null) {
                    if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
                    mStartExitAnimation.cancel();
@@ -721,6 +739,7 @@ class ScreenRotationAnimation {
                    mFinishExitAnimation = null;
                    mFinishExitTransformation.clear();
                }
            }
            if (mRotateExitAnimation != null) {
                if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
                mRotateExitAnimation.cancel();
@@ -729,7 +748,8 @@ class ScreenRotationAnimation {
            }
        }

        if (!mMoreStartEnter && !mMoreRotateEnter && !mMoreFinishEnter) {
        if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
            if (TWO_PHASE_ANIMATION) {
                if (mStartEnterAnimation != null) {
                    if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
                    mStartEnterAnimation.cancel();
@@ -742,6 +762,7 @@ class ScreenRotationAnimation {
                    mFinishEnterAnimation = null;
                    mFinishEnterTransformation.clear();
                }
            }
            if (mRotateEnterAnimation != null) {
                if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
                mRotateEnterAnimation.cancel();
@@ -772,12 +793,14 @@ class ScreenRotationAnimation {
        }

        mExitTransformation.set(mRotateExitTransformation);
        mEnterTransformation.set(mRotateEnterTransformation);
        if (TWO_PHASE_ANIMATION) {
            mExitTransformation.compose(mStartExitTransformation);
            mExitTransformation.compose(mFinishExitTransformation);

        mEnterTransformation.set(mRotateEnterTransformation);
            mEnterTransformation.compose(mStartEnterTransformation);
            mEnterTransformation.compose(mFinishEnterTransformation);
        }

        if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
        if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
@@ -793,9 +816,11 @@ class ScreenRotationAnimation {
            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
        }

        final boolean more = mMoreStartEnter || mMoreStartExit || mMoreStartFrame
                || mMoreFinishEnter || mMoreFinishExit || mMoreFinishFrame
                || mMoreRotateEnter || mMoreRotateExit || mMoreRotateFrame
        final boolean more = (TWO_PHASE_ANIMATION
                    && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
                || (USE_CUSTOM_BLACK_FRAME
                        && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
                || mMoreRotateEnter || mMoreRotateExit 
                || !mFinishAnimReady;

        mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
@@ -858,33 +883,37 @@ class ScreenRotationAnimation {

        if (!mAnimRunning) {
            if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
            if (TWO_PHASE_ANIMATION) {
                if (mStartEnterAnimation != null) {
                    mStartEnterAnimation.setStartTime(now);
                }
                if (mStartExitAnimation != null) {
                    mStartExitAnimation.setStartTime(now);
                }
            if (mStartFrameAnimation != null) {
                mStartFrameAnimation.setStartTime(now);
            }
                if (mFinishEnterAnimation != null) {
                    mFinishEnterAnimation.setStartTime(0);
                }
                if (mFinishExitAnimation != null) {
                    mFinishExitAnimation.setStartTime(0);
                }
            }
            if (USE_CUSTOM_BLACK_FRAME) {
                if (mStartFrameAnimation != null) {
                    mStartFrameAnimation.setStartTime(now);
                }
                if (mFinishFrameAnimation != null) {
                    mFinishFrameAnimation.setStartTime(0);
                }
                if (mRotateFrameAnimation != null) {
                    mRotateFrameAnimation.setStartTime(now);
                }
            }
            if (mRotateEnterAnimation != null) {
                mRotateEnterAnimation.setStartTime(now);
            }
            if (mRotateExitAnimation != null) {
                mRotateExitAnimation.setStartTime(now);
            }
            if (mRotateFrameAnimation != null) {
                mRotateFrameAnimation.setStartTime(now);
            }
            mAnimRunning = true;
        }

+14 −1
Original line number Diff line number Diff line
@@ -431,6 +431,10 @@ public class WindowAnimator {
        mPendingLayoutChanges = 0;
        mCurrentTime = SystemClock.uptimeMillis();
        mBulkUpdateParams = 0;
        mAnimating = false;
        if (WindowManagerService.DEBUG_WINDOW_TRACE) {
            Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
        }

        // Update animations of all applications, including those
        // associated with exiting/removed apps
@@ -478,7 +482,16 @@ public class WindowAnimator {
            Surface.closeTransaction();
        }

        mService.bulkSetParameters(mBulkUpdateParams);
        mService.bulkSetParameters(mBulkUpdateParams, mPendingLayoutChanges);

        if (mAnimating) {
            mService.scheduleAnimationLocked();
        }
        if (WindowManagerService.DEBUG_WINDOW_TRACE) {
            Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
                + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
                + " mPendingLayoutChanges=" + Integer.toHexString(mPendingLayoutChanges));
        }
    }

    WindowState mCurrentFocus;
+69 −33
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ public class WindowManagerService extends IWindowManager.Stub
    static final boolean DEBUG_BOOT = false;
    static final boolean DEBUG_LAYOUT_REPEATS = true;
    static final boolean DEBUG_SURFACE_TRACE = false;
    static final boolean DEBUG_WINDOW_TRACE = false;
    static final boolean SHOW_SURFACE_ALLOC = false;
    static final boolean SHOW_TRANSACTIONS = false;
    static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -593,6 +594,7 @@ public class WindowManagerService extends IWindowManager.Stub
        static final int SET_WALLPAPER_MAY_CHANGE           = 1 << 1;
        static final int SET_FORCE_HIDING_CHANGED           = 1 << 2;
        static final int CLEAR_ORIENTATION_CHANGE_COMPLETE  = 1 << 3;
        static final int SET_TURN_ON_SCREEN                 = 1 << 4;

        boolean mWallpaperForceHidingChanged = false;
        boolean mWallpaperMayChange = false;
@@ -616,7 +618,20 @@ public class WindowManagerService extends IWindowManager.Stub
        public void run() {
            synchronized(mWindowMap) {
                mAnimationScheduled = false;
                performLayoutAndPlaceSurfacesLocked();
                // Update animations of all applications, including those
                // associated with exiting/removed apps
                synchronized (mAnimator) {
                    final ArrayList<WindowStateAnimator> winAnimators = mAnimator.mWinAnimators;
                    winAnimators.clear();
                    final int N = mWindows.size();
                    for (int i = 0; i < N; i++) {
                        final WindowStateAnimator winAnimator = mWindows.get(i).mWinAnimator;
                        if (winAnimator.mSurface != null) {
                            winAnimators.add(winAnimator);
                        }
                    }
                    mAnimator.animate();
                }
            }
        }
    }
@@ -6487,6 +6502,9 @@ public class WindowManagerService extends IWindowManager.Stub

        @Override
        public void handleMessage(Message msg) {
            if (DEBUG_WINDOW_TRACE) {
                Slog.v(TAG, "handleMessage: entry what=" + msg.what);
            }
            switch (msg.what) {
                case REPORT_FOCUS_CHANGE: {
                    WindowState lastFocus;
@@ -6918,6 +6936,14 @@ public class WindowManagerService extends IWindowManager.Stub
                                doRequest = true;
                            }
                        }
                        if ((msg.arg1 & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
                            mTurnOnScreen = true;
                        }

                        mPendingLayoutChanges |= msg.arg2;
                        if (mPendingLayoutChanges != 0) {
                            doRequest = true;
                        }

                        if (doRequest) {
                            requestTraversalLocked();
@@ -6962,6 +6988,9 @@ public class WindowManagerService extends IWindowManager.Stub
                    break;
                }
            }
            if (DEBUG_WINDOW_TRACE) {
                Slog.v(TAG, "handleMessage: exit");
            }
        }
    }

@@ -6969,6 +6998,7 @@ public class WindowManagerService extends IWindowManager.Stub
    // IWindowManager API
    // -------------------------------------------------------------

    @Override
    public IWindowSession openSession(IInputMethodClient client,
            IInputContext inputContext) {
        if (client == null) throw new IllegalArgumentException("null client");
@@ -6977,6 +7007,7 @@ public class WindowManagerService extends IWindowManager.Stub
        return session;
    }

    @Override
    public boolean inputMethodClientHasFocus(IInputMethodClient client) {
        synchronized (mWindowMap) {
            // The focus for the client is the window immediately below
@@ -7411,12 +7442,6 @@ public class WindowManagerService extends IWindowManager.Stub
                mLayoutRepeatCount = 0;
            }

            if (mAnimator.mAnimating) {
                // Do this even if requestTraversalLocked was called above so we get a frame drawn
                // at the proper time as well as the one drawn early.
                scheduleAnimationLocked();
            }

            if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
                mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
                mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
@@ -8033,6 +8058,9 @@ public class WindowManagerService extends IWindowManager.Stub
    // "Something has changed!  Let's make it correct now."
    private final void performLayoutAndPlaceSurfacesLockedInner(
            boolean recoveringMemory) {
        if (DEBUG_WINDOW_TRACE) {
            Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry");
        }
        if (mDisplay == null) {
            Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
            return;
@@ -8065,7 +8093,6 @@ public class WindowManagerService extends IWindowManager.Stub
        mInnerFields.mHoldScreen = null;
        mInnerFields.mScreenBrightness = -1;
        mInnerFields.mButtonBrightness = -1;
        mAnimator.mAnimating = false;

        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
@@ -8294,22 +8321,6 @@ public class WindowManagerService extends IWindowManager.Stub
            }
        }

        // Update animations of all applications, including those
        // associated with exiting/removed apps
        synchronized (mAnimator) {
            final ArrayList<WindowStateAnimator> winAnimators = mAnimator.mWinAnimators;
            winAnimators.clear();
            for (i = 0; i < N; i++) {
                final WindowStateAnimator winAnimator = mWindows.get(i).mWinAnimator;
                if (winAnimator.mSurface != null) {
                    winAnimators.add(winAnimator);
                }
            }
            mAnimator.animate();
            mPendingLayoutChanges |= mAnimator.mPendingLayoutChanges;
            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animate()", mPendingLayoutChanges);
        }

        if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
                "With display frozen, orientationChangeComplete="
                + mInnerFields.mOrientationChangeComplete);
@@ -8475,9 +8486,14 @@ public class WindowManagerService extends IWindowManager.Stub
        // Check to see if we are now in a state where the screen should
        // be enabled, because the window obscured flags have changed.
        enableScreenIfNeededLocked();
//        Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: mPendingLayoutChanges="
//                + Integer.toHexString(mPendingLayoutChanges) + " mLayoutNeeded=" + mLayoutNeeded
//                + " animating=" + mAnimator.mAnimating);

        scheduleAnimationLocked();

        if (DEBUG_WINDOW_TRACE) {
            Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: mPendingLayoutChanges="
                + Integer.toHexString(mPendingLayoutChanges) + " mLayoutNeeded=" + mLayoutNeeded
                + " animating=" + mAnimator.mAnimating);
        }
    }

    void checkDrawnWindowsLocked() {
@@ -8850,6 +8866,7 @@ public class WindowManagerService extends IWindowManager.Stub
                    mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) {
                scheduleAnimationLocked();
            } else {
                mAnimator.mScreenRotationAnimation.kill();
                mAnimator.mScreenRotationAnimation = null;
                updateRotation = true;
            }
@@ -9517,12 +9534,31 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    void bulkSetParameters(final int bulkUpdateParams) {
        mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams, 0));
    void bulkSetParameters(final int bulkUpdateParams, int pendingLayoutChanges) {
        mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams,
                pendingLayoutChanges));
    }

    static String getCaller() {
        StackTraceElement caller = Thread.currentThread().getStackTrace()[4];
    /**
     * Never call directly. Only call through getCallers(int) or getCaller(). Otherwise
     * the depth will be off.
     * @param depth What level stack to return.
     * @return A String indicating who the caller of the method that calls this is.
     */
    static String getCaller(int depth) {
        StackTraceElement caller = Thread.currentThread().getStackTrace()[5 + depth];
        return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
    }

    static String getCallers(final int depth) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < depth; i++) {
            sb.append(getCaller(i)).append(" ");
        }
        return sb.toString();
    }

    static String getCaller() {
        return getCallers(1);
    }
}
+36 −23

File changed.

Preview size limit exceeded, changes collapsed.