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(
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
)
589 if ((observer_type
== ObserverType::ACTIVE
&&
590 !animations_
[i
]->affects_active_observers()) ||
591 (observer_type
== ObserverType::PENDING
&&
592 !animations_
[i
]->affects_pending_observers()))
595 const TransformAnimationCurve
* transform_animation_curve
=
596 animations_
[i
]->curve()->ToTransformAnimationCurve();
597 if (!transform_animation_curve
->IsTranslation())
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
)
610 const TransformAnimationCurve
* transform_animation_curve
=
611 animations_
[i
]->curve()->ToTransformAnimationCurve();
612 if (!transform_animation_curve
->PreservesAxisAlignment())
619 bool LayerAnimationController::AnimationStartScale(ObserverType observer_type
,
620 float* start_scale
) const {
622 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
623 if (animations_
[i
]->is_finished() ||
624 animations_
[i
]->target_property() != Animation::TRANSFORM
)
627 if ((observer_type
== ObserverType::ACTIVE
&&
628 !animations_
[i
]->affects_active_observers()) ||
629 (observer_type
== ObserverType::PENDING
&&
630 !animations_
[i
]->affects_pending_observers()))
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;
639 case Animation::DIRECTION_REVERSE
:
640 case Animation::DIRECTION_ALTERNATE_REVERSE
:
641 forward_direction
= animations_
[i
]->playback_rate() < 0.0;
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
))
651 *start_scale
= std::max(*start_scale
, animation_start_scale
);
656 bool LayerAnimationController::MaximumTargetScale(ObserverType observer_type
,
657 float* max_scale
) const {
659 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
660 if (animations_
[i
]->is_finished() ||
661 animations_
[i
]->target_property() != Animation::TRANSFORM
)
664 if ((observer_type
== ObserverType::ACTIVE
&&
665 !animations_
[i
]->affects_active_observers()) ||
666 (observer_type
== ObserverType::PENDING
&&
667 !animations_
[i
]->affects_pending_observers()))
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;
676 case Animation::DIRECTION_REVERSE
:
677 case Animation::DIRECTION_ALTERNATE_REVERSE
:
678 forward_direction
= animations_
[i
]->playback_rate() < 0.0;
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
,
688 *max_scale
= std::max(*max_scale
, animation_scale
);
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()))
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();
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
);
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
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
,
763 AffectsActiveOnlyAndIsWaitingForDeletion
),
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());
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();
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
855 if (null_intersection
) {
856 animation_waiting_for_target
->SetRunState(Animation::STARTING
,
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
);
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
);
882 base::TimeTicks start_time
;
883 if (animations_
[i
]->has_set_start_time())
884 start_time
= animations_
[i
]->start_time();
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
);
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(),
934 events
->push_back(aborted_event
);
936 animations_
[i
]->SetRunState(Animation::WAITING_FOR_DELETION
,
938 marked_animations_for_deletions
= true;
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;
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
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
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
];
990 AnimationEvent
finished_event(
991 AnimationEvent::FINISHED
, id_
,
992 animations_
[animation_index
]->group(),
993 animations_
[animation_index
]->target_property(),
995 finished_event
.is_impl_only
=
996 animations_
[animation_index
]->is_impl_only();
997 if (finished_event
.is_impl_only
)
998 NotifyAnimationFinished(finished_event
);
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(),
1020 IsWaitingForDeletion
),
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
))
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(
1043 animations_
[i
]->affects_active_observers(),
1044 animations_
[i
]->affects_pending_observers());
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(
1055 animations_
[i
]->affects_active_observers(),
1056 animations_
[i
]->affects_pending_observers());
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(
1067 animations_
[i
]->affects_active_observers(),
1068 animations_
[i
]->affects_pending_observers());
1072 case Animation::BACKGROUND_COLOR
: {
1073 // Not yet implemented.
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(
1084 animations_
[i
]->affects_active_observers(),
1085 animations_
[i
]->affects_pending_observers());
1093 void LayerAnimationController::UpdateActivation(UpdateActivationType type
) {
1094 bool force
= type
== FORCE_ACTIVATION
;
1096 bool was_active
= is_active_
;
1098 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
1099 if (animations_
[i
]->run_state() != Animation::WAITING_FOR_DELETION
) {
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(
1114 bool notify_active_observers
,
1115 bool notify_pending_observers
) {
1116 if (value_observers_
.might_have_observers()) {
1117 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
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(
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(
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(
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
,
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(
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(
1209 return it
.GetNext() != nullptr;
1214 bool LayerAnimationController::HasActiveValueObserver() {
1215 if (value_observers_
.might_have_observers()) {
1216 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
1218 LayerAnimationValueObserver
* obs
;
1219 while ((obs
= it
.GetNext()) != nullptr)
1220 if (obs
->IsActive())