Bug 22738

Summary: Get rid of animation start, end and iteration timers
Product: WebKit Reporter: Chris Marrin <cmarrin>
Component: CSSAssignee: Chris Marrin <cmarrin>
Status: RESOLVED FIXED    
Severity: Normal CC: simon.fraser
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Mac   
OS: OS X 10.5   
Attachments:
Description Flags
Patch to fix bug hyatt: review+

Description Chris Marrin 2008-12-08 11:05:13 PST
Today, each animation or transition has a timer which fires 2 or more times per animation. The start timer always fires when the delay time is up. This is true even with a 0 delay - the timer fires as soon as possible. An end timer always fires as well when the duration is up, unless it is a repeating animation, in which case the timer fires after each iteration. 

These timers are used not only to send the animation events as needed, but they update the state machine as well. But they are really unnecessary because the AnimationController is already running a timer to do the animations themselves. So this timer can serve the purpose of handling state machine changes and event generation.

This will not only be more efficient (one timer per document, rather than one timer per animation), but it will make it easier to deal with other issues on my plate, such as synchronizing multiple animations and making sure the end animation callback comes at the correct instant rather than several hundred ms later, which is sometimes the case today.
Comment 1 Chris Marrin 2008-12-08 12:00:28 PST
Created attachment 25848 [details]
Patch to fix bug

        Fixed https://bugs.webkit.org/show_bug.cgi?id=22738

        This gets rid of the per-animation timers which were used when an animation
        started, ended and looped. Their job is now done by the main AnimationController's
        timer. It is now set to fire as needed. For instance, if there is a delay, it will
        fire after the delay time and then every 30ms to run the animation. The start, loop
        and end events are generated as needed during the firing of this timer.

        I had to add one more bit of code. When animation timers used to fire the animation events.
        This would always happen from the RunLoop, so any style changes that happened in the
        event handler would get picked up on the next updateRendering() call. But now the start
        event is generated during the styleIsAvailable() call, which is in the middle of the 
        updateRendering() cycle. And calling an event handler in the middle of updateRendering()
        is not allowed and causes style changes to get missed. We already have a mechanism in
        AnimationController to defer updateRendering() calls. So I added logic to defer all
        event handling to there. Now, I put any request for event handling into a list and ask
        for a deferred updateRendering() call. When that deferred timer fires, I go through that
        list, send all the events and then call updateRendering().
Comment 2 Dave Hyatt 2008-12-10 14:39:14 PST
Comment on attachment 25848 [details]
Patch to fix bug

r=me
Comment 3 Chris Marrin 2008-12-11 08:25:02 PST
Sending        WebCore/ChangeLog
Sending        WebCore/page/animation/AnimationBase.cpp
Sending        WebCore/page/animation/AnimationBase.h
Sending        WebCore/page/animation/AnimationController.cpp
Sending        WebCore/page/animation/AnimationController.h
Sending        WebCore/page/animation/CompositeAnimation.cpp
Sending        WebCore/page/animation/CompositeAnimation.h
Sending        WebCore/page/animation/ImplicitAnimation.cpp
Sending        WebCore/page/animation/ImplicitAnimation.h
Sending        WebCore/page/animation/KeyframeAnimation.cpp
Sending        WebCore/page/animation/KeyframeAnimation.h
Transmitting file data ...........
Committed revision 39211.