| Index: third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
|
| diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
|
| index ee7be35fabdebe16b7cf658e7770e2a03d23f6cb..c4fce9302a62270ee0ec3c0759d9f2f8da4d9ad9 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
|
| @@ -520,9 +520,11 @@ void BitmapImage::startAnimation(CatchUpAnimation catchUpIfNecessary)
|
| if (time < frameAfterNextStartTime)
|
| break;
|
|
|
| - // Yes; skip over it without notifying our observers.
|
| - if (!internalAdvanceAnimation(true))
|
| + // Skip the next frame by advancing the animation forward one frame.
|
| + if (!internalAdvanceAnimation(SkipFramesToCatchUp)) {
|
| + DCHECK(m_animationFinished);
|
| return;
|
| + }
|
| m_desiredFrameStartTime = frameAfterNextStartTime;
|
| nextFrame = frameAfterNext;
|
| }
|
| @@ -573,7 +575,7 @@ void BitmapImage::advanceTime(double deltaTimeInSeconds)
|
|
|
| void BitmapImage::advanceAnimation(TimerBase*)
|
| {
|
| - internalAdvanceAnimation(false);
|
| + internalAdvanceAnimation();
|
| // At this point the image region has been marked dirty, and if it's
|
| // onscreen, we'll soon make a call to draw(), which will call
|
| // startAnimation() again to keep the animation moving.
|
| @@ -581,46 +583,62 @@ void BitmapImage::advanceAnimation(TimerBase*)
|
|
|
| void BitmapImage::advanceAnimationWithoutCatchUp(TimerBase*)
|
| {
|
| - if (internalAdvanceAnimation(false))
|
| + if (internalAdvanceAnimation())
|
| startAnimation(DoNotCatchUp);
|
| }
|
|
|
| -bool BitmapImage::internalAdvanceAnimation(bool skippingFrames)
|
| +bool BitmapImage::internalAdvanceAnimation(AnimationAdvancement advancement)
|
| {
|
| // Stop the animation.
|
| stopAnimation();
|
|
|
| // See if anyone is still paying attention to this animation. If not, we don't
|
| // advance and will remain suspended at the current frame until the animation is resumed.
|
| - if (!skippingFrames && getImageObserver()->shouldPauseAnimation(this))
|
| + if (advancement != SkipFramesToCatchUp && getImageObserver()->shouldPauseAnimation(this))
|
| return false;
|
|
|
| - ++m_currentFrame;
|
| - bool advancedAnimation = true;
|
| - if (m_currentFrame >= frameCount()) {
|
| - ++m_repetitionsComplete;
|
| + if (m_currentFrame + 1 < frameCount()) {
|
| + m_currentFrame++;
|
| + } else {
|
| + m_repetitionsComplete++;
|
|
|
| - // Get the repetition count again. If we weren't able to get a
|
| + // Get the repetition count again. If we weren't able to get a
|
| // repetition count before, we should have decoded the whole image by
|
| // now, so it should now be available.
|
| - // Note that we don't need to special-case cAnimationLoopOnce here
|
| - // because it is 0 (see comments on its declaration in ImageAnimation.h).
|
| + // We don't need to special-case cAnimationLoopOnce here because it is
|
| + // 0 (see comments on its declaration in ImageAnimation.h).
|
| if ((repetitionCount(true) != cAnimationLoopInfinite && m_repetitionsComplete > m_repetitionCount)
|
| || m_animationPolicy == ImageAnimationPolicyAnimateOnce) {
|
| m_animationFinished = true;
|
| m_desiredFrameStartTime = 0;
|
| - --m_currentFrame;
|
| - advancedAnimation = false;
|
| - } else
|
| - m_currentFrame = 0;
|
| +
|
| + // We skipped to the last frame and cannot advance further. The
|
| + // observer will not receive animationAdvanced notifications while
|
| + // skipping but we still need to notify the observer to draw the
|
| + // last frame. Skipping frames occurs while painting so we do not
|
| + // synchronously notify the observer which could cause a layout.
|
| + if (advancement == SkipFramesToCatchUp) {
|
| + m_frameTimer = wrapUnique(new Timer<BitmapImage>(this, &BitmapImage::notifyObserversOfAnimationAdvance));
|
| + m_frameTimer->startOneShot(0, BLINK_FROM_HERE);
|
| + }
|
| +
|
| + return false;
|
| + }
|
| +
|
| + // Loop the animation back to the first frame.
|
| + m_currentFrame = 0;
|
| }
|
|
|
| - // We need to draw this frame if we advanced to it while not skipping, or if
|
| - // while trying to skip frames we hit the last frame and thus had to stop.
|
| - if (skippingFrames != advancedAnimation)
|
| + // We need to draw this frame if we advanced to it while not skipping.
|
| + if (advancement != SkipFramesToCatchUp)
|
| getImageObserver()->animationAdvanced(this);
|
|
|
| - return advancedAnimation;
|
| + return true;
|
| +}
|
| +
|
| +void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*)
|
| +{
|
| + getImageObserver()->animationAdvanced(this);
|
| }
|
|
|
| } // namespace blink
|
|
|