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
cc / animation / keyframe_model.h [blame]
// Copyright 2012 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_KEYFRAME_MODEL_H_
#define CC_ANIMATION_KEYFRAME_MODEL_H_
#include <memory>
#include <string>
#include "base/check.h"
#include "base/time/time.h"
#include "cc/animation/animation_export.h"
#include "cc/paint/element_id.h"
#include "cc/paint/paint_worklet_input.h"
#include "ui/gfx/animation/keyframe/keyframe_model.h"
namespace cc {
// A KeyframeModel contains all the state required to play an AnimationCurve.
// Specifically, the affected property, the run state (paused, finished, etc.),
// loop count, last pause time, and the total time spent paused.
// It represents a model of the keyframes (internally represented as a curve).
class CC_ANIMATION_EXPORT KeyframeModel : public gfx::KeyframeModel {
public:
static const KeyframeModel* ToCcKeyframeModel(
const gfx::KeyframeModel* keyframe_model);
static KeyframeModel* ToCcKeyframeModel(gfx::KeyframeModel* keyframe_model);
static const int kInvalidGroup = -1;
// Bundles a property id with its name and native type.
class CC_ANIMATION_EXPORT TargetPropertyId {
public:
// For a property that is neither TargetProperty::CSS_CUSTOM_PROPERTY nor
// TargetProperty::NATIVE_PROPERTY.
explicit TargetPropertyId(int target_property_type);
// For TargetProperty::CSS_CUSTOM_PROPERTY, the string is the custom
// property name.
TargetPropertyId(int target_property_type,
const std::string& custom_property_name);
// For TargetProperty::NATIVE_PROPERTY.
TargetPropertyId(
int target_property_type,
PaintWorkletInput::NativePropertyType native_property_type);
TargetPropertyId(const TargetPropertyId&);
TargetPropertyId(TargetPropertyId&&);
~TargetPropertyId();
TargetPropertyId& operator=(TargetPropertyId&& other);
int target_property_type() const { return target_property_type_; }
const std::string& custom_property_name() const {
return custom_property_name_;
}
PaintWorkletInput::NativePropertyType native_property_type() const {
return native_property_type_;
}
private:
int target_property_type_;
// Name of the animated custom property. Empty if it is an animated native
// property.
std::string custom_property_name_;
// Type of the animated native property.
PaintWorkletInput::NativePropertyType native_property_type_;
};
static std::unique_ptr<KeyframeModel> Create(
std::unique_ptr<gfx::AnimationCurve> curve,
int keyframe_model_id,
int group_id,
TargetPropertyId target_property_id);
std::unique_ptr<KeyframeModel> CreateImplInstance(
RunState initial_run_state) const;
KeyframeModel(const KeyframeModel&) = delete;
~KeyframeModel() override;
KeyframeModel& operator=(const KeyframeModel&) = delete;
int group() const { return group_; }
void ungroup() { group_ = kInvalidGroup; }
int TargetProperty() const override;
void SetRunState(RunState run_state, base::TimeTicks monotonic_time) override;
ElementId element_id() const { return element_id_; }
void set_element_id(ElementId element_id) { element_id_ = element_id; }
bool InEffect(base::TimeTicks monotonic_time) const;
// If this is true, even if the keyframe model is running, it will not be
// tickable until it is given a start time. This is true for KeyframeModels
// running on the main thread.
bool needs_synchronized_start_time() const {
return needs_synchronized_start_time_;
}
void set_needs_synchronized_start_time(bool needs_synchronized_start_time) {
needs_synchronized_start_time_ = needs_synchronized_start_time;
}
// This is true for KeyframeModels running on the main thread when the
// FINISHED event sent by the corresponding impl keyframe model has been
// received.
bool received_finished_event() const { return received_finished_event_; }
void set_received_finished_event(bool received_finished_event) {
received_finished_event_ = received_finished_event;
}
void set_is_controlling_instance_for_test(bool is_controlling_instance) {
is_controlling_instance_ = is_controlling_instance;
}
bool is_controlling_instance() const { return is_controlling_instance_; }
void PushPropertiesTo(KeyframeModel* other) const;
std::string ToString() const;
void SetIsImplOnly();
bool is_impl_only() const { return is_impl_only_; }
void set_affects_active_elements(bool affects_active_elements) {
affects_active_elements_ = affects_active_elements;
}
bool affects_active_elements() const { return affects_active_elements_; }
void set_affects_pending_elements(bool affects_pending_elements) {
affects_pending_elements_ = affects_pending_elements;
}
bool affects_pending_elements() const { return affects_pending_elements_; }
const std::string& custom_property_name() const {
return target_property_id_.custom_property_name();
}
PaintWorkletInput::NativePropertyType native_property_type() const {
return target_property_id_.native_property_type();
}
bool StartShouldBeDeferred() const override;
private:
KeyframeModel(std::unique_ptr<gfx::AnimationCurve> curve,
int keyframe_model_id,
int group_id,
TargetPropertyId target_property_id);
// KeyframeModels that must be run together are called 'grouped' and have the
// same group id. Grouped KeyframeModels are guaranteed to start at the same
// time and no other KeyframeModels may animate any of the group's target
// properties until all KeyframeModels in the group have finished animating.
int group_;
TargetPropertyId target_property_id_;
// If specified, overrides the ElementId to apply this KeyframeModel's effect
// value on.
ElementId element_id_;
#if DCHECK_IS_ON()
// This id is unique, modulo overflow. Permits quick instance equality checks.
int debug_id_ = 0;
#endif
bool needs_synchronized_start_time_;
bool received_finished_event_;
// KeyframeModels lead dual lives. An active keyframe model will be
// conceptually owned by two controllers, one on the impl thread and one on
// the main. In reality, there will be two separate KeyframeModel instances
// for the same keyframe model. They will have the same group id and the same
// target property (these two values uniquely identify a keyframe model). The
// instance on the impl thread is the instance that ultimately controls the
// values of the animating layer and so we will refer to it as the
// 'controlling instance'.
// Impl only keyframe models are the exception to this rule. They have only a
// single instance. We consider this instance as the 'controlling instance'.
bool is_controlling_instance_;
bool is_impl_only_;
// When pushed from a main-thread controller to a compositor-thread
// controller, a keyframe model will initially only affect pending elements
// (corresponding to layers in the pending tree). KeyframeModels that only
// affect pending elements are able to reach the STARTING state and tick
// pending elements, but cannot proceed any further and do not tick active
// elements. After activation, such KeyframeModels affect both kinds of
// elements and are able to proceed past the STARTING state. When the removal
// of a keyframe model is pushed from a main-thread controller to a
// compositor-thread controller, this initially only makes the keyframe model
// stop affecting pending elements. After activation, such KeyframeModels no
// longer affect any elements, and are deleted.
bool affects_active_elements_;
bool affects_pending_elements_;
};
} // namespace cc
#endif // CC_ANIMATION_KEYFRAME_MODEL_H_