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