Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1448)

Unified Diff: Source/core/svg/animation/SMILTimeContainer.cpp

Issue 179293004: Drive SVG Animations via requestAnimationFrame (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/svg/animation/SMILTimeContainer.cpp
diff --git a/Source/core/svg/animation/SMILTimeContainer.cpp b/Source/core/svg/animation/SMILTimeContainer.cpp
index c41555d4d18203e592dc1c81d5ce2f275f8c3608..936d795478328df13d2e1e0fdf8f7ef5b7692864 100644
--- a/Source/core/svg/animation/SMILTimeContainer.cpp
+++ b/Source/core/svg/animation/SMILTimeContainer.cpp
@@ -27,6 +27,7 @@
#include "core/svg/animation/SMILTimeContainer.h"
#include "core/dom/ElementTraversal.h"
+#include "core/frame/FrameView.h"
#include "core/svg/SVGSVGElement.h"
#include "core/svg/animation/SVGSMILElement.h"
#include "wtf/CurrentTime.h"
@@ -35,7 +36,8 @@ using namespace std;
namespace WebCore {
-static const double animationFrameDelay = 0.025;
+// Blatantly copied from core/animation/DocumentTimeline.cpp.
+static const double minimumDelay = 0.04;
pdr. 2014/03/03 17:47:33 Can you use DocumentTimeline::s_minimumDelay direc
dstockwell 2014/03/04 01:19:04 I'm OK with this duplication for now, but this log
fs 2014/03/04 10:28:19 I suppose we can trade this two line hack for a on
SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner)
: m_beginTime(0)
@@ -44,7 +46,9 @@ SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner)
, m_accumulatedActiveTime(0)
, m_presetStartTime(0)
, m_documentOrderIndexesDirty(false)
- , m_timer(this, &SMILTimeContainer::timerFired)
+ , m_framePending(false)
+ , m_clockFrozen(false)
pdr. 2014/03/03 17:47:33 I'm wary of adding more clock-related state to thi
fs 2014/03/04 10:28:19 I will try to formalize this somewhat - probably b
+ , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired)
, m_ownerSVGElement(owner)
#ifndef NDEBUG
, m_preventScheduledAnimationsChanges(false)
@@ -55,7 +59,7 @@ SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner)
SMILTimeContainer::~SMILTimeContainer()
{
cancelAnimationFrame();
- ASSERT(!m_timer.isActive());
+ ASSERT(!m_wakeupTimer.isActive());
#ifndef NDEBUG
ASSERT(!m_preventScheduledAnimationsChanges);
#endif
@@ -99,6 +103,11 @@ void SMILTimeContainer::unschedule(SVGSMILElement* animation, SVGElement* target
scheduled->remove(idx);
}
+bool SMILTimeContainer::hasAnimations() const
+{
+ return !m_scheduledAnimations.isEmpty();
+}
+
void SMILTimeContainer::notifyIntervalsChanged()
{
// Schedule updateAnimations() to be called asynchronously so multiple intervals
@@ -108,7 +117,7 @@ void SMILTimeContainer::notifyIntervalsChanged()
SMILTime SMILTimeContainer::elapsed() const
{
- if (!m_beginTime)
+ if (!m_beginTime || m_clockFrozen)
return 0;
if (isPaused())
@@ -135,12 +144,15 @@ void SMILTimeContainer::begin()
// 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;
- updateAnimations(SMILTime(m_presetStartTime), m_presetStartTime ? true : false);
+ bool hadPresetStartTime = m_presetStartTime ? true : false;
+ updateAnimations(SMILTime(m_presetStartTime), hadPresetStartTime);
m_presetStartTime = 0;
if (m_pauseTime) {
m_pauseTime = now;
cancelAnimationFrame();
+ } else {
+ m_clockFrozen = !hadPresetStartTime;
}
}
@@ -154,6 +166,7 @@ void SMILTimeContainer::pause()
cancelAnimationFrame();
}
m_resumeTime = 0;
+ m_clockFrozen = false;
}
void SMILTimeContainer::resume()
@@ -163,6 +176,7 @@ void SMILTimeContainer::resume()
m_pauseTime = 0;
scheduleAnimationFrame();
+ m_clockFrozen = false;
}
void SMILTimeContainer::setElapsed(SMILTime time)
@@ -173,6 +187,8 @@ void SMILTimeContainer::setElapsed(SMILTime time)
return;
}
+ m_clockFrozen = false;
+
if (m_beginTime)
pdr. 2014/03/03 17:47:33 How did this if statement get here? :P
fs 2014/03/04 10:28:19 Magic? =P Maybe it should've been some other cond
cancelAnimationFrame();
@@ -216,8 +232,11 @@ void SMILTimeContainer::scheduleAnimationFrame(SMILTime fireTime)
if (!fireTime.isFinite())
return;
- SMILTime delay = max(fireTime - elapsed(), SMILTime(animationFrameDelay));
- m_timer.startOneShot(delay.value());
+ SMILTime delay = fireTime - elapsed();
+ if (delay.value() < minimumDelay)
+ serviceOnNextFrame();
+ else
+ m_wakeupTimer.startOneShot(delay.value() - minimumDelay);
}
void SMILTimeContainer::scheduleAnimationFrame()
@@ -225,18 +244,21 @@ void SMILTimeContainer::scheduleAnimationFrame()
if (!isTimelineRunning())
return;
- m_timer.startOneShot(0);
+ // Could also schedule a wakeup at +0 seconds, but that could still
+ // potentially race with the servicing of the next frame.
+ serviceOnNextFrame();
}
void SMILTimeContainer::cancelAnimationFrame()
{
- m_timer.stop();
+ m_framePending = false;
+ m_wakeupTimer.stop();
}
-void SMILTimeContainer::timerFired(Timer<SMILTimeContainer>*)
+void SMILTimeContainer::wakeupTimerFired(Timer<SMILTimeContainer>*)
{
ASSERT(isTimelineRunning());
- updateAnimations(elapsed());
+ serviceOnNextFrame();
}
void SMILTimeContainer::updateDocumentOrderIndexes()
@@ -266,6 +288,30 @@ struct PriorityCompare {
SMILTime m_elapsed;
};
+Document& SMILTimeContainer::document() const
+{
+ ASSERT(m_ownerSVGElement);
+ return m_ownerSVGElement->document();
+}
+
+void SMILTimeContainer::serviceOnNextFrame()
+{
+ if (document().view()) {
+ document().view()->scheduleAnimation();
+ m_framePending = true;
+ }
+}
+
+void SMILTimeContainer::serviceAnimations(double monotonicAnimationStartTime)
dstockwell 2014/03/04 01:19:04 This patch just moves updates to be driven by the
fs 2014/03/04 10:28:19 Yes, I plan to that in follow up CLs. Had original
+{
+ if (!m_framePending)
+ return;
+
+ m_framePending = false;
+ updateAnimations(elapsed());
+ m_clockFrozen = false;
+}
+
void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
{
SMILTime earliestFireTime = SMILTime::unresolved();

Powered by Google App Engine
This is Rietveld 408576698