Commit 12c039d9 authored by fs's avatar fs Committed by Commit bot

Avoid setting timers from SVGImage::resetAnimation()

When resetting the timeline to t=0, we may up generating syncbase
notification, which sets up a timer (to update any possibly dependent
intervals.) Since resetAnimation() is what's called when the (SVG)Image
no longer has any clients, we should try to make sure it is indeed
idle after that happens. This avoids trying to update animation state
while the image is otherwise dead, leaving "reactivation" to the time
it is next painted.

BUG=627418

Review-Url: https://codereview.chromium.org/2247783003
Cr-Commit-Position: refs/heads/master@{#412798}
parent 0c08e95b
...@@ -64,6 +64,7 @@ namespace blink { ...@@ -64,6 +64,7 @@ namespace blink {
SVGImage::SVGImage(ImageObserver* observer) SVGImage::SVGImage(ImageObserver* observer)
: Image(observer) : Image(observer)
, m_hasPendingTimelineRewind(false)
{ {
} }
...@@ -352,6 +353,13 @@ void SVGImage::drawInternal(SkCanvas* canvas, const SkPaint& paint, const FloatR ...@@ -352,6 +353,13 @@ void SVGImage::drawInternal(SkCanvas* canvas, const SkPaint& paint, const FloatR
// there may have been a previous url/fragment that needs to be reset. // there may have been a previous url/fragment that needs to be reset.
view->processUrlFragment(url); view->processUrlFragment(url);
// If the image was reset, we need to rewind the timeline back to 0. This
// needs to be done before painting, or else we wouldn't get the correct
// reset semantics (we'd paint the "last" frame rather than the one at
// time=0.) The reason we do this here and not in resetAnimation() is to
// avoid setting timers from the latter.
flushPendingTimelineRewind();
SkPictureBuilder imagePicture(dstRect); SkPictureBuilder imagePicture(dstRect);
{ {
ClipRecorder clipRecorder(imagePicture.context(), imagePicture, DisplayItem::ClipNodeImage, enclosingIntRect(dstRect)); ClipRecorder clipRecorder(imagePicture.context(), imagePicture, DisplayItem::ClipNodeImage, enclosingIntRect(dstRect));
...@@ -397,6 +405,20 @@ LayoutReplaced* SVGImage::embeddedReplacedContent() const ...@@ -397,6 +405,20 @@ LayoutReplaced* SVGImage::embeddedReplacedContent() const
return toLayoutSVGRoot(rootElement->layoutObject()); return toLayoutSVGRoot(rootElement->layoutObject());
} }
void SVGImage::scheduleTimelineRewind()
{
m_hasPendingTimelineRewind = true;
}
void SVGImage::flushPendingTimelineRewind()
{
if (!m_hasPendingTimelineRewind)
return;
if (SVGSVGElement* rootElement = svgRootElement(m_page.get()))
rootElement->setCurrentTime(0);
m_hasPendingTimelineRewind = false;
}
// FIXME: support CatchUpAnimation = CatchUp. // FIXME: support CatchUpAnimation = CatchUp.
void SVGImage::startAnimation(CatchUpAnimation) void SVGImage::startAnimation(CatchUpAnimation)
{ {
...@@ -424,7 +446,7 @@ void SVGImage::resetAnimation() ...@@ -424,7 +446,7 @@ void SVGImage::resetAnimation()
return; return;
m_chromeClient->suspendAnimation(); m_chromeClient->suspendAnimation();
rootElement->pauseAnimations(); rootElement->pauseAnimations();
rootElement->setCurrentTime(0); scheduleTimelineRewind();
} }
bool SVGImage::hasAnimations() const bool SVGImage::hasAnimations() const
......
...@@ -115,6 +115,8 @@ private: ...@@ -115,6 +115,8 @@ private:
ImageClampingMode, const KURL&); ImageClampingMode, const KURL&);
void stopAnimation(); void stopAnimation();
void scheduleTimelineRewind();
void flushPendingTimelineRewind();
Persistent<SVGImageChromeClient> m_chromeClient; Persistent<SVGImageChromeClient> m_chromeClient;
Persistent<Page> m_page; Persistent<Page> m_page;
...@@ -126,6 +128,7 @@ private: ...@@ -126,6 +128,7 @@ private:
// SVGImage. SVGImageForContainer carried the final image size, // SVGImage. SVGImageForContainer carried the final image size,
// also called concrete object size. // also called concrete object size.
IntSize m_intrinsicSize; IntSize m_intrinsicSize;
bool m_hasPendingTimelineRewind;
}; };
DEFINE_IMAGE_TYPE_CASTS(SVGImage); DEFINE_IMAGE_TYPE_CASTS(SVGImage);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment