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/base/scoped_ptr_algorithm.h" 15 #include "ui/gfx/transform.h" 16 17 namespace cc { 18 19 LayerAnimationController::LayerAnimationController(int id) 20 : force_sync_(false), 21 registrar_(0), 22 id_(id), 23 is_active_(false), 24 last_tick_time_(0), 25 layer_animation_delegate_(NULL) {} 26 27 LayerAnimationController::~LayerAnimationController() { 28 if (registrar_) 29 registrar_->UnregisterAnimationController(this); 30 } 31 32 scoped_refptr<LayerAnimationController> LayerAnimationController::Create( 33 int id) { 34 return make_scoped_refptr(new LayerAnimationController(id)); 35 } 36 37 void LayerAnimationController::PauseAnimation(int animation_id, 38 double time_offset) { 39 for (size_t i = 0; i < active_animations_.size(); ++i) { 40 if (active_animations_[i]->id() == animation_id) { 41 active_animations_[i]->SetRunState( 42 Animation::Paused, time_offset + active_animations_[i]->start_time()); 43 } 44 } 45 } 46 47 struct HasAnimationId { 48 explicit HasAnimationId(int id) : id_(id) {} 49 bool operator()(Animation* animation) const { 50 return animation->id() == id_; 51 } 52 53 private: 54 int id_; 55 }; 56 57 void LayerAnimationController::RemoveAnimation(int animation_id) { 58 ScopedPtrVector<Animation>& animations = active_animations_; 59 animations.erase(cc::remove_if(&animations, 60 animations.begin(), 61 animations.end(), 62 HasAnimationId(animation_id)), 63 animations.end()); 64 UpdateActivation(NormalActivation); 65 } 66 67 struct HasAnimationIdAndProperty { 68 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property) 69 : id_(id), target_property_(target_property) {} 70 bool operator()(Animation* animation) const { 71 return animation->id() == id_ && 72 animation->target_property() == target_property_; 73 } 74 75 private: 76 int id_; 77 Animation::TargetProperty target_property_; 78 }; 79 80 void LayerAnimationController::RemoveAnimation( 81 int animation_id, 82 Animation::TargetProperty target_property) { 83 ScopedPtrVector<Animation>& animations = active_animations_; 84 animations.erase(cc::remove_if(&animations, 85 animations.begin(), 86 animations.end(), 87 HasAnimationIdAndProperty(animation_id, 88 target_property)), 89 animations.end()); 90 UpdateActivation(NormalActivation); 91 } 92 93 // According to render layer backing, these are for testing only. 94 void LayerAnimationController::SuspendAnimations(double monotonic_time) { 95 for (size_t i = 0; i < active_animations_.size(); ++i) { 96 if (!active_animations_[i]->is_finished()) 97 active_animations_[i]->SetRunState(Animation::Paused, monotonic_time); 98 } 99 } 100 101 // Looking at GraphicsLayerCA, this appears to be the analog to 102 // SuspendAnimations, which is for testing. 103 void LayerAnimationController::ResumeAnimations(double monotonic_time) { 104 for (size_t i = 0; i < active_animations_.size(); ++i) { 105 if (active_animations_[i]->run_state() == Animation::Paused) 106 active_animations_[i]->SetRunState(Animation::Running, monotonic_time); 107 } 108 } 109 110 // Ensures that the list of active animations on the main thread and the impl 111 // thread are kept in sync. 112 void LayerAnimationController::PushAnimationUpdatesTo( 113 LayerAnimationController* controller_impl) { 114 DCHECK(this != controller_impl); 115 if (force_sync_) { 116 ReplaceImplThreadAnimations(controller_impl); 117 force_sync_ = false; 118 } else { 119 PurgeAnimationsMarkedForDeletion(); 120 PushNewAnimationsToImplThread(controller_impl); 121 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); 126 127 PushPropertiesToImplThread(controller_impl); 128 } 129 controller_impl->UpdateActivation(NormalActivation); 130 UpdateActivation(NormalActivation); 131 } 132 133 void LayerAnimationController::Animate(double monotonic_time) { 134 if (!HasValueObserver()) 135 return; 136 137 StartAnimationsWaitingForNextTick(monotonic_time); 138 StartAnimationsWaitingForStartTime(monotonic_time); 139 StartAnimationsWaitingForTargetAvailability(monotonic_time); 140 ResolveConflicts(monotonic_time); 141 TickAnimations(monotonic_time); 142 last_tick_time_ = monotonic_time; 143 } 144 145 void LayerAnimationController::AccumulatePropertyUpdates( 146 double monotonic_time, 147 AnimationEventsVector* events) { 148 if (!events) 149 return; 150 151 for (size_t i = 0; i < active_animations_.size(); ++i) { 152 Animation* animation = active_animations_[i]; 153 if (!animation->is_impl_only()) 154 continue; 155 156 if (animation->target_property() == Animation::Opacity) { 157 AnimationEvent event(AnimationEvent::PropertyUpdate, 158 id_, 159 animation->group(), 160 Animation::Opacity, 161 monotonic_time); 162 event.opacity = animation->curve()->ToFloatAnimationCurve()->GetValue( 163 monotonic_time); 164 event.is_impl_only = true; 165 events->push_back(event); 166 } else if (animation->target_property() == Animation::Transform) { 167 AnimationEvent event(AnimationEvent::PropertyUpdate, 168 id_, 169 animation->group(), 170 Animation::Transform, 171 monotonic_time); 172 event.transform = 173 animation->curve()->ToTransformAnimationCurve()->GetValue( 174 monotonic_time); 175 event.is_impl_only = true; 176 events->push_back(event); 177 } 178 } 179 } 180 181 void LayerAnimationController::UpdateState(bool start_ready_animations, 182 AnimationEventsVector* events) { 183 if (!HasActiveValueObserver()) 184 return; 185 186 if (start_ready_animations) 187 PromoteStartedAnimations(last_tick_time_, events); 188 189 MarkFinishedAnimations(last_tick_time_); 190 MarkAnimationsForDeletion(last_tick_time_, events); 191 192 if (start_ready_animations) { 193 StartAnimationsWaitingForTargetAvailability(last_tick_time_); 194 PromoteStartedAnimations(last_tick_time_, events); 195 } 196 197 AccumulatePropertyUpdates(last_tick_time_, events); 198 199 UpdateActivation(NormalActivation); 200 } 201 202 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) { 203 active_animations_.push_back(animation.Pass()); 204 UpdateActivation(NormalActivation); 205 } 206 207 Animation* LayerAnimationController::GetAnimation( 208 int group_id, 209 Animation::TargetProperty target_property) const { 210 for (size_t i = 0; i < active_animations_.size(); ++i) 211 if (active_animations_[i]->group() == group_id && 212 active_animations_[i]->target_property() == target_property) 213 return active_animations_[i]; 214 return 0; 215 } 216 217 Animation* LayerAnimationController::GetAnimation( 218 Animation::TargetProperty target_property) const { 219 for (size_t i = 0; i < active_animations_.size(); ++i) { 220 size_t index = active_animations_.size() - i - 1; 221 if (active_animations_[index]->target_property() == target_property) 222 return active_animations_[index]; 223 } 224 return 0; 225 } 226 227 bool LayerAnimationController::HasActiveAnimation() const { 228 for (size_t i = 0; i < active_animations_.size(); ++i) { 229 if (!active_animations_[i]->is_finished()) 230 return true; 231 } 232 return false; 233 } 234 235 bool LayerAnimationController::IsAnimatingProperty( 236 Animation::TargetProperty target_property) const { 237 for (size_t i = 0; i < active_animations_.size(); ++i) { 238 if (!active_animations_[i]->is_finished() && 239 active_animations_[i]->target_property() == target_property) 240 return true; 241 } 242 return false; 243 } 244 245 void LayerAnimationController::SetAnimationRegistrar( 246 AnimationRegistrar* registrar) { 247 if (registrar_ == registrar) 248 return; 249 250 if (registrar_) 251 registrar_->UnregisterAnimationController(this); 252 253 registrar_ = registrar; 254 if (registrar_) 255 registrar_->RegisterAnimationController(this); 256 257 UpdateActivation(ForceActivation); 258 } 259 260 void LayerAnimationController::NotifyAnimationStarted( 261 const AnimationEvent& event, 262 double wall_clock_time) { 263 if (event.is_impl_only) { 264 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_, 265 OnAnimationStarted(event)); 266 if (layer_animation_delegate_) 267 layer_animation_delegate_->NotifyAnimationStarted(wall_clock_time); 268 269 return; 270 } 271 272 for (size_t i = 0; i < active_animations_.size(); ++i) { 273 if (active_animations_[i]->group() == event.group_id && 274 active_animations_[i]->target_property() == event.target_property && 275 active_animations_[i]->needs_synchronized_start_time()) { 276 active_animations_[i]->set_needs_synchronized_start_time(false); 277 active_animations_[i]->set_start_time(event.monotonic_time); 278 279 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_, 280 OnAnimationStarted(event)); 281 if (layer_animation_delegate_) 282 layer_animation_delegate_->NotifyAnimationStarted(wall_clock_time); 283 284 return; 285 } 286 } 287 } 288 289 void LayerAnimationController::NotifyAnimationFinished( 290 const AnimationEvent& event, 291 double wall_clock_time) { 292 if (event.is_impl_only) { 293 if (layer_animation_delegate_) 294 layer_animation_delegate_->NotifyAnimationFinished(wall_clock_time); 295 return; 296 } 297 298 for (size_t i = 0; i < active_animations_.size(); ++i) { 299 if (active_animations_[i]->group() == event.group_id && 300 active_animations_[i]->target_property() == event.target_property) { 301 active_animations_[i]->set_received_finished_event(true); 302 if (layer_animation_delegate_) 303 layer_animation_delegate_->NotifyAnimationFinished(wall_clock_time); 304 305 return; 306 } 307 } 308 } 309 310 void LayerAnimationController::NotifyAnimationPropertyUpdate( 311 const AnimationEvent& event) { 312 switch (event.target_property) { 313 case Animation::Opacity: 314 NotifyObserversOpacityAnimated(event.opacity); 315 break; 316 case Animation::Transform: 317 NotifyObserversTransformAnimated(event.transform); 318 break; 319 default: 320 NOTREACHED(); 321 } 322 } 323 324 void LayerAnimationController::AddValueObserver( 325 LayerAnimationValueObserver* observer) { 326 if (!value_observers_.HasObserver(observer)) 327 value_observers_.AddObserver(observer); 328 } 329 330 void LayerAnimationController::RemoveValueObserver( 331 LayerAnimationValueObserver* observer) { 332 value_observers_.RemoveObserver(observer); 333 } 334 335 void LayerAnimationController::AddEventObserver( 336 LayerAnimationEventObserver* observer) { 337 if (!event_observers_.HasObserver(observer)) 338 event_observers_.AddObserver(observer); 339 } 340 341 void LayerAnimationController::RemoveEventObserver( 342 LayerAnimationEventObserver* observer) { 343 event_observers_.RemoveObserver(observer); 344 } 345 346 void LayerAnimationController::PushNewAnimationsToImplThread( 347 LayerAnimationController* controller_impl) const { 348 // Any new animations owned by the main thread's controller are cloned and 349 // add to the impl thread's controller. 350 for (size_t i = 0; i < active_animations_.size(); ++i) { 351 // If the animation is already running on the impl thread, there is no 352 // need to copy it over. 353 if (controller_impl->GetAnimation(active_animations_[i]->group(), 354 active_animations_[i]->target_property())) 355 continue; 356 357 // If the animation is not running on the impl thread, it does not 358 // necessarily mean that it needs to be copied over and started; it may 359 // have already finished. In this case, the impl thread animation will 360 // have already notified that it has started and the main thread animation 361 // will no longer need 362 // a synchronized start time. 363 if (!active_animations_[i]->needs_synchronized_start_time()) 364 continue; 365 366 // The new animation should be set to run as soon as possible. 367 Animation::RunState initial_run_state = 368 Animation::WaitingForTargetAvailability; 369 double start_time = 0; 370 scoped_ptr<Animation> to_add(active_animations_[i]->CloneAndInitialize( 371 Animation::ControllingInstance, initial_run_state, start_time)); 372 DCHECK(!to_add->needs_synchronized_start_time()); 373 controller_impl->AddAnimation(to_add.Pass()); 374 } 375 } 376 377 struct IsCompleted { 378 explicit IsCompleted(const LayerAnimationController& main_thread_controller) 379 : main_thread_controller_(main_thread_controller) {} 380 bool operator()(Animation* animation) const { 381 if (animation->is_impl_only()) { 382 return (animation->run_state() == Animation::WaitingForDeletion); 383 } else { 384 return !main_thread_controller_.GetAnimation( 385 animation->group(), 386 animation->target_property()); 387 } 388 } 389 390 private: 391 const LayerAnimationController& main_thread_controller_; 392 }; 393 394 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread( 395 LayerAnimationController* controller_impl) const { 396 // Delete all impl thread animations for which there is no corresponding 397 // main thread animation. Each iteration, 398 // controller->active_animations_.size() is decremented or i is incremented 399 // guaranteeing progress towards loop termination. 400 ScopedPtrVector<Animation>& animations = 401 controller_impl->active_animations_; 402 animations.erase(cc::remove_if(&animations, 403 animations.begin(), 404 animations.end(), 405 IsCompleted(*this)), 406 animations.end()); 407 } 408 409 void LayerAnimationController::PushPropertiesToImplThread( 410 LayerAnimationController* controller_impl) const { 411 for (size_t i = 0; i < active_animations_.size(); ++i) { 412 Animation* current_impl = 413 controller_impl->GetAnimation( 414 active_animations_[i]->group(), 415 active_animations_[i]->target_property()); 416 if (current_impl) 417 active_animations_[i]->PushPropertiesTo(current_impl); 418 } 419 } 420 421 void LayerAnimationController::StartAnimationsWaitingForNextTick( 422 double monotonic_time) { 423 for (size_t i = 0; i < active_animations_.size(); ++i) { 424 if (active_animations_[i]->run_state() == Animation::WaitingForNextTick) 425 active_animations_[i]->SetRunState(Animation::Starting, monotonic_time); 426 } 427 } 428 429 void LayerAnimationController::StartAnimationsWaitingForStartTime( 430 double monotonic_time) { 431 for (size_t i = 0; i < active_animations_.size(); ++i) { 432 if (active_animations_[i]->run_state() == Animation::WaitingForStartTime && 433 active_animations_[i]->start_time() <= monotonic_time) 434 active_animations_[i]->SetRunState(Animation::Starting, monotonic_time); 435 } 436 } 437 438 void LayerAnimationController::StartAnimationsWaitingForTargetAvailability( 439 double monotonic_time) { 440 // First collect running properties. 441 TargetProperties blocked_properties; 442 for (size_t i = 0; i < active_animations_.size(); ++i) { 443 if (active_animations_[i]->run_state() == Animation::Starting || 444 active_animations_[i]->run_state() == Animation::Running) 445 blocked_properties.insert(active_animations_[i]->target_property()); 446 } 447 448 for (size_t i = 0; i < active_animations_.size(); ++i) { 449 if (active_animations_[i]->run_state() == 450 Animation::WaitingForTargetAvailability) { 451 // Collect all properties for animations with the same group id (they 452 // should all also be in the list of animations). 453 TargetProperties enqueued_properties; 454 enqueued_properties.insert(active_animations_[i]->target_property()); 455 for (size_t j = i + 1; j < active_animations_.size(); ++j) { 456 if (active_animations_[i]->group() == active_animations_[j]->group()) 457 enqueued_properties.insert(active_animations_[j]->target_property()); 458 } 459 460 // Check to see if intersection of the list of properties affected by 461 // the group and the list of currently blocked properties is null. In 462 // any case, the group's target properties need to be added to the list 463 // of blocked properties. 464 bool null_intersection = true; 465 for (TargetProperties::iterator p_iter = enqueued_properties.begin(); 466 p_iter != enqueued_properties.end(); 467 ++p_iter) { 468 if (!blocked_properties.insert(*p_iter).second) 469 null_intersection = false; 470 } 471 472 // If the intersection is null, then we are free to start the animations 473 // in the group. 474 if (null_intersection) { 475 active_animations_[i]->SetRunState( 476 Animation::Starting, monotonic_time); 477 for (size_t j = i + 1; j < active_animations_.size(); ++j) { 478 if (active_animations_[i]->group() == 479 active_animations_[j]->group()) { 480 active_animations_[j]->SetRunState( 481 Animation::Starting, monotonic_time); 482 } 483 } 484 } 485 } 486 } 487 } 488 489 void LayerAnimationController::PromoteStartedAnimations( 490 double monotonic_time, 491 AnimationEventsVector* events) { 492 for (size_t i = 0; i < active_animations_.size(); ++i) { 493 if (active_animations_[i]->run_state() == Animation::Starting) { 494 active_animations_[i]->SetRunState(Animation::Running, monotonic_time); 495 if (!active_animations_[i]->has_set_start_time()) 496 active_animations_[i]->set_start_time(monotonic_time); 497 if (events) { 498 AnimationEvent started_event( 499 AnimationEvent::Started, 500 id_, 501 active_animations_[i]->group(), 502 active_animations_[i]->target_property(), 503 monotonic_time); 504 started_event.is_impl_only = active_animations_[i]->is_impl_only(); 505 events->push_back(started_event); 506 } 507 } 508 } 509 } 510 511 void LayerAnimationController::MarkFinishedAnimations(double monotonic_time) { 512 for (size_t i = 0; i < active_animations_.size(); ++i) { 513 if (active_animations_[i]->IsFinishedAt(monotonic_time) && 514 active_animations_[i]->run_state() != Animation::WaitingForDeletion) 515 active_animations_[i]->SetRunState(Animation::Finished, monotonic_time); 516 } 517 } 518 519 void LayerAnimationController::ResolveConflicts(double monotonic_time) { 520 // Find any animations that are animating the same property and resolve the 521 // confict. We could eventually blend, but for now we'll just abort the 522 // previous animation (where 'previous' means: (1) has a prior start time or 523 // (2) has an equal start time, but was added to the queue earlier, i.e., 524 // has a lower index in active_animations_). 525 for (size_t i = 0; i < active_animations_.size(); ++i) { 526 if (active_animations_[i]->run_state() == Animation::Starting || 527 active_animations_[i]->run_state() == Animation::Running) { 528 for (size_t j = i + 1; j < active_animations_.size(); ++j) { 529 if ((active_animations_[j]->run_state() == Animation::Starting || 530 active_animations_[j]->run_state() == Animation::Running) && 531 active_animations_[i]->target_property() == 532 active_animations_[j]->target_property()) { 533 if (active_animations_[i]->start_time() > 534 active_animations_[j]->start_time()) { 535 active_animations_[j]->SetRunState(Animation::Aborted, 536 monotonic_time); 537 } else { 538 active_animations_[i]->SetRunState(Animation::Aborted, 539 monotonic_time); 540 } 541 } 542 } 543 } 544 } 545 } 546 547 void LayerAnimationController::MarkAnimationsForDeletion( 548 double monotonic_time, AnimationEventsVector* events) { 549 // Non-aborted animations are marked for deletion after a corresponding 550 // AnimationEvent::Finished event is sent or received. This means that if 551 // we don't have an events vector, we must ensure that non-aborted animations 552 // have received a finished event before marking them for deletion. 553 for (size_t i = 0; i < active_animations_.size(); i++) { 554 int group_id = active_animations_[i]->group(); 555 bool all_anims_with_same_id_are_finished = false; 556 557 // Since deleting an animation on the main thread leads to its deletion 558 // on the impl thread, we only mark a Finished main thread animation for 559 // deletion once it has received a Finished event from the impl thread. 560 bool animation_i_will_send_or_has_received_finish_event = 561 events || active_animations_[i]->received_finished_event(); 562 // If an animation is finished, and not already marked for deletion, 563 // find out if all other animations in the same group are also finished. 564 if (active_animations_[i]->run_state() == Animation::Aborted || 565 (active_animations_[i]->run_state() == Animation::Finished && 566 animation_i_will_send_or_has_received_finish_event)) { 567 all_anims_with_same_id_are_finished = true; 568 for (size_t j = 0; j < active_animations_.size(); ++j) { 569 bool animation_j_will_send_or_has_received_finish_event = 570 events || active_animations_[j]->received_finished_event(); 571 if (group_id == active_animations_[j]->group() && 572 (!active_animations_[j]->is_finished() || 573 (active_animations_[j]->run_state() == Animation::Finished && 574 !animation_j_will_send_or_has_received_finish_event))) { 575 all_anims_with_same_id_are_finished = false; 576 break; 577 } 578 } 579 } 580 if (all_anims_with_same_id_are_finished) { 581 // We now need to remove all animations with the same group id as 582 // group_id (and send along animation finished notifications, if 583 // necessary). 584 for (size_t j = i; j < active_animations_.size(); j++) { 585 if (group_id == active_animations_[j]->group()) { 586 if (events) { 587 AnimationEvent finished_event( 588 AnimationEvent::Finished, 589 id_, 590 active_animations_[j]->group(), 591 active_animations_[j]->target_property(), 592 monotonic_time); 593 finished_event.is_impl_only = active_animations_[j]->is_impl_only(); 594 events->push_back(finished_event); 595 } 596 active_animations_[j]->SetRunState(Animation::WaitingForDeletion, 597 monotonic_time); 598 } 599 } 600 } 601 } 602 } 603 604 static bool IsWaitingForDeletion(Animation* animation) { 605 return animation->run_state() == Animation::WaitingForDeletion; 606 } 607 608 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() { 609 ScopedPtrVector<Animation>& animations = active_animations_; 610 animations.erase(cc::remove_if(&animations, 611 animations.begin(), 612 animations.end(), 613 IsWaitingForDeletion), 614 animations.end()); 615 } 616 617 void LayerAnimationController::ReplaceImplThreadAnimations( 618 LayerAnimationController* controller_impl) const { 619 controller_impl->active_animations_.clear(); 620 for (size_t i = 0; i < active_animations_.size(); ++i) { 621 scoped_ptr<Animation> to_add; 622 if (active_animations_[i]->needs_synchronized_start_time()) { 623 // We haven't received an animation started notification yet, so it 624 // is important that we add it in a 'waiting' and not 'running' state. 625 Animation::RunState initial_run_state = 626 Animation::WaitingForTargetAvailability; 627 double start_time = 0; 628 to_add = active_animations_[i]->CloneAndInitialize( 629 Animation::ControllingInstance, 630 initial_run_state, start_time).Pass(); 631 } else { 632 to_add = active_animations_[i]->Clone( 633 Animation::ControllingInstance).Pass(); 634 } 635 636 controller_impl->AddAnimation(to_add.Pass()); 637 } 638 } 639 640 void LayerAnimationController::TickAnimations(double monotonic_time) { 641 for (size_t i = 0; i < active_animations_.size(); ++i) { 642 if (active_animations_[i]->run_state() == Animation::Starting || 643 active_animations_[i]->run_state() == Animation::Running || 644 active_animations_[i]->run_state() == Animation::Paused) { 645 double trimmed = 646 active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time); 647 648 // Animation assumes its initial value until it gets the synchronized 649 // start time from the impl thread and can start ticking. 650 if (active_animations_[i]->needs_synchronized_start_time()) 651 trimmed = 0; 652 653 // A just-started animation assumes its initial value. 654 if (active_animations_[i]->run_state() == Animation::Starting && 655 !active_animations_[i]->has_set_start_time()) 656 trimmed = 0; 657 658 switch (active_animations_[i]->target_property()) { 659 case Animation::Transform: { 660 const TransformAnimationCurve* transform_animation_curve = 661 active_animations_[i]->curve()->ToTransformAnimationCurve(); 662 const gfx::Transform transform = 663 transform_animation_curve->GetValue(trimmed); 664 NotifyObserversTransformAnimated(transform); 665 break; 666 } 667 668 case Animation::Opacity: { 669 const FloatAnimationCurve* float_animation_curve = 670 active_animations_[i]->curve()->ToFloatAnimationCurve(); 671 const float opacity = float_animation_curve->GetValue(trimmed); 672 NotifyObserversOpacityAnimated(opacity); 673 break; 674 } 675 676 // Do nothing for sentinel value. 677 case Animation::TargetPropertyEnumSize: 678 NOTREACHED(); 679 } 680 } 681 } 682 } 683 684 void LayerAnimationController::UpdateActivation(UpdateActivationType type) { 685 bool force = type == ForceActivation; 686 if (registrar_) { 687 if (!active_animations_.empty() && (!is_active_ || force)) 688 registrar_->DidActivateAnimationController(this); 689 else if (active_animations_.empty() && (is_active_ || force)) 690 registrar_->DidDeactivateAnimationController(this); 691 is_active_ = !active_animations_.empty(); 692 } 693 } 694 695 void LayerAnimationController::NotifyObserversOpacityAnimated(float opacity) { 696 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 697 value_observers_, 698 OnOpacityAnimated(opacity)); 699 } 700 701 void LayerAnimationController::NotifyObserversTransformAnimated( 702 const gfx::Transform& transform) { 703 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 704 value_observers_, 705 OnTransformAnimated(transform)); 706 } 707 708 bool LayerAnimationController::HasValueObserver() { 709 if (value_observers_.might_have_observers()) { 710 ObserverListBase<LayerAnimationValueObserver>::Iterator it( 711 value_observers_); 712 return it.GetNext() != NULL; 713 } 714 return false; 715 } 716 717 bool LayerAnimationController::HasActiveValueObserver() { 718 if (value_observers_.might_have_observers()) { 719 ObserverListBase<LayerAnimationValueObserver>::Iterator it( 720 value_observers_); 721 LayerAnimationValueObserver* obs; 722 while ((obs = it.GetNext()) != NULL) 723 if (obs->IsActive()) 724 return true; 725 } 726 return false; 727 } 728 729 } // namespace cc 730