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"
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"
24 LayerAnimationController::LayerAnimationController(int id
)
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() {
37 registrar_
->UnregisterAnimationController(this);
40 scoped_refptr
<LayerAnimationController
> LayerAnimationController::Create(
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_
;
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
)
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_
;
128 Animation::TargetProperty target_property_
;
131 void LayerAnimationController::RemoveAnimation(
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())
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())
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())
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
) {
204 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
205 Animation
* animation
= animations_
[i
];
206 if (!animation
->is_impl_only())
209 if (!animation
->InEffect(monotonic_time
))
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
,
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
);
227 case Animation::TRANSFORM
: {
228 AnimationEvent
event(AnimationEvent::PROPERTY_UPDATE
, id_
,
229 animation
->group(), Animation::TRANSFORM
,
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
);
239 case Animation::FILTER
: {
240 AnimationEvent
event(AnimationEvent::PROPERTY_UPDATE
, id_
,
241 animation
->group(), Animation::FILTER
,
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
);
251 case Animation::BACKGROUND_COLOR
: {
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
265 void LayerAnimationController::UpdateState(bool start_ready_animations
,
266 AnimationEventsVector
* events
) {
267 if (!HasActiveValueObserver())
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())
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_
,
311 AffectsNoObservers()),
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
];
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
];
346 bool LayerAnimationController::HasActiveAnimation() const {
347 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
348 if (!animations_
[i
]->is_finished())
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()))
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()))
387 void LayerAnimationController::SetAnimationRegistrar(
388 AnimationRegistrar
* registrar
) {
389 if (registrar_
== registrar
)
393 registrar_
->UnregisterAnimationController(this);
395 registrar_
= 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
);
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
);
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
);
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
);
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
);
478 case Animation::TRANSFORM
:
479 NotifyObserversTransformAnimated(
480 event
.transform
, notify_active_observers
, notify_pending_observers
);
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
&&
515 ->ToFilterAnimationCurve()
516 ->HasFilterThatMovesPixels())
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.
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 "
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
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
)
554 const TransformAnimationCurve
* transform_animation_curve
=
555 animations_
[i
]->curve()->ToTransformAnimationCurve();
556 gfx::BoxF animation_bounds
;
558 transform_animation_curve
->AnimatedBoundsForBox(box
, &animation_bounds
);
561 bounds
->Union(animation_bounds
);
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
)
573 const TransformAnimationCurve
* transform_animation_curve
=
574 animations_
[i
]->curve()->ToTransformAnimationCurve();
575 if (transform_animation_curve
->AffectsScale())
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
)
588 const TransformAnimationCurve
* transform_animation_curve
=
589 animations_
[i
]->curve()->ToTransformAnimationCurve();
590 if (!transform_animation_curve
->IsTranslation())
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
)
603 const TransformAnimationCurve
* transform_animation_curve
=
604 animations_
[i
]->curve()->ToTransformAnimationCurve();
605 if (!transform_animation_curve
->PreservesAxisAlignment())
612 bool LayerAnimationController::AnimationStartScale(float* start_scale
) const {
614 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
615 if (animations_
[i
]->is_finished() ||
616 animations_
[i
]->target_property() != Animation::TRANSFORM
)
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;
625 case Animation::DIRECTION_REVERSE
:
626 case Animation::DIRECTION_ALTERNATE_REVERSE
:
627 forward_direction
= animations_
[i
]->playback_rate() < 0.0;
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
))
637 *start_scale
= std::max(*start_scale
, animation_start_scale
);
642 bool LayerAnimationController::MaximumTargetScale(float* max_scale
) const {
644 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
645 if (animations_
[i
]->is_finished() ||
646 animations_
[i
]->target_property() != Animation::TRANSFORM
)
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;
655 case Animation::DIRECTION_REVERSE
:
656 case Animation::DIRECTION_ALTERNATE_REVERSE
:
657 forward_direction
= animations_
[i
]->playback_rate() < 0.0;
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
,
667 *max_scale
= std::max(*max_scale
, animation_scale
);
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()))
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();
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
);
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
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
,
742 AffectsActiveOnlyAndIsWaitingForDeletion
),
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());
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();
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
834 if (null_intersection
) {
835 animation_waiting_for_target
->SetRunState(Animation::STARTING
,
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
);
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
);
861 base::TimeTicks start_time
;
862 if (animations_
[i
]->has_set_start_time())
863 start_time
= animations_
[i
]->start_time();
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
);
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(),
913 events
->push_back(aborted_event
);
915 animations_
[i
]->SetRunState(Animation::WAITING_FOR_DELETION
,
917 marked_animations_for_deletions
= true;
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;
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
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
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
];
969 AnimationEvent
finished_event(
970 AnimationEvent::FINISHED
, id_
,
971 animations_
[animation_index
]->group(),
972 animations_
[animation_index
]->target_property(),
974 finished_event
.is_impl_only
=
975 animations_
[animation_index
]->is_impl_only();
976 if (finished_event
.is_impl_only
)
977 NotifyAnimationFinished(finished_event
);
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_
,
999 IsWaitingForDeletion
),
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
))
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(
1022 animations_
[i
]->affects_active_observers(),
1023 animations_
[i
]->affects_pending_observers());
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(
1034 animations_
[i
]->affects_active_observers(),
1035 animations_
[i
]->affects_pending_observers());
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(
1046 animations_
[i
]->affects_active_observers(),
1047 animations_
[i
]->affects_pending_observers());
1051 case Animation::BACKGROUND_COLOR
: {
1052 // Not yet implemented.
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(
1063 animations_
[i
]->affects_active_observers(),
1064 animations_
[i
]->affects_pending_observers());
1072 void LayerAnimationController::UpdateActivation(UpdateActivationType type
) {
1073 bool force
= type
== FORCE_ACTIVATION
;
1075 bool was_active
= is_active_
;
1077 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
1078 if (animations_
[i
]->run_state() != Animation::WAITING_FOR_DELETION
) {
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(
1093 bool notify_active_observers
,
1094 bool notify_pending_observers
) {
1095 if (value_observers_
.might_have_observers()) {
1096 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
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(
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(
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(
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
,
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(
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(
1188 return it
.GetNext() != nullptr;
1193 bool LayerAnimationController::HasActiveValueObserver() {
1194 if (value_observers_
.might_have_observers()) {
1195 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
1197 LayerAnimationValueObserver
* obs
;
1198 while ((obs
= it
.GetNext()) != nullptr)
1199 if (obs
->IsActive())