summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-05-07 16:43:25 -0700
committerJeff Brown <jeffbrown@google.com>2012-05-07 16:49:42 -0700
commit59bbef0cd781f4933fd8a0a85b6067f36e529e02 (patch)
tree49baf2e961500a19dc6dc41652a42a859d6f56bd /core
parent2321301fe75f945b002372d6d35c597191564452 (diff)
downloadframeworks_base-59bbef0cd781f4933fd8a0a85b6067f36e529e02.zip
frameworks_base-59bbef0cd781f4933fd8a0a85b6067f36e529e02.tar.gz
frameworks_base-59bbef0cd781f4933fd8a0a85b6067f36e529e02.tar.bz2
Improve animation timing.
Detect when a vsync message was significantly delayed which may indicate that a frame was skipped. When this happens, update the frame time to reflect the approximate start time of the current frame instead of the start time of the frame that was skipped a long time ago. Removed an unnecessary call to getCurrentPlayTime() in the animator framework. The result was always zero and the call just made the code confusing. Bug: 6443611 Change-Id: I92b24f7ffd74c59b75a727b6bfc0bb51fc92a73a
Diffstat (limited to 'core')
-rwxr-xr-xcore/java/android/animation/ValueAnimator.java2
-rw-r--r--core/java/android/view/Choreographer.java33
2 files changed, 29 insertions, 6 deletions
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 326f27c..f3a442a 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -910,7 +910,7 @@ public class ValueAnimator extends Animator {
animationHandler.mPendingAnimations.add(this);
if (mStartDelay == 0) {
// This sets the initial value of the animation, prior to actually starting it running
- setCurrentPlayTime(getCurrentPlayTime());
+ setCurrentPlayTime(0);
mPlayingState = STOPPED;
mRunning = true;
notifyStartListeners();
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index b319cd5..825f351 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -92,6 +92,7 @@ public final class Choreographer {
private boolean mFrameScheduled;
private boolean mCallbacksRunning;
private long mLastFrameTimeNanos;
+ private long mFrameIntervalNanos;
/**
* Callback type: Input callback. Runs first.
@@ -116,6 +117,8 @@ public final class Choreographer {
mHandler = new FrameHandler(looper);
mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null;
mLastFrameTimeNanos = Long.MIN_VALUE;
+ mFrameIntervalNanos = (long)(1000000000 /
+ new Display(Display.DEFAULT_DISPLAY, null).getRefreshRate());
mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
for (int i = 0; i <= CALLBACK_LAST; i++) {
@@ -343,17 +346,37 @@ public final class Choreographer {
}
void doFrame(long timestampNanos, int frame) {
+ final long startNanos;
synchronized (mLock) {
if (!mFrameScheduled) {
return; // no work to do
}
- mFrameScheduled = false;
- mLastFrameTimeNanos = timestampNanos;
- }
- final long startNanos;
- if (DEBUG) {
startNanos = System.nanoTime();
+ final long jitterNanos = startNanos - timestampNanos;
+ if (jitterNanos >= mFrameIntervalNanos) {
+ final long lastFrameOffset = jitterNanos % mFrameIntervalNanos;
+ if (DEBUG) {
+ Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms "
+ + "which is more than the frame interval of "
+ + (mFrameIntervalNanos * 0.000001f) + " ms! "
+ + "Setting frame time to " + (lastFrameOffset * 0.000001f)
+ + " ms in the past.");
+ }
+ timestampNanos = startNanos - lastFrameOffset;
+ }
+
+ if (timestampNanos < mLastFrameTimeNanos) {
+ if (DEBUG) {
+ Log.d(TAG, "Frame time appears to be going backwards. May be due to a "
+ + "previously skipped frame. Waiting for next vsync");
+ }
+ scheduleVsyncLocked();
+ return;
+ }
+
+ mFrameScheduled = false;
+ mLastFrameTimeNanos = timestampNanos;
}
doCallbacks(Choreographer.CALLBACK_INPUT);