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
cc / animation / animation.h [blame]
// 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_