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