layer_animation_controller.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
1// Copyright 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 "cc/animation/layer_animation_controller.h"
6
7#include <algorithm>
8
9#include "cc/animation/animation.h"
10#include "cc/animation/animation_delegate.h"
11#include "cc/animation/animation_registrar.h"
12#include "cc/animation/keyframed_animation_curve.h"
13#include "cc/animation/layer_animation_value_observer.h"
14#include "cc/base/scoped_ptr_algorithm.h"
15#include "cc/output/filter_operations.h"
16#include "ui/gfx/box_f.h"
17#include "ui/gfx/transform.h"
18
19namespace cc {
20
21LayerAnimationController::LayerAnimationController(int id)
22    : force_sync_(false),
23      registrar_(0),
24      id_(id),
25      is_active_(false),
26      last_tick_time_(0),
27      layer_animation_delegate_(NULL) {}
28
29LayerAnimationController::~LayerAnimationController() {
30  if (registrar_)
31    registrar_->UnregisterAnimationController(this);
32}
33
34scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
35    int id) {
36  return make_scoped_refptr(new LayerAnimationController(id));
37}
38
39void LayerAnimationController::PauseAnimation(int animation_id,
40                                              double time_offset) {
41  for (size_t i = 0; i < active_animations_.size(); ++i) {
42    if (active_animations_[i]->id() == animation_id) {
43      active_animations_[i]->SetRunState(
44          Animation::Paused, time_offset + active_animations_[i]->start_time());
45    }
46  }
47}
48
49struct HasAnimationId {
50  explicit HasAnimationId(int id) : id_(id) {}
51  bool operator()(Animation* animation) const {
52    return animation->id() == id_;
53  }
54
55 private:
56  int id_;
57};
58
59void LayerAnimationController::RemoveAnimation(int animation_id) {
60  ScopedPtrVector<Animation>& animations = active_animations_;
61  animations.erase(cc::remove_if(&animations,
62                                 animations.begin(),
63                                 animations.end(),
64                                 HasAnimationId(animation_id)),
65                   animations.end());
66  UpdateActivation(NormalActivation);
67}
68
69struct HasAnimationIdAndProperty {
70  HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
71      : id_(id), target_property_(target_property) {}
72  bool operator()(Animation* animation) const {
73    return animation->id() == id_ &&
74        animation->target_property() == target_property_;
75  }
76
77 private:
78  int id_;
79  Animation::TargetProperty target_property_;
80};
81
82void LayerAnimationController::RemoveAnimation(
83    int animation_id,
84    Animation::TargetProperty target_property) {
85  ScopedPtrVector<Animation>& animations = active_animations_;
86  animations.erase(cc::remove_if(&animations,
87                                 animations.begin(),
88                                 animations.end(),
89                                 HasAnimationIdAndProperty(animation_id,
90                                                           target_property)),
91                   animations.end());
92  UpdateActivation(NormalActivation);
93}
94
95// According to render layer backing, these are for testing only.
96void LayerAnimationController::SuspendAnimations(double monotonic_time) {
97  for (size_t i = 0; i < active_animations_.size(); ++i) {
98    if (!active_animations_[i]->is_finished())
99      active_animations_[i]->SetRunState(Animation::Paused, monotonic_time);
100  }
101}
102
103// Looking at GraphicsLayerCA, this appears to be the analog to
104// SuspendAnimations, which is for testing.
105void LayerAnimationController::ResumeAnimations(double monotonic_time) {
106  for (size_t i = 0; i < active_animations_.size(); ++i) {
107    if (active_animations_[i]->run_state() == Animation::Paused)
108      active_animations_[i]->SetRunState(Animation::Running, monotonic_time);
109  }
110}
111
112// Ensures that the list of active animations on the main thread and the impl
113// thread are kept in sync.
114void LayerAnimationController::PushAnimationUpdatesTo(
115    LayerAnimationController* controller_impl) {
116  DCHECK(this != controller_impl);
117  if (force_sync_) {
118    ReplaceImplThreadAnimations(controller_impl);
119    force_sync_ = false;
120  } else {
121    PurgeAnimationsMarkedForDeletion();
122    PushNewAnimationsToImplThread(controller_impl);
123
124    // Remove finished impl side animations only after pushing,
125    // and only after the animations are deleted on the main thread
126    // this insures we will never push an animation twice.
127    RemoveAnimationsCompletedOnMainThread(controller_impl);
128
129    PushPropertiesToImplThread(controller_impl);
130  }
131  controller_impl->UpdateActivation(NormalActivation);
132  UpdateActivation(NormalActivation);
133}
134
135void LayerAnimationController::Animate(double monotonic_time) {
136  if (!HasValueObserver())
137    return;
138
139  StartAnimationsWaitingForNextTick(monotonic_time);
140  StartAnimationsWaitingForStartTime(monotonic_time);
141  StartAnimationsWaitingForTargetAvailability(monotonic_time);
142  ResolveConflicts(monotonic_time);
143  TickAnimations(monotonic_time);
144  last_tick_time_ = monotonic_time;
145}
146
147void LayerAnimationController::AccumulatePropertyUpdates(
148    double monotonic_time,
149    AnimationEventsVector* events) {
150  if (!events)
151    return;
152
153  for (size_t i = 0; i < active_animations_.size(); ++i) {
154    Animation* animation = active_animations_[i];
155    if (!animation->is_impl_only())
156      continue;
157
158    switch (animation->target_property()) {
159      case Animation::Opacity: {
160        AnimationEvent event(AnimationEvent::PropertyUpdate,
161                             id_,
162                             animation->group(),
163                             Animation::Opacity,
164                             monotonic_time);
165        event.opacity = animation->curve()->ToFloatAnimationCurve()->GetValue(
166            monotonic_time);
167        event.is_impl_only = true;
168        events->push_back(event);
169        break;
170      }
171
172      case Animation::Transform: {
173        AnimationEvent event(AnimationEvent::PropertyUpdate,
174                             id_,
175                             animation->group(),
176                             Animation::Transform,
177                             monotonic_time);
178        event.transform =
179            animation->curve()->ToTransformAnimationCurve()->GetValue(
180                monotonic_time);
181        event.is_impl_only = true;
182        events->push_back(event);
183        break;
184      }
185
186      case Animation::Filter: {
187        AnimationEvent event(AnimationEvent::PropertyUpdate,
188                             id_,
189                             animation->group(),
190                             Animation::Filter,
191                             monotonic_time);
192        event.filters = animation->curve()->ToFilterAnimationCurve()->GetValue(
193            monotonic_time);
194        event.is_impl_only = true;
195        events->push_back(event);
196        break;
197      }
198
199      case Animation::TargetPropertyEnumSize:
200        NOTREACHED();
201    }
202  }
203}
204
205void LayerAnimationController::UpdateState(bool start_ready_animations,
206                                           AnimationEventsVector* events) {
207  if (!HasActiveValueObserver())
208    return;
209
210  if (start_ready_animations)
211    PromoteStartedAnimations(last_tick_time_, events);
212
213  MarkFinishedAnimations(last_tick_time_);
214  MarkAnimationsForDeletion(last_tick_time_, events);
215
216  if (start_ready_animations) {
217    StartAnimationsWaitingForTargetAvailability(last_tick_time_);
218    PromoteStartedAnimations(last_tick_time_, events);
219  }
220
221  AccumulatePropertyUpdates(last_tick_time_, events);
222
223  UpdateActivation(NormalActivation);
224}
225
226void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
227  active_animations_.push_back(animation.Pass());
228  UpdateActivation(NormalActivation);
229}
230
231Animation* LayerAnimationController::GetAnimation(
232    int group_id,
233    Animation::TargetProperty target_property) const {
234  for (size_t i = 0; i < active_animations_.size(); ++i)
235    if (active_animations_[i]->group() == group_id &&
236        active_animations_[i]->target_property() == target_property)
237      return active_animations_[i];
238  return 0;
239}
240
241Animation* LayerAnimationController::GetAnimation(
242    Animation::TargetProperty target_property) const {
243  for (size_t i = 0; i < active_animations_.size(); ++i) {
244    size_t index = active_animations_.size() - i - 1;
245    if (active_animations_[index]->target_property() == target_property)
246      return active_animations_[index];
247  }
248  return 0;
249}
250
251bool LayerAnimationController::HasActiveAnimation() const {
252  for (size_t i = 0; i < active_animations_.size(); ++i) {
253    if (!active_animations_[i]->is_finished())
254      return true;
255  }
256  return false;
257}
258
259bool LayerAnimationController::IsAnimatingProperty(
260    Animation::TargetProperty target_property) const {
261  for (size_t i = 0; i < active_animations_.size(); ++i) {
262    if (!active_animations_[i]->is_finished() &&
263        active_animations_[i]->target_property() == target_property)
264      return true;
265  }
266  return false;
267}
268
269void LayerAnimationController::SetAnimationRegistrar(
270    AnimationRegistrar* registrar) {
271  if (registrar_ == registrar)
272    return;
273
274  if (registrar_)
275    registrar_->UnregisterAnimationController(this);
276
277  registrar_ = registrar;
278  if (registrar_)
279    registrar_->RegisterAnimationController(this);
280
281  UpdateActivation(ForceActivation);
282}
283
284void LayerAnimationController::NotifyAnimationStarted(
285    const AnimationEvent& event,
286    double wall_clock_time) {
287  if (event.is_impl_only) {
288    FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
289                      OnAnimationStarted(event));
290    if (layer_animation_delegate_)
291      layer_animation_delegate_->NotifyAnimationStarted(wall_clock_time);
292
293    return;
294  }
295
296  for (size_t i = 0; i < active_animations_.size(); ++i) {
297    if (active_animations_[i]->group() == event.group_id &&
298        active_animations_[i]->target_property() == event.target_property &&
299        active_animations_[i]->needs_synchronized_start_time()) {
300      active_animations_[i]->set_needs_synchronized_start_time(false);
301      active_animations_[i]->set_start_time(event.monotonic_time);
302
303      FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
304                        OnAnimationStarted(event));
305      if (layer_animation_delegate_)
306        layer_animation_delegate_->NotifyAnimationStarted(wall_clock_time);
307
308      return;
309    }
310  }
311}
312
313void LayerAnimationController::NotifyAnimationFinished(
314    const AnimationEvent& event,
315    double wall_clock_time) {
316  if (event.is_impl_only) {
317    if (layer_animation_delegate_)
318      layer_animation_delegate_->NotifyAnimationFinished(wall_clock_time);
319    return;
320  }
321
322  for (size_t i = 0; i < active_animations_.size(); ++i) {
323    if (active_animations_[i]->group() == event.group_id &&
324        active_animations_[i]->target_property() == event.target_property) {
325      active_animations_[i]->set_received_finished_event(true);
326      if (layer_animation_delegate_)
327        layer_animation_delegate_->NotifyAnimationFinished(wall_clock_time);
328
329      return;
330    }
331  }
332}
333
334void LayerAnimationController::NotifyAnimationPropertyUpdate(
335    const AnimationEvent& event) {
336  switch (event.target_property) {
337    case Animation::Opacity:
338      NotifyObserversOpacityAnimated(event.opacity);
339      break;
340    case Animation::Transform:
341      NotifyObserversTransformAnimated(event.transform);
342      break;
343    default:
344      NOTREACHED();
345  }
346}
347
348void LayerAnimationController::AddValueObserver(
349    LayerAnimationValueObserver* observer) {
350  if (!value_observers_.HasObserver(observer))
351    value_observers_.AddObserver(observer);
352}
353
354void LayerAnimationController::RemoveValueObserver(
355    LayerAnimationValueObserver* observer) {
356  value_observers_.RemoveObserver(observer);
357}
358
359void LayerAnimationController::AddEventObserver(
360    LayerAnimationEventObserver* observer) {
361  if (!event_observers_.HasObserver(observer))
362    event_observers_.AddObserver(observer);
363}
364
365void LayerAnimationController::RemoveEventObserver(
366    LayerAnimationEventObserver* observer) {
367  event_observers_.RemoveObserver(observer);
368}
369
370bool LayerAnimationController::AnimatedBoundsForBox(const gfx::BoxF& box,
371                                                    gfx::BoxF* bounds) {
372  // Compute bounds based on animations for which is_finished() is false.
373  // Do nothing if there are no such animations; in this case, it is assumed
374  // that callers will take care of computing bounds based on the owning layer's
375  // actual transform.
376  *bounds = gfx::BoxF();
377  for (size_t i = 0; i < active_animations_.size(); ++i) {
378    if (active_animations_[i]->is_finished() ||
379        active_animations_[i]->target_property() != Animation::Transform)
380      continue;
381
382    const TransformAnimationCurve* transform_animation_curve =
383        active_animations_[i]->curve()->ToTransformAnimationCurve();
384    gfx::BoxF animation_bounds;
385    bool success =
386        transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
387    if (!success)
388      return false;
389    bounds->Union(animation_bounds);
390  }
391
392  return true;
393}
394
395void LayerAnimationController::PushNewAnimationsToImplThread(
396    LayerAnimationController* controller_impl) const {
397  // Any new animations owned by the main thread's controller are cloned and
398  // add to the impl thread's controller.
399  for (size_t i = 0; i < active_animations_.size(); ++i) {
400    // If the animation is already running on the impl thread, there is no
401    // need to copy it over.
402    if (controller_impl->GetAnimation(active_animations_[i]->group(),
403                                      active_animations_[i]->target_property()))
404      continue;
405
406    // If the animation is not running on the impl thread, it does not
407    // necessarily mean that it needs to be copied over and started; it may
408    // have already finished. In this case, the impl thread animation will
409    // have already notified that it has started and the main thread animation
410    // will no longer need
411    // a synchronized start time.
412    if (!active_animations_[i]->needs_synchronized_start_time())
413      continue;
414
415    // The new animation should be set to run as soon as possible.
416    Animation::RunState initial_run_state =
417        Animation::WaitingForTargetAvailability;
418    double start_time = 0;
419    scoped_ptr<Animation> to_add(active_animations_[i]->CloneAndInitialize(
420        initial_run_state, start_time));
421    DCHECK(!to_add->needs_synchronized_start_time());
422    controller_impl->AddAnimation(to_add.Pass());
423  }
424}
425
426struct IsCompleted {
427  explicit IsCompleted(const LayerAnimationController& main_thread_controller)
428      : main_thread_controller_(main_thread_controller) {}
429  bool operator()(Animation* animation) const {
430    if (animation->is_impl_only()) {
431      return (animation->run_state() == Animation::WaitingForDeletion);
432    } else {
433      return !main_thread_controller_.GetAnimation(
434          animation->group(),
435          animation->target_property());
436    }
437  }
438
439 private:
440  const LayerAnimationController& main_thread_controller_;
441};
442
443void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
444    LayerAnimationController* controller_impl) const {
445  // Delete all impl thread animations for which there is no corresponding
446  // main thread animation. Each iteration,
447  // controller->active_animations_.size() is decremented or i is incremented
448  // guaranteeing progress towards loop termination.
449  ScopedPtrVector<Animation>& animations =
450      controller_impl->active_animations_;
451  animations.erase(cc::remove_if(&animations,
452                                 animations.begin(),
453                                 animations.end(),
454                                 IsCompleted(*this)),
455                   animations.end());
456}
457
458void LayerAnimationController::PushPropertiesToImplThread(
459    LayerAnimationController* controller_impl) const {
460  for (size_t i = 0; i < active_animations_.size(); ++i) {
461    Animation* current_impl =
462        controller_impl->GetAnimation(
463            active_animations_[i]->group(),
464            active_animations_[i]->target_property());
465    if (current_impl)
466      active_animations_[i]->PushPropertiesTo(current_impl);
467  }
468}
469
470void LayerAnimationController::StartAnimationsWaitingForNextTick(
471    double monotonic_time) {
472  for (size_t i = 0; i < active_animations_.size(); ++i) {
473    if (active_animations_[i]->run_state() == Animation::WaitingForNextTick)
474      active_animations_[i]->SetRunState(Animation::Starting, monotonic_time);
475  }
476}
477
478void LayerAnimationController::StartAnimationsWaitingForStartTime(
479    double monotonic_time) {
480  for (size_t i = 0; i < active_animations_.size(); ++i) {
481    if (active_animations_[i]->run_state() == Animation::WaitingForStartTime &&
482        active_animations_[i]->start_time() <= monotonic_time)
483      active_animations_[i]->SetRunState(Animation::Starting, monotonic_time);
484  }
485}
486
487void LayerAnimationController::StartAnimationsWaitingForTargetAvailability(
488    double monotonic_time) {
489  // First collect running properties.
490  TargetProperties blocked_properties;
491  for (size_t i = 0; i < active_animations_.size(); ++i) {
492    if (active_animations_[i]->run_state() == Animation::Starting ||
493        active_animations_[i]->run_state() == Animation::Running)
494      blocked_properties.insert(active_animations_[i]->target_property());
495  }
496
497  for (size_t i = 0; i < active_animations_.size(); ++i) {
498    if (active_animations_[i]->run_state() ==
499        Animation::WaitingForTargetAvailability) {
500      // Collect all properties for animations with the same group id (they
501      // should all also be in the list of animations).
502      TargetProperties enqueued_properties;
503      enqueued_properties.insert(active_animations_[i]->target_property());
504      for (size_t j = i + 1; j < active_animations_.size(); ++j) {
505        if (active_animations_[i]->group() == active_animations_[j]->group())
506          enqueued_properties.insert(active_animations_[j]->target_property());
507      }
508
509      // Check to see if intersection of the list of properties affected by
510      // the group and the list of currently blocked properties is null. In
511      // any case, the group's target properties need to be added to the list
512      // of blocked properties.
513      bool null_intersection = true;
514      for (TargetProperties::iterator p_iter = enqueued_properties.begin();
515           p_iter != enqueued_properties.end();
516           ++p_iter) {
517        if (!blocked_properties.insert(*p_iter).second)
518          null_intersection = false;
519      }
520
521      // If the intersection is null, then we are free to start the animations
522      // in the group.
523      if (null_intersection) {
524        active_animations_[i]->SetRunState(
525            Animation::Starting, monotonic_time);
526        for (size_t j = i + 1; j < active_animations_.size(); ++j) {
527          if (active_animations_[i]->group() ==
528              active_animations_[j]->group()) {
529            active_animations_[j]->SetRunState(
530                Animation::Starting, monotonic_time);
531          }
532        }
533      }
534    }
535  }
536}
537
538void LayerAnimationController::PromoteStartedAnimations(
539    double monotonic_time,
540    AnimationEventsVector* events) {
541  for (size_t i = 0; i < active_animations_.size(); ++i) {
542    if (active_animations_[i]->run_state() == Animation::Starting) {
543      active_animations_[i]->SetRunState(Animation::Running, monotonic_time);
544      if (!active_animations_[i]->has_set_start_time())
545        active_animations_[i]->set_start_time(monotonic_time);
546      if (events) {
547        AnimationEvent started_event(
548            AnimationEvent::Started,
549            id_,
550            active_animations_[i]->group(),
551            active_animations_[i]->target_property(),
552            monotonic_time);
553        started_event.is_impl_only = active_animations_[i]->is_impl_only();
554        events->push_back(started_event);
555      }
556    }
557  }
558}
559
560void LayerAnimationController::MarkFinishedAnimations(double monotonic_time) {
561  for (size_t i = 0; i < active_animations_.size(); ++i) {
562    if (active_animations_[i]->IsFinishedAt(monotonic_time) &&
563        active_animations_[i]->run_state() != Animation::WaitingForDeletion)
564      active_animations_[i]->SetRunState(Animation::Finished, monotonic_time);
565  }
566}
567
568void LayerAnimationController::ResolveConflicts(double monotonic_time) {
569  // Find any animations that are animating the same property and resolve the
570  // confict. We could eventually blend, but for now we'll just abort the
571  // previous animation (where 'previous' means: (1) has a prior start time or
572  // (2) has an equal start time, but was added to the queue earlier, i.e.,
573  // has a lower index in active_animations_).
574  for (size_t i = 0; i < active_animations_.size(); ++i) {
575    if (active_animations_[i]->run_state() == Animation::Starting ||
576        active_animations_[i]->run_state() == Animation::Running) {
577      for (size_t j = i + 1; j < active_animations_.size(); ++j) {
578        if ((active_animations_[j]->run_state() == Animation::Starting ||
579             active_animations_[j]->run_state() == Animation::Running) &&
580            active_animations_[i]->target_property() ==
581            active_animations_[j]->target_property()) {
582          if (active_animations_[i]->start_time() >
583              active_animations_[j]->start_time()) {
584            active_animations_[j]->SetRunState(Animation::Aborted,
585                                               monotonic_time);
586          } else {
587            active_animations_[i]->SetRunState(Animation::Aborted,
588                                               monotonic_time);
589          }
590        }
591      }
592    }
593  }
594}
595
596void LayerAnimationController::MarkAnimationsForDeletion(
597    double monotonic_time, AnimationEventsVector* events) {
598  // Non-aborted animations are marked for deletion after a corresponding
599  // AnimationEvent::Finished event is sent or received. This means that if
600  // we don't have an events vector, we must ensure that non-aborted animations
601  // have received a finished event before marking them for deletion.
602  for (size_t i = 0; i < active_animations_.size(); i++) {
603    int group_id = active_animations_[i]->group();
604    bool all_anims_with_same_id_are_finished = false;
605
606    // Since deleting an animation on the main thread leads to its deletion
607    // on the impl thread, we only mark a Finished main thread animation for
608    // deletion once it has received a Finished event from the impl thread.
609    bool animation_i_will_send_or_has_received_finish_event =
610        events || active_animations_[i]->received_finished_event();
611    // If an animation is finished, and not already marked for deletion,
612    // find out if all other animations in the same group are also finished.
613    if (active_animations_[i]->run_state() == Animation::Aborted ||
614        (active_animations_[i]->run_state() == Animation::Finished &&
615         animation_i_will_send_or_has_received_finish_event)) {
616      all_anims_with_same_id_are_finished = true;
617      for (size_t j = 0; j < active_animations_.size(); ++j) {
618        bool animation_j_will_send_or_has_received_finish_event =
619            events || active_animations_[j]->received_finished_event();
620        if (group_id == active_animations_[j]->group() &&
621            (!active_animations_[j]->is_finished() ||
622             (active_animations_[j]->run_state() == Animation::Finished &&
623              !animation_j_will_send_or_has_received_finish_event))) {
624          all_anims_with_same_id_are_finished = false;
625          break;
626        }
627      }
628    }
629    if (all_anims_with_same_id_are_finished) {
630      // We now need to remove all animations with the same group id as
631      // group_id (and send along animation finished notifications, if
632      // necessary).
633      for (size_t j = i; j < active_animations_.size(); j++) {
634        if (group_id == active_animations_[j]->group()) {
635          if (events) {
636            AnimationEvent finished_event(
637                AnimationEvent::Finished,
638                id_,
639                active_animations_[j]->group(),
640                active_animations_[j]->target_property(),
641                monotonic_time);
642            finished_event.is_impl_only = active_animations_[j]->is_impl_only();
643            events->push_back(finished_event);
644          }
645          active_animations_[j]->SetRunState(Animation::WaitingForDeletion,
646                                             monotonic_time);
647        }
648      }
649    }
650  }
651}
652
653static bool IsWaitingForDeletion(Animation* animation) {
654  return animation->run_state() == Animation::WaitingForDeletion;
655}
656
657void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
658  ScopedPtrVector<Animation>& animations = active_animations_;
659  animations.erase(cc::remove_if(&animations,
660                                 animations.begin(),
661                                 animations.end(),
662                                 IsWaitingForDeletion),
663                   animations.end());
664}
665
666void LayerAnimationController::ReplaceImplThreadAnimations(
667    LayerAnimationController* controller_impl) const {
668  controller_impl->active_animations_.clear();
669  for (size_t i = 0; i < active_animations_.size(); ++i) {
670    scoped_ptr<Animation> to_add;
671    if (active_animations_[i]->needs_synchronized_start_time()) {
672      // We haven't received an animation started notification yet, so it
673      // is important that we add it in a 'waiting' and not 'running' state.
674      Animation::RunState initial_run_state =
675          Animation::WaitingForTargetAvailability;
676      double start_time = 0;
677      to_add = active_animations_[i]->CloneAndInitialize(
678          initial_run_state, start_time).Pass();
679    } else {
680      to_add = active_animations_[i]->Clone().Pass();
681    }
682
683    controller_impl->AddAnimation(to_add.Pass());
684  }
685}
686
687void LayerAnimationController::TickAnimations(double monotonic_time) {
688  for (size_t i = 0; i < active_animations_.size(); ++i) {
689    if (active_animations_[i]->run_state() == Animation::Starting ||
690        active_animations_[i]->run_state() == Animation::Running ||
691        active_animations_[i]->run_state() == Animation::Paused) {
692      double trimmed =
693          active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
694
695      switch (active_animations_[i]->target_property()) {
696        case Animation::Transform: {
697          const TransformAnimationCurve* transform_animation_curve =
698              active_animations_[i]->curve()->ToTransformAnimationCurve();
699          const gfx::Transform transform =
700              transform_animation_curve->GetValue(trimmed);
701          NotifyObserversTransformAnimated(transform);
702          break;
703        }
704
705        case Animation::Opacity: {
706          const FloatAnimationCurve* float_animation_curve =
707              active_animations_[i]->curve()->ToFloatAnimationCurve();
708          const float opacity = float_animation_curve->GetValue(trimmed);
709          NotifyObserversOpacityAnimated(opacity);
710          break;
711        }
712
713        case Animation::Filter: {
714          const FilterAnimationCurve* filter_animation_curve =
715              active_animations_[i]->curve()->ToFilterAnimationCurve();
716          const FilterOperations filter =
717              filter_animation_curve->GetValue(trimmed);
718          NotifyObserversFilterAnimated(filter);
719          break;
720        }
721
722        // Do nothing for sentinel value.
723        case Animation::TargetPropertyEnumSize:
724          NOTREACHED();
725      }
726    }
727  }
728}
729
730void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
731  bool force = type == ForceActivation;
732  if (registrar_) {
733    if (!active_animations_.empty() && (!is_active_ || force))
734      registrar_->DidActivateAnimationController(this);
735    else if (active_animations_.empty() && (is_active_ || force))
736      registrar_->DidDeactivateAnimationController(this);
737    is_active_ = !active_animations_.empty();
738  }
739}
740
741void LayerAnimationController::NotifyObserversOpacityAnimated(float opacity) {
742  FOR_EACH_OBSERVER(LayerAnimationValueObserver,
743                    value_observers_,
744                    OnOpacityAnimated(opacity));
745}
746
747void LayerAnimationController::NotifyObserversTransformAnimated(
748    const gfx::Transform& transform) {
749  FOR_EACH_OBSERVER(LayerAnimationValueObserver,
750                    value_observers_,
751                    OnTransformAnimated(transform));
752}
753
754void LayerAnimationController::NotifyObserversFilterAnimated(
755    const FilterOperations& filters) {
756  FOR_EACH_OBSERVER(LayerAnimationValueObserver,
757                    value_observers_,
758                    OnFilterAnimated(filters));
759}
760
761bool LayerAnimationController::HasValueObserver() {
762  if (value_observers_.might_have_observers()) {
763    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
764        value_observers_);
765    return it.GetNext() != NULL;
766  }
767  return false;
768}
769
770bool LayerAnimationController::HasActiveValueObserver() {
771  if (value_observers_.might_have_observers()) {
772    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
773        value_observers_);
774    LayerAnimationValueObserver* obs;
775    while ((obs = it.GetNext()) != NULL)
776      if (obs->IsActive())
777        return true;
778  }
779  return false;
780}
781
782}  // namespace cc
783