| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 // We've already reached or passed the time for the next frame to start. | 513 // We've already reached or passed the time for the next frame to start. |
| 514 // See if we've also passed the time for frames after that to start, in | 514 // See if we've also passed the time for frames after that to start, in |
| 515 // case we need to skip some frames entirely. Remember not to advance | 515 // case we need to skip some frames entirely. Remember not to advance |
| 516 // to an incomplete frame. | 516 // to an incomplete frame. |
| 517 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsComp
leteAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount()) { | 517 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsComp
leteAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount()) { |
| 518 // Should we skip the next frame? | 518 // Should we skip the next frame? |
| 519 double frameAfterNextStartTime = m_desiredFrameStartTime + frameDura
tionAtIndex(nextFrame); | 519 double frameAfterNextStartTime = m_desiredFrameStartTime + frameDura
tionAtIndex(nextFrame); |
| 520 if (time < frameAfterNextStartTime) | 520 if (time < frameAfterNextStartTime) |
| 521 break; | 521 break; |
| 522 | 522 |
| 523 // Yes; skip over it without notifying our observers. | 523 // Skip the next frame by advancing the animation forward one frame. |
| 524 if (!internalAdvanceAnimation(true)) | 524 if (!internalAdvanceAnimation(SkipFramesToCatchUp)) { |
| 525 DCHECK(m_animationFinished); |
| 525 return; | 526 return; |
| 527 } |
| 526 m_desiredFrameStartTime = frameAfterNextStartTime; | 528 m_desiredFrameStartTime = frameAfterNextStartTime; |
| 527 nextFrame = frameAfterNext; | 529 nextFrame = frameAfterNext; |
| 528 } | 530 } |
| 529 | 531 |
| 530 // Post a task to advance the frame immediately. m_desiredFrameStartTime | 532 // Post a task to advance the frame immediately. m_desiredFrameStartTime |
| 531 // may be in the past, meaning the next time through this function we'll | 533 // may be in the past, meaning the next time through this function we'll |
| 532 // kick off the next advancement sooner than this frame's duration would | 534 // kick off the next advancement sooner than this frame's duration would |
| 533 // suggest. | 535 // suggest. |
| 534 m_frameTimer = wrapUnique(new Timer<BitmapImage>(this, &BitmapImage::adv
anceAnimationWithoutCatchUp)); | 536 m_frameTimer = wrapUnique(new Timer<BitmapImage>(this, &BitmapImage::adv
anceAnimationWithoutCatchUp)); |
| 535 m_frameTimer->startOneShot(0, BLINK_FROM_HERE); | 537 m_frameTimer->startOneShot(0, BLINK_FROM_HERE); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 566 void BitmapImage::advanceTime(double deltaTimeInSeconds) | 568 void BitmapImage::advanceTime(double deltaTimeInSeconds) |
| 567 { | 569 { |
| 568 if (m_desiredFrameStartTime) | 570 if (m_desiredFrameStartTime) |
| 569 m_desiredFrameStartTime -= deltaTimeInSeconds; | 571 m_desiredFrameStartTime -= deltaTimeInSeconds; |
| 570 else | 572 else |
| 571 m_desiredFrameStartTime = monotonicallyIncreasingTime() - deltaTimeInSec
onds; | 573 m_desiredFrameStartTime = monotonicallyIncreasingTime() - deltaTimeInSec
onds; |
| 572 } | 574 } |
| 573 | 575 |
| 574 void BitmapImage::advanceAnimation(TimerBase*) | 576 void BitmapImage::advanceAnimation(TimerBase*) |
| 575 { | 577 { |
| 576 internalAdvanceAnimation(false); | 578 internalAdvanceAnimation(); |
| 577 // At this point the image region has been marked dirty, and if it's | 579 // At this point the image region has been marked dirty, and if it's |
| 578 // onscreen, we'll soon make a call to draw(), which will call | 580 // onscreen, we'll soon make a call to draw(), which will call |
| 579 // startAnimation() again to keep the animation moving. | 581 // startAnimation() again to keep the animation moving. |
| 580 } | 582 } |
| 581 | 583 |
| 582 void BitmapImage::advanceAnimationWithoutCatchUp(TimerBase*) | 584 void BitmapImage::advanceAnimationWithoutCatchUp(TimerBase*) |
| 583 { | 585 { |
| 584 if (internalAdvanceAnimation(false)) | 586 if (internalAdvanceAnimation()) |
| 585 startAnimation(DoNotCatchUp); | 587 startAnimation(DoNotCatchUp); |
| 586 } | 588 } |
| 587 | 589 |
| 588 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) | 590 bool BitmapImage::internalAdvanceAnimation(AnimationAdvancement advancement) |
| 589 { | 591 { |
| 590 // Stop the animation. | 592 // Stop the animation. |
| 591 stopAnimation(); | 593 stopAnimation(); |
| 592 | 594 |
| 593 // See if anyone is still paying attention to this animation. If not, we do
n't | 595 // See if anyone is still paying attention to this animation. If not, we do
n't |
| 594 // advance and will remain suspended at the current frame until the animatio
n is resumed. | 596 // advance and will remain suspended at the current frame until the animatio
n is resumed. |
| 595 if (!skippingFrames && getImageObserver()->shouldPauseAnimation(this)) | 597 if (advancement != SkipFramesToCatchUp && getImageObserver()->shouldPauseAni
mation(this)) |
| 596 return false; | 598 return false; |
| 597 | 599 |
| 598 ++m_currentFrame; | 600 if (m_currentFrame + 1 < frameCount()) { |
| 599 bool advancedAnimation = true; | 601 m_currentFrame++; |
| 600 if (m_currentFrame >= frameCount()) { | 602 } else { |
| 601 ++m_repetitionsComplete; | 603 m_repetitionsComplete++; |
| 602 | 604 |
| 603 // Get the repetition count again. If we weren't able to get a | 605 // Get the repetition count again. If we weren't able to get a |
| 604 // repetition count before, we should have decoded the whole image by | 606 // repetition count before, we should have decoded the whole image by |
| 605 // now, so it should now be available. | 607 // now, so it should now be available. |
| 606 // Note that we don't need to special-case cAnimationLoopOnce here | 608 // We don't need to special-case cAnimationLoopOnce here because it is |
| 607 // because it is 0 (see comments on its declaration in ImageAnimation.h)
. | 609 // 0 (see comments on its declaration in ImageAnimation.h). |
| 608 if ((repetitionCount(true) != cAnimationLoopInfinite && m_repetitionsCom
plete > m_repetitionCount) | 610 if ((repetitionCount(true) != cAnimationLoopInfinite && m_repetitionsCom
plete > m_repetitionCount) |
| 609 || m_animationPolicy == ImageAnimationPolicyAnimateOnce) { | 611 || m_animationPolicy == ImageAnimationPolicyAnimateOnce) { |
| 610 m_animationFinished = true; | 612 m_animationFinished = true; |
| 611 m_desiredFrameStartTime = 0; | 613 m_desiredFrameStartTime = 0; |
| 612 --m_currentFrame; | 614 |
| 613 advancedAnimation = false; | 615 // We skipped to the last frame and cannot advance further. The |
| 614 } else | 616 // observer will not receive animationAdvanced notifications while |
| 615 m_currentFrame = 0; | 617 // skipping but we still need to notify the observer to draw the |
| 618 // last frame. Skipping frames occurs while painting so we do not |
| 619 // synchronously notify the observer which could cause a layout. |
| 620 if (advancement == SkipFramesToCatchUp) { |
| 621 m_frameTimer = wrapUnique(new Timer<BitmapImage>(this, &BitmapIm
age::notifyObserversOfAnimationAdvance)); |
| 622 m_frameTimer->startOneShot(0, BLINK_FROM_HERE); |
| 623 } |
| 624 |
| 625 return false; |
| 626 } |
| 627 |
| 628 // Loop the animation back to the first frame. |
| 629 m_currentFrame = 0; |
| 616 } | 630 } |
| 617 | 631 |
| 618 // We need to draw this frame if we advanced to it while not skipping, or if | 632 // We need to draw this frame if we advanced to it while not skipping. |
| 619 // while trying to skip frames we hit the last frame and thus had to stop. | 633 if (advancement != SkipFramesToCatchUp) |
| 620 if (skippingFrames != advancedAnimation) | |
| 621 getImageObserver()->animationAdvanced(this); | 634 getImageObserver()->animationAdvanced(this); |
| 622 | 635 |
| 623 return advancedAnimation; | 636 return true; |
| 637 } |
| 638 |
| 639 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) |
| 640 { |
| 641 getImageObserver()->animationAdvanced(this); |
| 624 } | 642 } |
| 625 | 643 |
| 626 } // namespace blink | 644 } // namespace blink |
| OLD | NEW |