Split out whether frame callback and tick is scheduled

Since the animation/gesture for screen zoom is running at
vsync-app, calling WMS.scheduleAnimation will schedule only
at the next frame. However, in the next frame, only the frame
callback is handled but not the tick yet, however
mAnimationScheduled was still true. Thus, the request to schedule
another frame callback is ignored, and then the things get
updated only every 2nd frame.

Fix this by splitting the information whether the frame callback
is scheduled or the actual tick.

Test: Use accessibility screen zoom, make sure gestures are
smooth.
Fixes: 37476440

Change-Id: I2301fab5bf3f3b896d4aa131fb041b89572fa3a7
This commit is contained in:
Jorim Jaggi
2017-04-28 16:39:19 +02:00
parent 0c21500920
commit 561eeb5e74

View File

@@ -87,8 +87,18 @@ public class WindowAnimator {
private final SurfaceFlingerVsyncChoreographer mSfChoreographer;
private Choreographer mChoreographer;
private boolean mAnimationScheduled;
/**
* Indicates whether we have an animation frame callback scheduled, which will happen at
* vsync-app and then schedule the animation tick at the right time (vsync-sf).
*/
private boolean mAnimationFrameCallbackScheduled;
/**
* Indicates whether we have an animation tick scheduled. The tick is the thing that actually
* executes the animation step, which will happen at vsync-sf.
*/
private boolean mAnimationTickScheduled;
WindowAnimator(final WindowManagerService service) {
mService = service;
@@ -104,13 +114,20 @@ public class WindowAnimator {
mService.getDefaultDisplayContentLocked().getDisplay(), mChoreographer);
mAnimationTick = () -> {
synchronized (mService.mWindowMap) {
mAnimationScheduled = false;
mAnimationTickScheduled = false;
animateLocked(mCurrentFrameTime);
}
};
mAnimationFrameCallback = frameTimeNs -> {
mCurrentFrameTime = frameTimeNs;
mSfChoreographer.scheduleAtSfVsync(mAnimationTick);
synchronized (mService.mWindowMap) {
mCurrentFrameTime = frameTimeNs;
mAnimationFrameCallbackScheduled = false;
if (mAnimationTickScheduled) {
return;
}
mAnimationTickScheduled = true;
mSfChoreographer.scheduleAtSfVsync(mAnimationTick);
}
};
}
@@ -371,8 +388,8 @@ public class WindowAnimator {
}
void scheduleAnimation() {
if (!mAnimationScheduled) {
mAnimationScheduled = true;
if (!mAnimationFrameCallbackScheduled) {
mAnimationFrameCallbackScheduled = true;
mChoreographer.postFrameCallback(mAnimationFrameCallback);
}
}
@@ -386,7 +403,7 @@ public class WindowAnimator {
}
boolean isAnimationScheduled() {
return mAnimationScheduled;
return mAnimationFrameCallbackScheduled || mAnimationTickScheduled;
}
Choreographer getChoreographer() {