| Index: third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
|
| diff --git a/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp b/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
|
| index 32ccfa066a988e2e442c6182a304bbb269fae506..0dc66056d202a6a8b6756f53575fcbb2e643a80d 100644
|
| --- a/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
|
| +++ b/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
|
| @@ -41,12 +41,11 @@ static const double initialFrameDelay = 0.025;
|
| static const double animationPolicyOnceDuration = 3.000;
|
|
|
| SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
|
| - : m_beginTime(0)
|
| - , m_pauseTime(0)
|
| - , m_resumeTime(0)
|
| - , m_accumulatedActiveTime(0)
|
| - , m_presetStartTime(0)
|
| + : m_presentationTime(0)
|
| + , m_referenceTime(0)
|
| , m_frameSchedulingState(Idle)
|
| + , m_started(false)
|
| + , m_paused(false)
|
| , m_documentOrderIndexesDirty(false)
|
| , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired)
|
| , m_animationPolicyOnceTimer(this, &SMILTimeContainer::animationPolicyTimerFired)
|
| @@ -136,29 +135,39 @@ void SMILTimeContainer::notifyIntervalsChanged()
|
|
|
| SMILTime SMILTimeContainer::elapsed() const
|
| {
|
| - if (!m_beginTime)
|
| + if (!isStarted())
|
| return 0;
|
|
|
| if (isPaused())
|
| - return m_accumulatedActiveTime;
|
| + return m_presentationTime;
|
| +
|
| + return m_presentationTime + (document().timeline().currentTimeInternal() - m_referenceTime);
|
| +}
|
|
|
| - return currentTime() + m_accumulatedActiveTime - lastResumeTime();
|
| +void SMILTimeContainer::synchronizeToDocumentTimeline()
|
| +{
|
| + m_referenceTime = document().timeline().currentTimeInternal();
|
| }
|
|
|
| bool SMILTimeContainer::isPaused() const
|
| {
|
| - // If animation policy is "none", it is always paused.
|
| - return m_pauseTime || animationPolicy() == ImageAnimationPolicyNoAnimation;
|
| + // If animation policy is "none", the timeline is always paused.
|
| + return m_paused || animationPolicy() == ImageAnimationPolicyNoAnimation;
|
| }
|
|
|
| bool SMILTimeContainer::isStarted() const
|
| {
|
| - return m_beginTime;
|
| + return m_started;
|
| +}
|
| +
|
| +bool SMILTimeContainer::isTimelineRunning() const
|
| +{
|
| + return isStarted() && !isPaused();
|
| }
|
|
|
| -void SMILTimeContainer::begin()
|
| +void SMILTimeContainer::start()
|
| {
|
| - RELEASE_ASSERT(!m_beginTime);
|
| + RELEASE_ASSERT(!isStarted());
|
|
|
| if (!document().isActive())
|
| return;
|
| @@ -166,81 +175,80 @@ void SMILTimeContainer::begin()
|
| if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused))
|
| return;
|
|
|
| - double now = currentTime();
|
| + // Sample the document timeline to get a time reference for the "presentation time".
|
| + synchronizeToDocumentTimeline();
|
| + m_started = true;
|
|
|
| - // If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began.
|
| - // In this case pass on 'seekToTime=true' to updateAnimations().
|
| - m_beginTime = now - m_presetStartTime;
|
| - SMILTime earliestFireTime = updateAnimations(SMILTime(m_presetStartTime), m_presetStartTime ? true : false);
|
| - m_presetStartTime = 0;
|
| + // If the "presentation time" is non-zero, the timeline was modified via
|
| + // setElapsed() before the document began.
|
| + // In this case pass on 'seekToTime=true' to updateAnimations() to issue a seek.
|
| + SMILTime earliestFireTime = updateAnimations(SMILTime(m_presentationTime), m_presentationTime ? true : false);
|
|
|
| - if (m_pauseTime) {
|
| - m_pauseTime = now;
|
| - // If updateAnimations() caused new syncbase instance to be generated,
|
| + if (isPaused()) {
|
| + // If updateAnimations() caused new syncbase instances to be generated,
|
| // we don't want to cancel those. Excepting that, no frame should've
|
| // been scheduled at this point.
|
| - ASSERT(m_frameSchedulingState == Idle || m_frameSchedulingState == SynchronizeAnimations);
|
| - } else if (!hasPendingSynchronization()) {
|
| - ASSERT(isTimelineRunning());
|
| - // If the timeline is running, and there's pending animation updates,
|
| - // always perform the first update after the timeline was started using
|
| - // the wake-up mechanism.
|
| - if (earliestFireTime.isFinite()) {
|
| - SMILTime delay = earliestFireTime - elapsed();
|
| - scheduleWakeUp(std::max(initialFrameDelay, delay.value()), SynchronizeAnimations);
|
| - }
|
| + DCHECK(m_frameSchedulingState == Idle || m_frameSchedulingState == SynchronizeAnimations);
|
| + return;
|
| }
|
| + // If synchronizations are pending, those will in turn schedule additional
|
| + // frames.
|
| + if (hasPendingSynchronization())
|
| + return;
|
| + DCHECK(isTimelineRunning());
|
| + if (!earliestFireTime.isFinite())
|
| + return;
|
| + // If the timeline is running, and there are pending animation updates,
|
| + // always perform the first update after the timeline was started using
|
| + // the wake-up mechanism.
|
| + SMILTime delay = earliestFireTime - m_presentationTime;
|
| + scheduleWakeUp(std::max(initialFrameDelay, delay.value()), SynchronizeAnimations);
|
| }
|
|
|
| void SMILTimeContainer::pause()
|
| {
|
| if (!handleAnimationPolicy(CancelOnceTimer))
|
| return;
|
| + DCHECK(!isPaused());
|
|
|
| - ASSERT(!isPaused());
|
| - m_pauseTime = currentTime();
|
| -
|
| - if (m_beginTime) {
|
| - m_accumulatedActiveTime += m_pauseTime - lastResumeTime();
|
| + if (isStarted()) {
|
| + m_presentationTime = elapsed().value();
|
| cancelAnimationFrame();
|
| }
|
| - m_resumeTime = 0;
|
| + // Update the flag after sampling elapsed().
|
| + m_paused = true;
|
| }
|
|
|
| void SMILTimeContainer::resume()
|
| {
|
| if (!handleAnimationPolicy(RestartOnceTimer))
|
| return;
|
| + DCHECK(isPaused());
|
| +
|
| + m_paused = false;
|
|
|
| - ASSERT(isPaused());
|
| - m_resumeTime = currentTime();
|
| + if (isStarted())
|
| + synchronizeToDocumentTimeline();
|
|
|
| - m_pauseTime = 0;
|
| scheduleWakeUp(0, SynchronizeAnimations);
|
| }
|
|
|
| void SMILTimeContainer::setElapsed(SMILTime time)
|
| {
|
| - // If the documment didn't begin yet, record a new start time, we'll seek to once its possible.
|
| - if (!m_beginTime) {
|
| - m_presetStartTime = time.value();
|
| + m_presentationTime = time.value();
|
| +
|
| + // If the document hasn't finished loading, |m_presentationTime| will be
|
| + // used as the start time to seek to once it's possible.
|
| + if (!isStarted())
|
| return;
|
| - }
|
|
|
| if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused))
|
| return;
|
|
|
| cancelAnimationFrame();
|
|
|
| - double now = currentTime();
|
| - m_beginTime = now - time.value();
|
| - m_resumeTime = 0;
|
| - if (m_pauseTime) {
|
| - m_pauseTime = now;
|
| - m_accumulatedActiveTime = time.value();
|
| - } else {
|
| - m_accumulatedActiveTime = 0;
|
| - }
|
| + if (!isPaused())
|
| + synchronizeToDocumentTimeline();
|
|
|
| #if ENABLE(ASSERT)
|
| m_preventScheduledAnimationsChanges = true;
|
| @@ -260,21 +268,16 @@ void SMILTimeContainer::setElapsed(SMILTime time)
|
| updateAnimationsAndScheduleFrameIfNeeded(time, true);
|
| }
|
|
|
| -bool SMILTimeContainer::isTimelineRunning() const
|
| +void SMILTimeContainer::scheduleAnimationFrame(double delayTime)
|
| {
|
| - return m_beginTime && !isPaused();
|
| -}
|
| -
|
| -void SMILTimeContainer::scheduleAnimationFrame(SMILTime fireTime)
|
| -{
|
| - ASSERT(isTimelineRunning() && fireTime.isFinite());
|
| - ASSERT(!m_wakeupTimer.isActive());
|
| + DCHECK(std::isfinite(delayTime));
|
| + DCHECK(isTimelineRunning());
|
| + DCHECK(!m_wakeupTimer.isActive());
|
|
|
| - SMILTime delay = fireTime - elapsed();
|
| - if (delay.value() < AnimationTimeline::s_minimumDelay) {
|
| + if (delayTime < AnimationTimeline::s_minimumDelay) {
|
| serviceOnNextFrame();
|
| } else {
|
| - scheduleWakeUp(delay.value() - AnimationTimeline::s_minimumDelay, FutureAnimationFrame);
|
| + scheduleWakeUp(delayTime - AnimationTimeline::s_minimumDelay, FutureAnimationFrame);
|
| }
|
| }
|
|
|
| @@ -397,11 +400,6 @@ Document& SMILTimeContainer::document() const
|
| return ownerSVGElement().document();
|
| }
|
|
|
| -double SMILTimeContainer::currentTime() const
|
| -{
|
| - return document().timeline().currentTimeInternal();
|
| -}
|
| -
|
| void SMILTimeContainer::serviceOnNextFrame()
|
| {
|
| if (document().view()) {
|
| @@ -436,7 +434,8 @@ void SMILTimeContainer::updateAnimationsAndScheduleFrameIfNeeded(SMILTime elapse
|
| if (!earliestFireTime.isFinite())
|
| return;
|
|
|
| - scheduleAnimationFrame(earliestFireTime);
|
| + SMILTime delay = earliestFireTime - elapsed;
|
| + scheduleAnimationFrame(delay.value());
|
| }
|
|
|
| SMILTime SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
|
|
|