After two runs of a SMIL SVG animation, an SVG item doesn't re-appear
https://bugs.webkit.org/show_bug.cgi?id=196596
rdar://49631053
Reviewed by Nikolas Zimmermann.
When several SMIL animations target the same element/attribute (a "sandwich"),
SMILTimeContainer::updateAnimations() sorts them by priority and applies their results in that
order, so the highest-priority (latest begin time) animation wins. The priority sort ran before
each animation's progress() advanced its current interval to the current time. An animation whose
interval only restarts at (or before) the current time — e.g. a sync-base dependent that just
gained a new, later begin time — was therefore sorted using its stale, earlier interval begin,
lost the sandwich to a lower-priority animation, and its result was overwritten. This is why, after
toggling minimize/maximize twice, the element failed to re-appear.
Fix this by resolving every scheduled animation's current interval (and active state) up front, in
a new updateIntervalForProgress() pass that runs before the priority sort, and having progress()
apply the value and fire events against that already-resolved state. progress() is now driven by a
ProgressDisposition recorded during that pass, which preserves each of the original early-outs via
two dispositions: NotContributing (an unresolved interval, or a seek landing before the interval)
and BeforeInterval (an interval not yet begun). The remaining Resolved disposition still fires
begin/end events for an interval that ends into a frozen state mid-frame.
The animation percent is now computed in progress(), after the interval has been resolved, rather
than before checkRestart(). Previously, on the frame an interval restarted, the percent was
computed against the just-ended interval (clamping to 1, i.e. the destination value), so the
restarting animation briefly painted its end value for one frame before correcting. Computing the
percent against the resolved interval yields ~0 (the interval's start) on that frame.
Tests: imported/w3c/web-platform-tests/svg/animations/syncbases-with-tangled-dependencies.html
svg/animations/restarted-interval-does-not-flash-end-value.html
* LayoutTests/imported/w3c/web-platform-tests/svg/animations/scripted/onhover-syncbases-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/svg/animations/syncbases-with-tangled-dependencies-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/svg/animations/syncbases-with-tangled-dependencies.html: Added.
* LayoutTests/svg/animations/restarted-interval-does-not-flash-end-value-expected.txt: Added.
* LayoutTests/svg/animations/restarted-interval-does-not-flash-end-value.html: Added.
* Source/WebCore/svg/animation/SMILTimeContainer.cpp:
(WebCore::SMILTimeContainer::updateAnimations):
* Source/WebCore/svg/animation/SVGSMILElement.cpp:
(WebCore::SVGSMILElement::reset):
(WebCore::SVGSMILElement::checkRestart):
(WebCore::SVGSMILElement::updateIntervalForProgress):
(WebCore::SVGSMILElement::progress):
* Source/WebCore/svg/animation/SVGSMILElement.h:
Canonical link: https://commits.webkit.org/317272@main C
Chris Dumez committed
1e92d3b75ea2374dd1343c066f82dbe719d80bec
Parent: 6d6a251