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.
4
5 #include "cc/animation/layer_animation_controller.h"
6
7 #include <algorithm>
8
9 #include "cc/animation/animation.h"
10 #include "cc/animation/animation_delegate.h"
11 #include "cc/animation/animation_registrar.h"
12 #include "cc/animation/keyframed_animation_curve.h"
13 #include "cc/animation/layer_animation_value_observer.h"
14 #include "cc/animation/layer_animation_value_provider.h"
15 #include "cc/animation/scroll_offset_animation_curve.h"
16 #include "cc/base/scoped_ptr_algorithm.h"
17 #include "cc/output/filter_operations.h"
18 #include "ui/gfx/box_f.h"
19 #include "ui/gfx/transform.h"
20
21 namespace cc {
22
LayerAnimationController(int id)23 LayerAnimationController::LayerAnimationController(int id)
24 : registrar_(0),
25 id_(id),
26 is_active_(false),
27 value_provider_(NULL),
28 layer_animation_delegate_(NULL),
29 needs_to_start_animations_(false) {
30 }
31
~LayerAnimationController()32 LayerAnimationController::~LayerAnimationController() {
33 if (registrar_)
34 registrar_->UnregisterAnimationController(this);
35 }
36
Create(int id)37 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
38 int id) {
39 return make_scoped_refptr(new LayerAnimationController(id));
40 }
41
PauseAnimation(int animation_id,base::TimeDelta time_offset)42 void LayerAnimationController::PauseAnimation(int animation_id,
43 base::TimeDelta time_offset) {
44 for (size_t i = 0; i < animations_.size(); ++i) {
45 if (animations_[i]->id() == animation_id) {
46 animations_[i]->SetRunState(Animation::Paused,
47 time_offset + animations_[i]->start_time());
48 }
49 }
50 }
51
52 struct HasAnimationId {
HasAnimationIdcc::HasAnimationId53 explicit HasAnimationId(int id) : id_(id) {}
operator ()cc::HasAnimationId54 bool operator()(Animation* animation) const {
55 return animation->id() == id_;
56 }
57
58 private:
59 int id_;
60 };
61
RemoveAnimation(int animation_id)62 void LayerAnimationController::RemoveAnimation(int animation_id) {
63 animations_.erase(cc::remove_if(&animations_,
64 animations_.begin(),
65 animations_.end(),
66 HasAnimationId(animation_id)),
67 animations_.end());
68 UpdateActivation(NormalActivation);
69 }
70
71 struct HasAnimationIdAndProperty {
HasAnimationIdAndPropertycc::HasAnimationIdAndProperty72 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
73 : id_(id), target_property_(target_property) {}
operator ()cc::HasAnimationIdAndProperty74 bool operator()(Animation* animation) const {
75 return animation->id() == id_ &&
76 animation->target_property() == target_property_;
77 }
78
79 private:
80 int id_;
81 Animation::TargetProperty target_property_;
82 };
83
RemoveAnimation(int animation_id,Animation::TargetProperty target_property)84 void LayerAnimationController::RemoveAnimation(
85 int animation_id,
86 Animation::TargetProperty target_property) {
87 animations_.erase(
88 cc::remove_if(&animations_,
89 animations_.begin(),
90 animations_.end(),
91 HasAnimationIdAndProperty(animation_id, target_property)),
92 animations_.end());
93 UpdateActivation(NormalActivation);
94 }
95
AbortAnimations(Animation::TargetProperty target_property)96 void LayerAnimationController::AbortAnimations(
97 Animation::TargetProperty target_property) {
98 for (size_t i = 0; i < animations_.size(); ++i) {
99 if (animations_[i]->target_property() == target_property &&
100 !animations_[i]->is_finished())
101 animations_[i]->SetRunState(Animation::Aborted, last_tick_time_);
102 }
103 }
104
105 // Ensures that the list of active animations on the main thread and the impl
106 // thread are kept in sync.
PushAnimationUpdatesTo(LayerAnimationController * controller_impl)107 void LayerAnimationController::PushAnimationUpdatesTo(
108 LayerAnimationController* controller_impl) {
109 DCHECK(this != controller_impl);
110 if (!has_any_animation() && !controller_impl->has_any_animation())
111 return;
112 PurgeAnimationsMarkedForDeletion();
113 PushNewAnimationsToImplThread(controller_impl);
114
115 // Remove finished impl side animations only after pushing,
116 // and only after the animations are deleted on the main thread
117 // this insures we will never push an animation twice.
118 RemoveAnimationsCompletedOnMainThread(controller_impl);
119
120 PushPropertiesToImplThread(controller_impl);
121 controller_impl->UpdateActivation(NormalActivation);
122 UpdateActivation(NormalActivation);
123 }
124
Animate(base::TimeTicks monotonic_time)125 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
126 DCHECK(!monotonic_time.is_null());
127 if (!HasValueObserver())
128 return;
129
130 if (needs_to_start_animations_)
131 StartAnimations(monotonic_time);
132 TickAnimations(monotonic_time);
133 last_tick_time_ = monotonic_time;
134 }
135
AccumulatePropertyUpdates(base::TimeTicks monotonic_time,AnimationEventsVector * events)136 void LayerAnimationController::AccumulatePropertyUpdates(
137 base::TimeTicks monotonic_time,
138 AnimationEventsVector* events) {
139 if (!events)
140 return;
141
142 for (size_t i = 0; i < animations_.size(); ++i) {
143 Animation* animation = animations_[i];
144 if (!animation->is_impl_only())
145 continue;
146
147 double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time);
148 switch (animation->target_property()) {
149 case Animation::Opacity: {
150 AnimationEvent event(AnimationEvent::PropertyUpdate,
151 id_,
152 animation->group(),
153 Animation::Opacity,
154 monotonic_time);
155 event.opacity = animation->curve()->ToFloatAnimationCurve()->GetValue(
156 trimmed);
157 event.is_impl_only = true;
158 events->push_back(event);
159 break;
160 }
161
162 case Animation::Transform: {
163 AnimationEvent event(AnimationEvent::PropertyUpdate,
164 id_,
165 animation->group(),
166 Animation::Transform,
167 monotonic_time);
168 event.transform =
169 animation->curve()->ToTransformAnimationCurve()->GetValue(trimmed);
170 event.is_impl_only = true;
171 events->push_back(event);
172 break;
173 }
174
175 case Animation::Filter: {
176 AnimationEvent event(AnimationEvent::PropertyUpdate,
177 id_,
178 animation->group(),
179 Animation::Filter,
180 monotonic_time);
181 event.filters = animation->curve()->ToFilterAnimationCurve()->GetValue(
182 trimmed);
183 event.is_impl_only = true;
184 events->push_back(event);
185 break;
186 }
187
188 case Animation::BackgroundColor: { break; }
189
190 case Animation::ScrollOffset: {
191 // Impl-side changes to scroll offset are already sent back to the
192 // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
193 // isn't needed.
194 break;
195 }
196
197 case Animation::TargetPropertyEnumSize:
198 NOTREACHED();
199 }
200 }
201 }
202
UpdateState(bool start_ready_animations,AnimationEventsVector * events)203 void LayerAnimationController::UpdateState(bool start_ready_animations,
204 AnimationEventsVector* events) {
205 if (!HasActiveValueObserver())
206 return;
207
208 DCHECK(last_tick_time_ != base::TimeTicks());
209 if (start_ready_animations)
210 PromoteStartedAnimations(last_tick_time_, events);
211
212 MarkFinishedAnimations(last_tick_time_);
213 MarkAnimationsForDeletion(last_tick_time_, events);
214
215 if (needs_to_start_animations_ && start_ready_animations) {
216 StartAnimations(last_tick_time_);
217 PromoteStartedAnimations(last_tick_time_, events);
218 }
219
220 AccumulatePropertyUpdates(last_tick_time_, events);
221
222 UpdateActivation(NormalActivation);
223 }
224
225 struct AffectsNoObservers {
operator ()cc::AffectsNoObservers226 bool operator()(Animation* animation) const {
227 return !animation->affects_active_observers() &&
228 !animation->affects_pending_observers();
229 }
230 };
231
ActivateAnimations()232 void LayerAnimationController::ActivateAnimations() {
233 for (size_t i = 0; i < animations_.size(); ++i) {
234 animations_[i]->set_affects_active_observers(
235 animations_[i]->affects_pending_observers());
236 }
237 animations_.erase(cc::remove_if(&animations_,
238 animations_.begin(),
239 animations_.end(),
240 AffectsNoObservers()),
241 animations_.end());
242 UpdateActivation(NormalActivation);
243 }
244
AddAnimation(scoped_ptr<Animation> animation)245 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
246 animations_.push_back(animation.Pass());
247 needs_to_start_animations_ = true;
248 UpdateActivation(NormalActivation);
249 }
250
GetAnimation(int group_id,Animation::TargetProperty target_property) const251 Animation* LayerAnimationController::GetAnimation(
252 int group_id,
253 Animation::TargetProperty target_property) const {
254 for (size_t i = 0; i < animations_.size(); ++i)
255 if (animations_[i]->group() == group_id &&
256 animations_[i]->target_property() == target_property)
257 return animations_[i];
258 return 0;
259 }
260
GetAnimation(Animation::TargetProperty target_property) const261 Animation* LayerAnimationController::GetAnimation(
262 Animation::TargetProperty target_property) const {
263 for (size_t i = 0; i < animations_.size(); ++i) {
264 size_t index = animations_.size() - i - 1;
265 if (animations_[index]->target_property() == target_property)
266 return animations_[index];
267 }
268 return 0;
269 }
270
HasActiveAnimation() const271 bool LayerAnimationController::HasActiveAnimation() const {
272 for (size_t i = 0; i < animations_.size(); ++i) {
273 if (!animations_[i]->is_finished())
274 return true;
275 }
276 return false;
277 }
278
IsAnimatingProperty(Animation::TargetProperty target_property) const279 bool LayerAnimationController::IsAnimatingProperty(
280 Animation::TargetProperty target_property) const {
281 for (size_t i = 0; i < animations_.size(); ++i) {
282 if (!animations_[i]->is_finished() &&
283 animations_[i]->target_property() == target_property)
284 return true;
285 }
286 return false;
287 }
288
SetAnimationRegistrar(AnimationRegistrar * registrar)289 void LayerAnimationController::SetAnimationRegistrar(
290 AnimationRegistrar* registrar) {
291 if (registrar_ == registrar)
292 return;
293
294 if (registrar_)
295 registrar_->UnregisterAnimationController(this);
296
297 registrar_ = registrar;
298 if (registrar_)
299 registrar_->RegisterAnimationController(this);
300
301 UpdateActivation(ForceActivation);
302 }
303
NotifyAnimationStarted(const AnimationEvent & event)304 void LayerAnimationController::NotifyAnimationStarted(
305 const AnimationEvent& event) {
306 if (event.is_impl_only) {
307 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
308 OnAnimationStarted(event));
309 if (layer_animation_delegate_)
310 layer_animation_delegate_->NotifyAnimationStarted(event.monotonic_time,
311 event.target_property);
312 return;
313 }
314
315 for (size_t i = 0; i < animations_.size(); ++i) {
316 if (animations_[i]->group() == event.group_id &&
317 animations_[i]->target_property() == event.target_property &&
318 animations_[i]->needs_synchronized_start_time()) {
319 animations_[i]->set_needs_synchronized_start_time(false);
320 if (!animations_[i]->has_set_start_time())
321 animations_[i]->set_start_time(event.monotonic_time);
322
323 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
324 OnAnimationStarted(event));
325 if (layer_animation_delegate_)
326 layer_animation_delegate_->NotifyAnimationStarted(
327 event.monotonic_time, event.target_property);
328
329 return;
330 }
331 }
332 }
333
NotifyAnimationFinished(const AnimationEvent & event)334 void LayerAnimationController::NotifyAnimationFinished(
335 const AnimationEvent& event) {
336 if (event.is_impl_only) {
337 if (layer_animation_delegate_)
338 layer_animation_delegate_->NotifyAnimationFinished(event.monotonic_time,
339 event.target_property);
340 return;
341 }
342
343 for (size_t i = 0; i < animations_.size(); ++i) {
344 if (animations_[i]->group() == event.group_id &&
345 animations_[i]->target_property() == event.target_property) {
346 animations_[i]->set_received_finished_event(true);
347 if (layer_animation_delegate_)
348 layer_animation_delegate_->NotifyAnimationFinished(
349 event.monotonic_time, event.target_property);
350
351 return;
352 }
353 }
354 }
355
NotifyAnimationAborted(const AnimationEvent & event)356 void LayerAnimationController::NotifyAnimationAborted(
357 const AnimationEvent& event) {
358 for (size_t i = 0; i < animations_.size(); ++i) {
359 if (animations_[i]->group() == event.group_id &&
360 animations_[i]->target_property() == event.target_property) {
361 animations_[i]->SetRunState(Animation::Aborted, event.monotonic_time);
362 }
363 }
364 }
365
NotifyAnimationPropertyUpdate(const AnimationEvent & event)366 void LayerAnimationController::NotifyAnimationPropertyUpdate(
367 const AnimationEvent& event) {
368 bool notify_active_observers = true;
369 bool notify_pending_observers = true;
370 switch (event.target_property) {
371 case Animation::Opacity:
372 NotifyObserversOpacityAnimated(
373 event.opacity, notify_active_observers, notify_pending_observers);
374 break;
375 case Animation::Transform:
376 NotifyObserversTransformAnimated(
377 event.transform, notify_active_observers, notify_pending_observers);
378 break;
379 default:
380 NOTREACHED();
381 }
382 }
383
AddValueObserver(LayerAnimationValueObserver * observer)384 void LayerAnimationController::AddValueObserver(
385 LayerAnimationValueObserver* observer) {
386 if (!value_observers_.HasObserver(observer))
387 value_observers_.AddObserver(observer);
388 }
389
RemoveValueObserver(LayerAnimationValueObserver * observer)390 void LayerAnimationController::RemoveValueObserver(
391 LayerAnimationValueObserver* observer) {
392 value_observers_.RemoveObserver(observer);
393 }
394
AddEventObserver(LayerAnimationEventObserver * observer)395 void LayerAnimationController::AddEventObserver(
396 LayerAnimationEventObserver* observer) {
397 if (!event_observers_.HasObserver(observer))
398 event_observers_.AddObserver(observer);
399 }
400
RemoveEventObserver(LayerAnimationEventObserver * observer)401 void LayerAnimationController::RemoveEventObserver(
402 LayerAnimationEventObserver* observer) {
403 event_observers_.RemoveObserver(observer);
404 }
405
HasFilterAnimationThatInflatesBounds() const406 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
407 for (size_t i = 0; i < animations_.size(); ++i) {
408 if (!animations_[i]->is_finished() &&
409 animations_[i]->target_property() == Animation::Filter &&
410 animations_[i]
411 ->curve()
412 ->ToFilterAnimationCurve()
413 ->HasFilterThatMovesPixels())
414 return true;
415 }
416
417 return false;
418 }
419
HasTransformAnimationThatInflatesBounds() const420 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
421 return IsAnimatingProperty(Animation::Transform);
422 }
423
FilterAnimationBoundsForBox(const gfx::BoxF & box,gfx::BoxF * bounds) const424 bool LayerAnimationController::FilterAnimationBoundsForBox(
425 const gfx::BoxF& box, gfx::BoxF* bounds) const {
426 // TODO(avallee): Implement.
427 return false;
428 }
429
TransformAnimationBoundsForBox(const gfx::BoxF & box,gfx::BoxF * bounds) const430 bool LayerAnimationController::TransformAnimationBoundsForBox(
431 const gfx::BoxF& box,
432 gfx::BoxF* bounds) const {
433 DCHECK(HasTransformAnimationThatInflatesBounds())
434 << "TransformAnimationBoundsForBox will give incorrect results if there "
435 << "are no transform animations affecting bounds, non-animated transform "
436 << "is not known";
437
438 // Compute bounds based on animations for which is_finished() is false.
439 // Do nothing if there are no such animations; in this case, it is assumed
440 // that callers will take care of computing bounds based on the owning layer's
441 // actual transform.
442 *bounds = gfx::BoxF();
443 for (size_t i = 0; i < animations_.size(); ++i) {
444 if (animations_[i]->is_finished() ||
445 animations_[i]->target_property() != Animation::Transform)
446 continue;
447
448 const TransformAnimationCurve* transform_animation_curve =
449 animations_[i]->curve()->ToTransformAnimationCurve();
450 gfx::BoxF animation_bounds;
451 bool success =
452 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
453 if (!success)
454 return false;
455 bounds->Union(animation_bounds);
456 }
457
458 return true;
459 }
460
HasAnimationThatAffectsScale() const461 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
462 for (size_t i = 0; i < animations_.size(); ++i) {
463 if (animations_[i]->is_finished() ||
464 animations_[i]->target_property() != Animation::Transform)
465 continue;
466
467 const TransformAnimationCurve* transform_animation_curve =
468 animations_[i]->curve()->ToTransformAnimationCurve();
469 if (transform_animation_curve->AffectsScale())
470 return true;
471 }
472
473 return false;
474 }
475
HasOnlyTranslationTransforms() const476 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
477 for (size_t i = 0; i < animations_.size(); ++i) {
478 if (animations_[i]->is_finished() ||
479 animations_[i]->target_property() != Animation::Transform)
480 continue;
481
482 const TransformAnimationCurve* transform_animation_curve =
483 animations_[i]->curve()->ToTransformAnimationCurve();
484 if (!transform_animation_curve->IsTranslation())
485 return false;
486 }
487
488 return true;
489 }
490
MaximumScale(float * max_scale) const491 bool LayerAnimationController::MaximumScale(float* max_scale) const {
492 *max_scale = 0.f;
493 for (size_t i = 0; i < animations_.size(); ++i) {
494 if (animations_[i]->is_finished() ||
495 animations_[i]->target_property() != Animation::Transform)
496 continue;
497
498 const TransformAnimationCurve* transform_animation_curve =
499 animations_[i]->curve()->ToTransformAnimationCurve();
500 float animation_scale = 0.f;
501 if (!transform_animation_curve->MaximumScale(&animation_scale))
502 return false;
503 *max_scale = std::max(*max_scale, animation_scale);
504 }
505
506 return true;
507 }
508
PushNewAnimationsToImplThread(LayerAnimationController * controller_impl) const509 void LayerAnimationController::PushNewAnimationsToImplThread(
510 LayerAnimationController* controller_impl) const {
511 // Any new animations owned by the main thread's controller are cloned and
512 // add to the impl thread's controller.
513 for (size_t i = 0; i < animations_.size(); ++i) {
514 // If the animation is already running on the impl thread, there is no
515 // need to copy it over.
516 if (controller_impl->GetAnimation(animations_[i]->group(),
517 animations_[i]->target_property()))
518 continue;
519
520 // If the animation is not running on the impl thread, it does not
521 // necessarily mean that it needs to be copied over and started; it may
522 // have already finished. In this case, the impl thread animation will
523 // have already notified that it has started and the main thread animation
524 // will no longer need
525 // a synchronized start time.
526 if (!animations_[i]->needs_synchronized_start_time())
527 continue;
528
529 // Scroll animations always start at the current scroll offset.
530 if (animations_[i]->target_property() == Animation::ScrollOffset) {
531 gfx::Vector2dF current_scroll_offset;
532 if (controller_impl->value_provider_) {
533 current_scroll_offset =
534 controller_impl->value_provider_->ScrollOffsetForAnimation();
535 } else {
536 // The owning layer isn't yet in the active tree, so the main thread
537 // scroll offset will be up-to-date.
538 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
539 }
540 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
541 current_scroll_offset);
542 }
543
544 // The new animation should be set to run as soon as possible.
545 Animation::RunState initial_run_state =
546 Animation::WaitingForTargetAvailability;
547 scoped_ptr<Animation> to_add(
548 animations_[i]->CloneAndInitialize(initial_run_state));
549 DCHECK(!to_add->needs_synchronized_start_time());
550 to_add->set_affects_active_observers(false);
551 controller_impl->AddAnimation(to_add.Pass());
552 }
553 }
554
IsCompleted(Animation * animation,const LayerAnimationController * main_thread_controller)555 static bool IsCompleted(
556 Animation* animation,
557 const LayerAnimationController* main_thread_controller) {
558 if (animation->is_impl_only()) {
559 return (animation->run_state() == Animation::WaitingForDeletion);
560 } else {
561 return !main_thread_controller->GetAnimation(animation->group(),
562 animation->target_property());
563 }
564 }
565
AffectsActiveOnlyAndIsWaitingForDeletion(Animation * animation)566 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
567 return animation->run_state() == Animation::WaitingForDeletion &&
568 !animation->affects_pending_observers();
569 }
570
RemoveAnimationsCompletedOnMainThread(LayerAnimationController * controller_impl) const571 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
572 LayerAnimationController* controller_impl) const {
573 // Animations removed on the main thread should no longer affect pending
574 // observers, and should stop affecting active observers after the next call
575 // to ActivateAnimations. If already WaitingForDeletion, they can be removed
576 // immediately.
577 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
578 for (size_t i = 0; i < animations.size(); ++i) {
579 if (IsCompleted(animations[i], this))
580 animations[i]->set_affects_pending_observers(false);
581 }
582 animations.erase(cc::remove_if(&animations,
583 animations.begin(),
584 animations.end(),
585 AffectsActiveOnlyAndIsWaitingForDeletion),
586 animations.end());
587 }
588
PushPropertiesToImplThread(LayerAnimationController * controller_impl) const589 void LayerAnimationController::PushPropertiesToImplThread(
590 LayerAnimationController* controller_impl) const {
591 for (size_t i = 0; i < animations_.size(); ++i) {
592 Animation* current_impl = controller_impl->GetAnimation(
593 animations_[i]->group(), animations_[i]->target_property());
594 if (current_impl)
595 animations_[i]->PushPropertiesTo(current_impl);
596 }
597 }
598
StartAnimations(base::TimeTicks monotonic_time)599 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
600 DCHECK(needs_to_start_animations_);
601 needs_to_start_animations_ = false;
602 // First collect running properties affecting each type of observer.
603 TargetProperties blocked_properties_for_active_observers;
604 TargetProperties blocked_properties_for_pending_observers;
605 for (size_t i = 0; i < animations_.size(); ++i) {
606 if (animations_[i]->run_state() == Animation::Starting ||
607 animations_[i]->run_state() == Animation::Running) {
608 if (animations_[i]->affects_active_observers()) {
609 blocked_properties_for_active_observers.insert(
610 animations_[i]->target_property());
611 }
612 if (animations_[i]->affects_pending_observers()) {
613 blocked_properties_for_pending_observers.insert(
614 animations_[i]->target_property());
615 }
616 }
617 }
618
619 for (size_t i = 0; i < animations_.size(); ++i) {
620 if (animations_[i]->run_state() ==
621 Animation::WaitingForTargetAvailability) {
622 // Collect all properties for animations with the same group id (they
623 // should all also be in the list of animations).
624 TargetProperties enqueued_properties;
625 bool affects_active_observers =
626 animations_[i]->affects_active_observers();
627 bool affects_pending_observers =
628 animations_[i]->affects_pending_observers();
629 enqueued_properties.insert(animations_[i]->target_property());
630 for (size_t j = i + 1; j < animations_.size(); ++j) {
631 if (animations_[i]->group() == animations_[j]->group()) {
632 enqueued_properties.insert(animations_[j]->target_property());
633 affects_active_observers |=
634 animations_[j]->affects_active_observers();
635 affects_pending_observers |=
636 animations_[j]->affects_pending_observers();
637 }
638 }
639
640 // Check to see if intersection of the list of properties affected by
641 // the group and the list of currently blocked properties is null, taking
642 // into account the type(s) of observers affected by the group. In any
643 // case, the group's target properties need to be added to the lists of
644 // blocked properties.
645 bool null_intersection = true;
646 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
647 p_iter != enqueued_properties.end();
648 ++p_iter) {
649 if (affects_active_observers &&
650 !blocked_properties_for_active_observers.insert(*p_iter).second)
651 null_intersection = false;
652 if (affects_pending_observers &&
653 !blocked_properties_for_pending_observers.insert(*p_iter).second)
654 null_intersection = false;
655 }
656
657 // If the intersection is null, then we are free to start the animations
658 // in the group.
659 if (null_intersection) {
660 animations_[i]->SetRunState(Animation::Starting, monotonic_time);
661 for (size_t j = i + 1; j < animations_.size(); ++j) {
662 if (animations_[i]->group() == animations_[j]->group()) {
663 animations_[j]->SetRunState(Animation::Starting, monotonic_time);
664 }
665 }
666 } else {
667 needs_to_start_animations_ = true;
668 }
669 }
670 }
671 }
672
PromoteStartedAnimations(base::TimeTicks monotonic_time,AnimationEventsVector * events)673 void LayerAnimationController::PromoteStartedAnimations(
674 base::TimeTicks monotonic_time,
675 AnimationEventsVector* events) {
676 for (size_t i = 0; i < animations_.size(); ++i) {
677 if (animations_[i]->run_state() == Animation::Starting &&
678 animations_[i]->affects_active_observers()) {
679 animations_[i]->SetRunState(Animation::Running, monotonic_time);
680 if (!animations_[i]->has_set_start_time() &&
681 !animations_[i]->needs_synchronized_start_time())
682 animations_[i]->set_start_time(monotonic_time);
683 if (events) {
684 AnimationEvent started_event(AnimationEvent::Started,
685 id_,
686 animations_[i]->group(),
687 animations_[i]->target_property(),
688 monotonic_time);
689 started_event.is_impl_only = animations_[i]->is_impl_only();
690 events->push_back(started_event);
691 }
692 }
693 }
694 }
695
MarkFinishedAnimations(base::TimeTicks monotonic_time)696 void LayerAnimationController::MarkFinishedAnimations(
697 base::TimeTicks monotonic_time) {
698 for (size_t i = 0; i < animations_.size(); ++i) {
699 if (animations_[i]->IsFinishedAt(monotonic_time) &&
700 animations_[i]->run_state() != Animation::Aborted &&
701 animations_[i]->run_state() != Animation::WaitingForDeletion)
702 animations_[i]->SetRunState(Animation::Finished, monotonic_time);
703 }
704 }
705
MarkAnimationsForDeletion(base::TimeTicks monotonic_time,AnimationEventsVector * events)706 void LayerAnimationController::MarkAnimationsForDeletion(
707 base::TimeTicks monotonic_time,
708 AnimationEventsVector* events) {
709 bool marked_animations_for_deletions = false;
710
711 // Non-aborted animations are marked for deletion after a corresponding
712 // AnimationEvent::Finished event is sent or received. This means that if
713 // we don't have an events vector, we must ensure that non-aborted animations
714 // have received a finished event before marking them for deletion.
715 for (size_t i = 0; i < animations_.size(); i++) {
716 int group_id = animations_[i]->group();
717 if (animations_[i]->run_state() == Animation::Aborted) {
718 if (events && !animations_[i]->is_impl_only()) {
719 AnimationEvent aborted_event(AnimationEvent::Aborted,
720 id_,
721 group_id,
722 animations_[i]->target_property(),
723 monotonic_time);
724 events->push_back(aborted_event);
725 }
726 animations_[i]->SetRunState(Animation::WaitingForDeletion,
727 monotonic_time);
728 marked_animations_for_deletions = true;
729 continue;
730 }
731
732 bool all_anims_with_same_id_are_finished = false;
733
734 // Since deleting an animation on the main thread leads to its deletion
735 // on the impl thread, we only mark a Finished main thread animation for
736 // deletion once it has received a Finished event from the impl thread.
737 bool animation_i_will_send_or_has_received_finish_event =
738 events || animations_[i]->received_finished_event();
739 // If an animation is finished, and not already marked for deletion,
740 // find out if all other animations in the same group are also finished.
741 if (animations_[i]->run_state() == Animation::Finished &&
742 animation_i_will_send_or_has_received_finish_event) {
743 all_anims_with_same_id_are_finished = true;
744 for (size_t j = 0; j < animations_.size(); ++j) {
745 bool animation_j_will_send_or_has_received_finish_event =
746 events || animations_[j]->received_finished_event();
747 if (group_id == animations_[j]->group() &&
748 (!animations_[j]->is_finished() ||
749 (animations_[j]->run_state() == Animation::Finished &&
750 !animation_j_will_send_or_has_received_finish_event))) {
751 all_anims_with_same_id_are_finished = false;
752 break;
753 }
754 }
755 }
756 if (all_anims_with_same_id_are_finished) {
757 // We now need to remove all animations with the same group id as
758 // group_id (and send along animation finished notifications, if
759 // necessary).
760 for (size_t j = i; j < animations_.size(); j++) {
761 if (animations_[j]->group() == group_id &&
762 animations_[j]->run_state() != Animation::Aborted) {
763 if (events) {
764 AnimationEvent finished_event(AnimationEvent::Finished,
765 id_,
766 animations_[j]->group(),
767 animations_[j]->target_property(),
768 monotonic_time);
769 finished_event.is_impl_only = animations_[j]->is_impl_only();
770 events->push_back(finished_event);
771 }
772 animations_[j]->SetRunState(Animation::WaitingForDeletion,
773 monotonic_time);
774 }
775 }
776 marked_animations_for_deletions = true;
777 }
778 }
779 if (marked_animations_for_deletions)
780 NotifyObserversAnimationWaitingForDeletion();
781 }
782
IsWaitingForDeletion(Animation * animation)783 static bool IsWaitingForDeletion(Animation* animation) {
784 return animation->run_state() == Animation::WaitingForDeletion;
785 }
786
PurgeAnimationsMarkedForDeletion()787 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
788 animations_.erase(cc::remove_if(&animations_,
789 animations_.begin(),
790 animations_.end(),
791 IsWaitingForDeletion),
792 animations_.end());
793 }
794
TickAnimations(base::TimeTicks monotonic_time)795 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
796 for (size_t i = 0; i < animations_.size(); ++i) {
797 if (animations_[i]->run_state() == Animation::Starting ||
798 animations_[i]->run_state() == Animation::Running ||
799 animations_[i]->run_state() == Animation::Paused) {
800 double trimmed =
801 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
802
803 switch (animations_[i]->target_property()) {
804 case Animation::Transform: {
805 const TransformAnimationCurve* transform_animation_curve =
806 animations_[i]->curve()->ToTransformAnimationCurve();
807 const gfx::Transform transform =
808 transform_animation_curve->GetValue(trimmed);
809 NotifyObserversTransformAnimated(
810 transform,
811 animations_[i]->affects_active_observers(),
812 animations_[i]->affects_pending_observers());
813 break;
814 }
815
816 case Animation::Opacity: {
817 const FloatAnimationCurve* float_animation_curve =
818 animations_[i]->curve()->ToFloatAnimationCurve();
819 const float opacity = float_animation_curve->GetValue(trimmed);
820 NotifyObserversOpacityAnimated(
821 opacity,
822 animations_[i]->affects_active_observers(),
823 animations_[i]->affects_pending_observers());
824 break;
825 }
826
827 case Animation::Filter: {
828 const FilterAnimationCurve* filter_animation_curve =
829 animations_[i]->curve()->ToFilterAnimationCurve();
830 const FilterOperations filter =
831 filter_animation_curve->GetValue(trimmed);
832 NotifyObserversFilterAnimated(
833 filter,
834 animations_[i]->affects_active_observers(),
835 animations_[i]->affects_pending_observers());
836 break;
837 }
838
839 case Animation::BackgroundColor: {
840 // Not yet implemented.
841 break;
842 }
843
844 case Animation::ScrollOffset: {
845 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
846 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
847 const gfx::Vector2dF scroll_offset =
848 scroll_offset_animation_curve->GetValue(trimmed);
849 NotifyObserversScrollOffsetAnimated(
850 scroll_offset,
851 animations_[i]->affects_active_observers(),
852 animations_[i]->affects_pending_observers());
853 break;
854 }
855
856 // Do nothing for sentinel value.
857 case Animation::TargetPropertyEnumSize:
858 NOTREACHED();
859 }
860 }
861 }
862 }
863
UpdateActivation(UpdateActivationType type)864 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
865 bool force = type == ForceActivation;
866 if (registrar_) {
867 bool was_active = is_active_;
868 is_active_ = false;
869 for (size_t i = 0; i < animations_.size(); ++i) {
870 if (animations_[i]->run_state() != Animation::WaitingForDeletion) {
871 is_active_ = true;
872 break;
873 }
874 }
875
876 if (is_active_ && (!was_active || force))
877 registrar_->DidActivateAnimationController(this);
878 else if (!is_active_ && (was_active || force))
879 registrar_->DidDeactivateAnimationController(this);
880 }
881 }
882
NotifyObserversOpacityAnimated(float opacity,bool notify_active_observers,bool notify_pending_observers)883 void LayerAnimationController::NotifyObserversOpacityAnimated(
884 float opacity,
885 bool notify_active_observers,
886 bool notify_pending_observers) {
887 if (value_observers_.might_have_observers()) {
888 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
889 value_observers_);
890 LayerAnimationValueObserver* obs;
891 while ((obs = it.GetNext()) != NULL) {
892 if ((notify_active_observers && obs->IsActive()) ||
893 (notify_pending_observers && !obs->IsActive()))
894 obs->OnOpacityAnimated(opacity);
895 }
896 }
897 }
898
NotifyObserversTransformAnimated(const gfx::Transform & transform,bool notify_active_observers,bool notify_pending_observers)899 void LayerAnimationController::NotifyObserversTransformAnimated(
900 const gfx::Transform& transform,
901 bool notify_active_observers,
902 bool notify_pending_observers) {
903 if (value_observers_.might_have_observers()) {
904 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
905 value_observers_);
906 LayerAnimationValueObserver* obs;
907 while ((obs = it.GetNext()) != NULL) {
908 if ((notify_active_observers && obs->IsActive()) ||
909 (notify_pending_observers && !obs->IsActive()))
910 obs->OnTransformAnimated(transform);
911 }
912 }
913 }
914
NotifyObserversFilterAnimated(const FilterOperations & filters,bool notify_active_observers,bool notify_pending_observers)915 void LayerAnimationController::NotifyObserversFilterAnimated(
916 const FilterOperations& filters,
917 bool notify_active_observers,
918 bool notify_pending_observers) {
919 if (value_observers_.might_have_observers()) {
920 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
921 value_observers_);
922 LayerAnimationValueObserver* obs;
923 while ((obs = it.GetNext()) != NULL) {
924 if ((notify_active_observers && obs->IsActive()) ||
925 (notify_pending_observers && !obs->IsActive()))
926 obs->OnFilterAnimated(filters);
927 }
928 }
929 }
930
NotifyObserversScrollOffsetAnimated(const gfx::Vector2dF & scroll_offset,bool notify_active_observers,bool notify_pending_observers)931 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
932 const gfx::Vector2dF& scroll_offset,
933 bool notify_active_observers,
934 bool notify_pending_observers) {
935 if (value_observers_.might_have_observers()) {
936 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
937 value_observers_);
938 LayerAnimationValueObserver* obs;
939 while ((obs = it.GetNext()) != NULL) {
940 if ((notify_active_observers && obs->IsActive()) ||
941 (notify_pending_observers && !obs->IsActive()))
942 obs->OnScrollOffsetAnimated(scroll_offset);
943 }
944 }
945 }
946
NotifyObserversAnimationWaitingForDeletion()947 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
948 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
949 value_observers_,
950 OnAnimationWaitingForDeletion());
951 }
952
HasValueObserver()953 bool LayerAnimationController::HasValueObserver() {
954 if (value_observers_.might_have_observers()) {
955 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
956 value_observers_);
957 return it.GetNext() != NULL;
958 }
959 return false;
960 }
961
HasActiveValueObserver()962 bool LayerAnimationController::HasActiveValueObserver() {
963 if (value_observers_.might_have_observers()) {
964 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
965 value_observers_);
966 LayerAnimationValueObserver* obs;
967 while ((obs = it.GetNext()) != NULL)
968 if (obs->IsActive())
969 return true;
970 }
971 return false;
972 }
973
974 } // namespace cc
975