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) {
34 LayerAnimationController::~LayerAnimationController() {
36 registrar_
->UnregisterAnimationController(this);
39 scoped_refptr
<LayerAnimationController
> LayerAnimationController::Create(
41 return make_scoped_refptr(new LayerAnimationController(id
));
44 void LayerAnimationController::PauseAnimation(int animation_id
,
45 base::TimeDelta time_offset
) {
46 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
47 if (animations_
[i
]->id() == animation_id
) {
48 animations_
[i
]->SetRunState(Animation::PAUSED
,
49 time_offset
+ animations_
[i
]->start_time());
54 struct HasAnimationId
{
55 explicit HasAnimationId(int id
) : id_(id
) {}
56 bool operator()(Animation
* animation
) const {
57 return animation
->id() == id_
;
64 void LayerAnimationController::RemoveAnimation(int animation_id
) {
65 auto animations_to_remove
=
66 animations_
.remove_if(HasAnimationId(animation_id
));
67 for (auto it
= animations_to_remove
; it
!= animations_
.end(); ++it
) {
68 if ((*it
)->target_property() == Animation::SCROLL_OFFSET
) {
69 scroll_offset_animation_was_interrupted_
= true;
73 animations_
.erase(animations_to_remove
, animations_
.end());
74 UpdateActivation(NORMAL_ACTIVATION
);
77 struct HasAnimationIdAndProperty
{
78 HasAnimationIdAndProperty(int id
, Animation::TargetProperty target_property
)
79 : id_(id
), target_property_(target_property
) {}
80 bool operator()(Animation
* animation
) const {
81 return animation
->id() == id_
&&
82 animation
->target_property() == target_property_
;
87 Animation::TargetProperty target_property_
;
90 void LayerAnimationController::RemoveAnimation(
92 Animation::TargetProperty target_property
) {
93 auto animations_to_remove
= animations_
.remove_if(
94 HasAnimationIdAndProperty(animation_id
, target_property
));
95 if (target_property
== Animation::SCROLL_OFFSET
&&
96 animations_to_remove
!= animations_
.end())
97 scroll_offset_animation_was_interrupted_
= true;
99 animations_
.erase(animations_to_remove
, animations_
.end());
100 UpdateActivation(NORMAL_ACTIVATION
);
103 void LayerAnimationController::AbortAnimations(
104 Animation::TargetProperty target_property
) {
105 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
106 if (animations_
[i
]->target_property() == target_property
&&
107 !animations_
[i
]->is_finished())
108 animations_
[i
]->SetRunState(Animation::ABORTED
, last_tick_time_
);
112 // Ensures that the list of active animations on the main thread and the impl
113 // thread are kept in sync.
114 void LayerAnimationController::PushAnimationUpdatesTo(
115 LayerAnimationController
* controller_impl
) {
116 DCHECK(this != controller_impl
);
117 if (!has_any_animation() && !controller_impl
->has_any_animation())
119 PurgeAnimationsMarkedForDeletion();
120 PushNewAnimationsToImplThread(controller_impl
);
122 // Remove finished impl side animations only after pushing,
123 // and only after the animations are deleted on the main thread
124 // this insures we will never push an animation twice.
125 RemoveAnimationsCompletedOnMainThread(controller_impl
);
127 PushPropertiesToImplThread(controller_impl
);
128 controller_impl
->UpdateActivation(NORMAL_ACTIVATION
);
129 UpdateActivation(NORMAL_ACTIVATION
);
132 void LayerAnimationController::Animate(base::TimeTicks monotonic_time
) {
133 DCHECK(!monotonic_time
.is_null());
134 if (!HasValueObserver())
137 if (needs_to_start_animations_
)
138 StartAnimations(monotonic_time
);
139 TickAnimations(monotonic_time
);
140 last_tick_time_
= monotonic_time
;
143 void LayerAnimationController::AccumulatePropertyUpdates(
144 base::TimeTicks monotonic_time
,
145 AnimationEventsVector
* events
) {
149 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
150 Animation
* animation
= animations_
[i
];
151 if (!animation
->is_impl_only())
154 if (!animation
->InEffect(monotonic_time
))
157 base::TimeDelta trimmed
=
158 animation
->TrimTimeToCurrentIteration(monotonic_time
);
159 switch (animation
->target_property()) {
160 case Animation::OPACITY
: {
161 AnimationEvent
event(AnimationEvent::PROPERTY_UPDATE
, id_
,
162 animation
->group(), Animation::OPACITY
,
164 const FloatAnimationCurve
* float_animation_curve
=
165 animation
->curve()->ToFloatAnimationCurve();
166 event
.opacity
= float_animation_curve
->GetValue(trimmed
);
167 event
.is_impl_only
= true;
168 events
->push_back(event
);
172 case Animation::TRANSFORM
: {
173 AnimationEvent
event(AnimationEvent::PROPERTY_UPDATE
, id_
,
174 animation
->group(), Animation::TRANSFORM
,
176 const TransformAnimationCurve
* transform_animation_curve
=
177 animation
->curve()->ToTransformAnimationCurve();
178 event
.transform
= transform_animation_curve
->GetValue(trimmed
);
179 event
.is_impl_only
= true;
180 events
->push_back(event
);
184 case Animation::FILTER
: {
185 AnimationEvent
event(AnimationEvent::PROPERTY_UPDATE
, id_
,
186 animation
->group(), Animation::FILTER
,
188 const FilterAnimationCurve
* filter_animation_curve
=
189 animation
->curve()->ToFilterAnimationCurve();
190 event
.filters
= filter_animation_curve
->GetValue(trimmed
);
191 event
.is_impl_only
= true;
192 events
->push_back(event
);
196 case Animation::BACKGROUND_COLOR
: {
200 case Animation::SCROLL_OFFSET
: {
201 // Impl-side changes to scroll offset are already sent back to the
202 // main thread (e.g. for user-driven scrolling), so a PROPERTY_UPDATE
210 void LayerAnimationController::UpdateState(bool start_ready_animations
,
211 AnimationEventsVector
* events
) {
212 if (!HasActiveValueObserver())
215 // Animate hasn't been called, this happens if an observer has been added
216 // between the Commit and Draw phases.
217 if (last_tick_time_
== base::TimeTicks())
220 if (start_ready_animations
)
221 PromoteStartedAnimations(last_tick_time_
, events
);
223 MarkFinishedAnimations(last_tick_time_
);
224 MarkAnimationsForDeletion(last_tick_time_
, events
);
226 if (needs_to_start_animations_
&& start_ready_animations
) {
227 StartAnimations(last_tick_time_
);
228 PromoteStartedAnimations(last_tick_time_
, events
);
231 AccumulatePropertyUpdates(last_tick_time_
, events
);
233 UpdateActivation(NORMAL_ACTIVATION
);
236 struct AffectsNoObservers
{
237 bool operator()(Animation
* animation
) const {
238 return !animation
->affects_active_observers() &&
239 !animation
->affects_pending_observers();
243 void LayerAnimationController::ActivateAnimations() {
244 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
245 animations_
[i
]->set_affects_active_observers(
246 animations_
[i
]->affects_pending_observers());
248 animations_
.erase(cc::remove_if(&animations_
,
251 AffectsNoObservers()),
253 scroll_offset_animation_was_interrupted_
= false;
254 UpdateActivation(NORMAL_ACTIVATION
);
257 void LayerAnimationController::AddAnimation(scoped_ptr
<Animation
> animation
) {
258 animations_
.push_back(animation
.Pass());
259 needs_to_start_animations_
= true;
260 UpdateActivation(NORMAL_ACTIVATION
);
263 Animation
* LayerAnimationController::GetAnimation(
264 Animation::TargetProperty target_property
) const {
265 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
266 size_t index
= animations_
.size() - i
- 1;
267 if (animations_
[index
]->target_property() == target_property
)
268 return animations_
[index
];
273 Animation
* LayerAnimationController::GetAnimationById(int animation_id
) const {
274 for (size_t i
= 0; i
< animations_
.size(); ++i
)
275 if (animations_
[i
]->id() == animation_id
)
276 return animations_
[i
];
280 bool LayerAnimationController::HasActiveAnimation() const {
281 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
282 if (!animations_
[i
]->is_finished())
288 bool LayerAnimationController::IsAnimatingProperty(
289 Animation::TargetProperty target_property
) const {
290 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
291 if (!animations_
[i
]->is_finished() &&
292 animations_
[i
]->InEffect(last_tick_time_
) &&
293 animations_
[i
]->target_property() == target_property
)
299 void LayerAnimationController::SetAnimationRegistrar(
300 AnimationRegistrar
* registrar
) {
301 if (registrar_
== registrar
)
305 registrar_
->UnregisterAnimationController(this);
307 registrar_
= registrar
;
309 registrar_
->RegisterAnimationController(this);
311 UpdateActivation(FORCE_ACTIVATION
);
314 void LayerAnimationController::NotifyAnimationStarted(
315 const AnimationEvent
& event
) {
316 if (event
.is_impl_only
) {
317 FOR_EACH_OBSERVER(LayerAnimationEventObserver
, event_observers_
,
318 OnAnimationStarted(event
));
319 if (layer_animation_delegate_
)
320 layer_animation_delegate_
->NotifyAnimationStarted(
321 event
.monotonic_time
, event
.target_property
, event
.group_id
);
325 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
326 if (animations_
[i
]->group() == event
.group_id
&&
327 animations_
[i
]->target_property() == event
.target_property
&&
328 animations_
[i
]->needs_synchronized_start_time()) {
329 animations_
[i
]->set_needs_synchronized_start_time(false);
330 if (!animations_
[i
]->has_set_start_time())
331 animations_
[i
]->set_start_time(event
.monotonic_time
);
333 FOR_EACH_OBSERVER(LayerAnimationEventObserver
, event_observers_
,
334 OnAnimationStarted(event
));
335 if (layer_animation_delegate_
)
336 layer_animation_delegate_
->NotifyAnimationStarted(
337 event
.monotonic_time
, event
.target_property
, event
.group_id
);
344 void LayerAnimationController::NotifyAnimationFinished(
345 const AnimationEvent
& event
) {
346 if (event
.is_impl_only
) {
347 if (layer_animation_delegate_
)
348 layer_animation_delegate_
->NotifyAnimationFinished(
349 event
.monotonic_time
, event
.target_property
, event
.group_id
);
353 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
354 if (animations_
[i
]->group() == event
.group_id
&&
355 animations_
[i
]->target_property() == event
.target_property
) {
356 animations_
[i
]->set_received_finished_event(true);
357 if (layer_animation_delegate_
)
358 layer_animation_delegate_
->NotifyAnimationFinished(
359 event
.monotonic_time
, event
.target_property
, event
.group_id
);
366 void LayerAnimationController::NotifyAnimationAborted(
367 const AnimationEvent
& event
) {
368 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
369 if (animations_
[i
]->group() == event
.group_id
&&
370 animations_
[i
]->target_property() == event
.target_property
) {
371 animations_
[i
]->SetRunState(Animation::ABORTED
, event
.monotonic_time
);
376 void LayerAnimationController::NotifyAnimationPropertyUpdate(
377 const AnimationEvent
& event
) {
378 bool notify_active_observers
= true;
379 bool notify_pending_observers
= true;
380 switch (event
.target_property
) {
381 case Animation::OPACITY
:
382 NotifyObserversOpacityAnimated(
383 event
.opacity
, notify_active_observers
, notify_pending_observers
);
385 case Animation::TRANSFORM
:
386 NotifyObserversTransformAnimated(
387 event
.transform
, notify_active_observers
, notify_pending_observers
);
394 void LayerAnimationController::AddValueObserver(
395 LayerAnimationValueObserver
* observer
) {
396 if (!value_observers_
.HasObserver(observer
))
397 value_observers_
.AddObserver(observer
);
400 void LayerAnimationController::RemoveValueObserver(
401 LayerAnimationValueObserver
* observer
) {
402 value_observers_
.RemoveObserver(observer
);
405 void LayerAnimationController::AddEventObserver(
406 LayerAnimationEventObserver
* observer
) {
407 if (!event_observers_
.HasObserver(observer
))
408 event_observers_
.AddObserver(observer
);
411 void LayerAnimationController::RemoveEventObserver(
412 LayerAnimationEventObserver
* observer
) {
413 event_observers_
.RemoveObserver(observer
);
416 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
417 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
418 if (!animations_
[i
]->is_finished() &&
419 animations_
[i
]->target_property() == Animation::FILTER
&&
422 ->ToFilterAnimationCurve()
423 ->HasFilterThatMovesPixels())
430 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
431 return IsAnimatingProperty(Animation::TRANSFORM
);
434 bool LayerAnimationController::FilterAnimationBoundsForBox(
435 const gfx::BoxF
& box
, gfx::BoxF
* bounds
) const {
436 // TODO(avallee): Implement.
440 bool LayerAnimationController::TransformAnimationBoundsForBox(
441 const gfx::BoxF
& box
,
442 gfx::BoxF
* bounds
) const {
443 DCHECK(HasTransformAnimationThatInflatesBounds())
444 << "TransformAnimationBoundsForBox will give incorrect results if there "
445 << "are no transform animations affecting bounds, non-animated transform "
448 // Compute bounds based on animations for which is_finished() is false.
449 // Do nothing if there are no such animations; in this case, it is assumed
450 // that callers will take care of computing bounds based on the owning layer's
452 *bounds
= gfx::BoxF();
453 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
454 if (animations_
[i
]->is_finished() ||
455 animations_
[i
]->target_property() != Animation::TRANSFORM
)
458 const TransformAnimationCurve
* transform_animation_curve
=
459 animations_
[i
]->curve()->ToTransformAnimationCurve();
460 gfx::BoxF animation_bounds
;
462 transform_animation_curve
->AnimatedBoundsForBox(box
, &animation_bounds
);
465 bounds
->Union(animation_bounds
);
471 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
472 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
473 if (animations_
[i
]->is_finished() ||
474 animations_
[i
]->target_property() != Animation::TRANSFORM
)
477 const TransformAnimationCurve
* transform_animation_curve
=
478 animations_
[i
]->curve()->ToTransformAnimationCurve();
479 if (transform_animation_curve
->AffectsScale())
486 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
487 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
488 if (animations_
[i
]->is_finished() ||
489 animations_
[i
]->target_property() != Animation::TRANSFORM
)
492 const TransformAnimationCurve
* transform_animation_curve
=
493 animations_
[i
]->curve()->ToTransformAnimationCurve();
494 if (!transform_animation_curve
->IsTranslation())
501 bool LayerAnimationController::AnimationsPreserveAxisAlignment() const {
502 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
503 if (animations_
[i
]->is_finished() ||
504 animations_
[i
]->target_property() != Animation::TRANSFORM
)
507 const TransformAnimationCurve
* transform_animation_curve
=
508 animations_
[i
]->curve()->ToTransformAnimationCurve();
509 if (!transform_animation_curve
->PreservesAxisAlignment())
516 bool LayerAnimationController::AnimationStartScale(float* start_scale
) const {
518 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
519 if (animations_
[i
]->is_finished() ||
520 animations_
[i
]->target_property() != Animation::TRANSFORM
)
523 bool forward_direction
= true;
524 switch (animations_
[i
]->direction()) {
525 case Animation::DIRECTION_NORMAL
:
526 case Animation::DIRECTION_ALTERNATE
:
527 forward_direction
= animations_
[i
]->playback_rate() >= 0.0;
529 case Animation::DIRECTION_REVERSE
:
530 case Animation::DIRECTION_ALTERNATE_REVERSE
:
531 forward_direction
= animations_
[i
]->playback_rate() < 0.0;
535 const TransformAnimationCurve
* transform_animation_curve
=
536 animations_
[i
]->curve()->ToTransformAnimationCurve();
537 float animation_start_scale
= 0.f
;
538 if (!transform_animation_curve
->AnimationStartScale(forward_direction
,
539 &animation_start_scale
))
541 *start_scale
= std::max(*start_scale
, animation_start_scale
);
546 bool LayerAnimationController::MaximumTargetScale(float* max_scale
) const {
548 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
549 if (animations_
[i
]->is_finished() ||
550 animations_
[i
]->target_property() != Animation::TRANSFORM
)
553 bool forward_direction
= true;
554 switch (animations_
[i
]->direction()) {
555 case Animation::DIRECTION_NORMAL
:
556 case Animation::DIRECTION_ALTERNATE
:
557 forward_direction
= animations_
[i
]->playback_rate() >= 0.0;
559 case Animation::DIRECTION_REVERSE
:
560 case Animation::DIRECTION_ALTERNATE_REVERSE
:
561 forward_direction
= animations_
[i
]->playback_rate() < 0.0;
565 const TransformAnimationCurve
* transform_animation_curve
=
566 animations_
[i
]->curve()->ToTransformAnimationCurve();
567 float animation_scale
= 0.f
;
568 if (!transform_animation_curve
->MaximumTargetScale(forward_direction
,
571 *max_scale
= std::max(*max_scale
, animation_scale
);
577 void LayerAnimationController::PushNewAnimationsToImplThread(
578 LayerAnimationController
* controller_impl
) const {
579 // Any new animations owned by the main thread's controller are cloned and
580 // add to the impl thread's controller.
581 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
582 // If the animation is already running on the impl thread, there is no
583 // need to copy it over.
584 if (controller_impl
->GetAnimationById(animations_
[i
]->id()))
587 // Scroll animations always start at the current scroll offset.
588 if (animations_
[i
]->target_property() == Animation::SCROLL_OFFSET
) {
589 gfx::ScrollOffset current_scroll_offset
;
590 if (controller_impl
->value_provider_
) {
591 current_scroll_offset
=
592 controller_impl
->value_provider_
->ScrollOffsetForAnimation();
594 // The owning layer isn't yet in the active tree, so the main thread
595 // scroll offset will be up-to-date.
596 current_scroll_offset
= value_provider_
->ScrollOffsetForAnimation();
598 animations_
[i
]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
599 current_scroll_offset
);
602 // The new animation should be set to run as soon as possible.
603 Animation::RunState initial_run_state
=
604 Animation::WAITING_FOR_TARGET_AVAILABILITY
;
605 scoped_ptr
<Animation
> to_add(
606 animations_
[i
]->CloneAndInitialize(initial_run_state
));
607 DCHECK(!to_add
->needs_synchronized_start_time());
608 to_add
->set_affects_active_observers(false);
609 controller_impl
->AddAnimation(to_add
.Pass());
613 static bool IsCompleted(
614 Animation
* animation
,
615 const LayerAnimationController
* main_thread_controller
) {
616 if (animation
->is_impl_only()) {
617 return (animation
->run_state() == Animation::WAITING_FOR_DELETION
);
619 return !main_thread_controller
->GetAnimationById(animation
->id());
623 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation
* animation
) {
624 return animation
->run_state() == Animation::WAITING_FOR_DELETION
&&
625 !animation
->affects_pending_observers();
628 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
629 LayerAnimationController
* controller_impl
) const {
630 // Animations removed on the main thread should no longer affect pending
631 // observers, and should stop affecting active observers after the next call
632 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed
634 ScopedPtrVector
<Animation
>& animations
= controller_impl
->animations_
;
635 for (size_t i
= 0; i
< animations
.size(); ++i
) {
636 if (IsCompleted(animations
[i
], this))
637 animations
[i
]->set_affects_pending_observers(false);
639 animations
.erase(cc::remove_if(&animations
,
642 AffectsActiveOnlyAndIsWaitingForDeletion
),
646 void LayerAnimationController::PushPropertiesToImplThread(
647 LayerAnimationController
* controller_impl
) {
648 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
649 Animation
* current_impl
=
650 controller_impl
->GetAnimationById(animations_
[i
]->id());
652 animations_
[i
]->PushPropertiesTo(current_impl
);
654 controller_impl
->scroll_offset_animation_was_interrupted_
=
655 scroll_offset_animation_was_interrupted_
;
656 scroll_offset_animation_was_interrupted_
= false;
659 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time
) {
660 DCHECK(needs_to_start_animations_
);
661 needs_to_start_animations_
= false;
662 // First collect running properties affecting each type of observer.
663 TargetProperties blocked_properties_for_active_observers
;
664 TargetProperties blocked_properties_for_pending_observers
;
665 std::vector
<size_t> animations_waiting_for_target
;
667 animations_waiting_for_target
.reserve(animations_
.size());
668 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
669 if (animations_
[i
]->run_state() == Animation::STARTING
||
670 animations_
[i
]->run_state() == Animation::RUNNING
) {
671 if (animations_
[i
]->affects_active_observers()) {
672 blocked_properties_for_active_observers
.insert(
673 animations_
[i
]->target_property());
675 if (animations_
[i
]->affects_pending_observers()) {
676 blocked_properties_for_pending_observers
.insert(
677 animations_
[i
]->target_property());
679 } else if (animations_
[i
]->run_state() ==
680 Animation::WAITING_FOR_TARGET_AVAILABILITY
) {
681 animations_waiting_for_target
.push_back(i
);
685 for (size_t i
= 0; i
< animations_waiting_for_target
.size(); ++i
) {
686 // Collect all properties for animations with the same group id (they
687 // should all also be in the list of animations).
688 size_t animation_index
= animations_waiting_for_target
[i
];
689 Animation
* animation_waiting_for_target
= animations_
[animation_index
];
690 // Check for the run state again even though the animation was waiting
691 // for target because it might have changed the run state while handling
692 // previous animation in this loop (if they belong to same group).
693 if (animation_waiting_for_target
->run_state() ==
694 Animation::WAITING_FOR_TARGET_AVAILABILITY
) {
695 TargetProperties enqueued_properties
;
696 bool affects_active_observers
=
697 animation_waiting_for_target
->affects_active_observers();
698 bool affects_pending_observers
=
699 animation_waiting_for_target
->affects_pending_observers();
700 enqueued_properties
.insert(
701 animation_waiting_for_target
->target_property());
702 for (size_t j
= animation_index
+ 1; j
< animations_
.size(); ++j
) {
703 if (animation_waiting_for_target
->group() == animations_
[j
]->group()) {
704 enqueued_properties
.insert(animations_
[j
]->target_property());
705 affects_active_observers
|=
706 animations_
[j
]->affects_active_observers();
707 affects_pending_observers
|=
708 animations_
[j
]->affects_pending_observers();
712 // Check to see if intersection of the list of properties affected by
713 // the group and the list of currently blocked properties is null, taking
714 // into account the type(s) of observers affected by the group. In any
715 // case, the group's target properties need to be added to the lists of
716 // blocked properties.
717 bool null_intersection
= true;
718 for (TargetProperties::iterator p_iter
= enqueued_properties
.begin();
719 p_iter
!= enqueued_properties
.end();
721 if (affects_active_observers
&&
722 !blocked_properties_for_active_observers
.insert(*p_iter
).second
)
723 null_intersection
= false;
724 if (affects_pending_observers
&&
725 !blocked_properties_for_pending_observers
.insert(*p_iter
).second
)
726 null_intersection
= false;
729 // If the intersection is null, then we are free to start the animations
731 if (null_intersection
) {
732 animation_waiting_for_target
->SetRunState(Animation::STARTING
,
734 for (size_t j
= animation_index
+ 1; j
< animations_
.size(); ++j
) {
735 if (animation_waiting_for_target
->group() ==
736 animations_
[j
]->group()) {
737 animations_
[j
]->SetRunState(Animation::STARTING
, monotonic_time
);
741 needs_to_start_animations_
= true;
747 void LayerAnimationController::PromoteStartedAnimations(
748 base::TimeTicks monotonic_time
,
749 AnimationEventsVector
* events
) {
750 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
751 if (animations_
[i
]->run_state() == Animation::STARTING
&&
752 animations_
[i
]->affects_active_observers()) {
753 animations_
[i
]->SetRunState(Animation::RUNNING
, monotonic_time
);
754 if (!animations_
[i
]->has_set_start_time() &&
755 !animations_
[i
]->needs_synchronized_start_time())
756 animations_
[i
]->set_start_time(monotonic_time
);
758 AnimationEvent
started_event(
759 AnimationEvent::STARTED
, id_
, animations_
[i
]->group(),
760 animations_
[i
]->target_property(), monotonic_time
);
761 started_event
.is_impl_only
= animations_
[i
]->is_impl_only();
762 if (started_event
.is_impl_only
)
763 NotifyAnimationStarted(started_event
);
765 events
->push_back(started_event
);
771 void LayerAnimationController::MarkFinishedAnimations(
772 base::TimeTicks monotonic_time
) {
773 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
774 if (animations_
[i
]->IsFinishedAt(monotonic_time
) &&
775 animations_
[i
]->run_state() != Animation::ABORTED
&&
776 animations_
[i
]->run_state() != Animation::WAITING_FOR_DELETION
)
777 animations_
[i
]->SetRunState(Animation::FINISHED
, monotonic_time
);
781 void LayerAnimationController::MarkAnimationsForDeletion(
782 base::TimeTicks monotonic_time
,
783 AnimationEventsVector
* events
) {
784 bool marked_animations_for_deletions
= false;
785 std::vector
<size_t> animations_with_same_group_id
;
787 animations_with_same_group_id
.reserve(animations_
.size());
788 // Non-aborted animations are marked for deletion after a corresponding
789 // AnimationEvent::FINISHED event is sent or received. This means that if
790 // we don't have an events vector, we must ensure that non-aborted animations
791 // have received a finished event before marking them for deletion.
792 for (size_t i
= 0; i
< animations_
.size(); i
++) {
793 int group_id
= animations_
[i
]->group();
794 if (animations_
[i
]->run_state() == Animation::ABORTED
) {
795 if (events
&& !animations_
[i
]->is_impl_only()) {
796 AnimationEvent
aborted_event(AnimationEvent::ABORTED
, id_
, group_id
,
797 animations_
[i
]->target_property(),
799 events
->push_back(aborted_event
);
801 animations_
[i
]->SetRunState(Animation::WAITING_FOR_DELETION
,
803 marked_animations_for_deletions
= true;
807 bool all_anims_with_same_id_are_finished
= false;
809 // Since deleting an animation on the main thread leads to its deletion
810 // on the impl thread, we only mark a FINISHED main thread animation for
811 // deletion once it has received a FINISHED event from the impl thread.
812 bool animation_i_will_send_or_has_received_finish_event
=
813 events
|| animations_
[i
]->received_finished_event();
814 // If an animation is finished, and not already marked for deletion,
815 // find out if all other animations in the same group are also finished.
816 if (animations_
[i
]->run_state() == Animation::FINISHED
&&
817 animation_i_will_send_or_has_received_finish_event
) {
818 // Clear the animations_with_same_group_id if it was added for
819 // the previous animation's iteration.
820 if (animations_with_same_group_id
.size() > 0)
821 animations_with_same_group_id
.clear();
822 all_anims_with_same_id_are_finished
= true;
823 for (size_t j
= 0; j
< animations_
.size(); ++j
) {
824 bool animation_j_will_send_or_has_received_finish_event
=
825 events
|| animations_
[j
]->received_finished_event();
826 if (group_id
== animations_
[j
]->group()) {
827 if (!animations_
[j
]->is_finished() ||
828 (animations_
[j
]->run_state() == Animation::FINISHED
&&
829 !animation_j_will_send_or_has_received_finish_event
)) {
830 all_anims_with_same_id_are_finished
= false;
833 animations_
[j
]->run_state() != Animation::ABORTED
) {
834 // Mark down the animations which belong to the same group
835 // and is not yet aborted. If this current iteration finds that all
836 // animations with same ID are finished, then the marked
837 // animations below will be set to WAITING_FOR_DELETION in next
839 animations_with_same_group_id
.push_back(j
);
844 if (all_anims_with_same_id_are_finished
) {
845 // We now need to remove all animations with the same group id as
846 // group_id (and send along animation finished notifications, if
848 for (size_t j
= 0; j
< animations_with_same_group_id
.size(); j
++) {
849 size_t animation_index
= animations_with_same_group_id
[j
];
851 AnimationEvent
finished_event(
852 AnimationEvent::FINISHED
, id_
,
853 animations_
[animation_index
]->group(),
854 animations_
[animation_index
]->target_property(),
856 finished_event
.is_impl_only
=
857 animations_
[animation_index
]->is_impl_only();
858 if (finished_event
.is_impl_only
)
859 NotifyAnimationFinished(finished_event
);
861 events
->push_back(finished_event
);
863 animations_
[animation_index
]->SetRunState(
864 Animation::WAITING_FOR_DELETION
, monotonic_time
);
866 marked_animations_for_deletions
= true;
869 if (marked_animations_for_deletions
)
870 NotifyObserversAnimationWaitingForDeletion();
873 static bool IsWaitingForDeletion(Animation
* animation
) {
874 return animation
->run_state() == Animation::WAITING_FOR_DELETION
;
877 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
878 animations_
.erase(cc::remove_if(&animations_
,
881 IsWaitingForDeletion
),
885 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time
) {
886 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
887 if (animations_
[i
]->run_state() == Animation::STARTING
||
888 animations_
[i
]->run_state() == Animation::RUNNING
||
889 animations_
[i
]->run_state() == Animation::PAUSED
) {
890 if (!animations_
[i
]->InEffect(monotonic_time
))
893 base::TimeDelta trimmed
=
894 animations_
[i
]->TrimTimeToCurrentIteration(monotonic_time
);
896 switch (animations_
[i
]->target_property()) {
897 case Animation::TRANSFORM
: {
898 const TransformAnimationCurve
* transform_animation_curve
=
899 animations_
[i
]->curve()->ToTransformAnimationCurve();
900 const gfx::Transform transform
=
901 transform_animation_curve
->GetValue(trimmed
);
902 NotifyObserversTransformAnimated(
904 animations_
[i
]->affects_active_observers(),
905 animations_
[i
]->affects_pending_observers());
909 case Animation::OPACITY
: {
910 const FloatAnimationCurve
* float_animation_curve
=
911 animations_
[i
]->curve()->ToFloatAnimationCurve();
912 const float opacity
= std::max(
913 std::min(float_animation_curve
->GetValue(trimmed
), 1.0f
), 0.f
);
914 NotifyObserversOpacityAnimated(
916 animations_
[i
]->affects_active_observers(),
917 animations_
[i
]->affects_pending_observers());
921 case Animation::FILTER
: {
922 const FilterAnimationCurve
* filter_animation_curve
=
923 animations_
[i
]->curve()->ToFilterAnimationCurve();
924 const FilterOperations filter
=
925 filter_animation_curve
->GetValue(trimmed
);
926 NotifyObserversFilterAnimated(
928 animations_
[i
]->affects_active_observers(),
929 animations_
[i
]->affects_pending_observers());
933 case Animation::BACKGROUND_COLOR
: {
934 // Not yet implemented.
938 case Animation::SCROLL_OFFSET
: {
939 const ScrollOffsetAnimationCurve
* scroll_offset_animation_curve
=
940 animations_
[i
]->curve()->ToScrollOffsetAnimationCurve();
941 const gfx::ScrollOffset scroll_offset
=
942 scroll_offset_animation_curve
->GetValue(trimmed
);
943 NotifyObserversScrollOffsetAnimated(
945 animations_
[i
]->affects_active_observers(),
946 animations_
[i
]->affects_pending_observers());
954 void LayerAnimationController::UpdateActivation(UpdateActivationType type
) {
955 bool force
= type
== FORCE_ACTIVATION
;
957 bool was_active
= is_active_
;
959 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
960 if (animations_
[i
]->run_state() != Animation::WAITING_FOR_DELETION
) {
966 if (is_active_
&& (!was_active
|| force
))
967 registrar_
->DidActivateAnimationController(this);
968 else if (!is_active_
&& (was_active
|| force
))
969 registrar_
->DidDeactivateAnimationController(this);
973 void LayerAnimationController::NotifyObserversOpacityAnimated(
975 bool notify_active_observers
,
976 bool notify_pending_observers
) {
977 if (value_observers_
.might_have_observers()) {
978 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
980 LayerAnimationValueObserver
* obs
;
981 while ((obs
= it
.GetNext()) != nullptr) {
982 if ((notify_active_observers
&& notify_pending_observers
) ||
983 (notify_active_observers
&& obs
->IsActive()) ||
984 (notify_pending_observers
&& !obs
->IsActive()))
985 obs
->OnOpacityAnimated(opacity
);
990 void LayerAnimationController::NotifyObserversTransformAnimated(
991 const gfx::Transform
& transform
,
992 bool notify_active_observers
,
993 bool notify_pending_observers
) {
994 if (value_observers_
.might_have_observers()) {
995 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
997 LayerAnimationValueObserver
* obs
;
998 while ((obs
= it
.GetNext()) != nullptr) {
999 if ((notify_active_observers
&& notify_pending_observers
) ||
1000 (notify_active_observers
&& obs
->IsActive()) ||
1001 (notify_pending_observers
&& !obs
->IsActive()))
1002 obs
->OnTransformAnimated(transform
);
1007 void LayerAnimationController::NotifyObserversFilterAnimated(
1008 const FilterOperations
& filters
,
1009 bool notify_active_observers
,
1010 bool notify_pending_observers
) {
1011 if (value_observers_
.might_have_observers()) {
1012 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
1014 LayerAnimationValueObserver
* obs
;
1015 while ((obs
= it
.GetNext()) != nullptr) {
1016 if ((notify_active_observers
&& notify_pending_observers
) ||
1017 (notify_active_observers
&& obs
->IsActive()) ||
1018 (notify_pending_observers
&& !obs
->IsActive()))
1019 obs
->OnFilterAnimated(filters
);
1024 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
1025 const gfx::ScrollOffset
& scroll_offset
,
1026 bool notify_active_observers
,
1027 bool notify_pending_observers
) {
1028 if (value_observers_
.might_have_observers()) {
1029 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
1031 LayerAnimationValueObserver
* obs
;
1032 while ((obs
= it
.GetNext()) != nullptr) {
1033 if ((notify_active_observers
&& notify_pending_observers
) ||
1034 (notify_active_observers
&& obs
->IsActive()) ||
1035 (notify_pending_observers
&& !obs
->IsActive()))
1036 obs
->OnScrollOffsetAnimated(scroll_offset
);
1041 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1042 FOR_EACH_OBSERVER(LayerAnimationValueObserver
,
1044 OnAnimationWaitingForDeletion());
1047 bool LayerAnimationController::HasValueObserver() {
1048 if (value_observers_
.might_have_observers()) {
1049 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
1051 return it
.GetNext() != nullptr;
1056 bool LayerAnimationController::HasActiveValueObserver() {
1057 if (value_observers_
.might_have_observers()) {
1058 base::ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
1060 LayerAnimationValueObserver
* obs
;
1061 while ((obs
= it
.GetNext()) != nullptr)
1062 if (obs
->IsActive())