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

Commit 8bcd54b9 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Use Choreographer for window manager animation timing.

Change-Id: Ic34aff698c63d383ecd06af7da9957475683a1db
parent 6baed6c1
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import android.os.SystemProperties;
import android.util.Log;

/**
 * Coodinates animations and drawing for UI on a particular thread.
 * Coordinates animations and drawing for UI on a particular thread.
 * @hide
 */
public final class Choreographer extends Handler {
@@ -94,8 +94,8 @@ public final class Choreographer extends Handler {
    }

    /**
     * Gets the choreographer for this thread.
     * Must be called on the UI thread.
     * Gets the choreographer for the calling thread.  Must be called from
     * a thread that already has a {@link android.os.Looper} associated with it.
     *
     * @return The choreographer for this thread.
     * @throws IllegalStateException if the thread does not have a looper.
@@ -162,6 +162,15 @@ public final class Choreographer extends Handler {
        }
    }

    /**
     * Return true if {@link #scheduleAnimation()} has been called but
     * {@link OnAnimateListener#onAnimate() OnAnimateListener.onAnimate()} has
     * not yet been called.
     */
    public boolean isAnimationScheduled() {
        return mAnimationScheduled;
    }

    /**
     * Schedules drawing to occur on the next frame synchronization boundary.
     * Must be called on the UI thread.
@@ -180,6 +189,15 @@ public final class Choreographer extends Handler {
        }
    }

    /**
     * Return true if {@link #scheduleDraw()} has been called but
     * {@link OnDrawListener#onDraw() OnDrawListener.onDraw()} has
     * not yet been called.
     */
    public boolean isDrawScheduled() {
        return mDrawScheduled;
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
+29 −18
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ import android.util.Pair;
import android.util.Slog;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.Choreographer;
import android.view.Display;
import android.view.Gravity;
import android.view.IApplicationToken;
@@ -141,7 +142,8 @@ import java.util.List;

/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
        Choreographer.OnAnimateListener {
    static final String TAG = "WindowManager";
    static final boolean DEBUG = false;
    static final boolean DEBUG_ADD_REMOVE = false;
@@ -456,7 +458,7 @@ public class WindowManagerService extends IWindowManager.Stub
    int mDeferredRotationPauseCount;

    boolean mLayoutNeeded = true;
    boolean mAnimationPending = false;
    boolean mTraversalScheduled = false;
    boolean mDisplayFrozen = false;
    boolean mWaitingForConfig = false;
    boolean mWindowsFreezingScreen = false;
@@ -503,7 +505,9 @@ public class WindowManagerService extends IWindowManager.Stub
    final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
    final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();

    H mH = new H();
    final H mH = new H();

    final Choreographer mChoreographer = Choreographer.getInstance();

    WindowState mCurrentFocus = null;
    WindowState mLastFocus = null;
@@ -691,6 +695,7 @@ public class WindowManagerService extends IWindowManager.Stub
            Looper.prepare();
            WindowManagerService s = new WindowManagerService(mContext, mPM,
                    mHaveInputMethods, mAllowBootMessages);
            s.mChoreographer.addOnAnimateListener(s);
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_DISPLAY);
            android.os.Process.setCanSelfBackground(false);
@@ -5390,7 +5395,7 @@ public class WindowManagerService extends IWindowManager.Stub
                if (mScreenRotationAnimation.setRotation(rotation, mFxSession,
                        MAX_ANIMATION_DURATION, mTransitionAnimationScale,
                        mCurDisplayWidth, mCurDisplayHeight)) {
                    requestAnimationLocked(0);
                    mChoreographer.scheduleAnimation();
                }
            }
            Surface.setOrientation(0, rotation);
@@ -6513,7 +6518,7 @@ public class WindowManagerService extends IWindowManager.Stub
    final class H extends Handler {
        public static final int REPORT_FOCUS_CHANGE = 2;
        public static final int REPORT_LOSING_FOCUS = 3;
        public static final int ANIMATE = 4;
        public static final int DO_TRAVERSAL = 4;
        public static final int ADD_STARTING = 5;
        public static final int REMOVE_STARTING = 6;
        public static final int FINISHED_STARTING = 7;
@@ -6607,9 +6612,9 @@ public class WindowManagerService extends IWindowManager.Stub
                    }
                } break;

                case ANIMATE: {
                case DO_TRAVERSAL: {
                    synchronized(mWindowMap) {
                        mAnimationPending = false;
                        mTraversalScheduled = false;
                        performLayoutAndPlaceSurfacesLocked();
                    }
                } break;
@@ -6830,7 +6835,7 @@ public class WindowManagerService extends IWindowManager.Stub

                case FORCE_GC: {
                    synchronized(mWindowMap) {
                        if (mAnimationPending) {
                        if (mChoreographer.isAnimationScheduled()) {
                            // If we are animating, don't do the gc now but
                            // delay a bit so we don't interrupt the animation.
                            mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
@@ -7389,7 +7394,7 @@ public class WindowManagerService extends IWindowManager.Stub
            } else {
                mInLayout = false;
                if (mLayoutNeeded) {
                    requestAnimationLocked(0);
                    requestTraversalLocked();
                }
            }
            if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
@@ -8822,10 +8827,9 @@ public class WindowManagerService extends IWindowManager.Stub
            needRelayout = adjustWallpaperWindowsLocked() != 0;
        }
        if (needRelayout) {
            requestAnimationLocked(0);
            requestTraversalLocked();
        } else if (animating) {
            final int refreshTimeUs = (int)(1000 / mDisplay.getRefreshRate());
            requestAnimationLocked(currentTime + refreshTimeUs - SystemClock.uptimeMillis());
            mChoreographer.scheduleAnimation();
        }

        // Finally update all input windows now that the window changes have stabilized.
@@ -8944,10 +8948,17 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    void requestAnimationLocked(long delay) {
        if (!mAnimationPending) {
            mAnimationPending = true;
            mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
    void requestTraversalLocked() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            mH.sendEmptyMessage(H.DO_TRAVERSAL);
        }
    }

    @Override
    public void onAnimate() {
        synchronized(mWindowMap) {
            performLayoutAndPlaceSurfacesLocked();
        }
    }

@@ -9267,7 +9278,7 @@ public class WindowManagerService extends IWindowManager.Stub
            if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
            if (mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
                    mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) {
                requestAnimationLocked(0);
                mChoreographer.scheduleAnimation();
            } else {
                mScreenRotationAnimation = null;
                updateRotation = true;
@@ -9759,7 +9770,7 @@ public class WindowManagerService extends IWindowManager.Stub
            pw.print("  mLastWindowForcedOrientation"); pw.print(mLastWindowForcedOrientation);
                    pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
            pw.print("  mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
            pw.print("  mAnimationPending="); pw.print(mAnimationPending);
            pw.print("  mTraversalScheduled="); pw.print(mTraversalScheduled);
                    pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
                    pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
            pw.print("  mNextAppTransition=0x");
+2 −2
Original line number Diff line number Diff line
@@ -1593,7 +1593,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
            mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
        }
        if (requestAnim) {
            mService.requestAnimationLocked(0);
            mService.mChoreographer.scheduleAnimation();
        }
        return true;
    }
@@ -1634,7 +1634,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
            }
        }
        if (requestAnim) {
            mService.requestAnimationLocked(0);
            mService.mChoreographer.scheduleAnimation();
        }
        return true;
    }