1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CC_ANIMATION_WORKLET_ANIMATION_H_
6 #define CC_ANIMATION_WORKLET_ANIMATION_H_
7
8 #include "base/gtest_prod_util.h"
9 #include "base/optional.h"
10 #include "base/time/time.h"
11 #include "cc/animation/animation.h"
12 #include "cc/animation/animation_export.h"
13 #include "cc/animation/animation_host.h"
14 #include "cc/trees/property_tree.h"
15
16 namespace cc {
17
18 namespace {
19 FORWARD_DECLARE_TEST(WorkletAnimationTest, NonImplInstanceDoesNotTickKeyframe);
20 } // namespace
21
22 class AnimationOptions;
23 class AnimationEffectTimings;
24
25 // A WorkletAnimation is an animation that allows its animation
26 // timing to be controlled by an animator instance that is running in a
27 // AnimationWorkletGlobalScope.
28
29 // Two instances of this class are created for Blink WorkletAnimation:
30 // 1. UI thread instance that keeps all the meta data.
31 // 2. Impl thread instance that ticks the animations on the Impl thread.
32 // When Blink WorkletAnimation is updated, it calls the UI thread instance to
33 // modify its properties. The updated properties are pushed by the UI thread
34 // instance to the Impl thread instance during commit.
35 class CC_ANIMATION_EXPORT WorkletAnimation final : public Animation {
36 public:
37 enum class State { PENDING, RUNNING, REMOVED };
38 WorkletAnimation(int cc_animation_id,
39 WorkletAnimationId worklet_animation_id,
40 const std::string& name,
41 double playback_rate,
42 std::unique_ptr<AnimationOptions> options,
43 std::unique_ptr<AnimationEffectTimings> effect_timings,
44 bool is_controlling_instance);
45 static scoped_refptr<WorkletAnimation> Create(
46 WorkletAnimationId worklet_animation_id,
47 const std::string& name,
48 double playback_rate,
49 std::unique_ptr<AnimationOptions> options,
50 std::unique_ptr<AnimationEffectTimings> effect_timings);
51 scoped_refptr<Animation> CreateImplInstance() const override;
52
worklet_animation_id()53 WorkletAnimationId worklet_animation_id() { return worklet_animation_id_; }
name()54 const std::string& name() const { return name_; }
55
56 bool IsWorkletAnimation() const override;
57
58 void Tick(base::TimeTicks monotonic_time) override;
59
60 void UpdateState(bool start_ready_animations,
61 AnimationEvents* events) override;
62
63 void TakeTimeUpdatedEvent(AnimationEvents* events) override;
64 void UpdateInputState(MutatorInputState* input_state,
65 base::TimeTicks monotonic_time,
66 const ScrollTree& scroll_tree,
67 bool is_active_tree);
68 void SetOutputState(const MutatorOutputState::AnimationState& state);
69
70 void PushPropertiesTo(Animation* animation_impl) override;
71
72 // Called by Blink WorkletAnimation when its playback rate is updated.
73 void UpdatePlaybackRate(double playback_rate);
SetPlaybackRateForTesting(double playback_rate)74 void SetPlaybackRateForTesting(double playback_rate) {
75 SetPlaybackRate(playback_rate);
76 }
77
78 void RemoveKeyframeModel(int keyframe_model_id) override;
ReleasePendingTreeLock()79 void ReleasePendingTreeLock() { has_pending_tree_lock_ = false; }
80
81 private:
82 FRIEND_TEST_ALL_PREFIXES(WorkletAnimationTest,
83 NonImplInstanceDoesNotTickKeyframe);
84 WorkletAnimation(int cc_animation_id,
85 WorkletAnimationId worklet_animation_id,
86 const std::string& name,
87 double playback_rate,
88 std::unique_ptr<AnimationOptions> options,
89 std::unique_ptr<AnimationEffectTimings> effect_timings,
90 bool is_controlling_instance,
91 std::unique_ptr<KeyframeEffect> effect);
92
93 ~WorkletAnimation() override;
94
95 // Returns the current time to be passed into the underlying AnimationWorklet.
96 // The current time is based on the timeline associated with the animation and
97 // in case of scroll timeline it may be nullopt when the associated scrolling
98 // node is not available in the particular ScrollTree.
99 base::Optional<base::TimeDelta> CurrentTime(base::TimeTicks monotonic_time,
100 const ScrollTree& scroll_tree,
101 bool is_active_tree);
102
103 // Returns true if the worklet animation needs to be updated which happens iff
104 // its current time is going to be different from last time given these input.
105 bool NeedsUpdate(base::TimeTicks monotonic_time,
106 const ScrollTree& scroll_tree,
107 bool is_active_tree);
108
CloneOptions()109 std::unique_ptr<AnimationOptions> CloneOptions() const {
110 return options_ ? options_->Clone() : nullptr;
111 }
112
CloneEffectTimings()113 std::unique_ptr<AnimationEffectTimings> CloneEffectTimings() const {
114 return effect_timings_ ? effect_timings_->Clone() : nullptr;
115 }
116
117 // Updates the playback rate of the Impl thread instance.
118 // Called by the UI thread WorkletAnimation instance during commit.
119 void SetPlaybackRate(double playback_rate);
120
121 bool IsTimelineActive(const ScrollTree& scroll_tree,
122 bool is_active_tree) const;
123
124 WorkletAnimationId worklet_animation_id_;
125 std::string name_;
126
127 // Controls speed of the animation.
128 // https://drafts.csswg.org/web-animations-2/#animation-effect-playback-rate
129
130 // For UI thread instance contains the meta value to be pushed to the Impl
131 // thread instance.
132 // For the Impl thread instance contains the actual playback rate of the
133 // animation.
134 double playback_rate_;
135
136 std::unique_ptr<AnimationOptions> options_;
137 std::unique_ptr<AnimationEffectTimings> effect_timings_;
138
139 // Local time is used as an input to the keyframe effect of this animation.
140 // The value comes from the user script that runs inside the animation worklet
141 // global scope.
142 base::Optional<base::TimeDelta> local_time_;
143 // Local time passed to the main thread worklet animation to update its
144 // keyframe effect. We only set the most recent local time, meaning that if
145 // there are multiple compositor frames without a single main frame only
146 // the local time associated with the latest frame is sent to the main thread.
147 base::Optional<base::TimeDelta> last_synced_local_time_;
148
149 base::Optional<base::TimeTicks> start_time_;
150
151 // Last current time used for updating. We use this to skip updating if
152 // current time has not changed since last update.
153 base::Optional<base::TimeDelta> last_current_time_;
154
155 // To ensure that 'time' progresses forward for scroll animations, we guard
156 // against allowing active tree mutations while the pending tree has a
157 // lock in the worklet. The lock is established when updating the input state
158 // for the pending tree and release on pending tree activation.
159 bool has_pending_tree_lock_;
160 State state_;
161
162 bool is_impl_instance_;
163 };
164
ToWorkletAnimation(Animation * animation)165 inline WorkletAnimation* ToWorkletAnimation(Animation* animation) {
166 DCHECK(animation->IsWorkletAnimation());
167 return static_cast<WorkletAnimation*>(animation);
168 }
169
170 } // namespace cc
171
172 #endif // CC_ANIMATION_WORKLET_ANIMATION_H_
173