diff options
| author | Dianne Hackborn <hackbod@google.com> | 2012-01-31 19:04:53 -0800 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2012-02-01 16:02:14 -0800 |
| commit | 8bcd54b98ad5d98d47364ff14e06910deadf9302 (patch) | |
| tree | 31f3a2a8c6283acc7a6b70abf4125d9872a68381 | |
| parent | 6baed6c11090fe6eb0a612ca4acee590e904ca58 (diff) | |
| download | frameworks_base-8bcd54b98ad5d98d47364ff14e06910deadf9302.zip frameworks_base-8bcd54b98ad5d98d47364ff14e06910deadf9302.tar.gz frameworks_base-8bcd54b98ad5d98d47364ff14e06910deadf9302.tar.bz2 | |
Use Choreographer for window manager animation timing.
Change-Id: Ic34aff698c63d383ecd06af7da9957475683a1db
| -rw-r--r-- | core/java/android/view/Choreographer.java | 24 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/WindowManagerService.java | 47 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/WindowState.java | 4 |
3 files changed, 52 insertions, 23 deletions
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 63de128..c86ea77 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -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. @@ -163,6 +163,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) { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 19d94a1..5178af5 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -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"); diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index 1067cad..6868cf6 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -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; } |
