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.
5 #include "cc/animation/layer_animation_controller.h"
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"
23 LayerAnimationController::LayerAnimationController(int id)
28 value_provider_(NULL),
29 layer_animation_delegate_(NULL),
30 needs_to_start_animations_(false) {
33 LayerAnimationController::~LayerAnimationController() {
35 registrar_->UnregisterAnimationController(this);
38 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
40 return make_scoped_refptr(new LayerAnimationController(id));
43 void LayerAnimationController::PauseAnimation(int animation_id,
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());
53 struct HasAnimationId {
54 explicit HasAnimationId(int id) : id_(id) {}
55 bool operator()(Animation* animation) const {
56 return animation->id() == id_;
63 void LayerAnimationController::RemoveAnimation(int animation_id) {
64 animations_.erase(cc::remove_if(&animations_,
67 HasAnimationId(animation_id)),
69 UpdateActivation(NormalActivation);
72 struct 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_;
82 Animation::TargetProperty target_property_;
85 void LayerAnimationController::RemoveAnimation(
87 Animation::TargetProperty target_property) {
89 cc::remove_if(&animations_,
92 HasAnimationIdAndProperty(animation_id, target_property)),
94 UpdateActivation(NormalActivation);
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_);
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())
113 PurgeAnimationsMarkedForDeletion();
114 PushNewAnimationsToImplThread(controller_impl);
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);
121 PushPropertiesToImplThread(controller_impl);
122 controller_impl->UpdateActivation(NormalActivation);
123 UpdateActivation(NormalActivation);
126 void LayerAnimationController::Animate(double monotonic_time) {
127 DCHECK(monotonic_time);
128 if (!HasValueObserver())
131 if (needs_to_start_animations_)
132 StartAnimations(monotonic_time);
133 TickAnimations(monotonic_time);
134 last_tick_time_ = monotonic_time;
137 void LayerAnimationController::AccumulatePropertyUpdates(
138 double monotonic_time,
139 AnimationEventsVector* events) {
143 for (size_t i = 0; i < animations_.size(); ++i) {
144 Animation* animation = animations_[i];
145 if (!animation->is_impl_only())
148 double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time);
149 switch (animation->target_property()) {
150 case Animation::Opacity: {
151 AnimationEvent event(AnimationEvent::PropertyUpdate,
156 event.opacity = animation->curve()->ToFloatAnimationCurve()->GetValue(
158 event.is_impl_only = true;
159 events->push_back(event);
163 case Animation::Transform: {
164 AnimationEvent event(AnimationEvent::PropertyUpdate,
167 Animation::Transform,
170 animation->curve()->ToTransformAnimationCurve()->GetValue(trimmed);
171 event.is_impl_only = true;
172 events->push_back(event);
176 case Animation::Filter: {
177 AnimationEvent event(AnimationEvent::PropertyUpdate,
182 event.filters = animation->curve()->ToFilterAnimationCurve()->GetValue(
184 event.is_impl_only = true;
185 events->push_back(event);
189 case Animation::BackgroundColor: { break; }
191 case Animation::ScrollOffset: {
192 // Impl-side changes to scroll offset are already sent back to the
193 // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
198 case Animation::TargetPropertyEnumSize:
204 void LayerAnimationController::UpdateState(bool start_ready_animations,
205 AnimationEventsVector* events) {
206 if (!HasActiveValueObserver())
209 DCHECK(last_tick_time_);
210 if (start_ready_animations)
211 PromoteStartedAnimations(last_tick_time_, events);
213 MarkFinishedAnimations(last_tick_time_);
214 MarkAnimationsForDeletion(last_tick_time_, events);
216 if (needs_to_start_animations_ && start_ready_animations) {
217 StartAnimations(last_tick_time_);
218 PromoteStartedAnimations(last_tick_time_, events);
221 AccumulatePropertyUpdates(last_tick_time_, events);
223 UpdateActivation(NormalActivation);
226 struct AffectsNoObservers {
227 bool operator()(Animation* animation) const {
228 return !animation->affects_active_observers() &&
229 !animation->affects_pending_observers();
233 void LayerAnimationController::ActivateAnimations() {
234 for (size_t i = 0; i < animations_.size(); ++i) {
235 animations_[i]->set_affects_active_observers(
236 animations_[i]->affects_pending_observers());
238 animations_.erase(cc::remove_if(&animations_,
241 AffectsNoObservers()),
243 UpdateActivation(NormalActivation);
246 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
247 animations_.push_back(animation.Pass());
248 needs_to_start_animations_ = true;
249 UpdateActivation(NormalActivation);
252 Animation* LayerAnimationController::GetAnimation(
254 Animation::TargetProperty target_property) const {
255 for (size_t i = 0; i < animations_.size(); ++i)
256 if (animations_[i]->group() == group_id &&
257 animations_[i]->target_property() == target_property)
258 return animations_[i];
262 Animation* LayerAnimationController::GetAnimation(
263 Animation::TargetProperty target_property) const {
264 for (size_t i = 0; i < animations_.size(); ++i) {
265 size_t index = animations_.size() - i - 1;
266 if (animations_[index]->target_property() == target_property)
267 return animations_[index];
272 bool LayerAnimationController::HasActiveAnimation() const {
273 for (size_t i = 0; i < animations_.size(); ++i) {
274 if (!animations_[i]->is_finished())
280 bool LayerAnimationController::IsAnimatingProperty(
281 Animation::TargetProperty target_property) const {
282 for (size_t i = 0; i < animations_.size(); ++i) {
283 if (!animations_[i]->is_finished() &&
284 animations_[i]->target_property() == target_property)
290 void LayerAnimationController::SetAnimationRegistrar(
291 AnimationRegistrar* registrar) {
292 if (registrar_ == registrar)
296 registrar_->UnregisterAnimationController(this);
298 registrar_ = registrar;
300 registrar_->RegisterAnimationController(this);
302 UpdateActivation(ForceActivation);
305 void LayerAnimationController::NotifyAnimationStarted(
306 const AnimationEvent& event) {
307 base::TimeTicks monotonic_time = base::TimeTicks::FromInternalValue(
308 event.monotonic_time * base::Time::kMicrosecondsPerSecond);
309 if (event.is_impl_only) {
310 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
311 OnAnimationStarted(event));
312 if (layer_animation_delegate_)
313 layer_animation_delegate_->NotifyAnimationStarted(monotonic_time,
314 event.target_property);
319 for (size_t i = 0; i < animations_.size(); ++i) {
320 if (animations_[i]->group() == event.group_id &&
321 animations_[i]->target_property() == event.target_property &&
322 animations_[i]->needs_synchronized_start_time()) {
323 animations_[i]->set_needs_synchronized_start_time(false);
324 if (!animations_[i]->has_set_start_time())
325 animations_[i]->set_start_time(event.monotonic_time);
327 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
328 OnAnimationStarted(event));
329 if (layer_animation_delegate_)
330 layer_animation_delegate_->NotifyAnimationStarted(
331 monotonic_time, event.target_property);
338 void LayerAnimationController::NotifyAnimationFinished(
339 const AnimationEvent& event) {
340 base::TimeTicks monotonic_time = base::TimeTicks::FromInternalValue(
341 event.monotonic_time * base::Time::kMicrosecondsPerSecond);
342 if (event.is_impl_only) {
343 if (layer_animation_delegate_)
344 layer_animation_delegate_->NotifyAnimationFinished(monotonic_time,
345 event.target_property);
349 for (size_t i = 0; i < animations_.size(); ++i) {
350 if (animations_[i]->group() == event.group_id &&
351 animations_[i]->target_property() == event.target_property) {
352 animations_[i]->set_received_finished_event(true);
353 if (layer_animation_delegate_)
354 layer_animation_delegate_->NotifyAnimationFinished(
355 monotonic_time, event.target_property);
362 void LayerAnimationController::NotifyAnimationAborted(
363 const AnimationEvent& event) {
364 for (size_t i = 0; i < animations_.size(); ++i) {
365 if (animations_[i]->group() == event.group_id &&
366 animations_[i]->target_property() == event.target_property) {
367 animations_[i]->SetRunState(Animation::Aborted, event.monotonic_time);
372 void LayerAnimationController::NotifyAnimationPropertyUpdate(
373 const AnimationEvent& event) {
374 bool notify_active_observers = true;
375 bool notify_pending_observers = true;
376 switch (event.target_property) {
377 case Animation::Opacity:
378 NotifyObserversOpacityAnimated(
379 event.opacity, notify_active_observers, notify_pending_observers);
381 case Animation::Transform:
382 NotifyObserversTransformAnimated(
383 event.transform, notify_active_observers, notify_pending_observers);
390 void LayerAnimationController::AddValueObserver(
391 LayerAnimationValueObserver* observer) {
392 if (!value_observers_.HasObserver(observer))
393 value_observers_.AddObserver(observer);
396 void LayerAnimationController::RemoveValueObserver(
397 LayerAnimationValueObserver* observer) {
398 value_observers_.RemoveObserver(observer);
401 void LayerAnimationController::AddEventObserver(
402 LayerAnimationEventObserver* observer) {
403 if (!event_observers_.HasObserver(observer))
404 event_observers_.AddObserver(observer);
407 void LayerAnimationController::RemoveEventObserver(
408 LayerAnimationEventObserver* observer) {
409 event_observers_.RemoveObserver(observer);
412 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
413 for (size_t i = 0; i < animations_.size(); ++i) {
414 if (!animations_[i]->is_finished() &&
415 animations_[i]->target_property() == Animation::Filter &&
418 ->ToFilterAnimationCurve()
419 ->HasFilterThatMovesPixels())
426 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
427 return IsAnimatingProperty(Animation::Transform);
430 bool LayerAnimationController::FilterAnimationBoundsForBox(
431 const gfx::BoxF& box, gfx::BoxF* bounds) const {
432 // TODO(avallee): Implement.
436 bool LayerAnimationController::TransformAnimationBoundsForBox(
437 const gfx::BoxF& box,
438 gfx::BoxF* bounds) const {
439 DCHECK(HasTransformAnimationThatInflatesBounds())
440 << "TransformAnimationBoundsForBox will give incorrect results if there "
441 << "are no transform animations affecting bounds, non-animated transform "
444 // Compute bounds based on animations for which is_finished() is false.
445 // Do nothing if there are no such animations; in this case, it is assumed
446 // that callers will take care of computing bounds based on the owning layer's
448 *bounds = gfx::BoxF();
449 for (size_t i = 0; i < animations_.size(); ++i) {
450 if (animations_[i]->is_finished() ||
451 animations_[i]->target_property() != Animation::Transform)
454 const TransformAnimationCurve* transform_animation_curve =
455 animations_[i]->curve()->ToTransformAnimationCurve();
456 gfx::BoxF animation_bounds;
458 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
461 bounds->Union(animation_bounds);
467 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
468 for (size_t i = 0; i < animations_.size(); ++i) {
469 if (animations_[i]->is_finished() ||
470 animations_[i]->target_property() != Animation::Transform)
473 const TransformAnimationCurve* transform_animation_curve =
474 animations_[i]->curve()->ToTransformAnimationCurve();
475 if (transform_animation_curve->AffectsScale())
482 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
483 for (size_t i = 0; i < animations_.size(); ++i) {
484 if (animations_[i]->is_finished() ||
485 animations_[i]->target_property() != Animation::Transform)
488 const TransformAnimationCurve* transform_animation_curve =
489 animations_[i]->curve()->ToTransformAnimationCurve();
490 if (!transform_animation_curve->IsTranslation())
497 bool LayerAnimationController::MaximumScale(float* max_scale) const {
499 for (size_t i = 0; i < animations_.size(); ++i) {
500 if (animations_[i]->is_finished() ||
501 animations_[i]->target_property() != Animation::Transform)
504 const TransformAnimationCurve* transform_animation_curve =
505 animations_[i]->curve()->ToTransformAnimationCurve();
506 float animation_scale = 0.f;
507 if (!transform_animation_curve->MaximumScale(&animation_scale))
509 *max_scale = std::max(*max_scale, animation_scale);
515 void LayerAnimationController::PushNewAnimationsToImplThread(
516 LayerAnimationController* controller_impl) const {
517 // Any new animations owned by the main thread's controller are cloned and
518 // add to the impl thread's controller.
519 for (size_t i = 0; i < animations_.size(); ++i) {
520 // If the animation is already running on the impl thread, there is no
521 // need to copy it over.
522 if (controller_impl->GetAnimation(animations_[i]->group(),
523 animations_[i]->target_property()))
526 // If the animation is not running on the impl thread, it does not
527 // necessarily mean that it needs to be copied over and started; it may
528 // have already finished. In this case, the impl thread animation will
529 // have already notified that it has started and the main thread animation
530 // will no longer need
531 // a synchronized start time.
532 if (!animations_[i]->needs_synchronized_start_time())
535 // Scroll animations always start at the current scroll offset.
536 if (animations_[i]->target_property() == Animation::ScrollOffset) {
537 gfx::Vector2dF current_scroll_offset;
538 if (controller_impl->value_provider_) {
539 current_scroll_offset =
540 controller_impl->value_provider_->ScrollOffsetForAnimation();
542 // The owning layer isn't yet in the active tree, so the main thread
543 // scroll offset will be up-to-date.
544 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
546 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
547 current_scroll_offset);
550 // The new animation should be set to run as soon as possible.
551 Animation::RunState initial_run_state =
552 Animation::WaitingForTargetAvailability;
553 scoped_ptr<Animation> to_add(
554 animations_[i]->CloneAndInitialize(initial_run_state));
555 DCHECK(!to_add->needs_synchronized_start_time());
556 to_add->set_affects_active_observers(false);
557 controller_impl->AddAnimation(to_add.Pass());
561 static bool IsCompleted(
562 Animation* animation,
563 const LayerAnimationController* main_thread_controller) {
564 if (animation->is_impl_only()) {
565 return (animation->run_state() == Animation::WaitingForDeletion);
567 return !main_thread_controller->GetAnimation(animation->group(),
568 animation->target_property());
572 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
573 return animation->run_state() == Animation::WaitingForDeletion &&
574 !animation->affects_pending_observers();
577 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
578 LayerAnimationController* controller_impl) const {
579 // Animations removed on the main thread should no longer affect pending
580 // observers, and should stop affecting active observers after the next call
581 // to ActivateAnimations. If already WaitingForDeletion, they can be removed
583 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
584 for (size_t i = 0; i < animations.size(); ++i) {
585 if (IsCompleted(animations[i], this))
586 animations[i]->set_affects_pending_observers(false);
588 animations.erase(cc::remove_if(&animations,
591 AffectsActiveOnlyAndIsWaitingForDeletion),
595 void LayerAnimationController::PushPropertiesToImplThread(
596 LayerAnimationController* controller_impl) const {
597 for (size_t i = 0; i < animations_.size(); ++i) {
598 Animation* current_impl = controller_impl->GetAnimation(
599 animations_[i]->group(), animations_[i]->target_property());
601 animations_[i]->PushPropertiesTo(current_impl);
605 void LayerAnimationController::StartAnimations(double monotonic_time) {
606 DCHECK(needs_to_start_animations_);
607 needs_to_start_animations_ = false;
608 // First collect running properties affecting each type of observer.
609 TargetProperties blocked_properties_for_active_observers;
610 TargetProperties blocked_properties_for_pending_observers;
611 for (size_t i = 0; i < animations_.size(); ++i) {
612 if (animations_[i]->run_state() == Animation::Starting ||
613 animations_[i]->run_state() == Animation::Running) {
614 if (animations_[i]->affects_active_observers()) {
615 blocked_properties_for_active_observers.insert(
616 animations_[i]->target_property());
618 if (animations_[i]->affects_pending_observers()) {
619 blocked_properties_for_pending_observers.insert(
620 animations_[i]->target_property());
625 for (size_t i = 0; i < animations_.size(); ++i) {
626 if (animations_[i]->run_state() ==
627 Animation::WaitingForTargetAvailability) {
628 // Collect all properties for animations with the same group id (they
629 // should all also be in the list of animations).
630 TargetProperties enqueued_properties;
631 bool affects_active_observers =
632 animations_[i]->affects_active_observers();
633 bool affects_pending_observers =
634 animations_[i]->affects_pending_observers();
635 enqueued_properties.insert(animations_[i]->target_property());
636 for (size_t j = i + 1; j < animations_.size(); ++j) {
637 if (animations_[i]->group() == animations_[j]->group()) {
638 enqueued_properties.insert(animations_[j]->target_property());
639 affects_active_observers |=
640 animations_[j]->affects_active_observers();
641 affects_pending_observers |=
642 animations_[j]->affects_pending_observers();
646 // Check to see if intersection of the list of properties affected by
647 // the group and the list of currently blocked properties is null, taking
648 // into account the type(s) of observers affected by the group. In any
649 // case, the group's target properties need to be added to the lists of
650 // blocked properties.
651 bool null_intersection = true;
652 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
653 p_iter != enqueued_properties.end();
655 if (affects_active_observers &&
656 !blocked_properties_for_active_observers.insert(*p_iter).second)
657 null_intersection = false;
658 if (affects_pending_observers &&
659 !blocked_properties_for_pending_observers.insert(*p_iter).second)
660 null_intersection = false;
663 // If the intersection is null, then we are free to start the animations
665 if (null_intersection) {
666 animations_[i]->SetRunState(Animation::Starting, monotonic_time);
667 for (size_t j = i + 1; j < animations_.size(); ++j) {
668 if (animations_[i]->group() == animations_[j]->group()) {
669 animations_[j]->SetRunState(Animation::Starting, monotonic_time);
673 needs_to_start_animations_ = true;
679 void LayerAnimationController::PromoteStartedAnimations(
680 double monotonic_time,
681 AnimationEventsVector* events) {
682 for (size_t i = 0; i < animations_.size(); ++i) {
683 if (animations_[i]->run_state() == Animation::Starting &&
684 animations_[i]->affects_active_observers()) {
685 animations_[i]->SetRunState(Animation::Running, monotonic_time);
686 if (!animations_[i]->has_set_start_time() &&
687 !animations_[i]->needs_synchronized_start_time())
688 animations_[i]->set_start_time(monotonic_time);
690 AnimationEvent started_event(AnimationEvent::Started,
692 animations_[i]->group(),
693 animations_[i]->target_property(),
695 started_event.is_impl_only = animations_[i]->is_impl_only();
696 events->push_back(started_event);
702 void LayerAnimationController::MarkFinishedAnimations(double monotonic_time) {
703 for (size_t i = 0; i < animations_.size(); ++i) {
704 if (animations_[i]->IsFinishedAt(monotonic_time) &&
705 animations_[i]->run_state() != Animation::Aborted &&
706 animations_[i]->run_state() != Animation::WaitingForDeletion)
707 animations_[i]->SetRunState(Animation::Finished, monotonic_time);
711 void LayerAnimationController::MarkAnimationsForDeletion(
712 double monotonic_time, AnimationEventsVector* events) {
713 bool marked_animations_for_deletions = false;
715 // Non-aborted animations are marked for deletion after a corresponding
716 // AnimationEvent::Finished event is sent or received. This means that if
717 // we don't have an events vector, we must ensure that non-aborted animations
718 // have received a finished event before marking them for deletion.
719 for (size_t i = 0; i < animations_.size(); i++) {
720 int group_id = animations_[i]->group();
721 if (animations_[i]->run_state() == Animation::Aborted) {
722 if (events && !animations_[i]->is_impl_only()) {
723 AnimationEvent aborted_event(AnimationEvent::Aborted,
726 animations_[i]->target_property(),
728 events->push_back(aborted_event);
730 animations_[i]->SetRunState(Animation::WaitingForDeletion,
732 marked_animations_for_deletions = true;
736 bool all_anims_with_same_id_are_finished = false;
738 // Since deleting an animation on the main thread leads to its deletion
739 // on the impl thread, we only mark a Finished main thread animation for
740 // deletion once it has received a Finished event from the impl thread.
741 bool animation_i_will_send_or_has_received_finish_event =
742 events || animations_[i]->received_finished_event();
743 // If an animation is finished, and not already marked for deletion,
744 // find out if all other animations in the same group are also finished.
745 if (animations_[i]->run_state() == Animation::Finished &&
746 animation_i_will_send_or_has_received_finish_event) {
747 all_anims_with_same_id_are_finished = true;
748 for (size_t j = 0; j < animations_.size(); ++j) {
749 bool animation_j_will_send_or_has_received_finish_event =
750 events || animations_[j]->received_finished_event();
751 if (group_id == animations_[j]->group() &&
752 (!animations_[j]->is_finished() ||
753 (animations_[j]->run_state() == Animation::Finished &&
754 !animation_j_will_send_or_has_received_finish_event))) {
755 all_anims_with_same_id_are_finished = false;
760 if (all_anims_with_same_id_are_finished) {
761 // We now need to remove all animations with the same group id as
762 // group_id (and send along animation finished notifications, if
764 for (size_t j = i; j < animations_.size(); j++) {
765 if (animations_[j]->group() == group_id &&
766 animations_[j]->run_state() != Animation::Aborted) {
768 AnimationEvent finished_event(AnimationEvent::Finished,
770 animations_[j]->group(),
771 animations_[j]->target_property(),
773 finished_event.is_impl_only = animations_[j]->is_impl_only();
774 events->push_back(finished_event);
776 animations_[j]->SetRunState(Animation::WaitingForDeletion,
780 marked_animations_for_deletions = true;
783 if (marked_animations_for_deletions)
784 NotifyObserversAnimationWaitingForDeletion();
787 static bool IsWaitingForDeletion(Animation* animation) {
788 return animation->run_state() == Animation::WaitingForDeletion;
791 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
792 animations_.erase(cc::remove_if(&animations_,
795 IsWaitingForDeletion),
799 void LayerAnimationController::TickAnimations(double monotonic_time) {
800 for (size_t i = 0; i < animations_.size(); ++i) {
801 if (animations_[i]->run_state() == Animation::Starting ||
802 animations_[i]->run_state() == Animation::Running ||
803 animations_[i]->run_state() == Animation::Paused) {
805 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
807 switch (animations_[i]->target_property()) {
808 case Animation::Transform: {
809 const TransformAnimationCurve* transform_animation_curve =
810 animations_[i]->curve()->ToTransformAnimationCurve();
811 const gfx::Transform transform =
812 transform_animation_curve->GetValue(trimmed);
813 NotifyObserversTransformAnimated(
815 animations_[i]->affects_active_observers(),
816 animations_[i]->affects_pending_observers());
820 case Animation::Opacity: {
821 const FloatAnimationCurve* float_animation_curve =
822 animations_[i]->curve()->ToFloatAnimationCurve();
823 const float opacity = float_animation_curve->GetValue(trimmed);
824 NotifyObserversOpacityAnimated(
826 animations_[i]->affects_active_observers(),
827 animations_[i]->affects_pending_observers());
831 case Animation::Filter: {
832 const FilterAnimationCurve* filter_animation_curve =
833 animations_[i]->curve()->ToFilterAnimationCurve();
834 const FilterOperations filter =
835 filter_animation_curve->GetValue(trimmed);
836 NotifyObserversFilterAnimated(
838 animations_[i]->affects_active_observers(),
839 animations_[i]->affects_pending_observers());
843 case Animation::BackgroundColor: {
844 // Not yet implemented.
848 case Animation::ScrollOffset: {
849 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
850 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
851 const gfx::Vector2dF scroll_offset =
852 scroll_offset_animation_curve->GetValue(trimmed);
853 NotifyObserversScrollOffsetAnimated(
855 animations_[i]->affects_active_observers(),
856 animations_[i]->affects_pending_observers());
860 // Do nothing for sentinel value.
861 case Animation::TargetPropertyEnumSize:
868 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
869 bool force = type == ForceActivation;
871 bool was_active = is_active_;
873 for (size_t i = 0; i < animations_.size(); ++i) {
874 if (animations_[i]->run_state() != Animation::WaitingForDeletion) {
880 if (is_active_ && (!was_active || force))
881 registrar_->DidActivateAnimationController(this);
882 else if (!is_active_ && (was_active || force))
883 registrar_->DidDeactivateAnimationController(this);
887 void LayerAnimationController::NotifyObserversOpacityAnimated(
889 bool notify_active_observers,
890 bool notify_pending_observers) {
891 if (value_observers_.might_have_observers()) {
892 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
894 LayerAnimationValueObserver* obs;
895 while ((obs = it.GetNext()) != NULL) {
896 if ((notify_active_observers && obs->IsActive()) ||
897 (notify_pending_observers && !obs->IsActive()))
898 obs->OnOpacityAnimated(opacity);
903 void LayerAnimationController::NotifyObserversTransformAnimated(
904 const gfx::Transform& transform,
905 bool notify_active_observers,
906 bool notify_pending_observers) {
907 if (value_observers_.might_have_observers()) {
908 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
910 LayerAnimationValueObserver* obs;
911 while ((obs = it.GetNext()) != NULL) {
912 if ((notify_active_observers && obs->IsActive()) ||
913 (notify_pending_observers && !obs->IsActive()))
914 obs->OnTransformAnimated(transform);
919 void LayerAnimationController::NotifyObserversFilterAnimated(
920 const FilterOperations& filters,
921 bool notify_active_observers,
922 bool notify_pending_observers) {
923 if (value_observers_.might_have_observers()) {
924 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
926 LayerAnimationValueObserver* obs;
927 while ((obs = it.GetNext()) != NULL) {
928 if ((notify_active_observers && obs->IsActive()) ||
929 (notify_pending_observers && !obs->IsActive()))
930 obs->OnFilterAnimated(filters);
935 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
936 const gfx::Vector2dF& scroll_offset,
937 bool notify_active_observers,
938 bool notify_pending_observers) {
939 if (value_observers_.might_have_observers()) {
940 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
942 LayerAnimationValueObserver* obs;
943 while ((obs = it.GetNext()) != NULL) {
944 if ((notify_active_observers && obs->IsActive()) ||
945 (notify_pending_observers && !obs->IsActive()))
946 obs->OnScrollOffsetAnimated(scroll_offset);
951 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
952 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
954 OnAnimationWaitingForDeletion());
957 bool LayerAnimationController::HasValueObserver() {
958 if (value_observers_.might_have_observers()) {
959 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
961 return it.GetNext() != NULL;
966 bool LayerAnimationController::HasActiveValueObserver() {
967 if (value_observers_.might_have_observers()) {
968 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
970 LayerAnimationValueObserver* obs;
971 while ((obs = it.GetNext()) != NULL)