• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 namespace cc {
23 
LayerAnimationController(int id)24 LayerAnimationController::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 
~LayerAnimationController()33 LayerAnimationController::~LayerAnimationController() {
34   if (registrar_)
35     registrar_->UnregisterAnimationController(this);
36 }
37 
Create(int id)38 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
39     int id) {
40   return make_scoped_refptr(new LayerAnimationController(id));
41 }
42 
PauseAnimation(int animation_id,base::TimeDelta time_offset)43 void 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 
53 struct HasAnimationId {
HasAnimationIdcc::HasAnimationId54   explicit HasAnimationId(int id) : id_(id) {}
operator ()cc::HasAnimationId55   bool operator()(Animation* animation) const {
56     return animation->id() == id_;
57   }
58 
59  private:
60   int id_;
61 };
62 
RemoveAnimation(int animation_id)63 void 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 
72 struct HasAnimationIdAndProperty {
HasAnimationIdAndPropertycc::HasAnimationIdAndProperty73   HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
74       : id_(id), target_property_(target_property) {}
operator ()cc::HasAnimationIdAndProperty75   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 
RemoveAnimation(int animation_id,Animation::TargetProperty target_property)85 void 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 
AbortAnimations(Animation::TargetProperty target_property)97 void 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.
PushAnimationUpdatesTo(LayerAnimationController * controller_impl)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 
Animate(base::TimeTicks monotonic_time)126 void 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 
AccumulatePropertyUpdates(base::TimeTicks monotonic_time,AnimationEventsVector * events)137 void 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 
UpdateState(bool start_ready_animations,AnimationEventsVector * events)210 void 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 
232 struct AffectsNoObservers {
operator ()cc::AffectsNoObservers233   bool operator()(Animation* animation) const {
234     return !animation->affects_active_observers() &&
235            !animation->affects_pending_observers();
236   }
237 };
238 
ActivateAnimations()239 void 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 
AddAnimation(scoped_ptr<Animation> animation)252 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
253   animations_.push_back(animation.Pass());
254   needs_to_start_animations_ = true;
255   UpdateActivation(NormalActivation);
256 }
257 
GetAnimation(int group_id,Animation::TargetProperty target_property) const258 Animation* 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 
GetAnimation(Animation::TargetProperty target_property) const268 Animation* 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 
HasActiveAnimation() const278 bool 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 
IsAnimatingProperty(Animation::TargetProperty target_property) const286 bool 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 
SetAnimationRegistrar(AnimationRegistrar * registrar)297 void 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 
NotifyAnimationStarted(const AnimationEvent & event)312 void 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 
NotifyAnimationFinished(const AnimationEvent & event)342 void 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 
NotifyAnimationAborted(const AnimationEvent & event)364 void 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 
NotifyAnimationPropertyUpdate(const AnimationEvent & event)374 void 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 
AddValueObserver(LayerAnimationValueObserver * observer)392 void LayerAnimationController::AddValueObserver(
393     LayerAnimationValueObserver* observer) {
394   if (!value_observers_.HasObserver(observer))
395     value_observers_.AddObserver(observer);
396 }
397 
RemoveValueObserver(LayerAnimationValueObserver * observer)398 void LayerAnimationController::RemoveValueObserver(
399     LayerAnimationValueObserver* observer) {
400   value_observers_.RemoveObserver(observer);
401 }
402 
AddEventObserver(LayerAnimationEventObserver * observer)403 void LayerAnimationController::AddEventObserver(
404     LayerAnimationEventObserver* observer) {
405   if (!event_observers_.HasObserver(observer))
406     event_observers_.AddObserver(observer);
407 }
408 
RemoveEventObserver(LayerAnimationEventObserver * observer)409 void LayerAnimationController::RemoveEventObserver(
410     LayerAnimationEventObserver* observer) {
411   event_observers_.RemoveObserver(observer);
412 }
413 
HasFilterAnimationThatInflatesBounds() const414 bool 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 
HasTransformAnimationThatInflatesBounds() const428 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
429   return IsAnimatingProperty(Animation::Transform);
430 }
431 
FilterAnimationBoundsForBox(const gfx::BoxF & box,gfx::BoxF * bounds) const432 bool LayerAnimationController::FilterAnimationBoundsForBox(
433     const gfx::BoxF& box, gfx::BoxF* bounds) const {
434   // TODO(avallee): Implement.
435   return false;
436 }
437 
TransformAnimationBoundsForBox(const gfx::BoxF & box,gfx::BoxF * bounds) const438 bool 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 
HasAnimationThatAffectsScale() const469 bool 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 
HasOnlyTranslationTransforms() const484 bool 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 
MaximumTargetScale(float * max_scale) const499 bool 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 
PushNewAnimationsToImplThread(LayerAnimationController * controller_impl) const530 void 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 
IsCompleted(Animation * animation,const LayerAnimationController * main_thread_controller)576 static 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 
AffectsActiveOnlyAndIsWaitingForDeletion(Animation * animation)587 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
588   return animation->run_state() == Animation::WaitingForDeletion &&
589          !animation->affects_pending_observers();
590 }
591 
RemoveAnimationsCompletedOnMainThread(LayerAnimationController * controller_impl) const592 void 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 
PushPropertiesToImplThread(LayerAnimationController * controller_impl) const610 void 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 
StartAnimations(base::TimeTicks monotonic_time)620 void 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 
PromoteStartedAnimations(base::TimeTicks monotonic_time,AnimationEventsVector * events)708 void 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 
MarkFinishedAnimations(base::TimeTicks monotonic_time)734 void 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 
MarkAnimationsForDeletion(base::TimeTicks monotonic_time,AnimationEventsVector * events)744 void 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 
IsWaitingForDeletion(Animation * animation)839 static bool IsWaitingForDeletion(Animation* animation) {
840   return animation->run_state() == Animation::WaitingForDeletion;
841 }
842 
PurgeAnimationsMarkedForDeletion()843 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
844   animations_.erase(cc::remove_if(&animations_,
845                                   animations_.begin(),
846                                   animations_.end(),
847                                   IsWaitingForDeletion),
848                     animations_.end());
849 }
850 
TickAnimations(base::TimeTicks monotonic_time)851 void 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 
UpdateActivation(UpdateActivationType type)924 void 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 
NotifyObserversOpacityAnimated(float opacity,bool notify_active_observers,bool notify_pending_observers)943 void 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 
NotifyObserversTransformAnimated(const gfx::Transform & transform,bool notify_active_observers,bool notify_pending_observers)960 void 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 
NotifyObserversFilterAnimated(const FilterOperations & filters,bool notify_active_observers,bool notify_pending_observers)977 void 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 
NotifyObserversScrollOffsetAnimated(const gfx::Vector2dF & scroll_offset,bool notify_active_observers,bool notify_pending_observers)994 void 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 
NotifyObserversAnimationWaitingForDeletion()1011 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1012   FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1013                     value_observers_,
1014                     OnAnimationWaitingForDeletion());
1015 }
1016 
HasValueObserver()1017 bool 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 
HasActiveValueObserver()1026 bool 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