The lifetime of a newly started cc::Animation is roughly the following:
- An update to style or a new animation triggers a new BeginMainFrame via ScheduleVisualUpdate.
- blink::DocumentAnimations::UpdateAnimations calls blink::Animation::PreCommit on each pending blink::Animation constructing the corresponding cc::Animation via blink::Animation::CreateCompositorAnimation (attaching the animation to the cc::AnimationTimeline resulting in it being later pushed). The KeyframeEffects are constructed via blink::Animation::StartAnimationOnCompositor.
- AnimationHost::RegisterKeyframeEffectForElement creates a cc::ElementAnimations for the target
element_id
if one does not already exist. This ElementAnimations instance is shared by all animations with the same target and tracks the existence of the target. - During the commit, cc::ElementAnimations::ElementRegistered is called on the main thread's AnimationHost either:
- Before BlinkGenPropertyTrees, when a layer with the target
element_id
is registered. - After BlinkGenPropertyTrees, after a property tree node with the target
element_id
is created on the main thread LayerTreeHost's property_trees_
. This begins ticking the attached KeyframeEffects and tracks that the element exists in the active layer / property tree.
- cc::LayerTreeHost::FinishCommitOnImplThread calls cc::AnimationHost::PushPropertiesTo which results in cc::AnimationTimeline::PushAttachedAnimationsToImplThread creating a cc::Animation on the compositor thread's AnimationTimeline for each animation missing from the compositor thread.
- cc::Animation::PushPropertiesTo is called on every animation on the timeline. When the
element_id
is pushed by cc::KeyframeEffect::PushPropertiesTo cc::Animation::AttachElementForKeyframeEffect creates a compositor side cc::ElementAnimations instance to track the existence of the element on the compositor. Since animations are pushed after the layer and property trees, the element should already exist on the pending tree. This will result in the animation being added to the ticking animations list. - Now the animation is ticking, meaning that cc::Animation::Tick will be called every frame and update the pending property tree nodes.
- When the pending tree is activated, cc::AnimationHost::ActivateAnimations updates the keyframe effects and cc::ElementAnimations::ElementRegistered is called for the newly added element id on the active tree, setting
has_element_in_active_list_
. - Subsequent animation ticks will now update the property nodes on the active tree.
Animation Events
The purpose of animation events (cc::AnimationEvent, not to confuse with blink::AnimationEvent) is to synchronize animation state from cc::animation to its client. The typical life cycle of the events is:
- Event Generation. Events are generated on IMPL thread and collected into cc::AnimationEvents container. cc::AnimationEvents are passed to the MAIN thread as part of BeginMainFrame arguments.
- Event Dispatch. On the MAIN thread events are dispatched to cc::KeyframeModels to ensure they are synchronized to their counterparts on the IMPL side. TIME_UPDATED events skip this step since cc::KeyframeModels of worklet animations don't participate in generating and reacting to these events.
- Event Delegation. After the events are dispatched, they are delegated to cc::AnimationDelegate, the final destination of the events on cc:animation's client.
There is a special type of events called impl_only events. They are generated by animations that are running on IMPL thread only. These events are not passed to the MAIN thread and skip dispatch stage. They are delegated to the cc::AnimationDelegate on the IMPL thread.
TODO(flackr): Document finishing / cancel / abort.
Interaction between cc/animation and ui/
TODO(smcgruer): Write this.
Additional References
The Compositor Property Trees talk slides includes discussion on compositor animations.
The Project Heaviside design document and slides provide history on the Chromium and Blink animation system. The slides in particular include helpful software architecture diagrams.
Smooth scrolling is implemented via animations. See also references to “scroll offset” animations in the cc code base. Smooth Scrolling in Chromium provides an overview of smooth scrolling. There is further class header documentation in Blink's platform/scroll directory.