15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef UI_COMPOSITOR_LAYER_ANIMATION_SEQUENCE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_COMPOSITOR_LAYER_ANIMATION_SEQUENCE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor_export.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_element.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LayerAnimationDelegate;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LayerAnimationObserver;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Contains a collection of layer animation elements to be played one after
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// another. Although it has a similar interface to LayerAnimationElement, it is
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not a LayerAnimationElement (i.e., it is not permitted to have a sequence in
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a sequence). Sequences own their elements, and sequences are themselves owned
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by a LayerAnimator.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(vollick) Create a 'blended' sequence for transitioning between
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sequences.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(vollick) Eventually, the LayerAnimator will switch to a model where new
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// work is scheduled rather than calling methods directly. This should make it
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// impossible for temporary pointers to running animations to go stale. When
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this happens, there will be no need for LayerAnimationSequences to support
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// weak pointers.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class COMPOSITOR_EXPORT LayerAnimationSequence
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::SupportsWeakPtr<LayerAnimationSequence> {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayerAnimationSequence();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Takes ownership of the given element and adds it to the sequence.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit LayerAnimationSequence(LayerAnimationElement* element);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~LayerAnimationSequence();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets the start time for the animation. This must be called before the
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // first call to {Start, IsFinished}. Once the animation is finished, this
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // must be called again in order to restart the animation.
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_start_time(base::TimeTicks start_time) { start_time_ = start_time; }
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks start_time() const { return start_time_; }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets a flag indicating that this sequence will start together with other
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // sequences, and at least one of the sequences in this group has a threaded
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // first element.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_waiting_for_group_start(bool waiting) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    waiting_for_group_start_ = waiting;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool waiting_for_group_start() { return waiting_for_group_start_; }
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This must be called before the first call to Progress. If starting the
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animation involves dispatching to another thread, then this will proceed
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // with that dispatch, ultimately resulting in the animation getting an
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // effective start time (the time the animation starts on the other thread).
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Start(LayerAnimationDelegate* delegate);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates the delegate to the appropriate value for |now|. Requests a
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // redraw if it is required.
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Progress(base::TimeTicks now, LayerAnimationDelegate* delegate);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if calling Progress now, with the given time, will finish
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the animation.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsFinished(base::TimeTicks time);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates the delegate to the end of the animation; if this sequence is
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // cyclic, updates the delegate to the end of one cycle of the sequence.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ProgressToEnd(LayerAnimationDelegate* delegate);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the target value to the value that would have been set had
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the sequence completed. Does nothing if the sequence is cyclic.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GetTargetValue(LayerAnimationElement::TargetValue* target) const;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Aborts the given animation.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Abort(LayerAnimationDelegate* delegate);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All properties modified by the sequence.
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerAnimationElement::AnimatableProperties properties() const {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return properties_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds an element to the sequence. The sequences takes ownership of this
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // element.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddElement(LayerAnimationElement* element);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sequences can be looped indefinitely.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_is_cyclic(bool is_cyclic) { is_cyclic_ = is_cyclic; }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_cyclic() const { return is_cyclic_; }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if this sequence has at least one element conflicting with a
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // property in |other|.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool HasConflictingProperty(
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerAnimationElement::AnimatableProperties other) const;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the first element animates on the compositor thread.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsFirstElementThreaded() const;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Used to identify groups of sequences that are supposed to start together.
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Once started, used to identify the sequence that owns a particular
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // threaded animation.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int animation_group_id() const { return animation_group_id_; }
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_animation_group_id(int id) { animation_group_id_ = id; }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These functions are used for adding or removing observers from the observer
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // list. The observers are notified when animations end.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddObserver(LayerAnimationObserver* observer);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveObserver(LayerAnimationObserver* observer);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when a threaded animation is actually started.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnThreadedAnimationStarted(const cc::AnimationEvent& event);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the animator schedules this sequence.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnScheduled();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the animator is destroyed.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnAnimatorDestroyed();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The last_progressed_fraction of the element most recently progressed by
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // by this sequence. Returns 0.0 if no elements have been progressed.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double last_progressed_fraction() const { return last_progressed_fraction_; }
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  size_t size() const;
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  LayerAnimationElement* FirstElement() const;
131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class LayerAnimatorTestController;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<linked_ptr<LayerAnimationElement> > Elements;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(LayerAnimatorTest,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ObserverReleasedBeforeAnimationSequenceEnds);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notifies the observers that this sequence has been scheduled.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyScheduled();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notifies the observers that this sequence has ended.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyEnded();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notifies the observers that this sequence has been aborted.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyAborted();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The currently animating element.
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  LayerAnimationElement* CurrentElement() const;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The union of all the properties modified by all elements in the sequence.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayerAnimationElement::AnimatableProperties properties_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The elements in the sequence.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Elements elements_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if the sequence should be looped forever.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_cyclic_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These are used when animating to efficiently find the next element.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t last_element_;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks last_start_;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The start time of the current run of the sequence.
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks start_time_;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // True if this sequence will start together with other sequences, and at
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // least one of the sequences in this group has a threaded first element.
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool waiting_for_group_start_;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Identifies groups of sequences that are supposed to start together.
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Also used to identify the owner of a particular threaded animation; any
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // in-progress threaded animation owned by this sequence will have this
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // group id.
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int animation_group_id_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These parties are notified when layer animations end.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<LayerAnimationObserver> observers_;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tracks the last_progressed_fraction() of the most recently progressed
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // element.
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double last_progressed_fraction_;
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::WeakPtrFactory<LayerAnimationSequence> weak_ptr_factory_;
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LayerAnimationSequence);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // UI_COMPOSITOR_LAYER_ANIMATION_SEQUENCE_H_
193