blob: fe0a875ffe9e370236ecbd287d5a2198476f0a2c [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <vector>
#include <memory>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "cc/animation/animation_curve.h"
#include "cc/animation/animation_export.h"
#include "cc/animation/element_animations.h"
#include "cc/animation/keyframe_model.h"
#include "cc/trees/element_id.h"
namespace cc {
class AnimationDelegate;
class AnimationEvents;
class AnimationHost;
class AnimationTimeline;
class KeyframeEffect;
struct AnimationEvent;
// An Animation is responsible for managing animating properties for a set of
// targets. Each target is represented by a KeyframeEffect and can be animating
// multiple properties on that target; see the KeyframeEffect class.
// A particular Animation may not own all the KeyframeEffects for a given
// target. Animation is only a grouping mechanism for related effects, and the
// grouping relationship is defined by the client. It is also the client's
// responsibility to deal with any conflicts that arise from animating the same
// property of the same target across multiple Animations.
// Each Animation has a copy on the impl thread, and will take care of
// synchronizing to/from the impl thread when requested.
class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
static scoped_refptr<Animation> Create(int id);
virtual scoped_refptr<Animation> CreateImplInstance() const;
int id() const { return id_; }
typedef size_t KeyframeEffectId;
ElementId element_id_of_keyframe_effect(
KeyframeEffectId keyframe_effect_id) const;
bool IsElementAttached(ElementId id) const;
// Parent AnimationHost. Animation can be detached from AnimationTimeline.
AnimationHost* animation_host() { return animation_host_; }
const AnimationHost* animation_host() const { return animation_host_; }
void SetAnimationHost(AnimationHost* animation_host);
bool has_animation_host() const { return !!animation_host_; }
// Parent AnimationTimeline.
AnimationTimeline* animation_timeline() { return animation_timeline_; }
const AnimationTimeline* animation_timeline() const {
return animation_timeline_;
virtual void SetAnimationTimeline(AnimationTimeline* timeline);
// TODO(smcgruer): If/once ScrollTimeline is supported on normal Animations,
// we will need to move the promotion logic from WorkletAnimation to here.
virtual void PromoteScrollTimelinePendingToActive() {}
bool has_element_animations() const;
scoped_refptr<ElementAnimations> element_animations(
KeyframeEffectId keyframe_effect_id) const;
void set_animation_delegate(AnimationDelegate* delegate) {
animation_delegate_ = delegate;
void AttachElementForKeyframeEffect(ElementId element_id,
KeyframeEffectId keyframe_effect_id);
void DetachElementForKeyframeEffect(ElementId element_id,
KeyframeEffectId keyframe_effect_id);
virtual void DetachElement();
void AddKeyframeModelForKeyframeEffect(
std::unique_ptr<KeyframeModel> keyframe_model,
KeyframeEffectId keyframe_effect_id);
void PauseKeyframeModelForKeyframeEffect(int keyframe_model_id,
double time_offset,
KeyframeEffectId keyframe_effect_id);
void RemoveKeyframeModelForKeyframeEffect(
int keyframe_model_id,
KeyframeEffectId keyframe_effect_id);
void AbortKeyframeModelForKeyframeEffect(int keyframe_model_id,
KeyframeEffectId keyframe_effect_id);
void AbortKeyframeModelsWithProperty(TargetProperty::Type target_property,
bool needs_completion);
virtual void PushPropertiesTo(Animation* animation_impl);
void UpdateState(bool start_ready_keyframe_models, AnimationEvents* events);
virtual void Tick(base::TimeTicks monotonic_time);
void AddToTicking();
void KeyframeModelRemovedFromTicking();
// AnimationDelegate routing.
void NotifyKeyframeModelStarted(const AnimationEvent& event);
void NotifyKeyframeModelFinished(const AnimationEvent& event);
void NotifyKeyframeModelAborted(const AnimationEvent& event);
void NotifyKeyframeModelTakeover(const AnimationEvent& event);
size_t TickingKeyframeModelsCount() const;
void SetNeedsPushProperties();
// Make KeyframeModels affect active elements if and only if they affect
// pending elements. Any KeyframeModels that no longer affect any elements
// are deleted.
void ActivateKeyframeEffects();
// Returns the keyframe model animating the given property that is either
// running, or is next to run, if such a keyframe model exists.
KeyframeModel* GetKeyframeModelForKeyframeEffect(
TargetProperty::Type target_property,
KeyframeEffectId keyframe_effect_id) const;
std::string ToString() const;
void SetNeedsCommit();
virtual bool IsWorkletAnimation() const;
void AddKeyframeEffect(std::unique_ptr<KeyframeEffect>);
KeyframeEffect* GetKeyframeEffectById(
KeyframeEffectId keyframe_effect_id) const;
KeyframeEffectId NextKeyframeEffectId() { return keyframe_effects_.size(); }
friend class base::RefCounted<Animation>;
void RegisterKeyframeEffect(ElementId element_id,
KeyframeEffectId keyframe_effect_id);
void UnregisterKeyframeEffect(ElementId element_id,
KeyframeEffectId keyframe_effect_id);
void RegisterKeyframeEffects();
void UnregisterKeyframeEffects();
void PushAttachedKeyframeEffectsToImplThread(Animation* animation_impl) const;
void PushPropertiesToImplThread(Animation* animation_impl);
explicit Animation(int id);
virtual ~Animation();
AnimationHost* animation_host_;
AnimationTimeline* animation_timeline_;
AnimationDelegate* animation_delegate_;
int id_;
using ElementToKeyframeEffectIdMap =
using KeyframeEffects = std::vector<std::unique_ptr<KeyframeEffect>>;
// It is possible for a keyframe_effect to be in keyframe_effects_ but not in
// element_to_keyframe_effect_id_map_ but the reverse is not possible.
ElementToKeyframeEffectIdMap element_to_keyframe_effect_id_map_;
KeyframeEffects keyframe_effects_;
int ticking_keyframe_effects_count;
} // namespace cc