| // Copyright (c) 2012 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 UI_COMPOSITOR_LAYER_ANIMATION_SEQUENCE_H_ |
| #define UI_COMPOSITOR_LAYER_ANIMATION_SEQUENCE_H_ |
| |
| #include <vector> |
| |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/linked_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/time/time.h" |
| #include "ui/compositor/compositor_export.h" |
| #include "ui/compositor/layer_animation_element.h" |
| |
| namespace ui { |
| |
| class LayerAnimationDelegate; |
| class LayerAnimationObserver; |
| |
| // Contains a collection of layer animation elements to be played one after |
| // another. Although it has a similar interface to LayerAnimationElement, it is |
| // not a LayerAnimationElement (i.e., it is not permitted to have a sequence in |
| // a sequence). Sequences own their elements, and sequences are themselves owned |
| // by a LayerAnimator. |
| // |
| // TODO(vollick) Create a 'blended' sequence for transitioning between |
| // sequences. |
| // TODO(vollick) Eventually, the LayerAnimator will switch to a model where new |
| // work is scheduled rather than calling methods directly. This should make it |
| // impossible for temporary pointers to running animations to go stale. When |
| // this happens, there will be no need for LayerAnimationSequences to support |
| // weak pointers. |
| class COMPOSITOR_EXPORT LayerAnimationSequence |
| : public base::SupportsWeakPtr<LayerAnimationSequence> { |
| public: |
| LayerAnimationSequence(); |
| // Takes ownership of the given element and adds it to the sequence. |
| explicit LayerAnimationSequence(LayerAnimationElement* element); |
| virtual ~LayerAnimationSequence(); |
| |
| // Sets the start time for the animation. This must be called before the |
| // first call to {Start, IsFinished}. Once the animation is finished, this |
| // must be called again in order to restart the animation. |
| void set_start_time(base::TimeTicks start_time) { start_time_ = start_time; } |
| base::TimeTicks start_time() const { return start_time_; } |
| |
| // Sets a flag indicating that this sequence will start together with other |
| // sequences, and at least one of the sequences in this group has a threaded |
| // first element. |
| void set_waiting_for_group_start(bool waiting) { |
| waiting_for_group_start_ = waiting; |
| } |
| bool waiting_for_group_start() { return waiting_for_group_start_; } |
| |
| // This must be called before the first call to Progress. If starting the |
| // animation involves dispatching to another thread, then this will proceed |
| // with that dispatch, ultimately resulting in the animation getting an |
| // effective start time (the time the animation starts on the other thread). |
| void Start(LayerAnimationDelegate* delegate); |
| |
| // Updates the delegate to the appropriate value for |now|. Requests a |
| // redraw if it is required. |
| void Progress(base::TimeTicks now, LayerAnimationDelegate* delegate); |
| |
| // Returns true if calling Progress now, with the given time, will finish |
| // the animation. |
| bool IsFinished(base::TimeTicks time); |
| |
| // Updates the delegate to the end of the animation; if this sequence is |
| // cyclic, updates the delegate to the end of one cycle of the sequence. |
| void ProgressToEnd(LayerAnimationDelegate* delegate); |
| |
| // Sets the target value to the value that would have been set had |
| // the sequence completed. Does nothing if the sequence is cyclic. |
| void GetTargetValue(LayerAnimationElement::TargetValue* target) const; |
| |
| // Aborts the given animation. |
| void Abort(LayerAnimationDelegate* delegate); |
| |
| // All properties modified by the sequence. |
| LayerAnimationElement::AnimatableProperties properties() const { |
| return properties_; |
| } |
| |
| // Adds an element to the sequence. The sequences takes ownership of this |
| // element. |
| void AddElement(LayerAnimationElement* element); |
| |
| // Sequences can be looped indefinitely. |
| void set_is_cyclic(bool is_cyclic) { is_cyclic_ = is_cyclic; } |
| bool is_cyclic() const { return is_cyclic_; } |
| |
| // Returns true if this sequence has at least one element conflicting with a |
| // property in |other|. |
| bool HasConflictingProperty( |
| LayerAnimationElement::AnimatableProperties other) const; |
| |
| // Returns true if the first element animates on the compositor thread. |
| bool IsFirstElementThreaded() const; |
| |
| // Used to identify groups of sequences that are supposed to start together. |
| // Once started, used to identify the sequence that owns a particular |
| // threaded animation. |
| int animation_group_id() const { return animation_group_id_; } |
| void set_animation_group_id(int id) { animation_group_id_ = id; } |
| |
| // These functions are used for adding or removing observers from the observer |
| // list. The observers are notified when animations end. |
| void AddObserver(LayerAnimationObserver* observer); |
| void RemoveObserver(LayerAnimationObserver* observer); |
| |
| // Called when a threaded animation is actually started. |
| void OnThreadedAnimationStarted(const cc::AnimationEvent& event); |
| |
| // Called when the animator schedules this sequence. |
| void OnScheduled(); |
| |
| // Called when the animator is destroyed. |
| void OnAnimatorDestroyed(); |
| |
| // The last_progressed_fraction of the element most recently progressed by |
| // by this sequence. Returns 0.0 if no elements have been progressed. |
| double last_progressed_fraction() const { return last_progressed_fraction_; } |
| |
| size_t size() const; |
| |
| LayerAnimationElement* FirstElement() const; |
| |
| private: |
| friend class LayerAnimatorTestController; |
| |
| typedef std::vector<linked_ptr<LayerAnimationElement> > Elements; |
| |
| FRIEND_TEST_ALL_PREFIXES(LayerAnimatorTest, |
| ObserverReleasedBeforeAnimationSequenceEnds); |
| |
| // Notifies the observers that this sequence has been scheduled. |
| void NotifyScheduled(); |
| |
| // Notifies the observers that this sequence has ended. |
| void NotifyEnded(); |
| |
| // Notifies the observers that this sequence has been aborted. |
| void NotifyAborted(); |
| |
| // The currently animating element. |
| LayerAnimationElement* CurrentElement() const; |
| |
| // The union of all the properties modified by all elements in the sequence. |
| LayerAnimationElement::AnimatableProperties properties_; |
| |
| // The elements in the sequence. |
| Elements elements_; |
| |
| // True if the sequence should be looped forever. |
| bool is_cyclic_; |
| |
| // These are used when animating to efficiently find the next element. |
| size_t last_element_; |
| base::TimeTicks last_start_; |
| |
| // The start time of the current run of the sequence. |
| base::TimeTicks start_time_; |
| |
| // True if this sequence will start together with other sequences, and at |
| // least one of the sequences in this group has a threaded first element. |
| bool waiting_for_group_start_; |
| |
| // Identifies groups of sequences that are supposed to start together. |
| // Also used to identify the owner of a particular threaded animation; any |
| // in-progress threaded animation owned by this sequence will have this |
| // group id. |
| int animation_group_id_; |
| |
| // These parties are notified when layer animations end. |
| ObserverList<LayerAnimationObserver> observers_; |
| |
| // Tracks the last_progressed_fraction() of the most recently progressed |
| // element. |
| double last_progressed_fraction_; |
| |
| base::WeakPtrFactory<LayerAnimationSequence> weak_ptr_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(LayerAnimationSequence); |
| }; |
| |
| } // namespace ui |
| |
| #endif // UI_COMPOSITOR_LAYER_ANIMATION_SEQUENCE_H_ |