Bug 63553 - SVG animation fill="freeze" doesn't set baseVal to current animVal if animation stops before reaching the end
Summary: SVG animation fill="freeze" doesn't set baseVal to current animVal if animati...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: SVG (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
: 26008 63547 (view as bug list)
Depends on:
Blocks: 41761
  Show dependency treegraph
 
Reported: 2011-06-28 12:32 PDT by Dirk Schulze
Modified: 2011-08-27 11:09 PDT (History)
8 users (show)

See Also:


Attachments
Animation aborted by clicking on the rect (332 bytes, image/svg+xml)
2011-06-28 12:32 PDT, Dirk Schulze
no flags Details
Patch (6.09 KB, patch)
2011-06-30 10:27 PDT, Young Han Lee
webkit.review.bot: commit-queue-
Details | Formatted Diff | Diff
Archive of layout-test-results from ec2-cr-linux-03 (1.30 MB, application/zip)
2011-06-30 10:50 PDT, WebKit Review Bot
no flags Details
Patch (7.71 KB, patch)
2011-07-10 09:24 PDT, Young Han Lee
no flags Details | Formatted Diff | Diff
Patch (7.55 KB, patch)
2011-07-17 08:14 PDT, Young Han Lee
no flags Details | Formatted Diff | Diff
Patch (6.55 KB, patch)
2011-07-20 12:13 PDT, Young Han Lee
no flags Details | Formatted Diff | Diff
Patch (6.55 KB, patch)
2011-08-27 06:55 PDT, Young Han Lee
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Schulze 2011-06-28 12:32:43 PDT
Created attachment 98958 [details]
Animation aborted by clicking on the rect

SVG animation fill="freeze" doesn't set baseVal to current animVal if animation stops before reaching the end. We just set baseVal to current animation value if 100% of the animation was reached. If we stop earlier the target attribute gets reset to its original value. We might want to check for fill="freeze" if 'end' of animation element fires.
Comment 1 Dirk Schulze 2011-06-28 12:33:08 PDT
*** Bug 26008 has been marked as a duplicate of this bug. ***
Comment 2 Dirk Schulze 2011-06-28 12:52:35 PDT
*** Bug 63550 has been marked as a duplicate of this bug. ***
Comment 3 Dirk Schulze 2011-06-28 12:53:28 PDT
*** Bug 63547 has been marked as a duplicate of this bug. ***
Comment 4 Young Han Lee 2011-06-30 10:27:59 PDT
Created attachment 99330 [details]
Patch
Comment 5 Young Han Lee 2011-06-30 10:29:36 PDT
The function for calculating animation progress is causing this issue. It returns 100% when the animation stops before reaching the end. It should return the progress value of the stop point.
Comment 6 Dirk Schulze 2011-06-30 10:45:58 PDT
Comment on attachment 99330 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=99330&action=review

> Source/WebCore/ChangeLog:10
> +        When the animation stops before reaching the end, the elapsed time is bigger than
> +        m_intervalEnd and smaller than simpleDuration. In that case, the progress of
> +        the animation doesn't 100%, it should be the value of the stop point.

Can you go a bit more into detail? I don't understand what you try to fix. What do the timings mean? To review the patch I have to know more about what we try to do here.

> Source/WebCore/svg/animation/SVGSMILElement.cpp:829
> +        activeTime = m_intervalEnd;

Why do you set activeTime here, we haven't done it before.
Comment 7 WebKit Review Bot 2011-06-30 10:50:05 PDT
Comment on attachment 99330 [details]
Patch

Attachment 99330 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/8959720

New failing tests:
svg/custom/animate-path-morphing.svg
svg/custom/animate-path-discrete.svg
Comment 8 WebKit Review Bot 2011-06-30 10:50:10 PDT
Created attachment 99331 [details]
Archive of layout-test-results from ec2-cr-linux-03

The attached test failures were seen while running run-webkit-tests on the chromium-ews.
Bot: ec2-cr-linux-03  Port: Chromium  Platform: Linux-2.6.35-28-virtual-x86_64-with-Ubuntu-10.10-maverick
Comment 9 Young Han Lee 2011-07-01 07:51:38 PDT
(In reply to comment #6)
> (From update of attachment 99330 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=99330&action=review
> 
> > Source/WebCore/ChangeLog:10
> > +        When the animation stops before reaching the end, the elapsed time is bigger than
> > +        m_intervalEnd and smaller than simpleDuration. In that case, the progress of
> > +        the animation doesn't 100%, it should be the value of the stop point.
> 
> Can you go a bit more into detail? I don't understand what you try to fix. What do the timings mean? To review the patch I have to know more about what we try to do here.

I'm sorry for the undetailed comment.

I believe this phenomenon is caused by the miscalculated progress value.

The animated position of an SVGElement is updated in SMILTimeContainer::updateAnimations() in every frame. When an animation with fill=freeze option stops before reaching the end, the animated position should be updated to somewhere in the animation route, but now it is updated to the end of the animation.

The newly updated position is come from SVGSMILElement::progress(), in which the position is calculated based on the progress value returned from SVGSMILElement::calculateAnimationPercentAndRepeat().

The calculateAnimationPercentAndRepeat() returns 100% in the attached testcase, so consequently the last animated position is updated to the end of the animation. I think the calculateAnimationPercentAndRepeat() have to return the progress of the stopping point on the animation, not 100%.


> 
> > Source/WebCore/svg/animation/SVGSMILElement.cpp:829
> > +        activeTime = m_intervalEnd;
> 
> Why do you set activeTime here, we haven't done it before.

This change makes the progress value is calculated with the stopping point when the elapsed value exceeds the stopping point. Thus, the function will return the progress of the stopping point if the animation stops before the end.

But I missed something in there, the activeTime should be m_intervalEnd - m_intervalBegin. I will upload the new patch if you agree with the approach I wrote.
Comment 10 Young Han Lee 2011-07-07 10:16:32 PDT
Comment on attachment 99330 [details]
Patch

I found a problem in this patch, so I will upload a new one again maybe in this weekend.
Comment 11 Young Han Lee 2011-07-10 09:24:18 PDT
Created attachment 100227 [details]
Patch
Comment 12 Dirk Schulze 2011-07-13 23:59:15 PDT
Comment on attachment 100227 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=100227&action=review

I'm confused about your ChangeLog entry since it is the same entry like on another bug. r- because of the layouttest.

> LayoutTests/svg/animations/script-tests/animate-end-attribute.js:33
> +    ok = isCloseEnough(rect.x.baseVal.value, 200, 0.2);
> +    if (ok)
> +        testPassed("rect.x.baseVal.value is almost 200");
> +    else
> +        testFailed("rect.x.baseVal.value is NOT almost 200, as expected");

Please don't do it manually we have a function called shouldBeCloseEnough() with three arguments. Take a look at other tests.

> LayoutTests/svg/animations/script-tests/animate-end-attribute.js:41
> +    ok = isCloseEnough(rect.x.baseVal.value, 200, 0.2);
> +    if (ok)
> +        testPassed("rect.x.baseVal.value is almost 200");
> +    else
> +        testFailed("rect.x.baseVal.value is NOT almost 200, as expected");

Ditto.

> LayoutTests/svg/animations/script-tests/animate-end-attribute.js:49
> +        ["animation", 2.0,    "rect", sample2],
> +        ["animation", 3.0,    "rect", sample3]

You can reuse sample3 for 2s. Can you please add an animation step at 0s to verify that we start from baseVal?

> Source/WebCore/ChangeLog:9
> +        calculateAnimationPercentAndRepeat() is returning 1, which means 100%, whenever
> +        elapsed >= m_intervalEnd, but this is wrong because m_intervalEnd can be before

Hm, wasn't it fixed with bug 63911?

> Source/WebCore/svg/animation/SVGSMILElement.cpp:833
> +        return 1.f;

just use 1, no .f after numbers.
Comment 13 Young Han Lee 2011-07-17 08:14:13 PDT
Created attachment 101117 [details]
Patch
Comment 14 Young Han Lee 2011-07-17 08:17:19 PDT
(In reply to comment #12)
> (From update of attachment 100227 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=100227&action=review
> 
> I'm confused about your ChangeLog entry since it is the same entry like on another bug. r- because of the layouttest.

Would you check this again?

This changeLog could be difficult to understand, I will rewrite the log if you meant it, but the log is not the same with any other bug's changeLog.

Did you mean it is the same with the changeLog on the first patch I uploaded in this bug?

> 
> > LayoutTests/svg/animations/script-tests/animate-end-attribute.js:33
> > +    ok = isCloseEnough(rect.x.baseVal.value, 200, 0.2);
> > +    if (ok)
> > +        testPassed("rect.x.baseVal.value is almost 200");
> > +    else
> > +        testFailed("rect.x.baseVal.value is NOT almost 200, as expected");
> 
> Please don't do it manually we have a function called shouldBeCloseEnough() with three arguments. Take a look at other tests.

Done.

> 
> > LayoutTests/svg/animations/script-tests/animate-end-attribute.js:41
> > +    ok = isCloseEnough(rect.x.baseVal.value, 200, 0.2);
> > +    if (ok)
> > +        testPassed("rect.x.baseVal.value is almost 200");
> > +    else
> > +        testFailed("rect.x.baseVal.value is NOT almost 200, as expected");
> 
> Ditto.

Done.

> 
> > LayoutTests/svg/animations/script-tests/animate-end-attribute.js:49
> > +        ["animation", 2.0,    "rect", sample2],
> > +        ["animation", 3.0,    "rect", sample3]
> 
> You can reuse sample3 for 2s. Can you please add an animation step at 0s to verify that we start from baseVal?

Done.

> 
> > Source/WebCore/ChangeLog:9
> > +        calculateAnimationPercentAndRepeat() is returning 1, which means 100%, whenever
> > +        elapsed >= m_intervalEnd, but this is wrong because m_intervalEnd can be before
> 
> Hm, wasn't it fixed with bug 63911?

No, bug 63911 doesn't fix a problem related to this bug.
The function is still returning 1, after the bug 63911 is applied.

> 
> > Source/WebCore/svg/animation/SVGSMILElement.cpp:833
> > +        return 1.f;
> 
> just use 1, no .f after numbers.

Done.

Thanks for the comments!
Comment 15 Dirk Schulze 2011-07-20 04:14:56 PDT
Comment on attachment 101117 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=101117&action=review

Sorry for the delay. I'm a bit busy at the moment. r- to get it from pending review list. Needs more discussion.

> Source/WebCore/ChangeLog:10
> +        elapsed >= m_intervalEnd, but this is wrong because m_intervalEnd can be before
> +        the end of the animation. (e.g. begin="0s" end="2s" dur="3s")

I'm confused about this interpretation. For me the ending of the interval is at 3s, even if we end the animation before that time. What about this example:
<rect width="0" height="100">
    <animate attributeName="width" from="0" to="300" begin="0s" dur="3s" end="2s" repeat="3"/>
</rect>

With your interpretation of interval end we would repeat the animation after 2s, not after 3s. I'd interprete the animation with start every 3 seconds but animate just 2 seconds. Maybe I just misunderstand your intention.

> Source/WebCore/ChangeLog:14
> +        This change makes the function return 100% only when
> +        m_intervalEnd - m_intervalBegin == simpleDuration, which means the animation stops
> +        at the end of the animation. This also does some refactoring to remove unnecessary

this sounds more reasonable.

> Source/WebCore/ChangeLog:17
> +        m_intervalEnd - m_intervalBegin. I believe this is more intuitive because the animation
> +        cannot progress beyond it.

Can you add an ASSERT if the animation shouldn't proceed beyond that time?

> Source/WebCore/svg/animation/SVGSMILElement.cpp:826
> +    SMILTime activeTime = min(elapsed, m_intervalEnd) - m_intervalBegin;

Still unsure about this.The variable is called activeTime. Is intervalBegin the relative time from the current repeat level or the absolute time like elapsedTime? It must be the abs time, otherwise it wouldn't make sense anyway. And then activeTime would be the relative time from the current repeated animation. Anyway why do you take intervalEnd if elapsedTime is bigger than elapsedTime? We should differ between the end of animation process (when end=.. is set) and the end of the current interval. Otherwise the example above would repeat every 2s instead of every 3s.
Comment 16 Young Han Lee 2011-07-20 12:13:37 PDT
Created attachment 101494 [details]
Patch
Comment 17 Young Han Lee 2011-07-20 12:17:20 PDT
(In reply to comment #15)
> (From update of attachment 101117 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=101117&action=review
> 
> Sorry for the delay. I'm a bit busy at the moment. r- to get it from pending review list. Needs more discussion.

No problem. I appreciate for the detailed comments :)

> 
> > Source/WebCore/ChangeLog:10
> > +        elapsed >= m_intervalEnd, but this is wrong because m_intervalEnd can be before
> > +        the end of the animation. (e.g. begin="0s" end="2s" dur="3s")
> 
> I'm confused about this interpretation. For me the ending of the interval is at 3s, even if we end the animation before that time. What about this example:
> <rect width="0" height="100">
>     <animate attributeName="width" from="0" to="300" begin="0s" dur="3s" end="2s" repeat="3"/>
> </rect>
> 
> With your interpretation of interval end we would repeat the animation after 2s, not after 3s. I'd interprete the animation with start every 3 seconds but animate just 2 seconds. Maybe I just misunderstand your intention.

The interval indicates a time from the beginning to end of the animation, not one iteration. The important thing is when the animation ends.

Let's see some examples.

<animate attributeName="width" from="0" to="300" begin="0s" dur="3s" end="2s" repeat="3"/>

You misunderstood the end attribute at this example. This animation doesn't repeat. The end attribute means absolute end time of the animation, not the end of the iteration. (You can find similar example with an explanation in here[1].)

So, the end of the interval is at 2s in this case.

<animate attributeName="width" from="0" to="300" begin="0s" dur="3s" repeat="3"/>

In this example, the end of the interval is at 9s because the animation ends at 9s.

<animate attributeName="width" from="0" to="300" begin="0s;10s" dur="3s" repeat="3"/>

Here is the example have more than one interval. As the animation has two begin values, it restarts after the first end. The end of the first interval is at 9s and the end of the second interval is at 19s. Here[2] is an explanation of the begin-time list and interval.

Now, looking my comments. 

+        calculateAnimationPercentAndRepeat() is returning 1, which means 100%, whenever
+        elapsed >= m_intervalEnd, but this is wrong because m_intervalEnd can be before
+        the end of the animation. (e.g. begin="0s" end="2s" dur="3s")

Like examples given above, m_intervalEnd is 2s in this case, so when the elapsed time becomes bigger than 2, the function returns 1, but it should be 0.66.

And the comment has fixed, as m_intervalEnd is just the end of the animation.

[1] http://www.w3.org/TR/smil-animation/#EndActive
[2] http://www.w3.org/TR/smil-animation/#Timing-EvaluationOfBeginEndTimeLists

> 
> > Source/WebCore/ChangeLog:14
> > +        This change makes the function return 100% only when
> > +        m_intervalEnd - m_intervalBegin == simpleDuration, which means the animation stops
> > +        at the end of the animation. This also does some refactoring to remove unnecessary
> 
> this sounds more reasonable.
> 
> > Source/WebCore/ChangeLog:17
> > +        m_intervalEnd - m_intervalBegin. I believe this is more intuitive because the animation
> > +        cannot progress beyond it.
> 
> Can you add an ASSERT if the animation shouldn't proceed beyond that time?

This change has disappeared.

> 
> > Source/WebCore/svg/animation/SVGSMILElement.cpp:826
> > +    SMILTime activeTime = min(elapsed, m_intervalEnd) - m_intervalBegin;
> 
> Still unsure about this.The variable is called activeTime. Is intervalBegin the relative time from the current repeat level or the absolute time like elapsedTime? It must be the abs time, otherwise it wouldn't make sense anyway. And then activeTime would be the relative time from the current repeated animation. Anyway why do you take intervalEnd if elapsedTime is bigger than elapsedTime? We should differ between the end of animation process (when end=.. is set) and the end of the current interval. Otherwise the example above would repeat every 2s instead of every 3s.

Ditto.


I removed the refactoring parts from the patch as it breaks some concepts you told and caused confusion. I should have done this earlier :)
Comment 18 WebKit Review Bot 2011-08-22 11:01:15 PDT
Comment on attachment 101494 [details]
Patch

Clearing flags on attachment: 101494

Committed r93517: <http://trac.webkit.org/changeset/93517>
Comment 19 WebKit Review Bot 2011-08-22 11:01:26 PDT
All reviewed patches have been landed.  Closing bug.
Comment 20 Peter Kasting 2011-08-22 12:52:15 PDT
This patch seems to have broken Chromium Win and GTK Linux.  Both are failing the "close enough to 200" test.

Chromium Win: 196.89999389648438
GTK Linux 32-bit: 196.38299560546875
GTK Linux 64-bit: 197.6179962158203

There are also downstream failures on the Chromium bots:

XP, Vista: 198.39999389648438
Windows 7: 196.8000030517578
Linux: 192.15499877929688
Mac 10.6: 191.6490020751953

I can't tell if the test is being too stringent in its "close enough" check, the code is not doing the correct rounding, the values are being checked at the wrong time, etc.

I'm going to roll back this change.
Comment 21 Peter Kasting 2011-08-22 13:38:49 PDT
Reverted r93517 for reason:

Breaks GTK Linux and Chromium Win

Committed r93532: <http://trac.webkit.org/changeset/93532>
Comment 22 Dirk Schulze 2011-08-23 01:24:12 PDT
(In reply to comment #20)
> This patch seems to have broken Chromium Win and GTK Linux.  Both are failing the "close enough to 200" test.
> 
> Chromium Win: 196.89999389648438
> GTK Linux 32-bit: 196.38299560546875
> GTK Linux 64-bit: 197.6179962158203
> 
> There are also downstream failures on the Chromium bots:
> 
> XP, Vista: 198.39999389648438
> Windows 7: 196.8000030517578
> Linux: 192.15499877929688
> Mac 10.6: 191.6490020751953
> 
> I can't tell if the test is being too stringent in its "close enough" check, the code is not doing the correct rounding, the values are being checked at the wrong time, etc.
> 
> I'm going to roll back this change.

Hi Peter. Which test (tests) failed after committing Young Hans patch?
Comment 23 Young Han Lee 2011-08-23 10:07:23 PDT
> 
> Hi Peter. Which test (tests) failed after committing Young Hans patch?

It must be the new test I added in this patch. I just reproduced the failure in my GTK port.

I don't know why it is failing as it passed when I upload the patch. There could be some changes landed recently which affect the test.

Anyway, I will find out the problem within this week.
Comment 24 Peter Kasting 2011-08-23 11:00:16 PDT
(In reply to comment #23)
> > Hi Peter. Which test (tests) failed after committing Young Hans patch?
> 
> It must be the new test I added in this patch.

Yes, sorry I wasn't clearer.
Comment 25 Young Han Lee 2011-08-27 06:55:36 PDT
Created attachment 105436 [details]
Patch

animate.setAttribute("begin", "click");
animate.setAttribute("end", "2s");

The test was wrong. The SVG animation in the test started when a 'click' event occurs and ended at '2s'. It was a mistake because I actually wanted to stop the animation 2 seconds after the animation starts. I changed the test as follows.

animate.setAttribute("begin", "click");
animate.setAttribute("end", "click+2s");
Comment 26 Dirk Schulze 2011-08-27 10:08:41 PDT
Comment on attachment 105436 [details]
Patch

Change in the test makes sense. r=me.
Comment 27 WebKit Review Bot 2011-08-27 11:09:21 PDT
Comment on attachment 105436 [details]
Patch

Clearing flags on attachment: 105436

Committed r93938: <http://trac.webkit.org/changeset/93938>
Comment 28 WebKit Review Bot 2011-08-27 11:09:30 PDT
All reviewed patches have been landed.  Closing bug.