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