Roll src/third_party/WebKit 2146135:dc7c4b0 (svn 202183:202185)
[chromium-blink-merge.git] / cc / animation / layer_animation_controller.cc
blobd649ac739724f91413a33b93a610de119fe26bb3
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(
583 ObserverType observer_type) const {
584 for (size_t i = 0; i < animations_.size(); ++i) {
585 if (animations_[i]->is_finished() ||
586 animations_[i]->target_property() != Animation::TRANSFORM)
587 continue;
589 if ((observer_type == ObserverType::ACTIVE &&
590 !animations_[i]->affects_active_observers()) ||
591 (observer_type == ObserverType::PENDING &&
592 !animations_[i]->affects_pending_observers()))
593 continue;
595 const TransformAnimationCurve* transform_animation_curve =
596 animations_[i]->curve()->ToTransformAnimationCurve();
597 if (!transform_animation_curve->IsTranslation())
598 return false;
601 return true;
604 bool LayerAnimationController::AnimationsPreserveAxisAlignment() const {
605 for (size_t i = 0; i < animations_.size(); ++i) {
606 if (animations_[i]->is_finished() ||
607 animations_[i]->target_property() != Animation::TRANSFORM)
608 continue;
610 const TransformAnimationCurve* transform_animation_curve =
611 animations_[i]->curve()->ToTransformAnimationCurve();
612 if (!transform_animation_curve->PreservesAxisAlignment())
613 return false;
616 return true;
619 bool LayerAnimationController::AnimationStartScale(ObserverType observer_type,
620 float* start_scale) const {
621 *start_scale = 0.f;
622 for (size_t i = 0; i < animations_.size(); ++i) {
623 if (animations_[i]->is_finished() ||
624 animations_[i]->target_property() != Animation::TRANSFORM)
625 continue;
627 if ((observer_type == ObserverType::ACTIVE &&
628 !animations_[i]->affects_active_observers()) ||
629 (observer_type == ObserverType::PENDING &&
630 !animations_[i]->affects_pending_observers()))
631 continue;
633 bool forward_direction = true;
634 switch (animations_[i]->direction()) {
635 case Animation::DIRECTION_NORMAL:
636 case Animation::DIRECTION_ALTERNATE:
637 forward_direction = animations_[i]->playback_rate() >= 0.0;
638 break;
639 case Animation::DIRECTION_REVERSE:
640 case Animation::DIRECTION_ALTERNATE_REVERSE:
641 forward_direction = animations_[i]->playback_rate() < 0.0;
642 break;
645 const TransformAnimationCurve* transform_animation_curve =
646 animations_[i]->curve()->ToTransformAnimationCurve();
647 float animation_start_scale = 0.f;
648 if (!transform_animation_curve->AnimationStartScale(forward_direction,
649 &animation_start_scale))
650 return false;
651 *start_scale = std::max(*start_scale, animation_start_scale);
653 return true;
656 bool LayerAnimationController::MaximumTargetScale(ObserverType observer_type,
657 float* max_scale) const {
658 *max_scale = 0.f;
659 for (size_t i = 0; i < animations_.size(); ++i) {
660 if (animations_[i]->is_finished() ||
661 animations_[i]->target_property() != Animation::TRANSFORM)
662 continue;
664 if ((observer_type == ObserverType::ACTIVE &&
665 !animations_[i]->affects_active_observers()) ||
666 (observer_type == ObserverType::PENDING &&
667 !animations_[i]->affects_pending_observers()))
668 continue;
670 bool forward_direction = true;
671 switch (animations_[i]->direction()) {
672 case Animation::DIRECTION_NORMAL:
673 case Animation::DIRECTION_ALTERNATE:
674 forward_direction = animations_[i]->playback_rate() >= 0.0;
675 break;
676 case Animation::DIRECTION_REVERSE:
677 case Animation::DIRECTION_ALTERNATE_REVERSE:
678 forward_direction = animations_[i]->playback_rate() < 0.0;
679 break;
682 const TransformAnimationCurve* transform_animation_curve =
683 animations_[i]->curve()->ToTransformAnimationCurve();
684 float animation_scale = 0.f;
685 if (!transform_animation_curve->MaximumTargetScale(forward_direction,
686 &animation_scale))
687 return false;
688 *max_scale = std::max(*max_scale, animation_scale);
691 return true;
694 void LayerAnimationController::PushNewAnimationsToImplThread(
695 LayerAnimationController* controller_impl) const {
696 // Any new animations owned by the main thread's controller are cloned and
697 // add to the impl thread's controller.
698 for (size_t i = 0; i < animations_.size(); ++i) {
699 // If the animation is already running on the impl thread, there is no
700 // need to copy it over.
701 if (controller_impl->GetAnimationById(animations_[i]->id()))
702 continue;
704 // Scroll animations always start at the current scroll offset.
705 if (animations_[i]->target_property() == Animation::SCROLL_OFFSET) {
706 gfx::ScrollOffset current_scroll_offset;
707 if (controller_impl->value_provider_) {
708 current_scroll_offset =
709 controller_impl->value_provider_->ScrollOffsetForAnimation();
710 } else {
711 // The owning layer isn't yet in the active tree, so the main thread
712 // scroll offset will be up-to-date.
713 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
715 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
716 current_scroll_offset);
719 // The new animation should be set to run as soon as possible.
720 Animation::RunState initial_run_state =
721 Animation::WAITING_FOR_TARGET_AVAILABILITY;
722 scoped_ptr<Animation> to_add(
723 animations_[i]->CloneAndInitialize(initial_run_state));
724 DCHECK(!to_add->needs_synchronized_start_time());
725 to_add->set_affects_active_observers(false);
726 controller_impl->AddAnimation(to_add.Pass());
730 static bool IsCompleted(
731 Animation* animation,
732 const LayerAnimationController* main_thread_controller) {
733 if (animation->is_impl_only()) {
734 return (animation->run_state() == Animation::WAITING_FOR_DELETION);
735 } else {
736 return !main_thread_controller->GetAnimationById(animation->id());
740 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
741 return animation->run_state() == Animation::WAITING_FOR_DELETION &&
742 !animation->affects_pending_observers();
745 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
746 LayerAnimationController* controller_impl) const {
747 bool removed_transform_animation = false;
748 // Animations removed on the main thread should no longer affect pending
749 // observers, and should stop affecting active observers after the next call
750 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed
751 // immediately.
752 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
753 for (size_t i = 0; i < animations.size(); ++i) {
754 if (IsCompleted(animations[i], this)) {
755 animations[i]->set_affects_pending_observers(false);
756 if (animations[i]->target_property() == Animation::TRANSFORM)
757 removed_transform_animation = true;
760 animations.erase(cc::remove_if(&animations,
761 animations.begin(),
762 animations.end(),
763 AffectsActiveOnlyAndIsWaitingForDeletion),
764 animations.end());
766 if (removed_transform_animation)
767 controller_impl->UpdatePotentiallyAnimatingTransform();
770 void LayerAnimationController::PushPropertiesToImplThread(
771 LayerAnimationController* controller_impl) {
772 for (size_t i = 0; i < animations_.size(); ++i) {
773 Animation* current_impl =
774 controller_impl->GetAnimationById(animations_[i]->id());
775 if (current_impl)
776 animations_[i]->PushPropertiesTo(current_impl);
778 controller_impl->scroll_offset_animation_was_interrupted_ =
779 scroll_offset_animation_was_interrupted_;
780 scroll_offset_animation_was_interrupted_ = false;
783 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
784 DCHECK(needs_to_start_animations_);
785 needs_to_start_animations_ = false;
786 // First collect running properties affecting each type of observer.
787 TargetProperties blocked_properties_for_active_observers;
788 TargetProperties blocked_properties_for_pending_observers;
789 std::vector<size_t> animations_waiting_for_target;
791 animations_waiting_for_target.reserve(animations_.size());
792 for (size_t i = 0; i < animations_.size(); ++i) {
793 if (animations_[i]->run_state() == Animation::STARTING ||
794 animations_[i]->run_state() == Animation::RUNNING) {
795 if (animations_[i]->affects_active_observers()) {
796 blocked_properties_for_active_observers.insert(
797 animations_[i]->target_property());
799 if (animations_[i]->affects_pending_observers()) {
800 blocked_properties_for_pending_observers.insert(
801 animations_[i]->target_property());
803 } else if (animations_[i]->run_state() ==
804 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
805 animations_waiting_for_target.push_back(i);
809 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
810 // Collect all properties for animations with the same group id (they
811 // should all also be in the list of animations).
812 size_t animation_index = animations_waiting_for_target[i];
813 Animation* animation_waiting_for_target = animations_[animation_index];
814 // Check for the run state again even though the animation was waiting
815 // for target because it might have changed the run state while handling
816 // previous animation in this loop (if they belong to same group).
817 if (animation_waiting_for_target->run_state() ==
818 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
819 TargetProperties enqueued_properties;
820 bool affects_active_observers =
821 animation_waiting_for_target->affects_active_observers();
822 bool affects_pending_observers =
823 animation_waiting_for_target->affects_pending_observers();
824 enqueued_properties.insert(
825 animation_waiting_for_target->target_property());
826 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
827 if (animation_waiting_for_target->group() == animations_[j]->group()) {
828 enqueued_properties.insert(animations_[j]->target_property());
829 affects_active_observers |=
830 animations_[j]->affects_active_observers();
831 affects_pending_observers |=
832 animations_[j]->affects_pending_observers();
836 // Check to see if intersection of the list of properties affected by
837 // the group and the list of currently blocked properties is null, taking
838 // into account the type(s) of observers affected by the group. In any
839 // case, the group's target properties need to be added to the lists of
840 // blocked properties.
841 bool null_intersection = true;
842 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
843 p_iter != enqueued_properties.end();
844 ++p_iter) {
845 if (affects_active_observers &&
846 !blocked_properties_for_active_observers.insert(*p_iter).second)
847 null_intersection = false;
848 if (affects_pending_observers &&
849 !blocked_properties_for_pending_observers.insert(*p_iter).second)
850 null_intersection = false;
853 // If the intersection is null, then we are free to start the animations
854 // in the group.
855 if (null_intersection) {
856 animation_waiting_for_target->SetRunState(Animation::STARTING,
857 monotonic_time);
858 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
859 if (animation_waiting_for_target->group() ==
860 animations_[j]->group()) {
861 animations_[j]->SetRunState(Animation::STARTING, monotonic_time);
864 } else {
865 needs_to_start_animations_ = true;
871 void LayerAnimationController::PromoteStartedAnimations(
872 base::TimeTicks monotonic_time,
873 AnimationEventsVector* events) {
874 for (size_t i = 0; i < animations_.size(); ++i) {
875 if (animations_[i]->run_state() == Animation::STARTING &&
876 animations_[i]->affects_active_observers()) {
877 animations_[i]->SetRunState(Animation::RUNNING, monotonic_time);
878 if (!animations_[i]->has_set_start_time() &&
879 !animations_[i]->needs_synchronized_start_time())
880 animations_[i]->set_start_time(monotonic_time);
881 if (events) {
882 base::TimeTicks start_time;
883 if (animations_[i]->has_set_start_time())
884 start_time = animations_[i]->start_time();
885 else
886 start_time = monotonic_time;
887 AnimationEvent started_event(
888 AnimationEvent::STARTED, id_, animations_[i]->group(),
889 animations_[i]->target_property(), start_time);
890 started_event.is_impl_only = animations_[i]->is_impl_only();
891 if (started_event.is_impl_only)
892 NotifyAnimationStarted(started_event);
893 else
894 events->push_back(started_event);
900 void LayerAnimationController::MarkFinishedAnimations(
901 base::TimeTicks monotonic_time) {
902 bool finished_transform_animation = false;
903 for (size_t i = 0; i < animations_.size(); ++i) {
904 if (!animations_[i]->is_finished() &&
905 animations_[i]->IsFinishedAt(monotonic_time)) {
906 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time);
907 if (animations_[i]->target_property() == Animation::TRANSFORM) {
908 finished_transform_animation = true;
912 if (finished_transform_animation)
913 UpdatePotentiallyAnimatingTransform();
916 void LayerAnimationController::MarkAnimationsForDeletion(
917 base::TimeTicks monotonic_time,
918 AnimationEventsVector* events) {
919 bool marked_animations_for_deletions = false;
920 std::vector<size_t> animations_with_same_group_id;
922 animations_with_same_group_id.reserve(animations_.size());
923 // Non-aborted animations are marked for deletion after a corresponding
924 // AnimationEvent::FINISHED event is sent or received. This means that if
925 // we don't have an events vector, we must ensure that non-aborted animations
926 // have received a finished event before marking them for deletion.
927 for (size_t i = 0; i < animations_.size(); i++) {
928 int group_id = animations_[i]->group();
929 if (animations_[i]->run_state() == Animation::ABORTED) {
930 if (events && !animations_[i]->is_impl_only()) {
931 AnimationEvent aborted_event(AnimationEvent::ABORTED, id_, group_id,
932 animations_[i]->target_property(),
933 monotonic_time);
934 events->push_back(aborted_event);
936 animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION,
937 monotonic_time);
938 marked_animations_for_deletions = true;
939 continue;
942 bool all_anims_with_same_id_are_finished = false;
944 // Since deleting an animation on the main thread leads to its deletion
945 // on the impl thread, we only mark a FINISHED main thread animation for
946 // deletion once it has received a FINISHED event from the impl thread.
947 bool animation_i_will_send_or_has_received_finish_event =
948 animations_[i]->is_controlling_instance() ||
949 animations_[i]->is_impl_only() ||
950 animations_[i]->received_finished_event();
951 // If an animation is finished, and not already marked for deletion,
952 // find out if all other animations in the same group are also finished.
953 if (animations_[i]->run_state() == Animation::FINISHED &&
954 animation_i_will_send_or_has_received_finish_event) {
955 // Clear the animations_with_same_group_id if it was added for
956 // the previous animation's iteration.
957 if (animations_with_same_group_id.size() > 0)
958 animations_with_same_group_id.clear();
959 all_anims_with_same_id_are_finished = true;
960 for (size_t j = 0; j < animations_.size(); ++j) {
961 bool animation_j_will_send_or_has_received_finish_event =
962 animations_[j]->is_controlling_instance() ||
963 animations_[j]->is_impl_only() ||
964 animations_[j]->received_finished_event();
965 if (group_id == animations_[j]->group()) {
966 if (!animations_[j]->is_finished() ||
967 (animations_[j]->run_state() == Animation::FINISHED &&
968 !animation_j_will_send_or_has_received_finish_event)) {
969 all_anims_with_same_id_are_finished = false;
970 break;
971 } else if (j >= i &&
972 animations_[j]->run_state() != Animation::ABORTED) {
973 // Mark down the animations which belong to the same group
974 // and is not yet aborted. If this current iteration finds that all
975 // animations with same ID are finished, then the marked
976 // animations below will be set to WAITING_FOR_DELETION in next
977 // iteration.
978 animations_with_same_group_id.push_back(j);
983 if (all_anims_with_same_id_are_finished) {
984 // We now need to remove all animations with the same group id as
985 // group_id (and send along animation finished notifications, if
986 // necessary).
987 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
988 size_t animation_index = animations_with_same_group_id[j];
989 if (events) {
990 AnimationEvent finished_event(
991 AnimationEvent::FINISHED, id_,
992 animations_[animation_index]->group(),
993 animations_[animation_index]->target_property(),
994 monotonic_time);
995 finished_event.is_impl_only =
996 animations_[animation_index]->is_impl_only();
997 if (finished_event.is_impl_only)
998 NotifyAnimationFinished(finished_event);
999 else
1000 events->push_back(finished_event);
1002 animations_[animation_index]->SetRunState(
1003 Animation::WAITING_FOR_DELETION, monotonic_time);
1005 marked_animations_for_deletions = true;
1008 if (marked_animations_for_deletions)
1009 NotifyObserversAnimationWaitingForDeletion();
1012 static bool IsWaitingForDeletion(Animation* animation) {
1013 return animation->run_state() == Animation::WAITING_FOR_DELETION;
1016 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
1017 animations_.erase(cc::remove_if(&animations_,
1018 animations_.begin(),
1019 animations_.end(),
1020 IsWaitingForDeletion),
1021 animations_.end());
1024 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
1025 for (size_t i = 0; i < animations_.size(); ++i) {
1026 if (animations_[i]->run_state() == Animation::STARTING ||
1027 animations_[i]->run_state() == Animation::RUNNING ||
1028 animations_[i]->run_state() == Animation::PAUSED) {
1029 if (!animations_[i]->InEffect(monotonic_time))
1030 continue;
1032 base::TimeDelta trimmed =
1033 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
1035 switch (animations_[i]->target_property()) {
1036 case Animation::TRANSFORM: {
1037 const TransformAnimationCurve* transform_animation_curve =
1038 animations_[i]->curve()->ToTransformAnimationCurve();
1039 const gfx::Transform transform =
1040 transform_animation_curve->GetValue(trimmed);
1041 NotifyObserversTransformAnimated(
1042 transform,
1043 animations_[i]->affects_active_observers(),
1044 animations_[i]->affects_pending_observers());
1045 break;
1048 case Animation::OPACITY: {
1049 const FloatAnimationCurve* float_animation_curve =
1050 animations_[i]->curve()->ToFloatAnimationCurve();
1051 const float opacity = std::max(
1052 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
1053 NotifyObserversOpacityAnimated(
1054 opacity,
1055 animations_[i]->affects_active_observers(),
1056 animations_[i]->affects_pending_observers());
1057 break;
1060 case Animation::FILTER: {
1061 const FilterAnimationCurve* filter_animation_curve =
1062 animations_[i]->curve()->ToFilterAnimationCurve();
1063 const FilterOperations filter =
1064 filter_animation_curve->GetValue(trimmed);
1065 NotifyObserversFilterAnimated(
1066 filter,
1067 animations_[i]->affects_active_observers(),
1068 animations_[i]->affects_pending_observers());
1069 break;
1072 case Animation::BACKGROUND_COLOR: {
1073 // Not yet implemented.
1074 break;
1077 case Animation::SCROLL_OFFSET: {
1078 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
1079 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
1080 const gfx::ScrollOffset scroll_offset =
1081 scroll_offset_animation_curve->GetValue(trimmed);
1082 NotifyObserversScrollOffsetAnimated(
1083 scroll_offset,
1084 animations_[i]->affects_active_observers(),
1085 animations_[i]->affects_pending_observers());
1086 break;
1093 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
1094 bool force = type == FORCE_ACTIVATION;
1095 if (registrar_) {
1096 bool was_active = is_active_;
1097 is_active_ = false;
1098 for (size_t i = 0; i < animations_.size(); ++i) {
1099 if (animations_[i]->run_state() != Animation::WAITING_FOR_DELETION) {
1100 is_active_ = true;
1101 break;
1105 if (is_active_ && (!was_active || force))
1106 registrar_->DidActivateAnimationController(this);
1107 else if (!is_active_ && (was_active || force))
1108 registrar_->DidDeactivateAnimationController(this);
1112 void LayerAnimationController::NotifyObserversOpacityAnimated(
1113 float opacity,
1114 bool notify_active_observers,
1115 bool notify_pending_observers) {
1116 if (value_observers_.might_have_observers()) {
1117 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1118 &value_observers_);
1119 LayerAnimationValueObserver* obs;
1120 while ((obs = it.GetNext()) != nullptr) {
1121 if ((notify_active_observers && notify_pending_observers) ||
1122 (notify_active_observers && obs->IsActive()) ||
1123 (notify_pending_observers && !obs->IsActive()))
1124 obs->OnOpacityAnimated(opacity);
1129 void LayerAnimationController::NotifyObserversTransformAnimated(
1130 const gfx::Transform& transform,
1131 bool notify_active_observers,
1132 bool notify_pending_observers) {
1133 if (value_observers_.might_have_observers()) {
1134 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1135 &value_observers_);
1136 LayerAnimationValueObserver* obs;
1137 while ((obs = it.GetNext()) != nullptr) {
1138 if ((notify_active_observers && notify_pending_observers) ||
1139 (notify_active_observers && obs->IsActive()) ||
1140 (notify_pending_observers && !obs->IsActive()))
1141 obs->OnTransformAnimated(transform);
1146 void LayerAnimationController::NotifyObserversFilterAnimated(
1147 const FilterOperations& filters,
1148 bool notify_active_observers,
1149 bool notify_pending_observers) {
1150 if (value_observers_.might_have_observers()) {
1151 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1152 &value_observers_);
1153 LayerAnimationValueObserver* obs;
1154 while ((obs = it.GetNext()) != nullptr) {
1155 if ((notify_active_observers && notify_pending_observers) ||
1156 (notify_active_observers && obs->IsActive()) ||
1157 (notify_pending_observers && !obs->IsActive()))
1158 obs->OnFilterAnimated(filters);
1163 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
1164 const gfx::ScrollOffset& scroll_offset,
1165 bool notify_active_observers,
1166 bool notify_pending_observers) {
1167 if (value_observers_.might_have_observers()) {
1168 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1169 &value_observers_);
1170 LayerAnimationValueObserver* obs;
1171 while ((obs = it.GetNext()) != nullptr) {
1172 if ((notify_active_observers && notify_pending_observers) ||
1173 (notify_active_observers && obs->IsActive()) ||
1174 (notify_pending_observers && !obs->IsActive()))
1175 obs->OnScrollOffsetAnimated(scroll_offset);
1180 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1181 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1182 value_observers_,
1183 OnAnimationWaitingForDeletion());
1186 void LayerAnimationController::
1187 NotifyObserversTransformIsPotentiallyAnimatingChanged(
1188 bool notify_active_observers,
1189 bool notify_pending_observers) {
1190 if (value_observers_.might_have_observers()) {
1191 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1192 &value_observers_);
1193 LayerAnimationValueObserver* obs;
1194 while ((obs = it.GetNext()) != nullptr) {
1195 if (notify_active_observers && obs->IsActive())
1196 obs->OnTransformIsPotentiallyAnimatingChanged(
1197 potentially_animating_transform_for_active_observers_);
1198 else if (notify_pending_observers && !obs->IsActive())
1199 obs->OnTransformIsPotentiallyAnimatingChanged(
1200 potentially_animating_transform_for_pending_observers_);
1205 bool LayerAnimationController::HasValueObserver() {
1206 if (value_observers_.might_have_observers()) {
1207 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1208 &value_observers_);
1209 return it.GetNext() != nullptr;
1211 return false;
1214 bool LayerAnimationController::HasActiveValueObserver() {
1215 if (value_observers_.might_have_observers()) {
1216 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1217 &value_observers_);
1218 LayerAnimationValueObserver* obs;
1219 while ((obs = it.GetNext()) != nullptr)
1220 if (obs->IsActive())
1221 return true;
1223 return false;
1226 } // namespace cc