• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "ui/compositor/layer_animation_element.h"
6 
7 #include "base/compiler_specific.h"
8 #include "cc/animation/animation.h"
9 #include "cc/animation/animation_id_provider.h"
10 #include "ui/compositor/float_animation_curve_adapter.h"
11 #include "ui/compositor/layer.h"
12 #include "ui/compositor/layer_animation_delegate.h"
13 #include "ui/compositor/layer_animator.h"
14 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
15 #include "ui/compositor/transform_animation_curve_adapter.h"
16 #include "ui/gfx/animation/tween.h"
17 #include "ui/gfx/interpolated_transform.h"
18 
19 namespace ui {
20 
21 namespace {
22 
23 // The factor by which duration is scaled up or down when using
24 // ScopedAnimationDurationScaleMode.
25 const int kSlowDurationScaleMultiplier = 4;
26 const int kFastDurationScaleDivisor = 4;
27 const int kNonZeroDurationScaleDivisor = 20;
28 
29 // Pause -----------------------------------------------------------------------
30 class Pause : public LayerAnimationElement {
31  public:
Pause(AnimatableProperties properties,base::TimeDelta duration)32   Pause(AnimatableProperties properties, base::TimeDelta duration)
33       : LayerAnimationElement(properties, duration) {
34   }
~Pause()35   virtual ~Pause() {}
36 
37  private:
OnStart(LayerAnimationDelegate * delegate)38   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {}
OnProgress(double t,LayerAnimationDelegate * delegate)39   virtual bool OnProgress(double t,
40                           LayerAnimationDelegate* delegate) OVERRIDE {
41     return false;
42   }
OnGetTarget(TargetValue * target) const43   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {}
OnAbort(LayerAnimationDelegate * delegate)44   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
45 
46   DISALLOW_COPY_AND_ASSIGN(Pause);
47 };
48 
49 // TransformTransition ---------------------------------------------------------
50 
51 class TransformTransition : public LayerAnimationElement {
52  public:
TransformTransition(const gfx::Transform & target,base::TimeDelta duration)53     TransformTransition(const gfx::Transform& target, base::TimeDelta duration)
54       : LayerAnimationElement(TRANSFORM, duration),
55         target_(target) {
56   }
~TransformTransition()57   virtual ~TransformTransition() {}
58 
59  protected:
OnStart(LayerAnimationDelegate * delegate)60   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
61     start_ = delegate->GetTransformForAnimation();
62   }
63 
OnProgress(double t,LayerAnimationDelegate * delegate)64   virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
65     delegate->SetTransformFromAnimation(
66         gfx::Tween::TransformValueBetween(t, start_, target_));
67     return true;
68   }
69 
OnGetTarget(TargetValue * target) const70   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
71     target->transform = target_;
72   }
73 
OnAbort(LayerAnimationDelegate * delegate)74   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
75 
76  private:
77   gfx::Transform start_;
78   const gfx::Transform target_;
79 
80   DISALLOW_COPY_AND_ASSIGN(TransformTransition);
81 };
82 
83 // InterpolatedTransformTransition ---------------------------------------------
84 
85 class InterpolatedTransformTransition : public LayerAnimationElement {
86  public:
InterpolatedTransformTransition(InterpolatedTransform * interpolated_transform,base::TimeDelta duration)87   InterpolatedTransformTransition(InterpolatedTransform* interpolated_transform,
88                                   base::TimeDelta duration)
89       : LayerAnimationElement(TRANSFORM, duration),
90         interpolated_transform_(interpolated_transform) {
91   }
~InterpolatedTransformTransition()92   virtual ~InterpolatedTransformTransition() {}
93 
94  protected:
OnStart(LayerAnimationDelegate * delegate)95   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
96   }
97 
OnProgress(double t,LayerAnimationDelegate * delegate)98   virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
99     delegate->SetTransformFromAnimation(
100         interpolated_transform_->Interpolate(static_cast<float>(t)));
101     return true;
102   }
103 
OnGetTarget(TargetValue * target) const104   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
105     target->transform = interpolated_transform_->Interpolate(1.0f);
106   }
107 
OnAbort(LayerAnimationDelegate * delegate)108   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
109 
110  private:
111   scoped_ptr<InterpolatedTransform> interpolated_transform_;
112 
113   DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformTransition);
114 };
115 
116 // BoundsTransition ------------------------------------------------------------
117 
118 class BoundsTransition : public LayerAnimationElement {
119  public:
BoundsTransition(const gfx::Rect & target,base::TimeDelta duration)120   BoundsTransition(const gfx::Rect& target, base::TimeDelta duration)
121       : LayerAnimationElement(BOUNDS, duration),
122         target_(target) {
123   }
~BoundsTransition()124   virtual ~BoundsTransition() {}
125 
126  protected:
OnStart(LayerAnimationDelegate * delegate)127   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
128     start_ = delegate->GetBoundsForAnimation();
129   }
130 
OnProgress(double t,LayerAnimationDelegate * delegate)131   virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
132     delegate->SetBoundsFromAnimation(
133         gfx::Tween::RectValueBetween(t, start_, target_));
134     return true;
135   }
136 
OnGetTarget(TargetValue * target) const137   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
138     target->bounds = target_;
139   }
140 
OnAbort(LayerAnimationDelegate * delegate)141   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
142 
143  private:
144   gfx::Rect start_;
145   const gfx::Rect target_;
146 
147   DISALLOW_COPY_AND_ASSIGN(BoundsTransition);
148 };
149 
150 // OpacityTransition -----------------------------------------------------------
151 
152 class OpacityTransition : public LayerAnimationElement {
153  public:
OpacityTransition(float target,base::TimeDelta duration)154   OpacityTransition(float target, base::TimeDelta duration)
155       : LayerAnimationElement(OPACITY, duration),
156         start_(0.0f),
157         target_(target) {
158   }
~OpacityTransition()159   virtual ~OpacityTransition() {}
160 
161  protected:
OnStart(LayerAnimationDelegate * delegate)162   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
163     start_ = delegate->GetOpacityForAnimation();
164   }
165 
OnProgress(double t,LayerAnimationDelegate * delegate)166   virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
167     delegate->SetOpacityFromAnimation(
168         gfx::Tween::FloatValueBetween(t, start_, target_));
169     return true;
170   }
171 
OnGetTarget(TargetValue * target) const172   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
173     target->opacity = target_;
174   }
175 
OnAbort(LayerAnimationDelegate * delegate)176   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
177 
178  private:
179   float start_;
180   const float target_;
181 
182   DISALLOW_COPY_AND_ASSIGN(OpacityTransition);
183 };
184 
185 // VisibilityTransition --------------------------------------------------------
186 
187 class VisibilityTransition : public LayerAnimationElement {
188  public:
VisibilityTransition(bool target,base::TimeDelta duration)189   VisibilityTransition(bool target, base::TimeDelta duration)
190       : LayerAnimationElement(VISIBILITY, duration),
191         start_(false),
192         target_(target) {
193   }
~VisibilityTransition()194   virtual ~VisibilityTransition() {}
195 
196  protected:
OnStart(LayerAnimationDelegate * delegate)197   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
198     start_ = delegate->GetVisibilityForAnimation();
199   }
200 
OnProgress(double t,LayerAnimationDelegate * delegate)201   virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
202     delegate->SetVisibilityFromAnimation(t == 1.0 ? target_ : start_);
203     return t == 1.0;
204   }
205 
OnGetTarget(TargetValue * target) const206   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
207     target->visibility = target_;
208   }
209 
OnAbort(LayerAnimationDelegate * delegate)210   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
211 
212  private:
213   bool start_;
214   const bool target_;
215 
216   DISALLOW_COPY_AND_ASSIGN(VisibilityTransition);
217 };
218 
219 // BrightnessTransition --------------------------------------------------------
220 
221 class BrightnessTransition : public LayerAnimationElement {
222  public:
BrightnessTransition(float target,base::TimeDelta duration)223   BrightnessTransition(float target, base::TimeDelta duration)
224       : LayerAnimationElement(BRIGHTNESS, duration),
225         start_(0.0f),
226         target_(target) {
227   }
~BrightnessTransition()228   virtual ~BrightnessTransition() {}
229 
230  protected:
OnStart(LayerAnimationDelegate * delegate)231   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
232     start_ = delegate->GetBrightnessForAnimation();
233   }
234 
OnProgress(double t,LayerAnimationDelegate * delegate)235   virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
236     delegate->SetBrightnessFromAnimation(
237         gfx::Tween::FloatValueBetween(t, start_, target_));
238     return true;
239   }
240 
OnGetTarget(TargetValue * target) const241   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
242     target->brightness = target_;
243   }
244 
OnAbort(LayerAnimationDelegate * delegate)245   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
246 
247  private:
248   float start_;
249   const float target_;
250 
251   DISALLOW_COPY_AND_ASSIGN(BrightnessTransition);
252 };
253 
254 // GrayscaleTransition ---------------------------------------------------------
255 
256 class GrayscaleTransition : public LayerAnimationElement {
257  public:
GrayscaleTransition(float target,base::TimeDelta duration)258   GrayscaleTransition(float target, base::TimeDelta duration)
259       : LayerAnimationElement(GRAYSCALE, duration),
260         start_(0.0f),
261         target_(target) {
262   }
~GrayscaleTransition()263   virtual ~GrayscaleTransition() {}
264 
265  protected:
OnStart(LayerAnimationDelegate * delegate)266   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
267     start_ = delegate->GetGrayscaleForAnimation();
268   }
269 
OnProgress(double t,LayerAnimationDelegate * delegate)270   virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
271     delegate->SetGrayscaleFromAnimation(
272         gfx::Tween::FloatValueBetween(t, start_, target_));
273     return true;
274   }
275 
OnGetTarget(TargetValue * target) const276   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
277     target->grayscale = target_;
278   }
279 
OnAbort(LayerAnimationDelegate * delegate)280   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
281 
282  private:
283   float start_;
284   const float target_;
285 
286   DISALLOW_COPY_AND_ASSIGN(GrayscaleTransition);
287 };
288 
289 // ColorTransition -------------------------------------------------------------
290 
291 class ColorTransition : public LayerAnimationElement {
292  public:
ColorTransition(SkColor target,base::TimeDelta duration)293   ColorTransition(SkColor target, base::TimeDelta duration)
294       : LayerAnimationElement(COLOR, duration),
295         start_(SK_ColorBLACK),
296         target_(target) {
297   }
~ColorTransition()298   virtual ~ColorTransition() {}
299 
300  protected:
OnStart(LayerAnimationDelegate * delegate)301   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
302     start_ = delegate->GetColorForAnimation();
303   }
304 
OnProgress(double t,LayerAnimationDelegate * delegate)305   virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
306     delegate->SetColorFromAnimation(
307         gfx::Tween::ColorValueBetween(t, start_, target_));
308     return true;
309   }
310 
OnGetTarget(TargetValue * target) const311   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
312     target->color = target_;
313   }
314 
OnAbort(LayerAnimationDelegate * delegate)315   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
316 
317  private:
318   SkColor start_;
319   const SkColor target_;
320 
321   DISALLOW_COPY_AND_ASSIGN(ColorTransition);
322 };
323 
324 // ThreadedLayerAnimationElement -----------------------------------------------
325 
326 class ThreadedLayerAnimationElement : public LayerAnimationElement {
327  public:
ThreadedLayerAnimationElement(AnimatableProperties properties,base::TimeDelta duration)328   ThreadedLayerAnimationElement(AnimatableProperties properties,
329                                 base::TimeDelta duration)
330       : LayerAnimationElement(properties, duration) {
331   }
~ThreadedLayerAnimationElement()332   virtual ~ThreadedLayerAnimationElement() {}
333 
IsThreaded() const334   virtual bool IsThreaded() const OVERRIDE {
335     return (duration() != base::TimeDelta());
336   }
337 
338  protected:
ThreadedLayerAnimationElement(const LayerAnimationElement & element)339   explicit ThreadedLayerAnimationElement(const LayerAnimationElement& element)
340     : LayerAnimationElement(element) {
341   }
342 
OnProgress(double t,LayerAnimationDelegate * delegate)343   virtual bool OnProgress(double t,
344                           LayerAnimationDelegate* delegate) OVERRIDE {
345     if (t < 1.0)
346       return false;
347 
348     if (Started()) {
349       delegate->RemoveThreadedAnimation(animation_id());
350     }
351 
352     OnEnd(delegate);
353     return true;
354   }
355 
OnAbort(LayerAnimationDelegate * delegate)356   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
357     if (delegate && Started()) {
358       delegate->RemoveThreadedAnimation(animation_id());
359     }
360   }
361 
RequestEffectiveStart(LayerAnimationDelegate * delegate)362   virtual void RequestEffectiveStart(
363       LayerAnimationDelegate* delegate) OVERRIDE {
364     DCHECK(animation_group_id());
365     if (duration() == base::TimeDelta()) {
366       set_effective_start_time(requested_start_time());
367       return;
368     }
369     set_effective_start_time(base::TimeTicks());
370     scoped_ptr<cc::Animation> animation = CreateCCAnimation();
371     animation->set_needs_synchronized_start_time(true);
372     delegate->AddThreadedAnimation(animation.Pass());
373   }
374 
375   virtual void OnEnd(LayerAnimationDelegate* delegate) = 0;
376 
377   virtual scoped_ptr<cc::Animation> CreateCCAnimation() = 0;
378 
379  private:
380   DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement);
381 };
382 
383 // ThreadedOpacityTransition ---------------------------------------------------
384 
385 class ThreadedOpacityTransition : public ThreadedLayerAnimationElement {
386  public:
ThreadedOpacityTransition(float target,base::TimeDelta duration)387   ThreadedOpacityTransition(float target, base::TimeDelta duration)
388       : ThreadedLayerAnimationElement(OPACITY, duration),
389         start_(0.0f),
390         target_(target) {
391   }
~ThreadedOpacityTransition()392   virtual ~ThreadedOpacityTransition() {}
393 
394  protected:
OnStart(LayerAnimationDelegate * delegate)395   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
396     start_ = delegate->GetOpacityForAnimation();
397   }
398 
OnAbort(LayerAnimationDelegate * delegate)399   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
400     if (delegate && Started()) {
401       ThreadedLayerAnimationElement::OnAbort(delegate);
402       delegate->SetOpacityFromAnimation(gfx::Tween::FloatValueBetween(
403           gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
404               start_,
405               target_));
406     }
407   }
408 
OnEnd(LayerAnimationDelegate * delegate)409   virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
410     delegate->SetOpacityFromAnimation(target_);
411   }
412 
CreateCCAnimation()413   virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
414     scoped_ptr<cc::AnimationCurve> animation_curve(
415         new FloatAnimationCurveAdapter(tween_type(),
416                                        start_,
417                                        target_,
418                                        duration()));
419     scoped_ptr<cc::Animation> animation(
420         cc::Animation::Create(animation_curve.Pass(),
421                               animation_id(),
422                               animation_group_id(),
423                               cc::Animation::Opacity));
424     return animation.Pass();
425   }
426 
OnGetTarget(TargetValue * target) const427   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
428     target->opacity = target_;
429   }
430 
431  private:
432   float start_;
433   const float target_;
434 
435   DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition);
436 };
437 
438 // ThreadedTransformTransition -------------------------------------------------
439 
440 class ThreadedTransformTransition : public ThreadedLayerAnimationElement {
441  public:
ThreadedTransformTransition(const gfx::Transform & target,base::TimeDelta duration)442   ThreadedTransformTransition(const gfx::Transform& target,
443                               base::TimeDelta duration)
444       : ThreadedLayerAnimationElement(TRANSFORM, duration),
445         target_(target) {
446   }
~ThreadedTransformTransition()447   virtual ~ThreadedTransformTransition() {}
448 
449  protected:
OnStart(LayerAnimationDelegate * delegate)450   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
451     start_ = delegate->GetTransformForAnimation();
452   }
453 
OnAbort(LayerAnimationDelegate * delegate)454   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
455     if (delegate && Started()) {
456       ThreadedLayerAnimationElement::OnAbort(delegate);
457       delegate->SetTransformFromAnimation(gfx::Tween::TransformValueBetween(
458           gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
459           start_,
460           target_));
461     }
462   }
463 
OnEnd(LayerAnimationDelegate * delegate)464   virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
465     delegate->SetTransformFromAnimation(target_);
466   }
467 
CreateCCAnimation()468   virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
469     scoped_ptr<cc::AnimationCurve> animation_curve(
470         new TransformAnimationCurveAdapter(tween_type(),
471                                            start_,
472                                            target_,
473                                            duration()));
474     scoped_ptr<cc::Animation> animation(
475         cc::Animation::Create(animation_curve.Pass(),
476                               animation_id(),
477                               animation_group_id(),
478                               cc::Animation::Transform));
479     return animation.Pass();
480   }
481 
OnGetTarget(TargetValue * target) const482   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
483     target->transform = target_;
484   }
485 
486  private:
487   gfx::Transform start_;
488   const gfx::Transform target_;
489 
490   DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition);
491 };
492 
493 // InverseTransformTransision --------------------------------------------------
494 
495 class InverseTransformTransition : public ThreadedLayerAnimationElement {
496  public:
InverseTransformTransition(const gfx::Transform & base_transform,const LayerAnimationElement * uninverted_transition)497   InverseTransformTransition(const gfx::Transform& base_transform,
498                              const LayerAnimationElement* uninverted_transition)
499       : ThreadedLayerAnimationElement(*uninverted_transition),
500         base_transform_(base_transform),
501         uninverted_transition_(
502             CheckAndCast<const ThreadedTransformTransition*>(
503               uninverted_transition)) {
504   }
~InverseTransformTransition()505   virtual ~InverseTransformTransition() {}
506 
Clone(const LayerAnimationElement * other)507   static InverseTransformTransition* Clone(const LayerAnimationElement* other) {
508     const InverseTransformTransition* other_inverse =
509       CheckAndCast<const InverseTransformTransition*>(other);
510     return new InverseTransformTransition(
511         other_inverse->base_transform_, other_inverse->uninverted_transition_);
512   }
513 
514  protected:
OnStart(LayerAnimationDelegate * delegate)515   virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
516     gfx::Transform start(delegate->GetTransformForAnimation());
517     effective_start_ = base_transform_ * start;
518 
519     TargetValue target;
520     uninverted_transition_->GetTargetValue(&target);
521     base_target_ = target.transform;
522 
523     set_tween_type(uninverted_transition_->tween_type());
524 
525     TransformAnimationCurveAdapter base_curve(tween_type(),
526                                               base_transform_,
527                                               base_target_,
528                                               duration());
529 
530     animation_curve_.reset(new InverseTransformCurveAdapter(
531         base_curve, start, duration()));
532     computed_target_transform_ = ComputeWithBaseTransform(effective_start_,
533                                                           base_target_);
534   }
535 
OnAbort(LayerAnimationDelegate * delegate)536   virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
537     if (delegate && Started()) {
538       ThreadedLayerAnimationElement::OnAbort(delegate);
539       delegate->SetTransformFromAnimation(ComputeCurrentTransform());
540     }
541   }
542 
OnEnd(LayerAnimationDelegate * delegate)543   virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
544     delegate->SetTransformFromAnimation(computed_target_transform_);
545   }
546 
CreateCCAnimation()547   virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
548     scoped_ptr<cc::Animation> animation(
549         cc::Animation::Create(animation_curve_->Clone(),
550                               animation_id(),
551                               animation_group_id(),
552                               cc::Animation::Transform));
553     return animation.Pass();
554   }
555 
OnGetTarget(TargetValue * target) const556   virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
557     target->transform = computed_target_transform_;
558   }
559 
560  private:
ComputeCurrentTransform() const561   gfx::Transform ComputeCurrentTransform() const {
562     gfx::Transform base_current = gfx::Tween::TransformValueBetween(
563         gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
564         base_transform_,
565         base_target_);
566     return ComputeWithBaseTransform(effective_start_, base_current);
567   }
568 
ComputeWithBaseTransform(gfx::Transform start,gfx::Transform target) const569   gfx::Transform ComputeWithBaseTransform(gfx::Transform start,
570                                           gfx::Transform target) const {
571     gfx::Transform to_return(gfx::Transform::kSkipInitialization);
572     bool success = target.GetInverse(&to_return);
573     DCHECK(success) << "Target transform must be invertible.";
574 
575     to_return.PreconcatTransform(start);
576     return to_return;
577   }
578 
579   template <typename T>
CheckAndCast(const LayerAnimationElement * element)580   static T CheckAndCast(const LayerAnimationElement* element) {
581     AnimatableProperties properties = element->properties();
582     DCHECK(properties & TRANSFORM);
583     return static_cast<T>(element);
584   }
585 
586   gfx::Transform effective_start_;
587   gfx::Transform computed_target_transform_;
588 
589   const gfx::Transform base_transform_;
590   gfx::Transform base_target_;
591 
592   scoped_ptr<cc::AnimationCurve> animation_curve_;
593 
594   const ThreadedTransformTransition* const uninverted_transition_;
595 
596   DISALLOW_COPY_AND_ASSIGN(InverseTransformTransition);
597 };
598 
599 }  // namespace
600 
601 // LayerAnimationElement::TargetValue ------------------------------------------
602 
TargetValue()603 LayerAnimationElement::TargetValue::TargetValue()
604     : opacity(0.0f),
605       visibility(false),
606       brightness(0.0f),
607       grayscale(0.0f),
608       color(SK_ColorBLACK) {
609 }
610 
TargetValue(const LayerAnimationDelegate * delegate)611 LayerAnimationElement::TargetValue::TargetValue(
612     const LayerAnimationDelegate* delegate)
613     : bounds(delegate ? delegate->GetBoundsForAnimation() : gfx::Rect()),
614       transform(delegate ?
615                 delegate->GetTransformForAnimation() : gfx::Transform()),
616       opacity(delegate ? delegate->GetOpacityForAnimation() : 0.0f),
617       visibility(delegate ? delegate->GetVisibilityForAnimation() : false),
618       brightness(delegate ? delegate->GetBrightnessForAnimation() : 0.0f),
619       grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f),
620       color(delegate ? delegate->GetColorForAnimation() : 0.0f) {
621 }
622 
623 // LayerAnimationElement -------------------------------------------------------
624 
LayerAnimationElement(AnimatableProperties properties,base::TimeDelta duration)625 LayerAnimationElement::LayerAnimationElement(
626     AnimatableProperties properties, base::TimeDelta duration)
627     : first_frame_(true),
628       properties_(properties),
629       duration_(GetEffectiveDuration(duration)),
630       tween_type_(gfx::Tween::LINEAR),
631       animation_id_(cc::AnimationIdProvider::NextAnimationId()),
632       animation_group_id_(0),
633       last_progressed_fraction_(0.0),
634       weak_ptr_factory_(this) {
635 }
636 
LayerAnimationElement(const LayerAnimationElement & element)637 LayerAnimationElement::LayerAnimationElement(
638     const LayerAnimationElement &element)
639     : first_frame_(element.first_frame_),
640       properties_(element.properties_),
641       duration_(element.duration_),
642       tween_type_(element.tween_type_),
643       animation_id_(cc::AnimationIdProvider::NextAnimationId()),
644       animation_group_id_(element.animation_group_id_),
645       last_progressed_fraction_(element.last_progressed_fraction_),
646       weak_ptr_factory_(this) {
647 }
648 
~LayerAnimationElement()649 LayerAnimationElement::~LayerAnimationElement() {
650 }
651 
Start(LayerAnimationDelegate * delegate,int animation_group_id)652 void LayerAnimationElement::Start(LayerAnimationDelegate* delegate,
653                                   int animation_group_id) {
654   DCHECK(requested_start_time_ != base::TimeTicks());
655   DCHECK(first_frame_);
656   animation_group_id_ = animation_group_id;
657   last_progressed_fraction_ = 0.0;
658   OnStart(delegate);
659   RequestEffectiveStart(delegate);
660   first_frame_ = false;
661 }
662 
Progress(base::TimeTicks now,LayerAnimationDelegate * delegate)663 bool LayerAnimationElement::Progress(base::TimeTicks now,
664                                      LayerAnimationDelegate* delegate) {
665   DCHECK(requested_start_time_ != base::TimeTicks());
666   DCHECK(!first_frame_);
667 
668   bool need_draw;
669   double t = 1.0;
670 
671   if ((effective_start_time_ == base::TimeTicks()) ||
672       (now < effective_start_time_))  {
673     // This hasn't actually started yet.
674     need_draw = false;
675     last_progressed_fraction_ = 0.0;
676     return need_draw;
677   }
678 
679   base::TimeDelta elapsed = now - effective_start_time_;
680   if ((duration_ > base::TimeDelta()) && (elapsed < duration_))
681     t = elapsed.InMillisecondsF() / duration_.InMillisecondsF();
682   base::WeakPtr<LayerAnimationElement> alive(weak_ptr_factory_.GetWeakPtr());
683   need_draw = OnProgress(gfx::Tween::CalculateValue(tween_type_, t), delegate);
684   if (!alive)
685     return need_draw;
686   first_frame_ = t == 1.0;
687   last_progressed_fraction_ = t;
688   return need_draw;
689 }
690 
IsFinished(base::TimeTicks time,base::TimeDelta * total_duration)691 bool LayerAnimationElement::IsFinished(base::TimeTicks time,
692                                        base::TimeDelta* total_duration) {
693   // If an effective start has been requested but the effective start time
694   // hasn't yet been set, the animation is not finished, regardless of the
695   // value of |time|.
696   if (!first_frame_ && (effective_start_time_ == base::TimeTicks()))
697     return false;
698 
699   base::TimeDelta queueing_delay;
700   if (!first_frame_)
701     queueing_delay = effective_start_time_ - requested_start_time_;
702 
703   base::TimeDelta elapsed = time - requested_start_time_;
704   if (elapsed >= duration_ + queueing_delay) {
705     *total_duration = duration_ + queueing_delay;
706     return true;
707   }
708   return false;
709 }
710 
ProgressToEnd(LayerAnimationDelegate * delegate)711 bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate* delegate) {
712   if (first_frame_)
713     OnStart(delegate);
714   base::WeakPtr<LayerAnimationElement> alive(weak_ptr_factory_.GetWeakPtr());
715   bool need_draw = OnProgress(1.0, delegate);
716   if (!alive)
717     return need_draw;
718   last_progressed_fraction_ = 1.0;
719   first_frame_ = true;
720   return need_draw;
721 }
722 
GetTargetValue(TargetValue * target) const723 void LayerAnimationElement::GetTargetValue(TargetValue* target) const {
724   OnGetTarget(target);
725 }
726 
IsThreaded() const727 bool LayerAnimationElement::IsThreaded() const {
728   return false;
729 }
730 
Abort(LayerAnimationDelegate * delegate)731 void LayerAnimationElement::Abort(LayerAnimationDelegate* delegate) {
732   OnAbort(delegate);
733   first_frame_ = true;
734 }
735 
RequestEffectiveStart(LayerAnimationDelegate * delegate)736 void LayerAnimationElement::RequestEffectiveStart(
737     LayerAnimationDelegate* delegate) {
738   DCHECK(requested_start_time_ != base::TimeTicks());
739   effective_start_time_ = requested_start_time_;
740 }
741 
742 // static
743 LayerAnimationElement::AnimatableProperty
ToAnimatableProperty(cc::Animation::TargetProperty property)744 LayerAnimationElement::ToAnimatableProperty(
745     cc::Animation::TargetProperty property) {
746   switch (property) {
747     case cc::Animation::Transform:
748       return TRANSFORM;
749     case cc::Animation::Opacity:
750       return OPACITY;
751     default:
752       NOTREACHED();
753       return AnimatableProperty();
754   }
755 }
756 
757 // static
GetEffectiveDuration(const base::TimeDelta & duration)758 base::TimeDelta LayerAnimationElement::GetEffectiveDuration(
759     const base::TimeDelta& duration) {
760   switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) {
761     case ScopedAnimationDurationScaleMode::NORMAL_DURATION:
762       return duration;
763     case ScopedAnimationDurationScaleMode::FAST_DURATION:
764       return duration / kFastDurationScaleDivisor;
765     case ScopedAnimationDurationScaleMode::SLOW_DURATION:
766       return duration * kSlowDurationScaleMultiplier;
767     case ScopedAnimationDurationScaleMode::NON_ZERO_DURATION:
768       return duration / kNonZeroDurationScaleDivisor;
769     case ScopedAnimationDurationScaleMode::ZERO_DURATION:
770       return base::TimeDelta();
771     default:
772       NOTREACHED();
773       return base::TimeDelta();
774   }
775 }
776 
777 // static
CreateTransformElement(const gfx::Transform & transform,base::TimeDelta duration)778 LayerAnimationElement* LayerAnimationElement::CreateTransformElement(
779     const gfx::Transform& transform,
780     base::TimeDelta duration) {
781   return new ThreadedTransformTransition(transform, duration);
782 }
783 
784 // static
CreateInverseTransformElement(const gfx::Transform & base_transform,const LayerAnimationElement * uninverted_transition)785 LayerAnimationElement* LayerAnimationElement::CreateInverseTransformElement(
786     const gfx::Transform& base_transform,
787     const LayerAnimationElement* uninverted_transition) {
788   return new InverseTransformTransition(base_transform, uninverted_transition);
789 }
790 
791 // static
CloneInverseTransformElement(const LayerAnimationElement * other)792 LayerAnimationElement* LayerAnimationElement::CloneInverseTransformElement(
793     const LayerAnimationElement* other) {
794   return InverseTransformTransition::Clone(other);
795 }
796 
797 // static
798 LayerAnimationElement*
CreateInterpolatedTransformElement(InterpolatedTransform * interpolated_transform,base::TimeDelta duration)799 LayerAnimationElement::CreateInterpolatedTransformElement(
800     InterpolatedTransform* interpolated_transform,
801     base::TimeDelta duration) {
802   return new InterpolatedTransformTransition(interpolated_transform, duration);
803 }
804 
805 // static
CreateBoundsElement(const gfx::Rect & bounds,base::TimeDelta duration)806 LayerAnimationElement* LayerAnimationElement::CreateBoundsElement(
807     const gfx::Rect& bounds,
808     base::TimeDelta duration) {
809   return new BoundsTransition(bounds, duration);
810 }
811 
812 // static
CreateOpacityElement(float opacity,base::TimeDelta duration)813 LayerAnimationElement* LayerAnimationElement::CreateOpacityElement(
814     float opacity,
815     base::TimeDelta duration) {
816   return new ThreadedOpacityTransition(opacity, duration);
817 }
818 
819 // static
CreateVisibilityElement(bool visibility,base::TimeDelta duration)820 LayerAnimationElement* LayerAnimationElement::CreateVisibilityElement(
821     bool visibility,
822     base::TimeDelta duration) {
823   return new VisibilityTransition(visibility, duration);
824 }
825 
826 // static
CreateBrightnessElement(float brightness,base::TimeDelta duration)827 LayerAnimationElement* LayerAnimationElement::CreateBrightnessElement(
828     float brightness,
829     base::TimeDelta duration) {
830   return new BrightnessTransition(brightness, duration);
831 }
832 
833 // static
CreateGrayscaleElement(float grayscale,base::TimeDelta duration)834 LayerAnimationElement* LayerAnimationElement::CreateGrayscaleElement(
835     float grayscale,
836     base::TimeDelta duration) {
837   return new GrayscaleTransition(grayscale, duration);
838 }
839 
840 // static
CreatePauseElement(AnimatableProperties properties,base::TimeDelta duration)841 LayerAnimationElement* LayerAnimationElement::CreatePauseElement(
842     AnimatableProperties properties,
843     base::TimeDelta duration) {
844   return new Pause(properties, duration);
845 }
846 
847 // static
CreateColorElement(SkColor color,base::TimeDelta duration)848 LayerAnimationElement* LayerAnimationElement::CreateColorElement(
849     SkColor color,
850     base::TimeDelta duration) {
851   return new ColorTransition(color, duration);
852 }
853 
854 }  // namespace ui
855