RESOLVED FIXED 25108
Animation timer can keep firing after accelerated transitions finish
https://bugs.webkit.org/show_bug.cgi?id=25108
Summary Animation timer can keep firing after accelerated transitions finish
Simon Fraser (smfr)
Reported 2009-04-08 21:53:26 PDT
There's a problem in the animation code that seems to only show up with accelerated compositing turned on. In some cases, the updateAnimationTimer() can keep firing, even when a transition has finished. I'll attach a testcase.
Attachments
Testcase (942 bytes, text/html)
2009-04-08 21:54 PDT, Simon Fraser (smfr)
no flags
Patch (5.16 KB, patch)
2009-04-10 11:35 PDT, Chris Marrin
simon.fraser: review-
Revised patch (10.16 KB, patch)
2009-04-10 14:33 PDT, Simon Fraser (smfr)
mitz: review+
Simon Fraser (smfr)
Comment 1 2009-04-08 21:54:10 PDT
Created attachment 29357 [details] Testcase You'll have to put a breakpoint in updateAnimationTimer() after the transition finishes in order to see the problem.
Simon Fraser (smfr)
Comment 2 2009-04-08 21:56:56 PDT
The problem seems to occur because animation controller assumes that calling setChanged() on a node will result in a subsequent call to CompositeAnimation::animate() for the appropriate renderer; that method can then call cleanupFinishedAnimations(). However, in this testcase, AnimationController::updateAnimations() is returning early, because neither oldStyle nor newStyle contain animations or transitions. I'm not sure how this can be, yet.
Simon Fraser (smfr)
Comment 3 2009-04-08 22:06:16 PDT
Ah, this happens when the transition styles are removed before the transition ends.
Chris Marrin
Comment 4 2009-04-10 11:35:27 PDT
Darin Adler
Comment 5 2009-04-10 13:44:01 PDT
Comment on attachment 29394 [details] Patch > + // We can now safely remove any animations or transitions that are finished. > + // We can't remove them any earlier because we might get a false restart of > + // a transition. This can happen because we have not yet set the final property > + // value until we call the rendering dispatcher. So this can make the current > + // style slightly different from the desired final style (because our last > + // animation step was, say 0.9999 or something). And we need to remove them > + // here because if there are no more animations running we'll never get back > + // into the animation code to clean them up. > + RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end(); > + for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) { > + RefPtr<CompositeAnimation> compAnim = it->second; > + compAnim->cleanupFinishedAnimations(); > + } Is there a guarantee that the cleanupFinishedAnimations function and the functions it calls won't result in a change to m_compositeAnimations? If not, then we'll need to copy the animations out of the map before iterating them, because you can't safely iterate a hash table if it might change. This unnecessarily thrashes the reference count of the CompositeAnimation object. The local variable should be a raw pointer, or be eliminated entirely. review- because of these two issues
Simon Fraser (smfr)
Comment 6 2009-04-10 14:16:56 PDT
Comment on attachment 29394 [details] Patch Ooops, we had a mid-air conflict. I'll clean up and re-submit the patch.
Simon Fraser (smfr)
Comment 7 2009-04-10 14:33:55 PDT
Created attachment 29398 [details] Revised patch I fixed some other lines to reduce ref churn while iterating, and added a comment that cleanupFinishedAnimations() will never affect m_compositeAnimations.
Simon Fraser (smfr)
Comment 8 2009-04-10 16:27:12 PDT
Note You need to log in before you can comment on or make changes to this bug.