1 // Copyright 2015 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_ANIMATION_HOST_H_
6 #define CC_ANIMATION_ANIMATION_HOST_H_
7 
8 #include <memory>
9 #include <unordered_map>
10 #include <vector>
11 
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/time/time.h"
15 #include "cc/animation/animation_export.h"
16 #include "cc/animation/keyframe_model.h"
17 #include "cc/trees/mutator_host.h"
18 #include "cc/trees/mutator_host_client.h"
19 #include "ui/gfx/geometry/box_f.h"
20 #include "ui/gfx/geometry/vector2d_f.h"
21 
22 namespace gfx {
23 class ScrollOffset;
24 }
25 
26 namespace cc {
27 
28 class Animation;
29 class AnimationTimeline;
30 class ElementAnimations;
31 class LayerTreeHost;
32 class ScrollOffsetAnimations;
33 class ScrollOffsetAnimationsImpl;
34 class WorkletAnimation;
35 
36 enum class ThreadInstance { MAIN, IMPL };
37 
38 // An AnimationHost contains all the state required to play animations.
39 // Specifically, it owns all the AnimationTimelines objects.
40 // There is just one AnimationHost for LayerTreeHost on main renderer thread
41 // and just one AnimationHost for LayerTreeHostImpl on impl thread.
42 // We synchronize them during the commit process in a one-way data flow process
43 // (PushPropertiesTo).
44 // An AnimationHost talks to its correspondent LayerTreeHost via
45 // MutatorHostClient interface.
46 class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
47                                           public LayerTreeMutatorClient {
48  public:
49   using ElementToAnimationsMap =
50       std::unordered_map<ElementId,
51                          scoped_refptr<ElementAnimations>,
52                          ElementIdHash>;
53   using AnimationsList = std::vector<scoped_refptr<Animation>>;
54 
55   static std::unique_ptr<AnimationHost> CreateMainInstance();
56   static std::unique_ptr<AnimationHost> CreateForTesting(
57       ThreadInstance thread_instance);
58 
59   AnimationHost(const AnimationHost&) = delete;
60   ~AnimationHost() override;
61 
62   AnimationHost& operator=(const AnimationHost&) = delete;
63 
64   void AddAnimationTimeline(scoped_refptr<AnimationTimeline> timeline);
65   void RemoveAnimationTimeline(scoped_refptr<AnimationTimeline> timeline);
66   AnimationTimeline* GetTimelineById(int timeline_id) const;
67 
68   void RegisterAnimationForElement(ElementId element_id, Animation* animation);
69   void UnregisterAnimationForElement(ElementId element_id,
70                                      Animation* animation);
71 
72   scoped_refptr<ElementAnimations> GetElementAnimationsForElementId(
73       ElementId element_id) const;
74 
75   // Parent LayerTreeHost or LayerTreeHostImpl.
mutator_host_client()76   MutatorHostClient* mutator_host_client() { return mutator_host_client_; }
mutator_host_client()77   const MutatorHostClient* mutator_host_client() const {
78     return mutator_host_client_;
79   }
80 
81   void SetNeedsCommit();
82   void SetNeedsPushProperties();
needs_push_properties()83   bool needs_push_properties() const { return needs_push_properties_; }
84 
85   bool SupportsScrollAnimations() const;
86 
87   // MutatorHost implementation.
88   std::unique_ptr<MutatorHost> CreateImplInstance(
89       bool supports_impl_scrolling) const override;
90   void ClearMutators() override;
91 
92   // Processes the current |element_to_animations_map_|, registering animations
93   // which can now be animated and unregistering those that can't based on the
94   // elements in the |changed_list|.
95   void UpdateRegisteredElementIds(ElementListType changed_list) override;
96   void InitClientAnimationState() override;
97 
98   void RegisterElementId(ElementId element_id,
99                          ElementListType list_type) override;
100   void UnregisterElementId(ElementId element_id,
101                            ElementListType list_type) override;
102 
103   void SetMutatorHostClient(MutatorHostClient* client) override;
104 
105   void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator) override;
106 
107   void PushPropertiesTo(MutatorHost* host_impl) override;
108 
109   void SetSupportsScrollAnimations(bool supports_scroll_animations) override;
110   void SetScrollAnimationDurationForTesting(base::TimeDelta duration) override;
111   bool NeedsTickAnimations() const override;
112 
113   bool ActivateAnimations(MutatorEvents* events) override;
114   bool TickAnimations(base::TimeTicks monotonic_time,
115                       const ScrollTree& scroll_tree,
116                       bool is_active_tree) override;
117   void TickScrollAnimations(base::TimeTicks monotonic_time,
118                             const ScrollTree& scroll_tree) override;
119   void TickWorkletAnimations() override;
120   bool UpdateAnimationState(bool start_ready_animations,
121                             MutatorEvents* events) override;
122   void TakeTimeUpdatedEvents(MutatorEvents* events) override;
123   // Should be called when the pending tree is promoted to active, as this may
124   // require updating the ElementId for the ScrollTimeline scroll source.
125   void PromoteScrollTimelinesPendingToActive() override;
126 
127   std::unique_ptr<MutatorEvents> CreateEvents() override;
128   void SetAnimationEvents(std::unique_ptr<MutatorEvents> events) override;
129 
130   bool ScrollOffsetAnimationWasInterrupted(ElementId element_id) const override;
131 
132   bool IsAnimatingFilterProperty(ElementId element_id,
133                                  ElementListType list_type) const override;
134   bool IsAnimatingBackdropFilterProperty(
135       ElementId element_id,
136       ElementListType list_type) const override;
137   bool IsAnimatingOpacityProperty(ElementId element_id,
138                                   ElementListType list_type) const override;
139   bool IsAnimatingTransformProperty(ElementId element_id,
140                                     ElementListType list_type) const override;
141 
142   bool HasPotentiallyRunningFilterAnimation(
143       ElementId element_id,
144       ElementListType list_type) const override;
145   bool HasPotentiallyRunningBackdropFilterAnimation(
146       ElementId element_id,
147       ElementListType list_type) const override;
148   bool HasPotentiallyRunningOpacityAnimation(
149       ElementId element_id,
150       ElementListType list_type) const override;
151   bool HasPotentiallyRunningTransformAnimation(
152       ElementId element_id,
153       ElementListType list_type) const override;
154 
155   bool HasAnyAnimationTargetingProperty(
156       ElementId element_id,
157       TargetProperty::Type property) const override;
158 
159   bool AnimationsPreserveAxisAlignment(ElementId element_id) const override;
160 
161   void GetAnimationScales(ElementId element_id,
162                           ElementListType list_type,
163                           float* maximum_scale,
164                           float* starting_scale) const override;
165 
166   bool IsElementAnimating(ElementId element_id) const override;
167   bool HasTickingKeyframeModelForTesting(ElementId element_id) const override;
168 
169   void ImplOnlyAutoScrollAnimationCreate(
170       ElementId element_id,
171       const gfx::ScrollOffset& target_offset,
172       const gfx::ScrollOffset& current_offset,
173       float autoscroll_velocity,
174       base::TimeDelta animation_start_offset) override;
175 
176   void ImplOnlyScrollAnimationCreate(
177       ElementId element_id,
178       const gfx::ScrollOffset& target_offset,
179       const gfx::ScrollOffset& current_offset,
180       base::TimeDelta delayed_by,
181       base::TimeDelta animation_start_offset) override;
182   bool ImplOnlyScrollAnimationUpdateTarget(
183       const gfx::Vector2dF& scroll_delta,
184       const gfx::ScrollOffset& max_scroll_offset,
185       base::TimeTicks frame_monotonic_time,
186       base::TimeDelta delayed_by) override;
187 
188   void ScrollAnimationAbort() override;
189 
190   ElementId ImplOnlyScrollAnimatingElement() const override;
191 
192   // This should only be called from the main thread.
193   ScrollOffsetAnimations& scroll_offset_animations() const;
194 
195   // Registers the given animation as ticking. A ticking animation is one that
196   // has a running keyframe model.
197   void AddToTicking(scoped_refptr<Animation> animation);
198 
199   // Unregisters the given animation. When this happens, the animation will no
200   // longer be ticked.
201   void RemoveFromTicking(scoped_refptr<Animation> animation);
202 
203   const AnimationsList& ticking_animations_for_testing() const;
204   const ElementToAnimationsMap& element_animations_for_testing() const;
205 
206   // LayerTreeMutatorClient.
207   void SetMutationUpdate(
208       std::unique_ptr<MutatorOutputState> output_state) override;
209 
210   size_t CompositedAnimationsCount() const override;
211   size_t MainThreadAnimationsCount() const override;
212   bool HasCustomPropertyAnimations() const override;
213   bool CurrentFrameHadRAF() const override;
214   bool NextFrameHasPendingRAF() const override;
215   void SetAnimationCounts(size_t total_animations_count,
216                           bool current_frame_had_raf,
217                           bool next_frame_has_pending_raf);
218 
219  private:
220   explicit AnimationHost(ThreadInstance thread_instance);
221 
222   void PushTimelinesToImplThread(AnimationHost* host_impl) const;
223   void RemoveTimelinesFromImplThread(AnimationHost* host_impl) const;
224   void PushPropertiesToImplThread(AnimationHost* host_impl);
225 
226   void EraseTimeline(scoped_refptr<AnimationTimeline> timeline);
227 
228   // Return true if there are any animations that get mutated.
229   void TickMutator(base::TimeTicks monotonic_time,
230                    const ScrollTree& scroll_tree,
231                    bool is_active_tree);
232 
233   // Return the state representing all ticking worklet animations.
234   std::unique_ptr<MutatorInputState> CollectWorkletAnimationsState(
235       base::TimeTicks timeline_time,
236       const ScrollTree& scroll_tree,
237       bool is_active_tree);
238 
239   // Returns a pointer to a worklet animation by worklet animation id or null
240   // if there is no match.
241   WorkletAnimation* FindWorkletAnimation(WorkletAnimationId id);
242 
243   ElementToAnimationsMap element_to_animations_map_;
244   AnimationsList ticking_animations_;
245 
246   // A list of all timelines which this host owns.
247   using IdToTimelineMap =
248       std::unordered_map<int, scoped_refptr<AnimationTimeline>>;
249   IdToTimelineMap id_to_timeline_map_;
250 
251   MutatorHostClient* mutator_host_client_;
252 
253   // Exactly one of scroll_offset_animations_ and scroll_offset_animations_impl_
254   // will be non-null for a given AnimationHost instance (the former if
255   // thread_instance_ == ThreadInstance::MAIN, the latter if thread_instance_ ==
256   // ThreadInstance::IMPL).
257   std::unique_ptr<ScrollOffsetAnimations> scroll_offset_animations_;
258   std::unique_ptr<ScrollOffsetAnimationsImpl> scroll_offset_animations_impl_;
259 
260   const ThreadInstance thread_instance_;
261 
262   bool supports_scroll_animations_;
263   bool needs_push_properties_;
264 
265   std::unique_ptr<LayerTreeMutator> mutator_;
266 
267   size_t main_thread_animations_count_ = 0;
268   bool current_frame_had_raf_ = false;
269   bool next_frame_has_pending_raf_ = false;
270 
271   base::WeakPtrFactory<AnimationHost> weak_factory_{this};
272 };
273 
274 }  // namespace cc
275 
276 #endif  // CC_ANIMATION_ANIMATION_HOST_H_
277