1// Copyright (c) 2012 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 UI_COMPOSITOR_LAYER_ANIMATION_ELEMENT_H_
6#define UI_COMPOSITOR_LAYER_ANIMATION_ELEMENT_H_
7
8#include <set>
9
10#include "base/memory/weak_ptr.h"
11#include "base/time/time.h"
12#include "cc/animation/animation.h"
13#include "cc/animation/animation_events.h"
14#include "third_party/skia/include/core/SkColor.h"
15#include "ui/compositor/compositor_export.h"
16#include "ui/gfx/animation/tween.h"
17#include "ui/gfx/rect.h"
18#include "ui/gfx/transform.h"
19
20namespace ui {
21
22class InterpolatedTransform;
23class LayerAnimationDelegate;
24
25// LayerAnimationElements represent one segment of an animation between two
26// keyframes. They know how to update a LayerAnimationDelegate given a value
27// between 0 and 1 (0 for initial, and 1 for final).
28class COMPOSITOR_EXPORT LayerAnimationElement {
29 public:
30  enum AnimatableProperty {
31    UNKNOWN = 0,
32    TRANSFORM = (1 << 0),
33    BOUNDS = (1 << 1),
34    OPACITY = (1 << 2),
35    VISIBILITY = (1 << 3),
36    BRIGHTNESS = (1 << 4),
37    GRAYSCALE = (1 << 5),
38    COLOR = (1 << 6),
39
40    // Used when iterating over properties.
41    FIRST_PROPERTY = TRANSFORM,
42    SENTINEL = (1 << 7)
43  };
44
45  static AnimatableProperty ToAnimatableProperty(
46      cc::Animation::TargetProperty property);
47
48  struct COMPOSITOR_EXPORT TargetValue {
49    TargetValue();
50    // Initializes the target value to match the delegate. NULL may be supplied.
51    explicit TargetValue(const LayerAnimationDelegate* delegate);
52
53    gfx::Rect bounds;
54    gfx::Transform transform;
55    float opacity;
56    bool visibility;
57    float brightness;
58    float grayscale;
59    SkColor color;
60  };
61
62  typedef uint32 AnimatableProperties;
63
64  LayerAnimationElement(AnimatableProperties properties,
65                        base::TimeDelta duration);
66
67  virtual ~LayerAnimationElement();
68
69  // Creates an element that transitions to the given transform. The caller owns
70  // the return value.
71  static LayerAnimationElement* CreateTransformElement(
72      const gfx::Transform& transform,
73      base::TimeDelta duration);
74
75  // Creates an element that counters a transition to the given transform.
76  // This element maintains the invariant uninverted_transition->at(t) *
77  // this->at(t) == base_transform * this->at(t_start) for any t. The caller
78  // owns the return value.
79  static LayerAnimationElement* CreateInverseTransformElement(
80      const gfx::Transform& base_transform,
81      const LayerAnimationElement* uninverted_transition);
82
83
84  // Duplicates elements as created by CreateInverseTransformElement.
85  static LayerAnimationElement* CloneInverseTransformElement(
86      const LayerAnimationElement* other);
87
88  // Creates an element that transitions to another in a way determined by an
89  // interpolated transform. The element accepts ownership of the interpolated
90  // transform. NB: at every step, the interpolated transform clobbers the
91  // existing transform. That is, it does not interpolate between the existing
92  // transform and the last value the interpolated transform will assume. It is
93  // therefore important that the value of the interpolated at time 0 matches
94  // the current transform.
95  static LayerAnimationElement* CreateInterpolatedTransformElement(
96      InterpolatedTransform* interpolated_transform,
97      base::TimeDelta duration);
98
99  // Creates an element that transitions to the given bounds. The caller owns
100  // the return value.
101  static LayerAnimationElement* CreateBoundsElement(
102      const gfx::Rect& bounds,
103      base::TimeDelta duration);
104
105  // Creates an element that transitions to the given opacity. The caller owns
106  // the return value.
107  static LayerAnimationElement* CreateOpacityElement(
108      float opacity,
109      base::TimeDelta duration);
110
111  // Creates an element that sets visibily following a delay. The caller owns
112  // the return value.
113  static LayerAnimationElement* CreateVisibilityElement(
114      bool visibility,
115      base::TimeDelta duration);
116
117  // Creates an element that transitions to the given brightness.
118  // The caller owns the return value.
119  static LayerAnimationElement* CreateBrightnessElement(
120      float brightness,
121      base::TimeDelta duration);
122
123  // Creates an element that transitions to the given grayscale value.
124  // The caller owns the return value.
125  static LayerAnimationElement* CreateGrayscaleElement(
126      float grayscale,
127      base::TimeDelta duration);
128
129  // Creates an element that pauses the given properties. The caller owns the
130  // return value.
131  static LayerAnimationElement* CreatePauseElement(
132      AnimatableProperties properties,
133      base::TimeDelta duration);
134
135  // Creates an element that transitions to the given color. The caller owns the
136  // return value.
137  static LayerAnimationElement* CreateColorElement(
138      SkColor color,
139      base::TimeDelta duration);
140
141  // Sets the start time for the animation. This must be called before the first
142  // call to {Start, IsFinished}. Once the animation is finished, this must
143  // be called again in order to restart the animation.
144  void set_requested_start_time(base::TimeTicks start_time) {
145    requested_start_time_ = start_time;
146  }
147  base::TimeTicks requested_start_time() const { return requested_start_time_; }
148
149  // Sets the actual start time for the animation, taking into account any
150  // queueing delays.
151  void set_effective_start_time(base::TimeTicks start_time) {
152    effective_start_time_ = start_time;
153  }
154  base::TimeTicks effective_start_time() const { return effective_start_time_; }
155
156  // This must be called before the first call to Progress. If starting the
157  // animation involves dispatching to another thread, then this will proceed
158  // with that dispatch, ultimately resulting in the animation getting an
159  // effective start time (the time the animation starts on the other thread).
160  void Start(LayerAnimationDelegate* delegate, int animation_group_id);
161
162  // Returns true if the animation has started but hasn't finished.
163  bool Started() { return !first_frame_; }
164
165  // Updates the delegate to the appropriate value for |now|. Returns true
166  // if a redraw is required.
167  bool Progress(base::TimeTicks now, LayerAnimationDelegate* delegate);
168
169  // If calling Progress now, with the given time, will finish the animation,
170  // returns true and sets |end_duration| to the actual duration for this
171  // animation, incuding any queueing delays.
172  bool IsFinished(base::TimeTicks time, base::TimeDelta* total_duration);
173
174  // Updates the delegate to the end of the animation. Returns true if a
175  // redraw is required.
176  bool ProgressToEnd(LayerAnimationDelegate* delegate);
177
178  // Called if the animation is not allowed to complete. This may be called
179  // before OnStarted or Progress.
180  void Abort(LayerAnimationDelegate* delegate);
181
182  // Assigns the target value to |target|.
183  void GetTargetValue(TargetValue* target) const;
184
185  // The properties that the element modifies.
186  AnimatableProperties properties() const { return properties_; }
187
188  // Whether this element animates on the compositor thread.
189  virtual bool IsThreaded() const;
190
191  gfx::Tween::Type tween_type() const { return tween_type_; }
192  void set_tween_type(gfx::Tween::Type tween_type) { tween_type_ = tween_type; }
193
194  // Each LayerAnimationElement has a unique animation_id. Elements belonging
195  // to sequences that are supposed to start together have the same
196  // animation_group_id.
197  int animation_id() const { return animation_id_; }
198  int animation_group_id() const { return animation_group_id_; }
199  void set_animation_group_id(int id) { animation_group_id_ = id; }
200
201  base::TimeDelta duration() const { return duration_; }
202
203  // The fraction of the animation that has been completed after the last
204  // call made to {Progress, ProgressToEnd}.
205  double last_progressed_fraction() const { return last_progressed_fraction_; }
206
207 protected:
208  // Called once each time the animation element is run before any call to
209  // OnProgress.
210  virtual void OnStart(LayerAnimationDelegate* delegate) = 0;
211  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) = 0;
212  virtual void OnGetTarget(TargetValue* target) const = 0;
213  virtual void OnAbort(LayerAnimationDelegate* delegate) = 0;
214
215  // Actually start the animation, dispatching to another thread if needed.
216  virtual void RequestEffectiveStart(LayerAnimationDelegate* delegate);
217
218  LayerAnimationElement(const LayerAnimationElement& element);
219
220 private:
221  // For debugging purposes, we sometimes alter the duration we actually use.
222  // For example, during tests we often set duration = 0, and it is sometimes
223  // useful to slow animations down to see them more clearly.
224  base::TimeDelta GetEffectiveDuration(const base::TimeDelta& delta);
225
226  bool first_frame_;
227  const AnimatableProperties properties_;
228  base::TimeTicks requested_start_time_;
229
230  // When the animation actually started, taking into account queueing delays.
231  base::TimeTicks effective_start_time_;
232  const base::TimeDelta duration_;
233  gfx::Tween::Type tween_type_;
234
235  const int animation_id_;
236  int animation_group_id_;
237
238  double last_progressed_fraction_;
239
240  base::WeakPtrFactory<LayerAnimationElement> weak_ptr_factory_;
241
242  DISALLOW_ASSIGN(LayerAnimationElement);
243};
244
245}  // namespace ui
246
247#endif  // UI_COMPOSITOR_LAYER_ANIMATION_ELEMENT_H_
248