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.
5 #include "ui/compositor/layer_animation_element.h"
7 #include "base/compiler_specific.h"
8 #include "cc/animation/animation.h"
9 #include "cc/animation/animation_id_provider.h"
10 #include "ui/base/animation/tween.h"
11 #include "ui/compositor/float_animation_curve_adapter.h"
12 #include "ui/compositor/layer.h"
13 #include "ui/compositor/layer_animation_delegate.h"
14 #include "ui/compositor/layer_animator.h"
15 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
16 #include "ui/compositor/transform_animation_curve_adapter.h"
17 #include "ui/gfx/interpolated_transform.h"
23 // The factor by which duration is scaled up or down when
24 // ScopedAnimationDurationScaleMode::duration_scale_mode() is SLOW_DURATION or
26 const int kSlowDurationScaleFactor
= 4;
27 const int kFastDurationScaleFactor
= 4;
29 // Pause -----------------------------------------------------------------------
30 class Pause
: public LayerAnimationElement
{
32 Pause(const AnimatableProperties
& properties
, base::TimeDelta duration
)
33 : LayerAnimationElement(properties
, duration
) {
38 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
39 virtual bool OnProgress(double t
,
40 LayerAnimationDelegate
* delegate
) OVERRIDE
{
43 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{}
44 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
46 DISALLOW_COPY_AND_ASSIGN(Pause
);
49 // TransformTransition ---------------------------------------------------------
51 class TransformTransition
: public LayerAnimationElement
{
53 TransformTransition(const gfx::Transform
& target
, base::TimeDelta duration
)
54 : LayerAnimationElement(GetProperties(), duration
),
57 virtual ~TransformTransition() {}
60 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
61 start_
= delegate
->GetTransformForAnimation();
64 virtual bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) OVERRIDE
{
65 delegate
->SetTransformFromAnimation(
66 Tween::ValueBetween(t
, start_
, target_
));
70 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
71 target
->transform
= target_
;
74 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
77 static AnimatableProperties
GetProperties() {
78 AnimatableProperties properties
;
79 properties
.insert(LayerAnimationElement::TRANSFORM
);
83 gfx::Transform start_
;
84 const gfx::Transform target_
;
86 DISALLOW_COPY_AND_ASSIGN(TransformTransition
);
89 // InterpolatedTransformTransition ---------------------------------------------
91 class InterpolatedTransformTransition
: public LayerAnimationElement
{
93 InterpolatedTransformTransition(InterpolatedTransform
* interpolated_transform
,
94 base::TimeDelta duration
)
95 : LayerAnimationElement(GetProperties(), duration
),
96 interpolated_transform_(interpolated_transform
) {
98 virtual ~InterpolatedTransformTransition() {}
101 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
104 virtual bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) OVERRIDE
{
105 delegate
->SetTransformFromAnimation(
106 interpolated_transform_
->Interpolate(static_cast<float>(t
)));
110 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
111 target
->transform
= interpolated_transform_
->Interpolate(1.0f
);
114 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
117 static AnimatableProperties
GetProperties() {
118 AnimatableProperties properties
;
119 properties
.insert(LayerAnimationElement::TRANSFORM
);
123 scoped_ptr
<InterpolatedTransform
> interpolated_transform_
;
125 DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformTransition
);
128 // BoundsTransition ------------------------------------------------------------
130 class BoundsTransition
: public LayerAnimationElement
{
132 BoundsTransition(const gfx::Rect
& target
, base::TimeDelta duration
)
133 : LayerAnimationElement(GetProperties(), duration
),
136 virtual ~BoundsTransition() {}
139 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
140 start_
= delegate
->GetBoundsForAnimation();
143 virtual bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) OVERRIDE
{
144 delegate
->SetBoundsFromAnimation(Tween::ValueBetween(t
, start_
, target_
));
148 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
149 target
->bounds
= target_
;
152 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
155 static AnimatableProperties
GetProperties() {
156 AnimatableProperties properties
;
157 properties
.insert(LayerAnimationElement::BOUNDS
);
162 const gfx::Rect target_
;
164 DISALLOW_COPY_AND_ASSIGN(BoundsTransition
);
167 // OpacityTransition -----------------------------------------------------------
169 class OpacityTransition
: public LayerAnimationElement
{
171 OpacityTransition(float target
, base::TimeDelta duration
)
172 : LayerAnimationElement(GetProperties(), duration
),
176 virtual ~OpacityTransition() {}
179 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
180 start_
= delegate
->GetOpacityForAnimation();
183 virtual bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) OVERRIDE
{
184 delegate
->SetOpacityFromAnimation(Tween::ValueBetween(t
, start_
, target_
));
188 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
189 target
->opacity
= target_
;
192 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
195 static AnimatableProperties
GetProperties() {
196 AnimatableProperties properties
;
197 properties
.insert(LayerAnimationElement::OPACITY
);
204 DISALLOW_COPY_AND_ASSIGN(OpacityTransition
);
207 // VisibilityTransition --------------------------------------------------------
209 class VisibilityTransition
: public LayerAnimationElement
{
211 VisibilityTransition(bool target
, base::TimeDelta duration
)
212 : LayerAnimationElement(GetProperties(), duration
),
216 virtual ~VisibilityTransition() {}
219 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
220 start_
= delegate
->GetVisibilityForAnimation();
223 virtual bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) OVERRIDE
{
224 delegate
->SetVisibilityFromAnimation(t
== 1.0 ? target_
: start_
);
228 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
229 target
->visibility
= target_
;
232 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
235 static AnimatableProperties
GetProperties() {
236 AnimatableProperties properties
;
237 properties
.insert(LayerAnimationElement::VISIBILITY
);
244 DISALLOW_COPY_AND_ASSIGN(VisibilityTransition
);
247 // BrightnessTransition --------------------------------------------------------
249 class BrightnessTransition
: public LayerAnimationElement
{
251 BrightnessTransition(float target
, base::TimeDelta duration
)
252 : LayerAnimationElement(GetProperties(), duration
),
256 virtual ~BrightnessTransition() {}
259 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
260 start_
= delegate
->GetBrightnessForAnimation();
263 virtual bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) OVERRIDE
{
264 delegate
->SetBrightnessFromAnimation(
265 Tween::ValueBetween(t
, start_
, target_
));
269 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
270 target
->brightness
= target_
;
273 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
276 static AnimatableProperties
GetProperties() {
277 AnimatableProperties properties
;
278 properties
.insert(LayerAnimationElement::BRIGHTNESS
);
285 DISALLOW_COPY_AND_ASSIGN(BrightnessTransition
);
288 // GrayscaleTransition ---------------------------------------------------------
290 class GrayscaleTransition
: public LayerAnimationElement
{
292 GrayscaleTransition(float target
, base::TimeDelta duration
)
293 : LayerAnimationElement(GetProperties(), duration
),
297 virtual ~GrayscaleTransition() {}
300 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
301 start_
= delegate
->GetGrayscaleForAnimation();
304 virtual bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) OVERRIDE
{
305 delegate
->SetGrayscaleFromAnimation(
306 Tween::ValueBetween(t
, start_
, target_
));
310 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
311 target
->grayscale
= target_
;
314 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
317 static AnimatableProperties
GetProperties() {
318 AnimatableProperties properties
;
319 properties
.insert(LayerAnimationElement::GRAYSCALE
);
326 DISALLOW_COPY_AND_ASSIGN(GrayscaleTransition
);
329 // ColorTransition -------------------------------------------------------------
331 class ColorTransition
: public LayerAnimationElement
{
333 ColorTransition(SkColor target
, base::TimeDelta duration
)
334 : LayerAnimationElement(GetProperties(), duration
),
335 start_(SK_ColorBLACK
),
338 virtual ~ColorTransition() {}
341 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
342 start_
= delegate
->GetColorForAnimation();
345 virtual bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) OVERRIDE
{
346 delegate
->SetColorFromAnimation(
348 Tween::ValueBetween(t
,
349 static_cast<int>(SkColorGetA(start_
)),
350 static_cast<int>(SkColorGetA(target_
))),
351 Tween::ValueBetween(t
,
352 static_cast<int>(SkColorGetR(start_
)),
353 static_cast<int>(SkColorGetR(target_
))),
354 Tween::ValueBetween(t
,
355 static_cast<int>(SkColorGetG(start_
)),
356 static_cast<int>(SkColorGetG(target_
))),
357 Tween::ValueBetween(t
,
358 static_cast<int>(SkColorGetB(start_
)),
359 static_cast<int>(SkColorGetB(target_
)))));
363 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
364 target
->color
= target_
;
367 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{}
370 static AnimatableProperties
GetProperties() {
371 AnimatableProperties properties
;
372 properties
.insert(LayerAnimationElement::COLOR
);
377 const SkColor target_
;
379 DISALLOW_COPY_AND_ASSIGN(ColorTransition
);
382 // ThreadedLayerAnimationElement -----------------------------------------------
384 class ThreadedLayerAnimationElement
: public LayerAnimationElement
{
386 ThreadedLayerAnimationElement(const AnimatableProperties
& properties
,
387 base::TimeDelta duration
)
388 : LayerAnimationElement(properties
, duration
) {
390 virtual ~ThreadedLayerAnimationElement() {}
392 virtual bool IsThreaded() const OVERRIDE
{
393 return (duration() != base::TimeDelta());
397 virtual bool OnProgress(double t
,
398 LayerAnimationDelegate
* delegate
) OVERRIDE
{
403 delegate
->RemoveThreadedAnimation(animation_id());
410 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{
411 if (delegate
&& Started()) {
412 delegate
->RemoveThreadedAnimation(animation_id());
416 virtual void RequestEffectiveStart(
417 LayerAnimationDelegate
* delegate
) OVERRIDE
{
418 DCHECK(animation_group_id());
419 if (duration() == base::TimeDelta()) {
420 set_effective_start_time(requested_start_time());
423 set_effective_start_time(base::TimeTicks());
424 scoped_ptr
<cc::Animation
> animation
= CreateCCAnimation();
425 animation
->set_needs_synchronized_start_time(true);
426 delegate
->AddThreadedAnimation(animation
.Pass());
429 virtual void OnEnd(LayerAnimationDelegate
* delegate
) = 0;
431 virtual scoped_ptr
<cc::Animation
> CreateCCAnimation() = 0;
434 DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement
);
437 // ThreadedOpacityTransition ---------------------------------------------------
439 class ThreadedOpacityTransition
: public ThreadedLayerAnimationElement
{
441 ThreadedOpacityTransition(float target
, base::TimeDelta duration
)
442 : ThreadedLayerAnimationElement(GetProperties(), duration
),
446 virtual ~ThreadedOpacityTransition() {}
449 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
450 start_
= delegate
->GetOpacityForAnimation();
453 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{
454 if (delegate
&& Started()) {
455 ThreadedLayerAnimationElement::OnAbort(delegate
);
456 delegate
->SetOpacityFromAnimation(Tween::ValueBetween(
457 Tween::CalculateValue(tween_type(), last_progressed_fraction()),
463 virtual void OnEnd(LayerAnimationDelegate
* delegate
) OVERRIDE
{
464 delegate
->SetOpacityFromAnimation(target_
);
467 virtual scoped_ptr
<cc::Animation
> CreateCCAnimation() OVERRIDE
{
468 scoped_ptr
<cc::AnimationCurve
> animation_curve(
469 new FloatAnimationCurveAdapter(tween_type(),
473 scoped_ptr
<cc::Animation
> animation(
474 cc::Animation::Create(animation_curve
.Pass(),
476 animation_group_id(),
477 cc::Animation::Opacity
));
478 return animation
.Pass();
481 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
482 target
->opacity
= target_
;
486 static AnimatableProperties
GetProperties() {
487 AnimatableProperties properties
;
488 properties
.insert(LayerAnimationElement::OPACITY
);
495 DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition
);
498 // ThreadedTransformTransition -------------------------------------------------
500 class ThreadedTransformTransition
: public ThreadedLayerAnimationElement
{
502 ThreadedTransformTransition(const gfx::Transform
& target
,
503 base::TimeDelta duration
)
504 : ThreadedLayerAnimationElement(GetProperties(), duration
),
507 virtual ~ThreadedTransformTransition() {}
510 virtual void OnStart(LayerAnimationDelegate
* delegate
) OVERRIDE
{
511 start_
= delegate
->GetTransformForAnimation();
512 float device_scale_factor
= delegate
->GetDeviceScaleFactor();
513 cc_start_
= Layer::ConvertTransformToCCTransform(start_
,
514 device_scale_factor
);
515 cc_target_
= Layer::ConvertTransformToCCTransform(target_
,
516 device_scale_factor
);
519 virtual void OnAbort(LayerAnimationDelegate
* delegate
) OVERRIDE
{
520 if (delegate
&& Started()) {
521 ThreadedLayerAnimationElement::OnAbort(delegate
);
522 delegate
->SetTransformFromAnimation(Tween::ValueBetween(
523 Tween::CalculateValue(tween_type(), last_progressed_fraction()),
529 virtual void OnEnd(LayerAnimationDelegate
* delegate
) OVERRIDE
{
530 delegate
->SetTransformFromAnimation(target_
);
533 virtual scoped_ptr
<cc::Animation
> CreateCCAnimation() OVERRIDE
{
534 scoped_ptr
<cc::AnimationCurve
> animation_curve(
535 new TransformAnimationCurveAdapter(tween_type(),
539 scoped_ptr
<cc::Animation
> animation(
540 cc::Animation::Create(animation_curve
.Pass(),
542 animation_group_id(),
543 cc::Animation::Transform
));
544 return animation
.Pass();
547 virtual void OnGetTarget(TargetValue
* target
) const OVERRIDE
{
548 target
->transform
= target_
;
552 static AnimatableProperties
GetProperties() {
553 AnimatableProperties properties
;
554 properties
.insert(LayerAnimationElement::TRANSFORM
);
558 gfx::Transform start_
;
559 gfx::Transform cc_start_
;
560 const gfx::Transform target_
;
561 gfx::Transform cc_target_
;
563 DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition
);
568 // LayerAnimationElement::TargetValue ------------------------------------------
570 LayerAnimationElement::TargetValue::TargetValue()
575 color(SK_ColorBLACK
) {
578 LayerAnimationElement::TargetValue::TargetValue(
579 const LayerAnimationDelegate
* delegate
)
580 : bounds(delegate
? delegate
->GetBoundsForAnimation() : gfx::Rect()),
582 delegate
->GetTransformForAnimation() : gfx::Transform()),
583 opacity(delegate
? delegate
->GetOpacityForAnimation() : 0.0f
),
584 visibility(delegate
? delegate
->GetVisibilityForAnimation() : false),
585 brightness(delegate
? delegate
->GetBrightnessForAnimation() : 0.0f
),
586 grayscale(delegate
? delegate
->GetGrayscaleForAnimation() : 0.0f
),
587 color(delegate
? delegate
->GetColorForAnimation() : 0.0f
) {
590 // LayerAnimationElement -------------------------------------------------------
592 LayerAnimationElement::LayerAnimationElement(
593 const AnimatableProperties
& properties
,
594 base::TimeDelta duration
)
595 : first_frame_(true),
596 properties_(properties
),
597 duration_(GetEffectiveDuration(duration
)),
598 tween_type_(Tween::LINEAR
),
599 animation_id_(cc::AnimationIdProvider::NextAnimationId()),
600 animation_group_id_(0),
601 last_progressed_fraction_(0.0) {
604 LayerAnimationElement::~LayerAnimationElement() {
607 void LayerAnimationElement::Start(LayerAnimationDelegate
* delegate
,
608 int animation_group_id
) {
609 DCHECK(requested_start_time_
!= base::TimeTicks());
610 DCHECK(first_frame_
);
611 animation_group_id_
= animation_group_id
;
612 last_progressed_fraction_
= 0.0;
614 RequestEffectiveStart(delegate
);
615 first_frame_
= false;
618 bool LayerAnimationElement::Progress(base::TimeTicks now
,
619 LayerAnimationDelegate
* delegate
) {
620 DCHECK(requested_start_time_
!= base::TimeTicks());
621 DCHECK(!first_frame_
);
626 if ((effective_start_time_
== base::TimeTicks()) ||
627 (now
< effective_start_time_
)) {
628 // This hasn't actually started yet.
630 last_progressed_fraction_
= 0.0;
634 base::TimeDelta elapsed
= now
- effective_start_time_
;
635 if ((duration_
> base::TimeDelta()) && (elapsed
< duration_
))
636 t
= elapsed
.InMillisecondsF() / duration_
.InMillisecondsF();
637 need_draw
= OnProgress(Tween::CalculateValue(tween_type_
, t
), delegate
);
638 first_frame_
= t
== 1.0;
639 last_progressed_fraction_
= t
;
643 bool LayerAnimationElement::IsFinished(base::TimeTicks time
,
644 base::TimeDelta
* total_duration
) {
645 // If an effective start has been requested but the effective start time
646 // hasn't yet been set, the animation is not finished, regardless of the
648 if (!first_frame_
&& (effective_start_time_
== base::TimeTicks()))
651 base::TimeDelta queueing_delay
;
653 queueing_delay
= effective_start_time_
- requested_start_time_
;
655 base::TimeDelta elapsed
= time
- requested_start_time_
;
656 if (elapsed
>= duration_
+ queueing_delay
) {
657 *total_duration
= duration_
+ queueing_delay
;
663 bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate
* delegate
) {
666 bool need_draw
= OnProgress(1.0, delegate
);
667 last_progressed_fraction_
= 1.0;
672 void LayerAnimationElement::GetTargetValue(TargetValue
* target
) const {
676 bool LayerAnimationElement::IsThreaded() const {
680 void LayerAnimationElement::Abort(LayerAnimationDelegate
* delegate
) {
685 void LayerAnimationElement::RequestEffectiveStart(
686 LayerAnimationDelegate
* delegate
) {
687 DCHECK(requested_start_time_
!= base::TimeTicks());
688 effective_start_time_
= requested_start_time_
;
692 LayerAnimationElement::AnimatableProperty
693 LayerAnimationElement::ToAnimatableProperty(
694 cc::Animation::TargetProperty property
) {
696 case cc::Animation::Transform
:
698 case cc::Animation::Opacity
:
702 return AnimatableProperty();
707 base::TimeDelta
LayerAnimationElement::GetEffectiveDuration(
708 const base::TimeDelta
& duration
) {
709 switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) {
710 case ScopedAnimationDurationScaleMode::NORMAL_DURATION
:
712 case ScopedAnimationDurationScaleMode::FAST_DURATION
:
713 return duration
/ kFastDurationScaleFactor
;
714 case ScopedAnimationDurationScaleMode::SLOW_DURATION
:
715 return duration
* kSlowDurationScaleFactor
;
716 case ScopedAnimationDurationScaleMode::ZERO_DURATION
:
717 return base::TimeDelta();
720 return base::TimeDelta();
725 LayerAnimationElement
* LayerAnimationElement::CreateTransformElement(
726 const gfx::Transform
& transform
,
727 base::TimeDelta duration
) {
728 return new ThreadedTransformTransition(transform
, duration
);
732 LayerAnimationElement
*
733 LayerAnimationElement::CreateInterpolatedTransformElement(
734 InterpolatedTransform
* interpolated_transform
,
735 base::TimeDelta duration
) {
736 return new InterpolatedTransformTransition(interpolated_transform
, duration
);
740 LayerAnimationElement
* LayerAnimationElement::CreateBoundsElement(
741 const gfx::Rect
& bounds
,
742 base::TimeDelta duration
) {
743 return new BoundsTransition(bounds
, duration
);
747 LayerAnimationElement
* LayerAnimationElement::CreateOpacityElement(
749 base::TimeDelta duration
) {
750 return new ThreadedOpacityTransition(opacity
, duration
);
754 LayerAnimationElement
* LayerAnimationElement::CreateVisibilityElement(
756 base::TimeDelta duration
) {
757 return new VisibilityTransition(visibility
, duration
);
761 LayerAnimationElement
* LayerAnimationElement::CreateBrightnessElement(
763 base::TimeDelta duration
) {
764 return new BrightnessTransition(brightness
, duration
);
768 LayerAnimationElement
* LayerAnimationElement::CreateGrayscaleElement(
770 base::TimeDelta duration
) {
771 return new GrayscaleTransition(grayscale
, duration
);
775 LayerAnimationElement
* LayerAnimationElement::CreatePauseElement(
776 const AnimatableProperties
& properties
,
777 base::TimeDelta duration
) {
778 return new Pause(properties
, duration
);
782 LayerAnimationElement
* LayerAnimationElement::CreateColorElement(
784 base::TimeDelta duration
) {
785 return new ColorTransition(color
, duration
);