// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_ANIMATION_ANIMATION_HOST_H_ #define CC_ANIMATION_ANIMATION_HOST_H_ #include #include #include #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "cc/animation/animation_export.h" #include "cc/animation/keyframe_model.h" #include "cc/trees/mutator_host.h" #include "cc/trees/mutator_host_client.h" #include "ui/gfx/geometry/box_f.h" #include "ui/gfx/geometry/vector2d_f.h" namespace gfx { class ScrollOffset; } namespace cc { class Animation; class AnimationTimeline; class ElementAnimations; class LayerTreeHost; class KeyframeEffect; class ScrollOffsetAnimations; class ScrollOffsetAnimationsImpl; enum class ThreadInstance { MAIN, IMPL }; // An AnimationHost contains all the state required to play animations. // Specifically, it owns all the AnimationTimelines objects. // There is just one AnimationHost for LayerTreeHost on main renderer thread // and just one AnimationHost for LayerTreeHostImpl on impl thread. // We synchronize them during the commit process in a one-way data flow process // (PushPropertiesTo). // An AnimationHost talks to its correspondent LayerTreeHost via // MutatorHostClient interface. class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost, public LayerTreeMutatorClient { public: using ElementToAnimationsMap = std::unordered_map, ElementIdHash>; using AnimationsList = std::vector>; static std::unique_ptr CreateMainInstance(); static std::unique_ptr CreateForTesting( ThreadInstance thread_instance); ~AnimationHost() override; void AddAnimationTimeline(scoped_refptr timeline); void RemoveAnimationTimeline(scoped_refptr timeline); AnimationTimeline* GetTimelineById(int timeline_id) const; void RegisterKeyframeEffectForElement(ElementId element_id, KeyframeEffect* keyframe_effect); void UnregisterKeyframeEffectForElement(ElementId element_id, KeyframeEffect* keyframe_effect); scoped_refptr GetElementAnimationsForElementId( ElementId element_id) const; // Parent LayerTreeHost or LayerTreeHostImpl. MutatorHostClient* mutator_host_client() { return mutator_host_client_; } const MutatorHostClient* mutator_host_client() const { return mutator_host_client_; } void SetNeedsCommit(); void SetNeedsPushProperties(); bool needs_push_properties() const { return needs_push_properties_; } bool SupportsScrollAnimations() const; // MutatorHost implementation. std::unique_ptr CreateImplInstance( bool supports_impl_scrolling) const override; void ClearMutators() override; void RegisterElement(ElementId element_id, ElementListType list_type) override; void UnregisterElement(ElementId element_id, ElementListType list_type) override; void SetMutatorHostClient(MutatorHostClient* client) override; void SetLayerTreeMutator(std::unique_ptr mutator) override; void PushPropertiesTo(MutatorHost* host_impl) override; void SetSupportsScrollAnimations(bool supports_scroll_animations) override; bool NeedsTickAnimations() const override; bool ActivateAnimations() override; bool TickAnimations(base::TimeTicks monotonic_time, const ScrollTree& scroll_tree) override; void TickScrollAnimations(base::TimeTicks monotonic_time, const ScrollTree& scroll_tree) override; bool UpdateAnimationState(bool start_ready_animations, MutatorEvents* events) override; std::unique_ptr CreateEvents() override; void SetAnimationEvents(std::unique_ptr events) override; bool ScrollOffsetAnimationWasInterrupted(ElementId element_id) const override; bool IsAnimatingFilterProperty(ElementId element_id, ElementListType list_type) const override; bool IsAnimatingOpacityProperty(ElementId element_id, ElementListType list_type) const override; bool IsAnimatingTransformProperty(ElementId element_id, ElementListType list_type) const override; bool HasPotentiallyRunningFilterAnimation( ElementId element_id, ElementListType list_type) const override; bool HasPotentiallyRunningOpacityAnimation( ElementId element_id, ElementListType list_type) const override; bool HasPotentiallyRunningTransformAnimation( ElementId element_id, ElementListType list_type) const override; bool HasAnyAnimationTargetingProperty( ElementId element_id, TargetProperty::Type property) const override; bool HasOnlyTranslationTransforms(ElementId element_id, ElementListType list_type) const override; bool AnimationsPreserveAxisAlignment(ElementId element_id) const override; bool MaximumTargetScale(ElementId element_id, ElementListType list_type, float* max_scale) const override; bool AnimationStartScale(ElementId element_id, ElementListType list_type, float* start_scale) const override; bool IsElementAnimating(ElementId element_id) const override; bool HasTickingKeyframeModelForTesting(ElementId element_id) const override; void ImplOnlyScrollAnimationCreate( ElementId element_id, const gfx::ScrollOffset& target_offset, const gfx::ScrollOffset& current_offset, base::TimeDelta delayed_by, base::TimeDelta animation_start_offset) override; bool ImplOnlyScrollAnimationUpdateTarget( ElementId element_id, const gfx::Vector2dF& scroll_delta, const gfx::ScrollOffset& max_scroll_offset, base::TimeTicks frame_monotonic_time, base::TimeDelta delayed_by) override; void ScrollAnimationAbort() override; // This should only be called from the main thread. ScrollOffsetAnimations& scroll_offset_animations() const; // Registers the given animation as ticking. A ticking animation is one that // has a running keyframe model. void AddToTicking(scoped_refptr animation); // Unregisters the given animation. When this happens, the animation will no // longer be ticked. void RemoveFromTicking(scoped_refptr animation); const AnimationsList& ticking_animations_for_testing() const; const ElementToAnimationsMap& element_animations_for_testing() const; // LayerTreeMutatorClient. void SetMutationUpdate( std::unique_ptr output_state) override; size_t CompositedAnimationsCount() const override; size_t MainThreadAnimationsCount() const override; size_t MainThreadCompositableAnimationsCount() const override; bool CurrentFrameHadRAF() const override; bool NextFrameHasPendingRAF() const override; void SetAnimationCounts(size_t total_animations_count, size_t main_thread_compositable_animations_count, bool current_frame_had_raf, bool next_frame_has_pending_raf); private: explicit AnimationHost(ThreadInstance thread_instance); void PushTimelinesToImplThread(AnimationHost* host_impl) const; void RemoveTimelinesFromImplThread(AnimationHost* host_impl) const; void PushPropertiesToImplThread(AnimationHost* host_impl); void EraseTimeline(scoped_refptr timeline); bool NeedsTickMutator(base::TimeTicks monotonic_time, const ScrollTree& scroll_tree) const; // Return the animator state representing all ticking worklet animations. std::unique_ptr CollectAnimatorsState( base::TimeTicks timeline_time, const ScrollTree& scroll_tree); ElementToAnimationsMap element_to_animations_map_; AnimationsList ticking_animations_; // A list of all timelines which this host owns. using IdToTimelineMap = std::unordered_map>; IdToTimelineMap id_to_timeline_map_; MutatorHostClient* mutator_host_client_; std::unique_ptr scroll_offset_animations_; std::unique_ptr scroll_offset_animations_impl_; const ThreadInstance thread_instance_; bool supports_scroll_animations_; bool needs_push_properties_; std::unique_ptr mutator_; size_t main_thread_animations_count_ = 0; size_t main_thread_compositable_animations_count_ = 0; bool current_frame_had_raf_ = false; bool next_frame_has_pending_raf_ = false; DISALLOW_COPY_AND_ASSIGN(AnimationHost); }; } // namespace cc #endif // CC_ANIMATION_ANIMATION_HOST_H_