- Revision
- 200171
- Author
- [email protected]
- Date
- 2016-04-27 22:27:01 -0700 (Wed, 27 Apr 2016)
Log Message
SVG SMIL animations run at less than 60fps
https://bugs.webkit.org/show_bug.cgi?id=157119
rdar://problem/25971304
Reviewed by Tim Horton.
If you re-fetch current time while doing animation computations you're gonna have
a bad time.
More specifically, SMILTimeContainer::startTimer() re-fetched elapsedTime() when
computing the delay for the next timer fire, then clamped to 16.667ms, so the timer
would actually be scheduled at intervals greater than desired, causing a ~54fps framerate.
Fix by using the elapsedTime fetched at the start of animation processing.
Tested by iOS content-animation performance tests.
* svg/SVGSVGElement.cpp:
(WebCore::SVGSVGElement::SVGSVGElement): Just cleanup.
* svg/animation/SMILTimeContainer.cpp:
(WebCore::SMILTimeContainer::notifyIntervalsChanged):
(WebCore::SMILTimeContainer::resume):
(WebCore::SMILTimeContainer::startTimer):
(WebCore::SMILTimeContainer::updateAnimations):
* svg/animation/SMILTimeContainer.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (200170 => 200171)
--- trunk/Source/WebCore/ChangeLog 2016-04-28 04:57:15 UTC (rev 200170)
+++ trunk/Source/WebCore/ChangeLog 2016-04-28 05:27:01 UTC (rev 200171)
@@ -1,3 +1,31 @@
+2016-04-27 Simon Fraser <[email protected]>
+
+ SVG SMIL animations run at less than 60fps
+ https://bugs.webkit.org/show_bug.cgi?id=157119
+ rdar://problem/25971304
+
+ Reviewed by Tim Horton.
+
+ If you re-fetch current time while doing animation computations you're gonna have
+ a bad time.
+
+ More specifically, SMILTimeContainer::startTimer() re-fetched elapsedTime() when
+ computing the delay for the next timer fire, then clamped to 16.667ms, so the timer
+ would actually be scheduled at intervals greater than desired, causing a ~54fps framerate.
+
+ Fix by using the elapsedTime fetched at the start of animation processing.
+
+ Tested by iOS content-animation performance tests.
+
+ * svg/SVGSVGElement.cpp:
+ (WebCore::SVGSVGElement::SVGSVGElement): Just cleanup.
+ * svg/animation/SMILTimeContainer.cpp:
+ (WebCore::SMILTimeContainer::notifyIntervalsChanged):
+ (WebCore::SMILTimeContainer::resume):
+ (WebCore::SMILTimeContainer::startTimer):
+ (WebCore::SMILTimeContainer::updateAnimations):
+ * svg/animation/SMILTimeContainer.h:
+
2016-04-27 Brady Eidson <[email protected]>
Build fix followup to r200163
Modified: trunk/Source/WebCore/svg/SVGSVGElement.cpp (200170 => 200171)
--- trunk/Source/WebCore/svg/SVGSVGElement.cpp 2016-04-28 04:57:15 UTC (rev 200170)
+++ trunk/Source/WebCore/svg/SVGSVGElement.cpp 2016-04-28 05:27:01 UTC (rev 200171)
@@ -64,7 +64,7 @@
, m_y(LengthModeHeight)
, m_width(LengthModeWidth, ASCIILiteral("100%"))
, m_height(LengthModeHeight, ASCIILiteral("100%"))
- , m_timeContainer(RefPtr<SMILTimeContainer>(SMILTimeContainer::create(this)).releaseNonNull())
+ , m_timeContainer(SMILTimeContainer::create(this))
{
ASSERT(hasTagName(SVGNames::svgTag));
registerAnimatedPropertiesForSVGSVGElement();
Modified: trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp (200170 => 200171)
--- trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp 2016-04-28 04:57:15 UTC (rev 200170)
+++ trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp 2016-04-28 05:27:01 UTC (rev 200171)
@@ -98,7 +98,7 @@
{
// Schedule updateAnimations() to be called asynchronously so multiple intervals
// can change with updateAnimations() only called once at the end.
- startTimer(0);
+ startTimer(elapsed(), 0);
}
SMILTime SMILTimeContainer::elapsed() const
@@ -159,7 +159,7 @@
m_resumeTime = monotonicallyIncreasingTime();
m_pauseTime = 0;
- startTimer(0);
+ startTimer(elapsed(), 0);
}
void SMILTimeContainer::setElapsed(SMILTime time)
@@ -196,7 +196,7 @@
updateAnimations(time, true);
}
-void SMILTimeContainer::startTimer(SMILTime fireTime, SMILTime minimumDelay)
+void SMILTimeContainer::startTimer(SMILTime elapsed, SMILTime fireTime, SMILTime minimumDelay)
{
if (!m_beginTime || isPaused())
return;
@@ -204,7 +204,7 @@
if (!fireTime.isFinite())
return;
- SMILTime delay = std::max(fireTime - elapsed(), minimumDelay);
+ SMILTime delay = std::max(fireTime - elapsed, minimumDelay);
m_timer.startOneShot(delay.value());
}
@@ -307,7 +307,7 @@
#ifndef NDEBUG
m_preventScheduledAnimationsChanges = false;
#endif
- startTimer(earliestFireTime, SMILAnimationFrameDelay);
+ startTimer(elapsed, earliestFireTime, SMILAnimationFrameDelay);
return;
}
@@ -319,7 +319,7 @@
m_preventScheduledAnimationsChanges = false;
#endif
- startTimer(earliestFireTime, SMILAnimationFrameDelay);
+ startTimer(elapsed, earliestFireTime, SMILAnimationFrameDelay);
}
}
Modified: trunk/Source/WebCore/svg/animation/SMILTimeContainer.h (200170 => 200171)
--- trunk/Source/WebCore/svg/animation/SMILTimeContainer.h 2016-04-28 04:57:15 UTC (rev 200170)
+++ trunk/Source/WebCore/svg/animation/SMILTimeContainer.h 2016-04-28 05:27:01 UTC (rev 200171)
@@ -67,7 +67,7 @@
SMILTimeContainer(SVGSVGElement* owner);
void timerFired();
- void startTimer(SMILTime fireTime, SMILTime minimumDelay = 0);
+ void startTimer(SMILTime elapsed, SMILTime fireTime, SMILTime minimumDelay = 0);
void updateAnimations(SMILTime elapsed, bool seekToTime = false);
void updateDocumentOrderIndexes();