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