1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_ANIMATION_ANIMATION_H_
#define CC_ANIMATION_ANIMATION_H_
#include <memory>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "cc/animation/animation_export.h"
#include "cc/animation/element_animations.h"
#include "cc/animation/keyframe_model.h"
#include "cc/base/protected_sequence_synchronizer.h"
#include "cc/paint/element_id.h"
#include "ui/gfx/animation/keyframe/animation_curve.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.
//
// There is a 1:1 relationship between Animation and KeyframeEffect.
class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation>,
public ProtectedSequenceSynchronizer {
public:
static scoped_refptr<Animation> Create(int id);
virtual scoped_refptr<Animation> CreateImplInstance() const;
Animation(const Animation&) = delete;
Animation& operator=(const Animation&) = delete;
int id() const { return id_; }
ElementId element_id() const;
KeyframeEffect* keyframe_effect() {
return keyframe_effect_.Write(*this).get();
}
const KeyframeEffect* keyframe_effect() const {
return keyframe_effect_.Read(*this);
}
// Parent AnimationHost. Animation can be detached from AnimationTimeline.
AnimationHost* animation_host() {
DCHECK(IsOwnerThread() || InProtectedSequence());
return animation_host_;
}
const AnimationHost* animation_host() const {
DCHECK(IsOwnerThread() || InProtectedSequence());
return animation_host_;
}
void SetAnimationHost(AnimationHost* animation_host);
bool has_animation_host() const { return !!animation_host(); }
// Parent AnimationTimeline.
AnimationTimeline* animation_timeline() {
return animation_timeline_.Read(*this);
}
const AnimationTimeline* animation_timeline() const {
return animation_timeline_.Read(*this);
}
void SetAnimationTimeline(AnimationTimeline* timeline);
scoped_refptr<const ElementAnimations> element_animations() const;
void set_animation_delegate(AnimationDelegate* delegate) {
animation_delegate_ = delegate;
}
void AttachElement(ElementId element_id);
void AttachPaintWorkletElement();
void DetachElement();
void AddKeyframeModel(std::unique_ptr<KeyframeModel> keyframe_model);
void PauseKeyframeModel(int keyframe_model_id, base::TimeDelta time_offset);
virtual void RemoveKeyframeModel(int keyframe_model_id);
void AbortKeyframeModel(int keyframe_model_id);
void NotifyKeyframeModelFinishedForTesting(
int timeline_id,
int keyframe_model_id,
TargetProperty::Type target_property,
int group_id);
void AbortKeyframeModelsWithProperty(TargetProperty::Type target_property,
bool needs_completion);
virtual void PushPropertiesTo(Animation* animation_impl);
virtual void UpdateState(bool start_ready_keyframe_models,
AnimationEvents* events);
// Adds TIME_UPDATED event generated in the current frame to the given
// animation events.
virtual void TakeTimeUpdatedEvent(AnimationEvents* events) {}
virtual bool Tick(base::TimeTicks tick_time);
bool IsScrollLinkedAnimation() const;
void AddToTicking();
void RemoveFromTicking();
// Dispatches animation event to the animation keyframe effect and model when
// appropriate, based on the event characteristics.
// Delegates animation event that was successfully dispatched or doesn't need
// to be dispatched.
void DispatchAndDelegateAnimationEvent(const AnimationEvent& event);
// Returns true if this animation effects pending tree, such as a custom
// property animation with paint worklet.
bool RequiresInvalidation() const;
// Returns true if this animation effects active tree, such as a transform
// animation.
bool AffectsNativeProperty() 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 ActivateKeyframeModels();
// Returns the keyframe model animating the given property that is either
// running, or is next to run, if such a keyframe model exists.
KeyframeModel* GetKeyframeModel(TargetProperty::Type target_property) const;
std::string ToString() const;
void SetNeedsCommit();
void set_is_replacement() { is_replacement_ = true; }
std::optional<base::TimeTicks> GetStartTime() const;
virtual bool IsWorkletAnimation() const;
void SetKeyframeEffectForTesting(std::unique_ptr<KeyframeEffect>);
// ProtectedSequenceSynchronizer implementation
bool IsOwnerThread() const override;
bool InProtectedSequence() const override;
void WaitForProtectedSequenceCompletion() const override;
private:
friend class base::RefCounted<Animation>;
void RegisterAnimation();
void UnregisterAnimation();
// Delegates animation event
void DelegateAnimationEvent(const AnimationEvent& event);
// Common code between AttachElement and AttachNoElement.
void AttachElementInternal(ElementId element_id);
protected:
explicit Animation(int id);
~Animation() override;
raw_ptr<AnimationDelegate> animation_delegate_ = nullptr;
const int id_;
private:
// If this Animation was created to replace an existing one of the same id,
// it should take the start time from the impl instance before replacing it,
// since the start time may not yet have been committed back to the client at
// the time the animation was restarted. The client sets this bit to true
// when such an animation is created so that the first commit pulls the start
// time into this Animation before pushing it.
//
// When this animation is pushed to the impl thread, it will update the
// existing Animation and KeyframeEffect rather than creating new ones. It
// will silently replace the effect's keyframe models with the new ones
// specified in this animation.
//
// Used only from the main thread and isn't synced to the compositor thread.
bool is_replacement_ = false;
// Animation's ProtectedSequenceSynchronizer implementation is implemented
// using this member. As such the various helpers can not be used to protect
// access (otherwise we would get infinite recursion).
raw_ptr<AnimationHost> animation_host_ = nullptr;
ProtectedSequenceReadable<raw_ptr<AnimationTimeline>> animation_timeline_{
nullptr};
ProtectedSequenceWritable<std::unique_ptr<KeyframeEffect>> keyframe_effect_;
};
} // namespace cc
#endif // CC_ANIMATION_ANIMATION_H_
|