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