in animated-drawable/src/main/java/com/facebook/fresco/animation/drawable/AnimatedDrawable2.java [189:262]
public void draw(Canvas canvas) {
if (mAnimationBackend == null || mFrameScheduler == null) {
return;
}
long actualRenderTimeStartMs = now();
long animationTimeMs =
mIsRunning
? actualRenderTimeStartMs - mStartTimeMs + mFrameSchedulingOffsetMs
: Math.max(mLastFrameAnimationTimeMs, 0);
// What frame should be drawn?
int frameNumberToDraw =
mFrameScheduler.getFrameNumberToRender(animationTimeMs, mLastFrameAnimationTimeMs);
// Check if the animation is finished and draw last frame if so
if (frameNumberToDraw == FrameScheduler.FRAME_NUMBER_DONE) {
frameNumberToDraw = mAnimationBackend.getFrameCount() - 1;
mAnimationListener.onAnimationStop(this);
mIsRunning = false;
} else if (frameNumberToDraw == 0) {
if (mLastDrawnFrameNumber != -1 && actualRenderTimeStartMs >= mExpectedRenderTimeMs) {
mAnimationListener.onAnimationRepeat(this);
}
}
// Draw the frame
boolean frameDrawn = mAnimationBackend.drawFrame(this, canvas, frameNumberToDraw);
if (frameDrawn) {
// Notify listeners that we draw a new frame and
// that the animation might be repeated
mAnimationListener.onAnimationFrame(this, frameNumberToDraw);
mLastDrawnFrameNumber = frameNumberToDraw;
}
// Log potential dropped frames
if (!frameDrawn) {
onFrameDropped();
}
long targetRenderTimeForNextFrameMs = FrameScheduler.NO_NEXT_TARGET_RENDER_TIME;
long scheduledRenderTimeForNextFrameMs = -1;
long actualRenderTimeEnd = now();
if (mIsRunning) {
// Schedule the next frame if needed.
targetRenderTimeForNextFrameMs =
mFrameScheduler.getTargetRenderTimeForNextFrameMs(actualRenderTimeEnd - mStartTimeMs);
if (targetRenderTimeForNextFrameMs != FrameScheduler.NO_NEXT_TARGET_RENDER_TIME) {
scheduledRenderTimeForNextFrameMs =
targetRenderTimeForNextFrameMs + mFrameSchedulingDelayMs;
scheduleNextFrame(scheduledRenderTimeForNextFrameMs);
} else {
mAnimationListener.onAnimationStop(this);
mIsRunning = false;
}
}
DrawListener listener = mDrawListener;
if (listener != null) {
listener.onDraw(
this,
mFrameScheduler,
frameNumberToDraw,
frameDrawn,
mIsRunning,
mStartTimeMs,
animationTimeMs,
mLastFrameAnimationTimeMs,
actualRenderTimeStartMs,
actualRenderTimeEnd,
targetRenderTimeForNextFrameMs,
scheduledRenderTimeForNextFrameMs);
}
mLastFrameAnimationTimeMs = animationTimeMs;
}