Add ICU message format support
[chromium-blink-merge.git] / cc / animation / layer_animation_controller.cc
blob67a727915627dc746e515352c446bd7a438a6204
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"
7 #include <algorithm>
8 #include <vector>
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/geometry/box_f.h"
20 #include "ui/gfx/transform.h"
22 namespace cc {
24 LayerAnimationController::LayerAnimationController(int id)
25 : registrar_(0),
26 id_(id),
27 is_active_(false),
28 value_provider_(nullptr),
29 layer_animation_delegate_(nullptr),
30 needs_to_start_animations_(false),
31 scroll_offset_animation_was_interrupted_(false),
32 potentially_animating_transform_for_active_observers_(false),
33 potentially_animating_transform_for_pending_observers_(false) {}
35 LayerAnimationController::~LayerAnimationController() {
36 if (registrar_)
37 registrar_->UnregisterAnimationController(this);
40 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
41 int id) {
42 return make_scoped_refptr(new LayerAnimationController(id));
45 void LayerAnimationController::PauseAnimation(int animation_id,
46 base::TimeDelta time_offset) {
47 for (size_t i = 0; i < animations_.size(); ++i) {
48 if (animations_[i]->id() == animation_id) {
49 animations_[i]->SetRunState(Animation::PAUSED,
50 time_offset + animations_[i]->start_time() +
51 animations_[i]->time_offset());
56 struct HasAnimationId {
57 explicit HasAnimationId(int id) : id_(id) {}
58 bool operator()(Animation* animation) const {
59 return animation->id() == id_;
62 private:
63 int id_;
66 void LayerAnimationController::UpdatePotentiallyAnimatingTransform() {
67 bool was_potentially_animating_transform_for_active_observers =
68 potentially_animating_transform_for_active_observers_;
69 bool was_potentially_animating_transform_for_pending_observers =
70 potentially_animating_transform_for_pending_observers_;
72 potentially_animating_transform_for_active_observers_ = false;
73 potentially_animating_transform_for_pending_observers_ = false;
75 for (Animation* animation : animations_) {
76 if (!animation->is_finished() &&
77 animation->target_property() == Animation::TRANSFORM) {
78 potentially_animating_transform_for_active_observers_ |=
79 animation->affects_active_observers();
80 potentially_animating_transform_for_pending_observers_ |=
81 animation->affects_pending_observers();
85 bool changed_for_active_observers =
86 was_potentially_animating_transform_for_active_observers !=
87 potentially_animating_transform_for_active_observers_;
88 bool changed_for_pending_observers =
89 was_potentially_animating_transform_for_pending_observers !=
90 potentially_animating_transform_for_pending_observers_;
92 if (!changed_for_active_observers && !changed_for_pending_observers)
93 return;
95 NotifyObserversTransformIsPotentiallyAnimatingChanged(
96 changed_for_active_observers, changed_for_pending_observers);
99 void LayerAnimationController::RemoveAnimation(int animation_id) {
100 bool removed_transform_animation = false;
101 auto animations_to_remove =
102 animations_.remove_if(HasAnimationId(animation_id));
103 for (auto it = animations_to_remove; it != animations_.end(); ++it) {
104 if ((*it)->target_property() == Animation::SCROLL_OFFSET) {
105 scroll_offset_animation_was_interrupted_ = true;
106 } else if ((*it)->target_property() == Animation::TRANSFORM &&
107 !(*it)->is_finished()) {
108 removed_transform_animation = true;
112 animations_.erase(animations_to_remove, animations_.end());
113 UpdateActivation(NORMAL_ACTIVATION);
114 if (removed_transform_animation)
115 UpdatePotentiallyAnimatingTransform();
118 struct HasAnimationIdAndProperty {
119 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
120 : id_(id), target_property_(target_property) {}
121 bool operator()(Animation* animation) const {
122 return animation->id() == id_ &&
123 animation->target_property() == target_property_;
126 private:
127 int id_;
128 Animation::TargetProperty target_property_;
131 void LayerAnimationController::RemoveAnimation(
132 int animation_id,
133 Animation::TargetProperty target_property) {
134 bool removed_transform_animation = false;
135 auto animations_to_remove = animations_.remove_if(
136 HasAnimationIdAndProperty(animation_id, target_property));
137 if (animations_to_remove == animations_.end())
138 return;
140 if (target_property == Animation::SCROLL_OFFSET)
141 scroll_offset_animation_was_interrupted_ = true;
142 else if (target_property == Animation::TRANSFORM &&
143 !(*animations_to_remove)->is_finished())
144 removed_transform_animation = true;
146 animations_.erase(animations_to_remove, animations_.end());
147 UpdateActivation(NORMAL_ACTIVATION);
148 if (removed_transform_animation)
149 UpdatePotentiallyAnimatingTransform();
152 void LayerAnimationController::AbortAnimations(
153 Animation::TargetProperty target_property) {
154 bool aborted_transform_animation = false;
155 for (size_t i = 0; i < animations_.size(); ++i) {
156 if (animations_[i]->target_property() == target_property &&
157 !animations_[i]->is_finished()) {
158 animations_[i]->SetRunState(Animation::ABORTED, last_tick_time_);
159 if (target_property == Animation::TRANSFORM)
160 aborted_transform_animation = true;
163 if (aborted_transform_animation)
164 UpdatePotentiallyAnimatingTransform();
167 // Ensures that the list of active animations on the main thread and the impl
168 // thread are kept in sync.
169 void LayerAnimationController::PushAnimationUpdatesTo(
170 LayerAnimationController* controller_impl) {
171 DCHECK(this != controller_impl);
172 if (!has_any_animation() && !controller_impl->has_any_animation())
173 return;
174 PurgeAnimationsMarkedForDeletion();
175 PushNewAnimationsToImplThread(controller_impl);
177 // Remove finished impl side animations only after pushing,
178 // and only after the animations are deleted on the main thread
179 // this insures we will never push an animation twice.
180 RemoveAnimationsCompletedOnMainThread(controller_impl);
182 PushPropertiesToImplThread(controller_impl);
183 controller_impl->UpdateActivation(NORMAL_ACTIVATION);
184 UpdateActivation(NORMAL_ACTIVATION);
187 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
188 DCHECK(!monotonic_time.is_null());
189 if (!HasValueObserver())
190 return;
192 if (needs_to_start_animations_)
193 StartAnimations(monotonic_time);
194 TickAnimations(monotonic_time);
195 last_tick_time_ = monotonic_time;
198 void LayerAnimationController::AccumulatePropertyUpdates(
199 base::TimeTicks monotonic_time,
200 AnimationEventsVector* events) {
201 if (!events)
202 return;
204 for (size_t i = 0; i < animations_.size(); ++i) {
205 Animation* animation = animations_[i];
206 if (!animation->is_impl_only())
207 continue;
209 if (!animation->InEffect(monotonic_time))
210 continue;
212 base::TimeDelta trimmed =
213 animation->TrimTimeToCurrentIteration(monotonic_time);
214 switch (animation->target_property()) {
215 case Animation::OPACITY: {
216 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
217 animation->group(), Animation::OPACITY,
218 monotonic_time);
219 const FloatAnimationCurve* float_animation_curve =
220 animation->curve()->ToFloatAnimationCurve();
221 event.opacity = float_animation_curve->GetValue(trimmed);
222 event.is_impl_only = true;
223 events->push_back(event);
224 break;
227 case Animation::TRANSFORM: {
228 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
229 animation->group(), Animation::TRANSFORM,
230 monotonic_time);
231 const TransformAnimationCurve* transform_animation_curve =
232 animation->curve()->ToTransformAnimationCurve();
233 event.transform = transform_animation_curve->GetValue(trimmed);
234 event.is_impl_only = true;
235 events->push_back(event);
236 break;
239 case Animation::FILTER: {
240 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
241 animation->group(), Animation::FILTER,
242 monotonic_time);
243 const FilterAnimationCurve* filter_animation_curve =
244 animation->curve()->ToFilterAnimationCurve();
245 event.filters = filter_animation_curve->GetValue(trimmed);
246 event.is_impl_only = true;
247 events->push_back(event);
248 break;
251 case Animation::BACKGROUND_COLOR: {
252 break;
255 case Animation::SCROLL_OFFSET: {
256 // Impl-side changes to scroll offset are already sent back to the
257 // main thread (e.g. for user-driven scrolling), so a PROPERTY_UPDATE
258 // isn't needed.
259 break;
265 void LayerAnimationController::UpdateState(bool start_ready_animations,
266 AnimationEventsVector* events) {
267 if (!HasActiveValueObserver())
268 return;
270 // Animate hasn't been called, this happens if an observer has been added
271 // between the Commit and Draw phases.
272 if (last_tick_time_ == base::TimeTicks())
273 return;
275 if (start_ready_animations)
276 PromoteStartedAnimations(last_tick_time_, events);
278 MarkFinishedAnimations(last_tick_time_);
279 MarkAnimationsForDeletion(last_tick_time_, events);
281 if (needs_to_start_animations_ && start_ready_animations) {
282 StartAnimations(last_tick_time_);
283 PromoteStartedAnimations(last_tick_time_, events);
286 AccumulatePropertyUpdates(last_tick_time_, events);
288 UpdateActivation(NORMAL_ACTIVATION);
291 struct AffectsNoObservers {
292 bool operator()(Animation* animation) const {
293 return !animation->affects_active_observers() &&
294 !animation->affects_pending_observers();
298 void LayerAnimationController::ActivateAnimations() {
299 bool changed_transform_animation = false;
300 for (size_t i = 0; i < animations_.size(); ++i) {
301 if (animations_[i]->affects_active_observers() !=
302 animations_[i]->affects_pending_observers() &&
303 animations_[i]->target_property() == Animation::TRANSFORM)
304 changed_transform_animation = true;
305 animations_[i]->set_affects_active_observers(
306 animations_[i]->affects_pending_observers());
308 animations_.erase(cc::remove_if(&animations_,
309 animations_.begin(),
310 animations_.end(),
311 AffectsNoObservers()),
312 animations_.end());
313 scroll_offset_animation_was_interrupted_ = false;
314 UpdateActivation(NORMAL_ACTIVATION);
315 if (changed_transform_animation)
316 UpdatePotentiallyAnimatingTransform();
319 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
320 bool added_transform_animation =
321 animation->target_property() == Animation::TRANSFORM;
322 animations_.push_back(animation.Pass());
323 needs_to_start_animations_ = true;
324 UpdateActivation(NORMAL_ACTIVATION);
325 if (added_transform_animation)
326 UpdatePotentiallyAnimatingTransform();
329 Animation* LayerAnimationController::GetAnimation(
330 Animation::TargetProperty target_property) const {
331 for (size_t i = 0; i < animations_.size(); ++i) {
332 size_t index = animations_.size() - i - 1;
333 if (animations_[index]->target_property() == target_property)
334 return animations_[index];
336 return 0;
339 Animation* LayerAnimationController::GetAnimationById(int animation_id) const {
340 for (size_t i = 0; i < animations_.size(); ++i)
341 if (animations_[i]->id() == animation_id)
342 return animations_[i];
343 return nullptr;
346 bool LayerAnimationController::HasActiveAnimation() const {
347 for (size_t i = 0; i < animations_.size(); ++i) {
348 if (!animations_[i]->is_finished())
349 return true;
351 return false;
354 bool LayerAnimationController::IsPotentiallyAnimatingProperty(
355 Animation::TargetProperty target_property,
356 ObserverType observer_type) const {
357 for (size_t i = 0; i < animations_.size(); ++i) {
358 if (!animations_[i]->is_finished() &&
359 animations_[i]->target_property() == target_property) {
360 if ((observer_type == ObserverType::ACTIVE &&
361 animations_[i]->affects_active_observers()) ||
362 (observer_type == ObserverType::PENDING &&
363 animations_[i]->affects_pending_observers()))
364 return true;
367 return false;
370 bool LayerAnimationController::IsCurrentlyAnimatingProperty(
371 Animation::TargetProperty target_property,
372 ObserverType observer_type) const {
373 for (size_t i = 0; i < animations_.size(); ++i) {
374 if (!animations_[i]->is_finished() &&
375 animations_[i]->InEffect(last_tick_time_) &&
376 animations_[i]->target_property() == target_property) {
377 if ((observer_type == ObserverType::ACTIVE &&
378 animations_[i]->affects_active_observers()) ||
379 (observer_type == ObserverType::PENDING &&
380 animations_[i]->affects_pending_observers()))
381 return true;
384 return false;
387 void LayerAnimationController::SetAnimationRegistrar(
388 AnimationRegistrar* registrar) {
389 if (registrar_ == registrar)
390 return;
392 if (registrar_)
393 registrar_->UnregisterAnimationController(this);
395 registrar_ = registrar;
396 if (registrar_)
397 registrar_->RegisterAnimationController(this);
399 UpdateActivation(FORCE_ACTIVATION);
402 void LayerAnimationController::NotifyAnimationStarted(
403 const AnimationEvent& event) {
404 if (event.is_impl_only) {
405 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
406 OnAnimationStarted(event));
407 if (layer_animation_delegate_)
408 layer_animation_delegate_->NotifyAnimationStarted(
409 event.monotonic_time, event.target_property, event.group_id);
410 return;
413 for (size_t i = 0; i < animations_.size(); ++i) {
414 if (animations_[i]->group() == event.group_id &&
415 animations_[i]->target_property() == event.target_property &&
416 animations_[i]->needs_synchronized_start_time()) {
417 animations_[i]->set_needs_synchronized_start_time(false);
418 if (!animations_[i]->has_set_start_time())
419 animations_[i]->set_start_time(event.monotonic_time);
421 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
422 OnAnimationStarted(event));
423 if (layer_animation_delegate_)
424 layer_animation_delegate_->NotifyAnimationStarted(
425 event.monotonic_time, event.target_property, event.group_id);
427 return;
432 void LayerAnimationController::NotifyAnimationFinished(
433 const AnimationEvent& event) {
434 if (event.is_impl_only) {
435 if (layer_animation_delegate_)
436 layer_animation_delegate_->NotifyAnimationFinished(
437 event.monotonic_time, event.target_property, event.group_id);
438 return;
441 for (size_t i = 0; i < animations_.size(); ++i) {
442 if (animations_[i]->group() == event.group_id &&
443 animations_[i]->target_property() == event.target_property) {
444 animations_[i]->set_received_finished_event(true);
445 if (layer_animation_delegate_)
446 layer_animation_delegate_->NotifyAnimationFinished(
447 event.monotonic_time, event.target_property, event.group_id);
449 return;
454 void LayerAnimationController::NotifyAnimationAborted(
455 const AnimationEvent& event) {
456 bool aborted_transform_animation = false;
457 for (size_t i = 0; i < animations_.size(); ++i) {
458 if (animations_[i]->group() == event.group_id &&
459 animations_[i]->target_property() == event.target_property) {
460 animations_[i]->SetRunState(Animation::ABORTED, event.monotonic_time);
461 if (event.target_property == Animation::TRANSFORM)
462 aborted_transform_animation = true;
465 if (aborted_transform_animation)
466 UpdatePotentiallyAnimatingTransform();
469 void LayerAnimationController::NotifyAnimationPropertyUpdate(
470 const AnimationEvent& event) {
471 bool notify_active_observers = true;
472 bool notify_pending_observers = true;
473 switch (event.target_property) {
474 case Animation::OPACITY:
475 NotifyObserversOpacityAnimated(
476 event.opacity, notify_active_observers, notify_pending_observers);
477 break;
478 case Animation::TRANSFORM:
479 NotifyObserversTransformAnimated(
480 event.transform, notify_active_observers, notify_pending_observers);
481 break;
482 default:
483 NOTREACHED();
487 void LayerAnimationController::AddValueObserver(
488 LayerAnimationValueObserver* observer) {
489 if (!value_observers_.HasObserver(observer))
490 value_observers_.AddObserver(observer);
493 void LayerAnimationController::RemoveValueObserver(
494 LayerAnimationValueObserver* observer) {
495 value_observers_.RemoveObserver(observer);
498 void LayerAnimationController::AddEventObserver(
499 LayerAnimationEventObserver* observer) {
500 if (!event_observers_.HasObserver(observer))
501 event_observers_.AddObserver(observer);
504 void LayerAnimationController::RemoveEventObserver(
505 LayerAnimationEventObserver* observer) {
506 event_observers_.RemoveObserver(observer);
509 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
510 for (size_t i = 0; i < animations_.size(); ++i) {
511 if (!animations_[i]->is_finished() &&
512 animations_[i]->target_property() == Animation::FILTER &&
513 animations_[i]
514 ->curve()
515 ->ToFilterAnimationCurve()
516 ->HasFilterThatMovesPixels())
517 return true;
520 return false;
523 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
524 return IsCurrentlyAnimatingProperty(Animation::TRANSFORM,
525 ObserverType::ACTIVE) ||
526 IsCurrentlyAnimatingProperty(Animation::TRANSFORM,
527 ObserverType::PENDING);
530 bool LayerAnimationController::FilterAnimationBoundsForBox(
531 const gfx::BoxF& box, gfx::BoxF* bounds) const {
532 // TODO(avallee): Implement.
533 return false;
536 bool LayerAnimationController::TransformAnimationBoundsForBox(
537 const gfx::BoxF& box,
538 gfx::BoxF* bounds) const {
539 DCHECK(HasTransformAnimationThatInflatesBounds())
540 << "TransformAnimationBoundsForBox will give incorrect results if there "
541 << "are no transform animations affecting bounds, non-animated transform "
542 << "is not known";
544 // Compute bounds based on animations for which is_finished() is false.
545 // Do nothing if there are no such animations; in this case, it is assumed
546 // that callers will take care of computing bounds based on the owning layer's
547 // actual transform.
548 *bounds = gfx::BoxF();
549 for (size_t i = 0; i < animations_.size(); ++i) {
550 if (animations_[i]->is_finished() ||
551 animations_[i]->target_property() != Animation::TRANSFORM)
552 continue;
554 const TransformAnimationCurve* transform_animation_curve =
555 animations_[i]->curve()->ToTransformAnimationCurve();
556 gfx::BoxF animation_bounds;
557 bool success =
558 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
559 if (!success)
560 return false;
561 bounds->Union(animation_bounds);
564 return true;
567 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
568 for (size_t i = 0; i < animations_.size(); ++i) {
569 if (animations_[i]->is_finished() ||
570 animations_[i]->target_property() != Animation::TRANSFORM)
571 continue;
573 const TransformAnimationCurve* transform_animation_curve =
574 animations_[i]->curve()->ToTransformAnimationCurve();
575 if (transform_animation_curve->AffectsScale())
576 return true;
579 return false;
582 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
583 for (size_t i = 0; i < animations_.size(); ++i) {
584 if (animations_[i]->is_finished() ||
585 animations_[i]->target_property() != Animation::TRANSFORM)
586 continue;
588 const TransformAnimationCurve* transform_animation_curve =
589 animations_[i]->curve()->ToTransformAnimationCurve();
590 if (!transform_animation_curve->IsTranslation())
591 return false;
594 return true;
597 bool LayerAnimationController::AnimationsPreserveAxisAlignment() const {
598 for (size_t i = 0; i < animations_.size(); ++i) {
599 if (animations_[i]->is_finished() ||
600 animations_[i]->target_property() != Animation::TRANSFORM)
601 continue;
603 const TransformAnimationCurve* transform_animation_curve =
604 animations_[i]->curve()->ToTransformAnimationCurve();
605 if (!transform_animation_curve->PreservesAxisAlignment())
606 return false;
609 return true;
612 bool LayerAnimationController::AnimationStartScale(float* start_scale) const {
613 *start_scale = 0.f;
614 for (size_t i = 0; i < animations_.size(); ++i) {
615 if (animations_[i]->is_finished() ||
616 animations_[i]->target_property() != Animation::TRANSFORM)
617 continue;
619 bool forward_direction = true;
620 switch (animations_[i]->direction()) {
621 case Animation::DIRECTION_NORMAL:
622 case Animation::DIRECTION_ALTERNATE:
623 forward_direction = animations_[i]->playback_rate() >= 0.0;
624 break;
625 case Animation::DIRECTION_REVERSE:
626 case Animation::DIRECTION_ALTERNATE_REVERSE:
627 forward_direction = animations_[i]->playback_rate() < 0.0;
628 break;
631 const TransformAnimationCurve* transform_animation_curve =
632 animations_[i]->curve()->ToTransformAnimationCurve();
633 float animation_start_scale = 0.f;
634 if (!transform_animation_curve->AnimationStartScale(forward_direction,
635 &animation_start_scale))
636 return false;
637 *start_scale = std::max(*start_scale, animation_start_scale);
639 return true;
642 bool LayerAnimationController::MaximumTargetScale(float* max_scale) const {
643 *max_scale = 0.f;
644 for (size_t i = 0; i < animations_.size(); ++i) {
645 if (animations_[i]->is_finished() ||
646 animations_[i]->target_property() != Animation::TRANSFORM)
647 continue;
649 bool forward_direction = true;
650 switch (animations_[i]->direction()) {
651 case Animation::DIRECTION_NORMAL:
652 case Animation::DIRECTION_ALTERNATE:
653 forward_direction = animations_[i]->playback_rate() >= 0.0;
654 break;
655 case Animation::DIRECTION_REVERSE:
656 case Animation::DIRECTION_ALTERNATE_REVERSE:
657 forward_direction = animations_[i]->playback_rate() < 0.0;
658 break;
661 const TransformAnimationCurve* transform_animation_curve =
662 animations_[i]->curve()->ToTransformAnimationCurve();
663 float animation_scale = 0.f;
664 if (!transform_animation_curve->MaximumTargetScale(forward_direction,
665 &animation_scale))
666 return false;
667 *max_scale = std::max(*max_scale, animation_scale);
670 return true;
673 void LayerAnimationController::PushNewAnimationsToImplThread(
674 LayerAnimationController* controller_impl) const {
675 // Any new animations owned by the main thread's controller are cloned and
676 // add to the impl thread's controller.
677 for (size_t i = 0; i < animations_.size(); ++i) {
678 // If the animation is already running on the impl thread, there is no
679 // need to copy it over.
680 if (controller_impl->GetAnimationById(animations_[i]->id()))
681 continue;
683 // Scroll animations always start at the current scroll offset.
684 if (animations_[i]->target_property() == Animation::SCROLL_OFFSET) {
685 gfx::ScrollOffset current_scroll_offset;
686 if (controller_impl->value_provider_) {
687 current_scroll_offset =
688 controller_impl->value_provider_->ScrollOffsetForAnimation();
689 } else {
690 // The owning layer isn't yet in the active tree, so the main thread
691 // scroll offset will be up-to-date.
692 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
694 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
695 current_scroll_offset);
698 // The new animation should be set to run as soon as possible.
699 Animation::RunState initial_run_state =
700 Animation::WAITING_FOR_TARGET_AVAILABILITY;
701 scoped_ptr<Animation> to_add(
702 animations_[i]->CloneAndInitialize(initial_run_state));
703 DCHECK(!to_add->needs_synchronized_start_time());
704 to_add->set_affects_active_observers(false);
705 controller_impl->AddAnimation(to_add.Pass());
709 static bool IsCompleted(
710 Animation* animation,
711 const LayerAnimationController* main_thread_controller) {
712 if (animation->is_impl_only()) {
713 return (animation->run_state() == Animation::WAITING_FOR_DELETION);
714 } else {
715 return !main_thread_controller->GetAnimationById(animation->id());
719 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
720 return animation->run_state() == Animation::WAITING_FOR_DELETION &&
721 !animation->affects_pending_observers();
724 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
725 LayerAnimationController* controller_impl) const {
726 bool removed_transform_animation = false;
727 // Animations removed on the main thread should no longer affect pending
728 // observers, and should stop affecting active observers after the next call
729 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed
730 // immediately.
731 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
732 for (size_t i = 0; i < animations.size(); ++i) {
733 if (IsCompleted(animations[i], this)) {
734 animations[i]->set_affects_pending_observers(false);
735 if (animations[i]->target_property() == Animation::TRANSFORM)
736 removed_transform_animation = true;
739 animations.erase(cc::remove_if(&animations,
740 animations.begin(),
741 animations.end(),
742 AffectsActiveOnlyAndIsWaitingForDeletion),
743 animations.end());
745 if (removed_transform_animation)
746 controller_impl->UpdatePotentiallyAnimatingTransform();
749 void LayerAnimationController::PushPropertiesToImplThread(
750 LayerAnimationController* controller_impl) {
751 for (size_t i = 0; i < animations_.size(); ++i) {
752 Animation* current_impl =
753 controller_impl->GetAnimationById(animations_[i]->id());
754 if (current_impl)
755 animations_[i]->PushPropertiesTo(current_impl);
757 controller_impl->scroll_offset_animation_was_interrupted_ =
758 scroll_offset_animation_was_interrupted_;
759 scroll_offset_animation_was_interrupted_ = false;
762 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
763 DCHECK(needs_to_start_animations_);
764 needs_to_start_animations_ = false;
765 // First collect running properties affecting each type of observer.
766 TargetProperties blocked_properties_for_active_observers;
767 TargetProperties blocked_properties_for_pending_observers;
768 std::vector<size_t> animations_waiting_for_target;
770 animations_waiting_for_target.reserve(animations_.size());
771 for (size_t i = 0; i < animations_.size(); ++i) {
772 if (animations_[i]->run_state() == Animation::STARTING ||
773 animations_[i]->run_state() == Animation::RUNNING) {
774 if (animations_[i]->affects_active_observers()) {
775 blocked_properties_for_active_observers.insert(
776 animations_[i]->target_property());
778 if (animations_[i]->affects_pending_observers()) {
779 blocked_properties_for_pending_observers.insert(
780 animations_[i]->target_property());
782 } else if (animations_[i]->run_state() ==
783 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
784 animations_waiting_for_target.push_back(i);
788 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
789 // Collect all properties for animations with the same group id (they
790 // should all also be in the list of animations).
791 size_t animation_index = animations_waiting_for_target[i];
792 Animation* animation_waiting_for_target = animations_[animation_index];
793 // Check for the run state again even though the animation was waiting
794 // for target because it might have changed the run state while handling
795 // previous animation in this loop (if they belong to same group).
796 if (animation_waiting_for_target->run_state() ==
797 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
798 TargetProperties enqueued_properties;
799 bool affects_active_observers =
800 animation_waiting_for_target->affects_active_observers();
801 bool affects_pending_observers =
802 animation_waiting_for_target->affects_pending_observers();
803 enqueued_properties.insert(
804 animation_waiting_for_target->target_property());
805 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
806 if (animation_waiting_for_target->group() == animations_[j]->group()) {
807 enqueued_properties.insert(animations_[j]->target_property());
808 affects_active_observers |=
809 animations_[j]->affects_active_observers();
810 affects_pending_observers |=
811 animations_[j]->affects_pending_observers();
815 // Check to see if intersection of the list of properties affected by
816 // the group and the list of currently blocked properties is null, taking
817 // into account the type(s) of observers affected by the group. In any
818 // case, the group's target properties need to be added to the lists of
819 // blocked properties.
820 bool null_intersection = true;
821 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
822 p_iter != enqueued_properties.end();
823 ++p_iter) {
824 if (affects_active_observers &&
825 !blocked_properties_for_active_observers.insert(*p_iter).second)
826 null_intersection = false;
827 if (affects_pending_observers &&
828 !blocked_properties_for_pending_observers.insert(*p_iter).second)
829 null_intersection = false;
832 // If the intersection is null, then we are free to start the animations
833 // in the group.
834 if (null_intersection) {
835 animation_waiting_for_target->SetRunState(Animation::STARTING,
836 monotonic_time);
837 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
838 if (animation_waiting_for_target->group() ==
839 animations_[j]->group()) {
840 animations_[j]->SetRunState(Animation::STARTING, monotonic_time);
843 } else {
844 needs_to_start_animations_ = true;
850 void LayerAnimationController::PromoteStartedAnimations(
851 base::TimeTicks monotonic_time,
852 AnimationEventsVector* events) {
853 for (size_t i = 0; i < animations_.size(); ++i) {
854 if (animations_[i]->run_state() == Animation::STARTING &&
855 animations_[i]->affects_active_observers()) {
856 animations_[i]->SetRunState(Animation::RUNNING, monotonic_time);
857 if (!animations_[i]->has_set_start_time() &&
858 !animations_[i]->needs_synchronized_start_time())
859 animations_[i]->set_start_time(monotonic_time);
860 if (events) {
861 base::TimeTicks start_time;
862 if (animations_[i]->has_set_start_time())
863 start_time = animations_[i]->start_time();
864 else
865 start_time = monotonic_time;
866 AnimationEvent started_event(
867 AnimationEvent::STARTED, id_, animations_[i]->group(),
868 animations_[i]->target_property(), start_time);
869 started_event.is_impl_only = animations_[i]->is_impl_only();
870 if (started_event.is_impl_only)
871 NotifyAnimationStarted(started_event);
872 else
873 events->push_back(started_event);
879 void LayerAnimationController::MarkFinishedAnimations(
880 base::TimeTicks monotonic_time) {
881 bool finished_transform_animation = false;
882 for (size_t i = 0; i < animations_.size(); ++i) {
883 if (!animations_[i]->is_finished() &&
884 animations_[i]->IsFinishedAt(monotonic_time)) {
885 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time);
886 if (animations_[i]->target_property() == Animation::TRANSFORM) {
887 finished_transform_animation = true;
891 if (finished_transform_animation)
892 UpdatePotentiallyAnimatingTransform();
895 void LayerAnimationController::MarkAnimationsForDeletion(
896 base::TimeTicks monotonic_time,
897 AnimationEventsVector* events) {
898 bool marked_animations_for_deletions = false;
899 std::vector<size_t> animations_with_same_group_id;
901 animations_with_same_group_id.reserve(animations_.size());
902 // Non-aborted animations are marked for deletion after a corresponding
903 // AnimationEvent::FINISHED event is sent or received. This means that if
904 // we don't have an events vector, we must ensure that non-aborted animations
905 // have received a finished event before marking them for deletion.
906 for (size_t i = 0; i < animations_.size(); i++) {
907 int group_id = animations_[i]->group();
908 if (animations_[i]->run_state() == Animation::ABORTED) {
909 if (events && !animations_[i]->is_impl_only()) {
910 AnimationEvent aborted_event(AnimationEvent::ABORTED, id_, group_id,
911 animations_[i]->target_property(),
912 monotonic_time);
913 events->push_back(aborted_event);
915 animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION,
916 monotonic_time);
917 marked_animations_for_deletions = true;
918 continue;
921 bool all_anims_with_same_id_are_finished = false;
923 // Since deleting an animation on the main thread leads to its deletion
924 // on the impl thread, we only mark a FINISHED main thread animation for
925 // deletion once it has received a FINISHED event from the impl thread.
926 bool animation_i_will_send_or_has_received_finish_event =
927 animations_[i]->is_controlling_instance() ||
928 animations_[i]->is_impl_only() ||
929 animations_[i]->received_finished_event();
930 // If an animation is finished, and not already marked for deletion,
931 // find out if all other animations in the same group are also finished.
932 if (animations_[i]->run_state() == Animation::FINISHED &&
933 animation_i_will_send_or_has_received_finish_event) {
934 // Clear the animations_with_same_group_id if it was added for
935 // the previous animation's iteration.
936 if (animations_with_same_group_id.size() > 0)
937 animations_with_same_group_id.clear();
938 all_anims_with_same_id_are_finished = true;
939 for (size_t j = 0; j < animations_.size(); ++j) {
940 bool animation_j_will_send_or_has_received_finish_event =
941 animations_[j]->is_controlling_instance() ||
942 animations_[j]->is_impl_only() ||
943 animations_[j]->received_finished_event();
944 if (group_id == animations_[j]->group()) {
945 if (!animations_[j]->is_finished() ||
946 (animations_[j]->run_state() == Animation::FINISHED &&
947 !animation_j_will_send_or_has_received_finish_event)) {
948 all_anims_with_same_id_are_finished = false;
949 break;
950 } else if (j >= i &&
951 animations_[j]->run_state() != Animation::ABORTED) {
952 // Mark down the animations which belong to the same group
953 // and is not yet aborted. If this current iteration finds that all
954 // animations with same ID are finished, then the marked
955 // animations below will be set to WAITING_FOR_DELETION in next
956 // iteration.
957 animations_with_same_group_id.push_back(j);
962 if (all_anims_with_same_id_are_finished) {
963 // We now need to remove all animations with the same group id as
964 // group_id (and send along animation finished notifications, if
965 // necessary).
966 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
967 size_t animation_index = animations_with_same_group_id[j];
968 if (events) {
969 AnimationEvent finished_event(
970 AnimationEvent::FINISHED, id_,
971 animations_[animation_index]->group(),
972 animations_[animation_index]->target_property(),
973 monotonic_time);
974 finished_event.is_impl_only =
975 animations_[animation_index]->is_impl_only();
976 if (finished_event.is_impl_only)
977 NotifyAnimationFinished(finished_event);
978 else
979 events->push_back(finished_event);
981 animations_[animation_index]->SetRunState(
982 Animation::WAITING_FOR_DELETION, monotonic_time);
984 marked_animations_for_deletions = true;
987 if (marked_animations_for_deletions)
988 NotifyObserversAnimationWaitingForDeletion();
991 static bool IsWaitingForDeletion(Animation* animation) {
992 return animation->run_state() == Animation::WAITING_FOR_DELETION;
995 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
996 animations_.erase(cc::remove_if(&animations_,
997 animations_.begin(),
998 animations_.end(),
999 IsWaitingForDeletion),
1000 animations_.end());
1003 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
1004 for (size_t i = 0; i < animations_.size(); ++i) {
1005 if (animations_[i]->run_state() == Animation::STARTING ||
1006 animations_[i]->run_state() == Animation::RUNNING ||
1007 animations_[i]->run_state() == Animation::PAUSED) {
1008 if (!animations_[i]->InEffect(monotonic_time))
1009 continue;
1011 base::TimeDelta trimmed =
1012 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
1014 switch (animations_[i]->target_property()) {
1015 case Animation::TRANSFORM: {
1016 const TransformAnimationCurve* transform_animation_curve =
1017 animations_[i]->curve()->ToTransformAnimationCurve();
1018 const gfx::Transform transform =
1019 transform_animation_curve->GetValue(trimmed);
1020 NotifyObserversTransformAnimated(
1021 transform,
1022 animations_[i]->affects_active_observers(),
1023 animations_[i]->affects_pending_observers());
1024 break;
1027 case Animation::OPACITY: {
1028 const FloatAnimationCurve* float_animation_curve =
1029 animations_[i]->curve()->ToFloatAnimationCurve();
1030 const float opacity = std::max(
1031 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
1032 NotifyObserversOpacityAnimated(
1033 opacity,
1034 animations_[i]->affects_active_observers(),
1035 animations_[i]->affects_pending_observers());
1036 break;
1039 case Animation::FILTER: {
1040 const FilterAnimationCurve* filter_animation_curve =
1041 animations_[i]->curve()->ToFilterAnimationCurve();
1042 const FilterOperations filter =
1043 filter_animation_curve->GetValue(trimmed);
1044 NotifyObserversFilterAnimated(
1045 filter,
1046 animations_[i]->affects_active_observers(),
1047 animations_[i]->affects_pending_observers());
1048 break;
1051 case Animation::BACKGROUND_COLOR: {
1052 // Not yet implemented.
1053 break;
1056 case Animation::SCROLL_OFFSET: {
1057 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
1058 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
1059 const gfx::ScrollOffset scroll_offset =
1060 scroll_offset_animation_curve->GetValue(trimmed);
1061 NotifyObserversScrollOffsetAnimated(
1062 scroll_offset,
1063 animations_[i]->affects_active_observers(),
1064 animations_[i]->affects_pending_observers());
1065 break;
1072 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
1073 bool force = type == FORCE_ACTIVATION;
1074 if (registrar_) {
1075 bool was_active = is_active_;
1076 is_active_ = false;
1077 for (size_t i = 0; i < animations_.size(); ++i) {
1078 if (animations_[i]->run_state() != Animation::WAITING_FOR_DELETION) {
1079 is_active_ = true;
1080 break;
1084 if (is_active_ && (!was_active || force))
1085 registrar_->DidActivateAnimationController(this);
1086 else if (!is_active_ && (was_active || force))
1087 registrar_->DidDeactivateAnimationController(this);
1091 void LayerAnimationController::NotifyObserversOpacityAnimated(
1092 float opacity,
1093 bool notify_active_observers,
1094 bool notify_pending_observers) {
1095 if (value_observers_.might_have_observers()) {
1096 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1097 &value_observers_);
1098 LayerAnimationValueObserver* obs;
1099 while ((obs = it.GetNext()) != nullptr) {
1100 if ((notify_active_observers && notify_pending_observers) ||
1101 (notify_active_observers && obs->IsActive()) ||
1102 (notify_pending_observers && !obs->IsActive()))
1103 obs->OnOpacityAnimated(opacity);
1108 void LayerAnimationController::NotifyObserversTransformAnimated(
1109 const gfx::Transform& transform,
1110 bool notify_active_observers,
1111 bool notify_pending_observers) {
1112 if (value_observers_.might_have_observers()) {
1113 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1114 &value_observers_);
1115 LayerAnimationValueObserver* obs;
1116 while ((obs = it.GetNext()) != nullptr) {
1117 if ((notify_active_observers && notify_pending_observers) ||
1118 (notify_active_observers && obs->IsActive()) ||
1119 (notify_pending_observers && !obs->IsActive()))
1120 obs->OnTransformAnimated(transform);
1125 void LayerAnimationController::NotifyObserversFilterAnimated(
1126 const FilterOperations& filters,
1127 bool notify_active_observers,
1128 bool notify_pending_observers) {
1129 if (value_observers_.might_have_observers()) {
1130 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1131 &value_observers_);
1132 LayerAnimationValueObserver* obs;
1133 while ((obs = it.GetNext()) != nullptr) {
1134 if ((notify_active_observers && notify_pending_observers) ||
1135 (notify_active_observers && obs->IsActive()) ||
1136 (notify_pending_observers && !obs->IsActive()))
1137 obs->OnFilterAnimated(filters);
1142 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
1143 const gfx::ScrollOffset& scroll_offset,
1144 bool notify_active_observers,
1145 bool notify_pending_observers) {
1146 if (value_observers_.might_have_observers()) {
1147 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1148 &value_observers_);
1149 LayerAnimationValueObserver* obs;
1150 while ((obs = it.GetNext()) != nullptr) {
1151 if ((notify_active_observers && notify_pending_observers) ||
1152 (notify_active_observers && obs->IsActive()) ||
1153 (notify_pending_observers && !obs->IsActive()))
1154 obs->OnScrollOffsetAnimated(scroll_offset);
1159 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1160 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1161 value_observers_,
1162 OnAnimationWaitingForDeletion());
1165 void LayerAnimationController::
1166 NotifyObserversTransformIsPotentiallyAnimatingChanged(
1167 bool notify_active_observers,
1168 bool notify_pending_observers) {
1169 if (value_observers_.might_have_observers()) {
1170 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1171 &value_observers_);
1172 LayerAnimationValueObserver* obs;
1173 while ((obs = it.GetNext()) != nullptr) {
1174 if (notify_active_observers && obs->IsActive())
1175 obs->OnTransformIsPotentiallyAnimatingChanged(
1176 potentially_animating_transform_for_active_observers_);
1177 else if (notify_pending_observers && !obs->IsActive())
1178 obs->OnTransformIsPotentiallyAnimatingChanged(
1179 potentially_animating_transform_for_pending_observers_);
1184 bool LayerAnimationController::HasValueObserver() {
1185 if (value_observers_.might_have_observers()) {
1186 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1187 &value_observers_);
1188 return it.GetNext() != nullptr;
1190 return false;
1193 bool LayerAnimationController::HasActiveValueObserver() {
1194 if (value_observers_.might_have_observers()) {
1195 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1196 &value_observers_);
1197 LayerAnimationValueObserver* obs;
1198 while ((obs = it.GetNext()) != nullptr)
1199 if (obs->IsActive())
1200 return true;
1202 return false;
1205 } // namespace cc