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 {
SVGImage::SVGImage(ImageObserver* observer)
: Image(observer)
, m_hasPendingTimelineRewind(false)
{
}
......@@ -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.
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);
{
ClipRecorder clipRecorder(imagePicture.context(), imagePicture, DisplayItem::ClipNodeImage, enclosingIntRect(dstRect));
......@@ -397,6 +405,20 @@ LayoutReplaced* SVGImage::embeddedReplacedContent() const
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.
void SVGImage::startAnimation(CatchUpAnimation)
{
......@@ -424,7 +446,7 @@ void SVGImage::resetAnimation()
return;
m_chromeClient->suspendAnimation();
rootElement->pauseAnimations();
rootElement->setCurrentTime(0);
scheduleTimelineRewind();
}
bool SVGImage::hasAnimations() const
......
......@@ -115,6 +115,8 @@ private:
ImageClampingMode, const KURL&);
void stopAnimation();
void scheduleTimelineRewind();
void flushPendingTimelineRewind();
Persistent<SVGImageChromeClient> m_chromeClient;
Persistent<Page> m_page;
......@@ -126,6 +128,7 @@ private:
// SVGImage. SVGImageForContainer carried the final image size,
// also called concrete object size.
IntSize m_intrinsicSize;
bool m_hasPendingTimelineRewind;
};
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