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 23 LayerAnimationController::LayerAnimationController(int id) 24 : registrar_(0), 25 id_(id), 26 is_active_(false), 27 last_tick_time_(0), 28 value_provider_(NULL), 29 layer_animation_delegate_(NULL) {} 30 31 LayerAnimationController::~LayerAnimationController() { 32 if (registrar_) 33 registrar_->UnregisterAnimationController(this); 34 } 35 36 scoped_refptr<LayerAnimationController> LayerAnimationController::Create( 37 int id) { 38 return make_scoped_refptr(new LayerAnimationController(id)); 39 } 40 41 void LayerAnimationController::PauseAnimation(int animation_id, 42 double time_offset) { 43 for (size_t i = 0; i < active_animations_.size(); ++i) { 44 if (active_animations_[i]->id() == animation_id) { 45 active_animations_[i]->SetRunState( 46 Animation::Paused, time_offset + active_animations_[i]->start_time()); 47 } 48 } 49 } 50 51 struct HasAnimationId { 52 explicit HasAnimationId(int id) : id_(id) {} 53 bool operator()(Animation* animation) const { 54 return animation->id() == id_; 55 } 56 57 private: 58 int id_; 59 }; 60 61 void LayerAnimationController::RemoveAnimation(int animation_id) { 62 ScopedPtrVector<Animation>& animations = active_animations_; 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 { 72 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property) 73 : id_(id), target_property_(target_property) {} 74 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 84 void LayerAnimationController::RemoveAnimation( 85 int animation_id, 86 Animation::TargetProperty target_property) { 87 ScopedPtrVector<Animation>& animations = active_animations_; 88 animations.erase( 89 cc::remove_if(&animations, 90 animations.begin(), 91 animations.end(), 92 HasAnimationIdAndProperty(animation_id, target_property)), 93 animations.end()); 94 UpdateActivation(NormalActivation); 95 } 96 97 void LayerAnimationController::AbortAnimations( 98 Animation::TargetProperty target_property) { 99 for (size_t i = 0; i < active_animations_.size(); ++i) { 100 if (active_animations_[i]->target_property() == target_property && 101 !active_animations_[i]->is_finished()) 102 active_animations_[i]->SetRunState(Animation::Aborted, last_tick_time_); 103 } 104 } 105 106 // Ensures that the list of active animations on the main thread and the impl 107 // thread are kept in sync. 108 void LayerAnimationController::PushAnimationUpdatesTo( 109 LayerAnimationController* controller_impl) { 110 DCHECK(this != controller_impl); 111 if (!has_any_animation() && !controller_impl->has_any_animation()) 112 return; 113 PurgeAnimationsMarkedForDeletion(); 114 PushNewAnimationsToImplThread(controller_impl); 115 116 // Remove finished impl side animations only after pushing, 117 // and only after the animations are deleted on the main thread 118 // this insures we will never push an animation twice. 119 RemoveAnimationsCompletedOnMainThread(controller_impl); 120 121 PushPropertiesToImplThread(controller_impl); 122 controller_impl->UpdateActivation(NormalActivation); 123 UpdateActivation(NormalActivation); 124 } 125 126 void LayerAnimationController::Animate(double monotonic_time) { 127 DCHECK(monotonic_time); 128 if (!HasValueObserver()) 129 return; 130 131 StartAnimations(monotonic_time); 132 TickAnimations(monotonic_time); 133 last_tick_time_ = monotonic_time; 134 } 135 136 void LayerAnimationController::AccumulatePropertyUpdates( 137 double monotonic_time, 138 AnimationEventsVector* events) { 139 if (!events) 140 return; 141 142 for (size_t i = 0; i < active_animations_.size(); ++i) { 143 Animation* animation = active_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 203 void LayerAnimationController::UpdateState(bool start_ready_animations, 204 AnimationEventsVector* events) { 205 if (!HasActiveValueObserver()) 206 return; 207 208 if (start_ready_animations) 209 PromoteStartedAnimations(last_tick_time_, events); 210 211 MarkFinishedAnimations(last_tick_time_); 212 MarkAnimationsForDeletion(last_tick_time_, events); 213 214 if (start_ready_animations) { 215 StartAnimations(last_tick_time_); 216 PromoteStartedAnimations(last_tick_time_, events); 217 } 218 219 AccumulatePropertyUpdates(last_tick_time_, events); 220 221 UpdateActivation(NormalActivation); 222 } 223 224 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) { 225 active_animations_.push_back(animation.Pass()); 226 UpdateActivation(NormalActivation); 227 } 228 229 Animation* LayerAnimationController::GetAnimation( 230 int group_id, 231 Animation::TargetProperty target_property) const { 232 for (size_t i = 0; i < active_animations_.size(); ++i) 233 if (active_animations_[i]->group() == group_id && 234 active_animations_[i]->target_property() == target_property) 235 return active_animations_[i]; 236 return 0; 237 } 238 239 Animation* LayerAnimationController::GetAnimation( 240 Animation::TargetProperty target_property) const { 241 for (size_t i = 0; i < active_animations_.size(); ++i) { 242 size_t index = active_animations_.size() - i - 1; 243 if (active_animations_[index]->target_property() == target_property) 244 return active_animations_[index]; 245 } 246 return 0; 247 } 248 249 bool LayerAnimationController::HasActiveAnimation() const { 250 for (size_t i = 0; i < active_animations_.size(); ++i) { 251 if (!active_animations_[i]->is_finished()) 252 return true; 253 } 254 return false; 255 } 256 257 bool LayerAnimationController::IsAnimatingProperty( 258 Animation::TargetProperty target_property) const { 259 for (size_t i = 0; i < active_animations_.size(); ++i) { 260 if (!active_animations_[i]->is_finished() && 261 active_animations_[i]->target_property() == target_property) 262 return true; 263 } 264 return false; 265 } 266 267 void LayerAnimationController::SetAnimationRegistrar( 268 AnimationRegistrar* registrar) { 269 if (registrar_ == registrar) 270 return; 271 272 if (registrar_) 273 registrar_->UnregisterAnimationController(this); 274 275 registrar_ = registrar; 276 if (registrar_) 277 registrar_->RegisterAnimationController(this); 278 279 UpdateActivation(ForceActivation); 280 } 281 282 void LayerAnimationController::NotifyAnimationStarted( 283 const AnimationEvent& event, 284 double wall_clock_time) { 285 base::TimeTicks monotonic_time = base::TimeTicks::FromInternalValue( 286 event.monotonic_time * base::Time::kMicrosecondsPerSecond); 287 if (event.is_impl_only) { 288 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_, 289 OnAnimationStarted(event)); 290 if (layer_animation_delegate_) 291 layer_animation_delegate_->NotifyAnimationStarted( 292 wall_clock_time, monotonic_time, event.target_property); 293 294 return; 295 } 296 297 for (size_t i = 0; i < active_animations_.size(); ++i) { 298 if (active_animations_[i]->group() == event.group_id && 299 active_animations_[i]->target_property() == event.target_property && 300 active_animations_[i]->needs_synchronized_start_time()) { 301 active_animations_[i]->set_needs_synchronized_start_time(false); 302 active_animations_[i]->set_start_time(event.monotonic_time); 303 304 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_, 305 OnAnimationStarted(event)); 306 if (layer_animation_delegate_) 307 layer_animation_delegate_->NotifyAnimationStarted( 308 wall_clock_time, monotonic_time, event.target_property); 309 310 return; 311 } 312 } 313 } 314 315 void LayerAnimationController::NotifyAnimationFinished( 316 const AnimationEvent& event, 317 double wall_clock_time) { 318 base::TimeTicks monotonic_time = base::TimeTicks::FromInternalValue( 319 event.monotonic_time * base::Time::kMicrosecondsPerSecond); 320 if (event.is_impl_only) { 321 if (layer_animation_delegate_) 322 layer_animation_delegate_->NotifyAnimationFinished( 323 wall_clock_time, monotonic_time, event.target_property); 324 return; 325 } 326 327 for (size_t i = 0; i < active_animations_.size(); ++i) { 328 if (active_animations_[i]->group() == event.group_id && 329 active_animations_[i]->target_property() == event.target_property) { 330 active_animations_[i]->set_received_finished_event(true); 331 if (layer_animation_delegate_) 332 layer_animation_delegate_->NotifyAnimationFinished( 333 wall_clock_time, monotonic_time, event.target_property); 334 335 return; 336 } 337 } 338 } 339 340 void LayerAnimationController::NotifyAnimationAborted( 341 const AnimationEvent& event) { 342 for (size_t i = 0; i < active_animations_.size(); ++i) { 343 if (active_animations_[i]->group() == event.group_id && 344 active_animations_[i]->target_property() == event.target_property) { 345 active_animations_[i]->SetRunState(Animation::Aborted, 346 event.monotonic_time); 347 } 348 } 349 } 350 351 void LayerAnimationController::NotifyAnimationPropertyUpdate( 352 const AnimationEvent& event) { 353 switch (event.target_property) { 354 case Animation::Opacity: 355 NotifyObserversOpacityAnimated(event.opacity); 356 break; 357 case Animation::Transform: 358 NotifyObserversTransformAnimated(event.transform); 359 break; 360 default: 361 NOTREACHED(); 362 } 363 } 364 365 void LayerAnimationController::AddValueObserver( 366 LayerAnimationValueObserver* observer) { 367 if (!value_observers_.HasObserver(observer)) 368 value_observers_.AddObserver(observer); 369 } 370 371 void LayerAnimationController::RemoveValueObserver( 372 LayerAnimationValueObserver* observer) { 373 value_observers_.RemoveObserver(observer); 374 } 375 376 void LayerAnimationController::AddEventObserver( 377 LayerAnimationEventObserver* observer) { 378 if (!event_observers_.HasObserver(observer)) 379 event_observers_.AddObserver(observer); 380 } 381 382 void LayerAnimationController::RemoveEventObserver( 383 LayerAnimationEventObserver* observer) { 384 event_observers_.RemoveObserver(observer); 385 } 386 387 bool LayerAnimationController::AnimatedBoundsForBox(const gfx::BoxF& box, 388 gfx::BoxF* bounds) { 389 // Compute bounds based on animations for which is_finished() is false. 390 // Do nothing if there are no such animations; in this case, it is assumed 391 // that callers will take care of computing bounds based on the owning layer's 392 // actual transform. 393 *bounds = gfx::BoxF(); 394 for (size_t i = 0; i < active_animations_.size(); ++i) { 395 if (active_animations_[i]->is_finished() || 396 active_animations_[i]->target_property() != Animation::Transform) 397 continue; 398 399 const TransformAnimationCurve* transform_animation_curve = 400 active_animations_[i]->curve()->ToTransformAnimationCurve(); 401 gfx::BoxF animation_bounds; 402 bool success = 403 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds); 404 if (!success) 405 return false; 406 bounds->Union(animation_bounds); 407 } 408 409 return true; 410 } 411 412 void LayerAnimationController::PushNewAnimationsToImplThread( 413 LayerAnimationController* controller_impl) const { 414 // Any new animations owned by the main thread's controller are cloned and 415 // add to the impl thread's controller. 416 for (size_t i = 0; i < active_animations_.size(); ++i) { 417 // If the animation is already running on the impl thread, there is no 418 // need to copy it over. 419 if (controller_impl->GetAnimation(active_animations_[i]->group(), 420 active_animations_[i]->target_property())) 421 continue; 422 423 // If the animation is not running on the impl thread, it does not 424 // necessarily mean that it needs to be copied over and started; it may 425 // have already finished. In this case, the impl thread animation will 426 // have already notified that it has started and the main thread animation 427 // will no longer need 428 // a synchronized start time. 429 if (!active_animations_[i]->needs_synchronized_start_time()) 430 continue; 431 432 // Scroll animations always start at the current scroll offset. 433 if (active_animations_[i]->target_property() == Animation::ScrollOffset) { 434 gfx::Vector2dF current_scroll_offset; 435 if (controller_impl->value_provider_) { 436 current_scroll_offset = 437 controller_impl->value_provider_->ScrollOffsetForAnimation(); 438 } else { 439 // The owning layer isn't yet in the active tree, so the main thread 440 // scroll offset will be up-to-date. 441 current_scroll_offset = value_provider_->ScrollOffsetForAnimation(); 442 } 443 active_animations_[i]->curve()->ToScrollOffsetAnimationCurve() 444 ->SetInitialValue(current_scroll_offset); 445 } 446 447 // The new animation should be set to run as soon as possible. 448 Animation::RunState initial_run_state = 449 Animation::WaitingForTargetAvailability; 450 double start_time = 0; 451 scoped_ptr<Animation> to_add(active_animations_[i]->CloneAndInitialize( 452 initial_run_state, start_time)); 453 DCHECK(!to_add->needs_synchronized_start_time()); 454 controller_impl->AddAnimation(to_add.Pass()); 455 } 456 } 457 458 struct IsCompleted { 459 explicit IsCompleted(const LayerAnimationController& main_thread_controller) 460 : main_thread_controller_(main_thread_controller) {} 461 bool operator()(Animation* animation) const { 462 if (animation->is_impl_only()) { 463 return (animation->run_state() == Animation::WaitingForDeletion); 464 } else { 465 return !main_thread_controller_.GetAnimation( 466 animation->group(), 467 animation->target_property()); 468 } 469 } 470 471 private: 472 const LayerAnimationController& main_thread_controller_; 473 }; 474 475 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread( 476 LayerAnimationController* controller_impl) const { 477 // Delete all impl thread animations for which there is no corresponding 478 // main thread animation. Each iteration, 479 // controller->active_animations_.size() is decremented or i is incremented 480 // guaranteeing progress towards loop termination. 481 ScopedPtrVector<Animation>& animations = 482 controller_impl->active_animations_; 483 animations.erase(cc::remove_if(&animations, 484 animations.begin(), 485 animations.end(), 486 IsCompleted(*this)), 487 animations.end()); 488 } 489 490 void LayerAnimationController::PushPropertiesToImplThread( 491 LayerAnimationController* controller_impl) const { 492 for (size_t i = 0; i < active_animations_.size(); ++i) { 493 Animation* current_impl = 494 controller_impl->GetAnimation( 495 active_animations_[i]->group(), 496 active_animations_[i]->target_property()); 497 if (current_impl) 498 active_animations_[i]->PushPropertiesTo(current_impl); 499 } 500 } 501 502 void LayerAnimationController::StartAnimations(double monotonic_time) { 503 // First collect running properties. 504 TargetProperties blocked_properties; 505 for (size_t i = 0; i < active_animations_.size(); ++i) { 506 if (active_animations_[i]->run_state() == Animation::Starting || 507 active_animations_[i]->run_state() == Animation::Running) 508 blocked_properties.insert(active_animations_[i]->target_property()); 509 } 510 511 for (size_t i = 0; i < active_animations_.size(); ++i) { 512 if (active_animations_[i]->run_state() == 513 Animation::WaitingForTargetAvailability) { 514 // Collect all properties for animations with the same group id (they 515 // should all also be in the list of animations). 516 TargetProperties enqueued_properties; 517 enqueued_properties.insert(active_animations_[i]->target_property()); 518 for (size_t j = i + 1; j < active_animations_.size(); ++j) { 519 if (active_animations_[i]->group() == active_animations_[j]->group()) 520 enqueued_properties.insert(active_animations_[j]->target_property()); 521 } 522 523 // Check to see if intersection of the list of properties affected by 524 // the group and the list of currently blocked properties is null. In 525 // any case, the group's target properties need to be added to the list 526 // of blocked properties. 527 bool null_intersection = true; 528 for (TargetProperties::iterator p_iter = enqueued_properties.begin(); 529 p_iter != enqueued_properties.end(); 530 ++p_iter) { 531 if (!blocked_properties.insert(*p_iter).second) 532 null_intersection = false; 533 } 534 535 // If the intersection is null, then we are free to start the animations 536 // in the group. 537 if (null_intersection) { 538 active_animations_[i]->SetRunState( 539 Animation::Starting, monotonic_time); 540 for (size_t j = i + 1; j < active_animations_.size(); ++j) { 541 if (active_animations_[i]->group() == 542 active_animations_[j]->group()) { 543 active_animations_[j]->SetRunState( 544 Animation::Starting, monotonic_time); 545 } 546 } 547 } 548 } 549 } 550 } 551 552 void LayerAnimationController::PromoteStartedAnimations( 553 double monotonic_time, 554 AnimationEventsVector* events) { 555 for (size_t i = 0; i < active_animations_.size(); ++i) { 556 if (active_animations_[i]->run_state() == Animation::Starting) { 557 active_animations_[i]->SetRunState(Animation::Running, monotonic_time); 558 if (!active_animations_[i]->has_set_start_time()) 559 active_animations_[i]->set_start_time(monotonic_time); 560 if (events) { 561 AnimationEvent started_event( 562 AnimationEvent::Started, 563 id_, 564 active_animations_[i]->group(), 565 active_animations_[i]->target_property(), 566 monotonic_time); 567 started_event.is_impl_only = active_animations_[i]->is_impl_only(); 568 events->push_back(started_event); 569 } 570 } 571 } 572 } 573 574 void LayerAnimationController::MarkFinishedAnimations(double monotonic_time) { 575 for (size_t i = 0; i < active_animations_.size(); ++i) { 576 if (active_animations_[i]->IsFinishedAt(monotonic_time) && 577 active_animations_[i]->run_state() != Animation::Aborted && 578 active_animations_[i]->run_state() != Animation::WaitingForDeletion) 579 active_animations_[i]->SetRunState(Animation::Finished, monotonic_time); 580 } 581 } 582 583 void LayerAnimationController::MarkAnimationsForDeletion( 584 double monotonic_time, AnimationEventsVector* events) { 585 bool marked_animations_for_deletions = false; 586 587 // Non-aborted animations are marked for deletion after a corresponding 588 // AnimationEvent::Finished event is sent or received. This means that if 589 // we don't have an events vector, we must ensure that non-aborted animations 590 // have received a finished event before marking them for deletion. 591 for (size_t i = 0; i < active_animations_.size(); i++) { 592 int group_id = active_animations_[i]->group(); 593 if (active_animations_[i]->run_state() == Animation::Aborted) { 594 if (events && !active_animations_[i]->is_impl_only()) { 595 AnimationEvent aborted_event( 596 AnimationEvent::Aborted, 597 id_, 598 group_id, 599 active_animations_[i]->target_property(), 600 monotonic_time); 601 events->push_back(aborted_event); 602 } 603 active_animations_[i]->SetRunState(Animation::WaitingForDeletion, 604 monotonic_time); 605 marked_animations_for_deletions = true; 606 continue; 607 } 608 609 bool all_anims_with_same_id_are_finished = false; 610 611 // Since deleting an animation on the main thread leads to its deletion 612 // on the impl thread, we only mark a Finished main thread animation for 613 // deletion once it has received a Finished event from the impl thread. 614 bool animation_i_will_send_or_has_received_finish_event = 615 events || active_animations_[i]->received_finished_event(); 616 // If an animation is finished, and not already marked for deletion, 617 // find out if all other animations in the same group are also finished. 618 if (active_animations_[i]->run_state() == Animation::Finished && 619 animation_i_will_send_or_has_received_finish_event) { 620 all_anims_with_same_id_are_finished = true; 621 for (size_t j = 0; j < active_animations_.size(); ++j) { 622 bool animation_j_will_send_or_has_received_finish_event = 623 events || active_animations_[j]->received_finished_event(); 624 if (group_id == active_animations_[j]->group() && 625 (!active_animations_[j]->is_finished() || 626 (active_animations_[j]->run_state() == Animation::Finished && 627 !animation_j_will_send_or_has_received_finish_event))) { 628 all_anims_with_same_id_are_finished = false; 629 break; 630 } 631 } 632 } 633 if (all_anims_with_same_id_are_finished) { 634 // We now need to remove all animations with the same group id as 635 // group_id (and send along animation finished notifications, if 636 // necessary). 637 for (size_t j = i; j < active_animations_.size(); j++) { 638 if (active_animations_[j]->group() == group_id && 639 active_animations_[j]->run_state() != Animation::Aborted) { 640 if (events) { 641 AnimationEvent finished_event( 642 AnimationEvent::Finished, 643 id_, 644 active_animations_[j]->group(), 645 active_animations_[j]->target_property(), 646 monotonic_time); 647 finished_event.is_impl_only = active_animations_[j]->is_impl_only(); 648 events->push_back(finished_event); 649 } 650 active_animations_[j]->SetRunState(Animation::WaitingForDeletion, 651 monotonic_time); 652 } 653 } 654 marked_animations_for_deletions = true; 655 } 656 } 657 if (marked_animations_for_deletions) 658 NotifyObserversAnimationWaitingForDeletion(); 659 } 660 661 static bool IsWaitingForDeletion(Animation* animation) { 662 return animation->run_state() == Animation::WaitingForDeletion; 663 } 664 665 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() { 666 ScopedPtrVector<Animation>& animations = active_animations_; 667 animations.erase(cc::remove_if(&animations, 668 animations.begin(), 669 animations.end(), 670 IsWaitingForDeletion), 671 animations.end()); 672 } 673 674 void LayerAnimationController::TickAnimations(double monotonic_time) { 675 for (size_t i = 0; i < active_animations_.size(); ++i) { 676 if (active_animations_[i]->run_state() == Animation::Starting || 677 active_animations_[i]->run_state() == Animation::Running || 678 active_animations_[i]->run_state() == Animation::Paused) { 679 double trimmed = 680 active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time); 681 682 switch (active_animations_[i]->target_property()) { 683 case Animation::Transform: { 684 const TransformAnimationCurve* transform_animation_curve = 685 active_animations_[i]->curve()->ToTransformAnimationCurve(); 686 const gfx::Transform transform = 687 transform_animation_curve->GetValue(trimmed); 688 NotifyObserversTransformAnimated(transform); 689 break; 690 } 691 692 case Animation::Opacity: { 693 const FloatAnimationCurve* float_animation_curve = 694 active_animations_[i]->curve()->ToFloatAnimationCurve(); 695 const float opacity = float_animation_curve->GetValue(trimmed); 696 NotifyObserversOpacityAnimated(opacity); 697 break; 698 } 699 700 case Animation::Filter: { 701 const FilterAnimationCurve* filter_animation_curve = 702 active_animations_[i]->curve()->ToFilterAnimationCurve(); 703 const FilterOperations filter = 704 filter_animation_curve->GetValue(trimmed); 705 NotifyObserversFilterAnimated(filter); 706 break; 707 } 708 709 case Animation::BackgroundColor: { 710 // Not yet implemented. 711 break; 712 } 713 714 case Animation::ScrollOffset: { 715 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = 716 active_animations_[i]->curve()->ToScrollOffsetAnimationCurve(); 717 const gfx::Vector2dF scroll_offset = 718 scroll_offset_animation_curve->GetValue(trimmed); 719 NotifyObserversScrollOffsetAnimated(scroll_offset); 720 break; 721 } 722 723 // Do nothing for sentinel value. 724 case Animation::TargetPropertyEnumSize: 725 NOTREACHED(); 726 } 727 } 728 } 729 } 730 731 void LayerAnimationController::UpdateActivation(UpdateActivationType type) { 732 bool force = type == ForceActivation; 733 if (registrar_) { 734 bool was_active = is_active_; 735 is_active_ = false; 736 for (size_t i = 0; i < active_animations_.size(); ++i) { 737 if (active_animations_[i]->run_state() != Animation::WaitingForDeletion) { 738 is_active_ = true; 739 break; 740 } 741 } 742 743 if (is_active_ && (!was_active || force)) 744 registrar_->DidActivateAnimationController(this); 745 else if (!is_active_ && (was_active || force)) 746 registrar_->DidDeactivateAnimationController(this); 747 } 748 } 749 750 void LayerAnimationController::NotifyObserversOpacityAnimated(float opacity) { 751 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 752 value_observers_, 753 OnOpacityAnimated(opacity)); 754 } 755 756 void LayerAnimationController::NotifyObserversTransformAnimated( 757 const gfx::Transform& transform) { 758 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 759 value_observers_, 760 OnTransformAnimated(transform)); 761 } 762 763 void LayerAnimationController::NotifyObserversFilterAnimated( 764 const FilterOperations& filters) { 765 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 766 value_observers_, 767 OnFilterAnimated(filters)); 768 } 769 770 void LayerAnimationController::NotifyObserversScrollOffsetAnimated( 771 gfx::Vector2dF scroll_offset) { 772 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 773 value_observers_, 774 OnScrollOffsetAnimated(scroll_offset)); 775 } 776 777 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() { 778 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 779 value_observers_, 780 OnAnimationWaitingForDeletion()); 781 } 782 783 bool LayerAnimationController::HasValueObserver() { 784 if (value_observers_.might_have_observers()) { 785 ObserverListBase<LayerAnimationValueObserver>::Iterator it( 786 value_observers_); 787 return it.GetNext() != NULL; 788 } 789 return false; 790 } 791 792 bool LayerAnimationController::HasActiveValueObserver() { 793 if (value_observers_.might_have_observers()) { 794 ObserverListBase<LayerAnimationValueObserver>::Iterator it( 795 value_observers_); 796 LayerAnimationValueObserver* obs; 797 while ((obs = it.GetNext()) != NULL) 798 if (obs->IsActive()) 799 return true; 800 } 801 return false; 802 } 803 804 } // namespace cc 805