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