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#include <vector>
9
10#include "cc/animation/animation.h"
11#include "cc/animation/animation_delegate.h"
12#include "cc/animation/animation_registrar.h"
13#include "cc/animation/keyframed_animation_curve.h"
14#include "cc/animation/layer_animation_value_observer.h"
15#include "cc/animation/layer_animation_value_provider.h"
16#include "cc/animation/scroll_offset_animation_curve.h"
17#include "cc/base/scoped_ptr_algorithm.h"
18#include "cc/output/filter_operations.h"
19#include "ui/gfx/box_f.h"
20#include "ui/gfx/transform.h"
21
22namespace cc {
23
24LayerAnimationController::LayerAnimationController(int id)
25    : registrar_(0),
26      id_(id),
27      is_active_(false),
28      value_provider_(NULL),
29      layer_animation_delegate_(NULL),
30      needs_to_start_animations_(false) {
31}
32
33LayerAnimationController::~LayerAnimationController() {
34  if (registrar_)
35    registrar_->UnregisterAnimationController(this);
36}
37
38scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
39    int id) {
40  return make_scoped_refptr(new LayerAnimationController(id));
41}
42
43void LayerAnimationController::PauseAnimation(int animation_id,
44                                              base::TimeDelta time_offset) {
45  for (size_t i = 0; i < animations_.size(); ++i) {
46    if (animations_[i]->id() == animation_id) {
47      animations_[i]->SetRunState(Animation::Paused,
48                                  time_offset + animations_[i]->start_time());
49    }
50  }
51}
52
53struct HasAnimationId {
54  explicit HasAnimationId(int id) : id_(id) {}
55  bool operator()(Animation* animation) const {
56    return animation->id() == id_;
57  }
58
59 private:
60  int id_;
61};
62
63void LayerAnimationController::RemoveAnimation(int animation_id) {
64  animations_.erase(cc::remove_if(&animations_,
65                                  animations_.begin(),
66                                  animations_.end(),
67                                  HasAnimationId(animation_id)),
68                    animations_.end());
69  UpdateActivation(NormalActivation);
70}
71
72struct HasAnimationIdAndProperty {
73  HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
74      : id_(id), target_property_(target_property) {}
75  bool operator()(Animation* animation) const {
76    return animation->id() == id_ &&
77        animation->target_property() == target_property_;
78  }
79
80 private:
81  int id_;
82  Animation::TargetProperty target_property_;
83};
84
85void LayerAnimationController::RemoveAnimation(
86    int animation_id,
87    Animation::TargetProperty target_property) {
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
97void LayerAnimationController::AbortAnimations(
98    Animation::TargetProperty target_property) {
99  for (size_t i = 0; i < animations_.size(); ++i) {
100    if (animations_[i]->target_property() == target_property &&
101        !animations_[i]->is_finished())
102      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.
108void 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
126void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
127  DCHECK(!monotonic_time.is_null());
128  if (!HasValueObserver())
129    return;
130
131  if (needs_to_start_animations_)
132    StartAnimations(monotonic_time);
133  TickAnimations(monotonic_time);
134  last_tick_time_ = monotonic_time;
135}
136
137void LayerAnimationController::AccumulatePropertyUpdates(
138    base::TimeTicks monotonic_time,
139    AnimationEventsVector* events) {
140  if (!events)
141    return;
142
143  for (size_t i = 0; i < animations_.size(); ++i) {
144    Animation* animation = animations_[i];
145    if (!animation->is_impl_only())
146      continue;
147
148    if (!animation->InEffect(monotonic_time))
149      continue;
150
151    double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time);
152    switch (animation->target_property()) {
153      case Animation::Opacity: {
154        AnimationEvent event(AnimationEvent::PropertyUpdate,
155                             id_,
156                             animation->group(),
157                             Animation::Opacity,
158                             monotonic_time);
159        const FloatAnimationCurve* float_animation_curve =
160            animation->curve()->ToFloatAnimationCurve();
161        event.opacity = float_animation_curve->GetValue(trimmed);
162        event.is_impl_only = true;
163        events->push_back(event);
164        break;
165      }
166
167      case Animation::Transform: {
168        AnimationEvent event(AnimationEvent::PropertyUpdate,
169                             id_,
170                             animation->group(),
171                             Animation::Transform,
172                             monotonic_time);
173        const TransformAnimationCurve* transform_animation_curve =
174            animation->curve()->ToTransformAnimationCurve();
175        event.transform = transform_animation_curve->GetValue(trimmed);
176        event.is_impl_only = true;
177        events->push_back(event);
178        break;
179      }
180
181      case Animation::Filter: {
182        AnimationEvent event(AnimationEvent::PropertyUpdate,
183                             id_,
184                             animation->group(),
185                             Animation::Filter,
186                             monotonic_time);
187        const FilterAnimationCurve* filter_animation_curve =
188            animation->curve()->ToFilterAnimationCurve();
189        event.filters = filter_animation_curve->GetValue(trimmed);
190        event.is_impl_only = true;
191        events->push_back(event);
192        break;
193      }
194
195      case Animation::BackgroundColor: { break; }
196
197      case Animation::ScrollOffset: {
198        // Impl-side changes to scroll offset are already sent back to the
199        // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
200        // isn't needed.
201        break;
202      }
203
204      case Animation::TargetPropertyEnumSize:
205        NOTREACHED();
206    }
207  }
208}
209
210void LayerAnimationController::UpdateState(bool start_ready_animations,
211                                           AnimationEventsVector* events) {
212  if (!HasActiveValueObserver())
213    return;
214
215  DCHECK(last_tick_time_ != base::TimeTicks());
216  if (start_ready_animations)
217    PromoteStartedAnimations(last_tick_time_, events);
218
219  MarkFinishedAnimations(last_tick_time_);
220  MarkAnimationsForDeletion(last_tick_time_, events);
221
222  if (needs_to_start_animations_ && start_ready_animations) {
223    StartAnimations(last_tick_time_);
224    PromoteStartedAnimations(last_tick_time_, events);
225  }
226
227  AccumulatePropertyUpdates(last_tick_time_, events);
228
229  UpdateActivation(NormalActivation);
230}
231
232struct AffectsNoObservers {
233  bool operator()(Animation* animation) const {
234    return !animation->affects_active_observers() &&
235           !animation->affects_pending_observers();
236  }
237};
238
239void LayerAnimationController::ActivateAnimations() {
240  for (size_t i = 0; i < animations_.size(); ++i) {
241    animations_[i]->set_affects_active_observers(
242        animations_[i]->affects_pending_observers());
243  }
244  animations_.erase(cc::remove_if(&animations_,
245                                  animations_.begin(),
246                                  animations_.end(),
247                                  AffectsNoObservers()),
248                    animations_.end());
249  UpdateActivation(NormalActivation);
250}
251
252void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
253  animations_.push_back(animation.Pass());
254  needs_to_start_animations_ = true;
255  UpdateActivation(NormalActivation);
256}
257
258Animation* LayerAnimationController::GetAnimation(
259    int group_id,
260    Animation::TargetProperty target_property) const {
261  for (size_t i = 0; i < animations_.size(); ++i)
262    if (animations_[i]->group() == group_id &&
263        animations_[i]->target_property() == target_property)
264      return animations_[i];
265  return 0;
266}
267
268Animation* LayerAnimationController::GetAnimation(
269    Animation::TargetProperty target_property) const {
270  for (size_t i = 0; i < animations_.size(); ++i) {
271    size_t index = animations_.size() - i - 1;
272    if (animations_[index]->target_property() == target_property)
273      return animations_[index];
274  }
275  return 0;
276}
277
278bool LayerAnimationController::HasActiveAnimation() const {
279  for (size_t i = 0; i < animations_.size(); ++i) {
280    if (!animations_[i]->is_finished())
281      return true;
282  }
283  return false;
284}
285
286bool LayerAnimationController::IsAnimatingProperty(
287    Animation::TargetProperty target_property) const {
288  for (size_t i = 0; i < animations_.size(); ++i) {
289    if (!animations_[i]->is_finished() &&
290        animations_[i]->InEffect(last_tick_time_) &&
291        animations_[i]->target_property() == target_property)
292      return true;
293  }
294  return false;
295}
296
297void LayerAnimationController::SetAnimationRegistrar(
298    AnimationRegistrar* registrar) {
299  if (registrar_ == registrar)
300    return;
301
302  if (registrar_)
303    registrar_->UnregisterAnimationController(this);
304
305  registrar_ = registrar;
306  if (registrar_)
307    registrar_->RegisterAnimationController(this);
308
309  UpdateActivation(ForceActivation);
310}
311
312void LayerAnimationController::NotifyAnimationStarted(
313    const AnimationEvent& event) {
314  if (event.is_impl_only) {
315    FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
316                      OnAnimationStarted(event));
317    if (layer_animation_delegate_)
318      layer_animation_delegate_->NotifyAnimationStarted(event.monotonic_time,
319                                                        event.target_property);
320    return;
321  }
322
323  for (size_t i = 0; i < animations_.size(); ++i) {
324    if (animations_[i]->group() == event.group_id &&
325        animations_[i]->target_property() == event.target_property &&
326        animations_[i]->needs_synchronized_start_time()) {
327      animations_[i]->set_needs_synchronized_start_time(false);
328      if (!animations_[i]->has_set_start_time())
329        animations_[i]->set_start_time(event.monotonic_time);
330
331      FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
332                        OnAnimationStarted(event));
333      if (layer_animation_delegate_)
334        layer_animation_delegate_->NotifyAnimationStarted(
335            event.monotonic_time, event.target_property);
336
337      return;
338    }
339  }
340}
341
342void LayerAnimationController::NotifyAnimationFinished(
343    const AnimationEvent& event) {
344  if (event.is_impl_only) {
345    if (layer_animation_delegate_)
346      layer_animation_delegate_->NotifyAnimationFinished(event.monotonic_time,
347                                                         event.target_property);
348    return;
349  }
350
351  for (size_t i = 0; i < animations_.size(); ++i) {
352    if (animations_[i]->group() == event.group_id &&
353        animations_[i]->target_property() == event.target_property) {
354      animations_[i]->set_received_finished_event(true);
355      if (layer_animation_delegate_)
356        layer_animation_delegate_->NotifyAnimationFinished(
357            event.monotonic_time, event.target_property);
358
359      return;
360    }
361  }
362}
363
364void LayerAnimationController::NotifyAnimationAborted(
365    const AnimationEvent& event) {
366  for (size_t i = 0; i < animations_.size(); ++i) {
367    if (animations_[i]->group() == event.group_id &&
368        animations_[i]->target_property() == event.target_property) {
369      animations_[i]->SetRunState(Animation::Aborted, event.monotonic_time);
370    }
371  }
372}
373
374void LayerAnimationController::NotifyAnimationPropertyUpdate(
375    const AnimationEvent& event) {
376  bool notify_active_observers = true;
377  bool notify_pending_observers = true;
378  switch (event.target_property) {
379    case Animation::Opacity:
380      NotifyObserversOpacityAnimated(
381          event.opacity, notify_active_observers, notify_pending_observers);
382      break;
383    case Animation::Transform:
384      NotifyObserversTransformAnimated(
385          event.transform, notify_active_observers, notify_pending_observers);
386      break;
387    default:
388      NOTREACHED();
389  }
390}
391
392void LayerAnimationController::AddValueObserver(
393    LayerAnimationValueObserver* observer) {
394  if (!value_observers_.HasObserver(observer))
395    value_observers_.AddObserver(observer);
396}
397
398void LayerAnimationController::RemoveValueObserver(
399    LayerAnimationValueObserver* observer) {
400  value_observers_.RemoveObserver(observer);
401}
402
403void LayerAnimationController::AddEventObserver(
404    LayerAnimationEventObserver* observer) {
405  if (!event_observers_.HasObserver(observer))
406    event_observers_.AddObserver(observer);
407}
408
409void LayerAnimationController::RemoveEventObserver(
410    LayerAnimationEventObserver* observer) {
411  event_observers_.RemoveObserver(observer);
412}
413
414bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
415  for (size_t i = 0; i < animations_.size(); ++i) {
416    if (!animations_[i]->is_finished() &&
417        animations_[i]->target_property() == Animation::Filter &&
418        animations_[i]
419            ->curve()
420            ->ToFilterAnimationCurve()
421            ->HasFilterThatMovesPixels())
422      return true;
423  }
424
425  return false;
426}
427
428bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
429  return IsAnimatingProperty(Animation::Transform);
430}
431
432bool LayerAnimationController::FilterAnimationBoundsForBox(
433    const gfx::BoxF& box, gfx::BoxF* bounds) const {
434  // TODO(avallee): Implement.
435  return false;
436}
437
438bool LayerAnimationController::TransformAnimationBoundsForBox(
439    const gfx::BoxF& box,
440    gfx::BoxF* bounds) const {
441  DCHECK(HasTransformAnimationThatInflatesBounds())
442      << "TransformAnimationBoundsForBox will give incorrect results if there "
443      << "are no transform animations affecting bounds, non-animated transform "
444      << "is not known";
445
446  // Compute bounds based on animations for which is_finished() is false.
447  // Do nothing if there are no such animations; in this case, it is assumed
448  // that callers will take care of computing bounds based on the owning layer's
449  // actual transform.
450  *bounds = gfx::BoxF();
451  for (size_t i = 0; i < animations_.size(); ++i) {
452    if (animations_[i]->is_finished() ||
453        animations_[i]->target_property() != Animation::Transform)
454      continue;
455
456    const TransformAnimationCurve* transform_animation_curve =
457        animations_[i]->curve()->ToTransformAnimationCurve();
458    gfx::BoxF animation_bounds;
459    bool success =
460        transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
461    if (!success)
462      return false;
463    bounds->Union(animation_bounds);
464  }
465
466  return true;
467}
468
469bool LayerAnimationController::HasAnimationThatAffectsScale() const {
470  for (size_t i = 0; i < animations_.size(); ++i) {
471    if (animations_[i]->is_finished() ||
472        animations_[i]->target_property() != Animation::Transform)
473      continue;
474
475    const TransformAnimationCurve* transform_animation_curve =
476        animations_[i]->curve()->ToTransformAnimationCurve();
477    if (transform_animation_curve->AffectsScale())
478      return true;
479  }
480
481  return false;
482}
483
484bool LayerAnimationController::HasOnlyTranslationTransforms() const {
485  for (size_t i = 0; i < animations_.size(); ++i) {
486    if (animations_[i]->is_finished() ||
487        animations_[i]->target_property() != Animation::Transform)
488      continue;
489
490    const TransformAnimationCurve* transform_animation_curve =
491        animations_[i]->curve()->ToTransformAnimationCurve();
492    if (!transform_animation_curve->IsTranslation())
493      return false;
494  }
495
496  return true;
497}
498
499bool LayerAnimationController::MaximumTargetScale(float* max_scale) const {
500  *max_scale = 0.f;
501  for (size_t i = 0; i < animations_.size(); ++i) {
502    if (animations_[i]->is_finished() ||
503        animations_[i]->target_property() != Animation::Transform)
504      continue;
505
506    bool forward_direction = true;
507    switch (animations_[i]->direction()) {
508      case Animation::Normal:
509      case Animation::Alternate:
510        forward_direction = animations_[i]->playback_rate() >= 0.0;
511        break;
512      case Animation::Reverse:
513      case Animation::AlternateReverse:
514        forward_direction = animations_[i]->playback_rate() < 0.0;
515        break;
516    }
517
518    const TransformAnimationCurve* transform_animation_curve =
519        animations_[i]->curve()->ToTransformAnimationCurve();
520    float animation_scale = 0.f;
521    if (!transform_animation_curve->MaximumTargetScale(forward_direction,
522                                                       &animation_scale))
523      return false;
524    *max_scale = std::max(*max_scale, animation_scale);
525  }
526
527  return true;
528}
529
530void LayerAnimationController::PushNewAnimationsToImplThread(
531    LayerAnimationController* controller_impl) const {
532  // Any new animations owned by the main thread's controller are cloned and
533  // add to the impl thread's controller.
534  for (size_t i = 0; i < animations_.size(); ++i) {
535    // If the animation is already running on the impl thread, there is no
536    // need to copy it over.
537    if (controller_impl->GetAnimation(animations_[i]->group(),
538                                      animations_[i]->target_property()))
539      continue;
540
541    // If the animation is not running on the impl thread, it does not
542    // necessarily mean that it needs to be copied over and started; it may
543    // have already finished. In this case, the impl thread animation will
544    // have already notified that it has started and the main thread animation
545    // will no longer need
546    // a synchronized start time.
547    if (!animations_[i]->needs_synchronized_start_time())
548      continue;
549
550    // Scroll animations always start at the current scroll offset.
551    if (animations_[i]->target_property() == Animation::ScrollOffset) {
552      gfx::Vector2dF current_scroll_offset;
553      if (controller_impl->value_provider_) {
554        current_scroll_offset =
555            controller_impl->value_provider_->ScrollOffsetForAnimation();
556      } else {
557        // The owning layer isn't yet in the active tree, so the main thread
558        // scroll offset will be up-to-date.
559        current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
560      }
561      animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
562          current_scroll_offset);
563    }
564
565    // The new animation should be set to run as soon as possible.
566    Animation::RunState initial_run_state =
567        Animation::WaitingForTargetAvailability;
568    scoped_ptr<Animation> to_add(
569        animations_[i]->CloneAndInitialize(initial_run_state));
570    DCHECK(!to_add->needs_synchronized_start_time());
571    to_add->set_affects_active_observers(false);
572    controller_impl->AddAnimation(to_add.Pass());
573  }
574}
575
576static bool IsCompleted(
577    Animation* animation,
578    const LayerAnimationController* main_thread_controller) {
579  if (animation->is_impl_only()) {
580    return (animation->run_state() == Animation::WaitingForDeletion);
581  } else {
582    return !main_thread_controller->GetAnimation(animation->group(),
583                                                 animation->target_property());
584  }
585}
586
587static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
588  return animation->run_state() == Animation::WaitingForDeletion &&
589         !animation->affects_pending_observers();
590}
591
592void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
593    LayerAnimationController* controller_impl) const {
594  // Animations removed on the main thread should no longer affect pending
595  // observers, and should stop affecting active observers after the next call
596  // to ActivateAnimations. If already WaitingForDeletion, they can be removed
597  // immediately.
598  ScopedPtrVector<Animation>& animations = controller_impl->animations_;
599  for (size_t i = 0; i < animations.size(); ++i) {
600    if (IsCompleted(animations[i], this))
601      animations[i]->set_affects_pending_observers(false);
602  }
603  animations.erase(cc::remove_if(&animations,
604                                 animations.begin(),
605                                 animations.end(),
606                                 AffectsActiveOnlyAndIsWaitingForDeletion),
607                   animations.end());
608}
609
610void LayerAnimationController::PushPropertiesToImplThread(
611    LayerAnimationController* controller_impl) const {
612  for (size_t i = 0; i < animations_.size(); ++i) {
613    Animation* current_impl = controller_impl->GetAnimation(
614        animations_[i]->group(), animations_[i]->target_property());
615    if (current_impl)
616      animations_[i]->PushPropertiesTo(current_impl);
617  }
618}
619
620void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
621  DCHECK(needs_to_start_animations_);
622  needs_to_start_animations_ = false;
623  // First collect running properties affecting each type of observer.
624  TargetProperties blocked_properties_for_active_observers;
625  TargetProperties blocked_properties_for_pending_observers;
626  std::vector<size_t> animations_waiting_for_target;
627
628  animations_waiting_for_target.reserve(animations_.size());
629  for (size_t i = 0; i < animations_.size(); ++i) {
630    if (animations_[i]->run_state() == Animation::Starting ||
631        animations_[i]->run_state() == Animation::Running) {
632      if (animations_[i]->affects_active_observers()) {
633        blocked_properties_for_active_observers.insert(
634            animations_[i]->target_property());
635      }
636      if (animations_[i]->affects_pending_observers()) {
637        blocked_properties_for_pending_observers.insert(
638            animations_[i]->target_property());
639      }
640    } else if (animations_[i]->run_state() ==
641               Animation::WaitingForTargetAvailability) {
642      animations_waiting_for_target.push_back(i);
643    }
644  }
645
646  for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
647      // Collect all properties for animations with the same group id (they
648      // should all also be in the list of animations).
649    size_t animation_index = animations_waiting_for_target[i];
650    Animation* animation_waiting_for_target = animations_[animation_index];
651    // Check for the run state again even though the animation was waiting
652    // for target because it might have changed the run state while handling
653    // previous animation in this loop (if they belong to same group).
654    if (animation_waiting_for_target->run_state() ==
655        Animation::WaitingForTargetAvailability) {
656      TargetProperties enqueued_properties;
657      bool affects_active_observers =
658          animation_waiting_for_target->affects_active_observers();
659      bool affects_pending_observers =
660          animation_waiting_for_target->affects_pending_observers();
661      enqueued_properties.insert(
662          animation_waiting_for_target->target_property());
663      for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
664        if (animation_waiting_for_target->group() == animations_[j]->group()) {
665          enqueued_properties.insert(animations_[j]->target_property());
666          affects_active_observers |=
667              animations_[j]->affects_active_observers();
668          affects_pending_observers |=
669              animations_[j]->affects_pending_observers();
670        }
671      }
672
673      // Check to see if intersection of the list of properties affected by
674      // the group and the list of currently blocked properties is null, taking
675      // into account the type(s) of observers affected by the group. In any
676      // case, the group's target properties need to be added to the lists of
677      // blocked properties.
678      bool null_intersection = true;
679      for (TargetProperties::iterator p_iter = enqueued_properties.begin();
680           p_iter != enqueued_properties.end();
681           ++p_iter) {
682        if (affects_active_observers &&
683            !blocked_properties_for_active_observers.insert(*p_iter).second)
684          null_intersection = false;
685        if (affects_pending_observers &&
686            !blocked_properties_for_pending_observers.insert(*p_iter).second)
687          null_intersection = false;
688      }
689
690      // If the intersection is null, then we are free to start the animations
691      // in the group.
692      if (null_intersection) {
693        animation_waiting_for_target->SetRunState(Animation::Starting,
694                                                  monotonic_time);
695        for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
696          if (animation_waiting_for_target->group() ==
697              animations_[j]->group()) {
698            animations_[j]->SetRunState(Animation::Starting, monotonic_time);
699          }
700        }
701      } else {
702        needs_to_start_animations_ = true;
703      }
704    }
705  }
706}
707
708void LayerAnimationController::PromoteStartedAnimations(
709    base::TimeTicks monotonic_time,
710    AnimationEventsVector* events) {
711  for (size_t i = 0; i < animations_.size(); ++i) {
712    if (animations_[i]->run_state() == Animation::Starting &&
713        animations_[i]->affects_active_observers()) {
714      animations_[i]->SetRunState(Animation::Running, monotonic_time);
715      if (!animations_[i]->has_set_start_time() &&
716          !animations_[i]->needs_synchronized_start_time())
717        animations_[i]->set_start_time(monotonic_time);
718      if (events) {
719        AnimationEvent started_event(AnimationEvent::Started,
720                                     id_,
721                                     animations_[i]->group(),
722                                     animations_[i]->target_property(),
723                                     monotonic_time);
724        started_event.is_impl_only = animations_[i]->is_impl_only();
725        if (started_event.is_impl_only)
726          NotifyAnimationStarted(started_event);
727        else
728          events->push_back(started_event);
729      }
730    }
731  }
732}
733
734void LayerAnimationController::MarkFinishedAnimations(
735    base::TimeTicks monotonic_time) {
736  for (size_t i = 0; i < animations_.size(); ++i) {
737    if (animations_[i]->IsFinishedAt(monotonic_time) &&
738        animations_[i]->run_state() != Animation::Aborted &&
739        animations_[i]->run_state() != Animation::WaitingForDeletion)
740      animations_[i]->SetRunState(Animation::Finished, monotonic_time);
741  }
742}
743
744void LayerAnimationController::MarkAnimationsForDeletion(
745    base::TimeTicks monotonic_time,
746    AnimationEventsVector* events) {
747  bool marked_animations_for_deletions = false;
748  std::vector<size_t> animations_with_same_group_id;
749
750  animations_with_same_group_id.reserve(animations_.size());
751  // Non-aborted animations are marked for deletion after a corresponding
752  // AnimationEvent::Finished event is sent or received. This means that if
753  // we don't have an events vector, we must ensure that non-aborted animations
754  // have received a finished event before marking them for deletion.
755  for (size_t i = 0; i < animations_.size(); i++) {
756    int group_id = animations_[i]->group();
757    if (animations_[i]->run_state() == Animation::Aborted) {
758      if (events && !animations_[i]->is_impl_only()) {
759        AnimationEvent aborted_event(AnimationEvent::Aborted,
760                                     id_,
761                                     group_id,
762                                     animations_[i]->target_property(),
763                                     monotonic_time);
764        events->push_back(aborted_event);
765      }
766      animations_[i]->SetRunState(Animation::WaitingForDeletion,
767                                  monotonic_time);
768      marked_animations_for_deletions = true;
769      continue;
770    }
771
772    bool all_anims_with_same_id_are_finished = false;
773
774    // Since deleting an animation on the main thread leads to its deletion
775    // on the impl thread, we only mark a Finished main thread animation for
776    // deletion once it has received a Finished event from the impl thread.
777    bool animation_i_will_send_or_has_received_finish_event =
778        events || animations_[i]->received_finished_event();
779    // If an animation is finished, and not already marked for deletion,
780    // find out if all other animations in the same group are also finished.
781    if (animations_[i]->run_state() == Animation::Finished &&
782        animation_i_will_send_or_has_received_finish_event) {
783      // Clear the animations_with_same_group_id if it was added for
784      // the previous animation's iteration.
785      if (animations_with_same_group_id.size() > 0)
786        animations_with_same_group_id.clear();
787      all_anims_with_same_id_are_finished = true;
788      for (size_t j = 0; j < animations_.size(); ++j) {
789        bool animation_j_will_send_or_has_received_finish_event =
790            events || animations_[j]->received_finished_event();
791        if (group_id == animations_[j]->group()) {
792          if (!animations_[j]->is_finished() ||
793              (animations_[j]->run_state() == Animation::Finished &&
794               !animation_j_will_send_or_has_received_finish_event)) {
795            all_anims_with_same_id_are_finished = false;
796            break;
797          } else if (j >= i &&
798                     animations_[j]->run_state() != Animation::Aborted) {
799            // Mark down the animations which belong to the same group
800            // and is not yet aborted. If this current iteration finds that all
801            // animations with same ID are finished, then the marked
802            // animations below will be set to WaitingForDeletion in next
803            // iteration.
804            animations_with_same_group_id.push_back(j);
805          }
806        }
807      }
808    }
809    if (all_anims_with_same_id_are_finished) {
810      // We now need to remove all animations with the same group id as
811      // group_id (and send along animation finished notifications, if
812      // necessary).
813      for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
814        size_t animation_index = animations_with_same_group_id[j];
815          if (events) {
816            AnimationEvent finished_event(
817                AnimationEvent::Finished,
818                id_,
819                animations_[animation_index]->group(),
820                animations_[animation_index]->target_property(),
821                monotonic_time);
822            finished_event.is_impl_only =
823                animations_[animation_index]->is_impl_only();
824            if (finished_event.is_impl_only)
825              NotifyAnimationFinished(finished_event);
826            else
827              events->push_back(finished_event);
828          }
829          animations_[animation_index]->SetRunState(
830              Animation::WaitingForDeletion, monotonic_time);
831      }
832      marked_animations_for_deletions = true;
833    }
834  }
835  if (marked_animations_for_deletions)
836    NotifyObserversAnimationWaitingForDeletion();
837}
838
839static bool IsWaitingForDeletion(Animation* animation) {
840  return animation->run_state() == Animation::WaitingForDeletion;
841}
842
843void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
844  animations_.erase(cc::remove_if(&animations_,
845                                  animations_.begin(),
846                                  animations_.end(),
847                                  IsWaitingForDeletion),
848                    animations_.end());
849}
850
851void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
852  for (size_t i = 0; i < animations_.size(); ++i) {
853    if (animations_[i]->run_state() == Animation::Starting ||
854        animations_[i]->run_state() == Animation::Running ||
855        animations_[i]->run_state() == Animation::Paused) {
856      if (!animations_[i]->InEffect(monotonic_time))
857        continue;
858
859      double trimmed =
860          animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
861
862      switch (animations_[i]->target_property()) {
863        case Animation::Transform: {
864          const TransformAnimationCurve* transform_animation_curve =
865              animations_[i]->curve()->ToTransformAnimationCurve();
866          const gfx::Transform transform =
867              transform_animation_curve->GetValue(trimmed);
868          NotifyObserversTransformAnimated(
869              transform,
870              animations_[i]->affects_active_observers(),
871              animations_[i]->affects_pending_observers());
872          break;
873        }
874
875        case Animation::Opacity: {
876          const FloatAnimationCurve* float_animation_curve =
877              animations_[i]->curve()->ToFloatAnimationCurve();
878          const float opacity = std::max(
879              std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
880          NotifyObserversOpacityAnimated(
881              opacity,
882              animations_[i]->affects_active_observers(),
883              animations_[i]->affects_pending_observers());
884          break;
885        }
886
887        case Animation::Filter: {
888          const FilterAnimationCurve* filter_animation_curve =
889              animations_[i]->curve()->ToFilterAnimationCurve();
890          const FilterOperations filter =
891              filter_animation_curve->GetValue(trimmed);
892          NotifyObserversFilterAnimated(
893              filter,
894              animations_[i]->affects_active_observers(),
895              animations_[i]->affects_pending_observers());
896          break;
897        }
898
899        case Animation::BackgroundColor: {
900          // Not yet implemented.
901          break;
902        }
903
904        case Animation::ScrollOffset: {
905          const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
906              animations_[i]->curve()->ToScrollOffsetAnimationCurve();
907          const gfx::Vector2dF scroll_offset =
908              scroll_offset_animation_curve->GetValue(trimmed);
909          NotifyObserversScrollOffsetAnimated(
910              scroll_offset,
911              animations_[i]->affects_active_observers(),
912              animations_[i]->affects_pending_observers());
913          break;
914        }
915
916        // Do nothing for sentinel value.
917        case Animation::TargetPropertyEnumSize:
918          NOTREACHED();
919      }
920    }
921  }
922}
923
924void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
925  bool force = type == ForceActivation;
926  if (registrar_) {
927    bool was_active = is_active_;
928    is_active_ = false;
929    for (size_t i = 0; i < animations_.size(); ++i) {
930      if (animations_[i]->run_state() != Animation::WaitingForDeletion) {
931        is_active_ = true;
932        break;
933      }
934    }
935
936    if (is_active_ && (!was_active || force))
937      registrar_->DidActivateAnimationController(this);
938    else if (!is_active_ && (was_active || force))
939      registrar_->DidDeactivateAnimationController(this);
940  }
941}
942
943void LayerAnimationController::NotifyObserversOpacityAnimated(
944    float opacity,
945    bool notify_active_observers,
946    bool notify_pending_observers) {
947  if (value_observers_.might_have_observers()) {
948    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
949        value_observers_);
950    LayerAnimationValueObserver* obs;
951    while ((obs = it.GetNext()) != NULL) {
952      if ((notify_active_observers && notify_pending_observers) ||
953          (notify_active_observers && obs->IsActive()) ||
954          (notify_pending_observers && !obs->IsActive()))
955        obs->OnOpacityAnimated(opacity);
956    }
957  }
958}
959
960void LayerAnimationController::NotifyObserversTransformAnimated(
961    const gfx::Transform& transform,
962    bool notify_active_observers,
963    bool notify_pending_observers) {
964  if (value_observers_.might_have_observers()) {
965    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
966        value_observers_);
967    LayerAnimationValueObserver* obs;
968    while ((obs = it.GetNext()) != NULL) {
969      if ((notify_active_observers && notify_pending_observers) ||
970          (notify_active_observers && obs->IsActive()) ||
971          (notify_pending_observers && !obs->IsActive()))
972        obs->OnTransformAnimated(transform);
973    }
974  }
975}
976
977void LayerAnimationController::NotifyObserversFilterAnimated(
978    const FilterOperations& filters,
979    bool notify_active_observers,
980    bool notify_pending_observers) {
981  if (value_observers_.might_have_observers()) {
982    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
983        value_observers_);
984    LayerAnimationValueObserver* obs;
985    while ((obs = it.GetNext()) != NULL) {
986      if ((notify_active_observers && notify_pending_observers) ||
987          (notify_active_observers && obs->IsActive()) ||
988          (notify_pending_observers && !obs->IsActive()))
989        obs->OnFilterAnimated(filters);
990    }
991  }
992}
993
994void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
995    const gfx::Vector2dF& scroll_offset,
996    bool notify_active_observers,
997    bool notify_pending_observers) {
998  if (value_observers_.might_have_observers()) {
999    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1000        value_observers_);
1001    LayerAnimationValueObserver* obs;
1002    while ((obs = it.GetNext()) != NULL) {
1003      if ((notify_active_observers && notify_pending_observers) ||
1004          (notify_active_observers && obs->IsActive()) ||
1005          (notify_pending_observers && !obs->IsActive()))
1006        obs->OnScrollOffsetAnimated(scroll_offset);
1007    }
1008  }
1009}
1010
1011void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1012  FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1013                    value_observers_,
1014                    OnAnimationWaitingForDeletion());
1015}
1016
1017bool LayerAnimationController::HasValueObserver() {
1018  if (value_observers_.might_have_observers()) {
1019    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1020        value_observers_);
1021    return it.GetNext() != NULL;
1022  }
1023  return false;
1024}
1025
1026bool LayerAnimationController::HasActiveValueObserver() {
1027  if (value_observers_.might_have_observers()) {
1028    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1029        value_observers_);
1030    LayerAnimationValueObserver* obs;
1031    while ((obs = it.GetNext()) != NULL)
1032      if (obs->IsActive())
1033        return true;
1034  }
1035  return false;
1036}
1037
1038}  // namespace cc
1039