1 // Copyright (c) 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 "ui/compositor/layer_animator.h" 6 7 #include "base/debug/trace_event.h" 8 #include "base/logging.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "cc/animation/animation_id_provider.h" 11 #include "ui/base/animation/animation_container.h" 12 #include "ui/compositor/compositor.h" 13 #include "ui/compositor/layer.h" 14 #include "ui/compositor/layer_animation_delegate.h" 15 #include "ui/compositor/layer_animation_observer.h" 16 #include "ui/compositor/layer_animation_sequence.h" 17 18 #define SAFE_INVOKE_VOID(function, running_anim, ...) \ 19 if (running_anim.is_sequence_alive()) \ 20 function(running_anim.sequence(), ##__VA_ARGS__) 21 #define SAFE_INVOKE_BOOL(function, running_anim) \ 22 ((running_anim.is_sequence_alive()) \ 23 ? function(running_anim.sequence()) \ 24 : false) 25 #define SAFE_INVOKE_PTR(function, running_anim) \ 26 ((running_anim.is_sequence_alive()) \ 27 ? function(running_anim.sequence()) \ 28 : NULL) 29 30 namespace ui { 31 32 class LayerAnimator; 33 34 namespace { 35 36 const int kDefaultTransitionDurationMs = 120; 37 const int kTimerIntervalMs = 10; 38 39 // Returns the AnimationContainer we're added to. 40 ui::AnimationContainer* GetAnimationContainer() { 41 static ui::AnimationContainer* container = NULL; 42 if (!container) { 43 container = new AnimationContainer(); 44 container->AddRef(); 45 } 46 return container; 47 } 48 49 } // namespace 50 51 // LayerAnimator public -------------------------------------------------------- 52 53 LayerAnimator::LayerAnimator(base::TimeDelta transition_duration) 54 : delegate_(NULL), 55 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET), 56 transition_duration_(transition_duration), 57 tween_type_(Tween::LINEAR), 58 is_started_(false), 59 disable_timer_for_test_(false), 60 adding_animations_(false) { 61 } 62 63 LayerAnimator::~LayerAnimator() { 64 for (size_t i = 0; i < running_animations_.size(); ++i) { 65 if (running_animations_[i].is_sequence_alive()) 66 running_animations_[i].sequence()->OnAnimatorDestroyed(); 67 } 68 ClearAnimationsInternal(); 69 delegate_ = NULL; 70 } 71 72 // static 73 LayerAnimator* LayerAnimator::CreateDefaultAnimator() { 74 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0)); 75 } 76 77 // static 78 LayerAnimator* LayerAnimator::CreateImplicitAnimator() { 79 return new LayerAnimator( 80 base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs)); 81 } 82 83 // This macro provides the implementation for the setter and getter (well, 84 // the getter of the target value) for an animated property. For example, 85 // it is used for the implementations of SetTransform and GetTargetTransform. 86 // It is worth noting that SetFoo avoids invoking the usual animation machinery 87 // if the transition duration is zero -- in this case we just set the property 88 // on the layer animation delegate immediately. 89 #define ANIMATED_PROPERTY(type, property, name, member_type, member) \ 90 void LayerAnimator::Set##name(type value) { \ 91 base::TimeDelta duration = GetTransitionDuration(); \ 92 if (duration == base::TimeDelta() && delegate() && \ 93 (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) { \ 94 StopAnimatingProperty(LayerAnimationElement::property); \ 95 delegate()->Set##name##FromAnimation(value); \ 96 return; \ 97 } \ 98 scoped_ptr<LayerAnimationElement> element( \ 99 LayerAnimationElement::Create##name##Element(value, duration)); \ 100 element->set_tween_type(tween_type_); \ 101 StartAnimation(new LayerAnimationSequence(element.release())); \ 102 } \ 103 \ 104 member_type LayerAnimator::GetTarget##name() const { \ 105 LayerAnimationElement::TargetValue target(delegate()); \ 106 GetTargetValue(&target); \ 107 return target.member; \ 108 } 109 110 ANIMATED_PROPERTY( 111 const gfx::Transform&, TRANSFORM, Transform, gfx::Transform, transform); 112 ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds); 113 ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity); 114 ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility); 115 ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness); 116 ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale); 117 ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color); 118 119 void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) { 120 delegate_ = delegate; 121 } 122 123 void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) { 124 scoped_refptr<LayerAnimator> retain(this); 125 OnScheduled(animation); 126 if (!StartSequenceImmediately(animation)) { 127 // Attempt to preempt a running animation. 128 switch (preemption_strategy_) { 129 case IMMEDIATELY_SET_NEW_TARGET: 130 ImmediatelySetNewTarget(animation); 131 break; 132 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET: 133 ImmediatelyAnimateToNewTarget(animation); 134 break; 135 case ENQUEUE_NEW_ANIMATION: 136 EnqueueNewAnimation(animation); 137 break; 138 case REPLACE_QUEUED_ANIMATIONS: 139 ReplaceQueuedAnimations(animation); 140 break; 141 case BLEND_WITH_CURRENT_ANIMATION: { 142 // TODO(vollick) Add support for blended sequences and use them here. 143 NOTIMPLEMENTED(); 144 break; 145 } 146 } 147 } 148 FinishAnyAnimationWithZeroDuration(); 149 UpdateAnimationState(); 150 } 151 152 void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) { 153 scoped_refptr<LayerAnimator> retain(this); 154 OnScheduled(animation); 155 if (is_animating()) { 156 animation_queue_.push_back(make_linked_ptr(animation)); 157 ProcessQueue(); 158 } else { 159 StartSequenceImmediately(animation); 160 } 161 UpdateAnimationState(); 162 } 163 164 void LayerAnimator::StartTogether( 165 const std::vector<LayerAnimationSequence*>& animations) { 166 scoped_refptr<LayerAnimator> retain(this); 167 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) { 168 std::vector<LayerAnimationSequence*>::const_iterator iter; 169 for (iter = animations.begin(); iter != animations.end(); ++iter) { 170 StartAnimation(*iter); 171 } 172 return; 173 } 174 175 adding_animations_ = true; 176 if (!is_animating()) { 177 if (GetAnimationContainer()->is_running()) 178 last_step_time_ = GetAnimationContainer()->last_tick_time(); 179 else 180 last_step_time_ = base::TimeTicks::Now(); 181 } 182 183 // Collect all the affected properties. 184 LayerAnimationElement::AnimatableProperties animated_properties; 185 std::vector<LayerAnimationSequence*>::const_iterator iter; 186 for (iter = animations.begin(); iter != animations.end(); ++iter) { 187 animated_properties.insert((*iter)->properties().begin(), 188 (*iter)->properties().end()); 189 } 190 191 // Starting a zero duration pause that affects all the animated properties 192 // will prevent any of the sequences from animating until there are no 193 // running animations that affect any of these properties, as well as 194 // handle preemption strategy. 195 StartAnimation(new LayerAnimationSequence( 196 LayerAnimationElement::CreatePauseElement(animated_properties, 197 base::TimeDelta()))); 198 199 bool wait_for_group_start = false; 200 for (iter = animations.begin(); iter != animations.end(); ++iter) 201 wait_for_group_start |= (*iter)->IsFirstElementThreaded(); 202 203 int group_id = cc::AnimationIdProvider::NextGroupId(); 204 205 // These animations (provided they don't animate any common properties) will 206 // now animate together if trivially scheduled. 207 for (iter = animations.begin(); iter != animations.end(); ++iter) { 208 (*iter)->set_animation_group_id(group_id); 209 (*iter)->set_waiting_for_group_start(wait_for_group_start); 210 ScheduleAnimation(*iter); 211 } 212 213 adding_animations_ = false; 214 UpdateAnimationState(); 215 } 216 217 218 void LayerAnimator::ScheduleTogether( 219 const std::vector<LayerAnimationSequence*>& animations) { 220 scoped_refptr<LayerAnimator> retain(this); 221 222 // Collect all the affected properties. 223 LayerAnimationElement::AnimatableProperties animated_properties; 224 std::vector<LayerAnimationSequence*>::const_iterator iter; 225 for (iter = animations.begin(); iter != animations.end(); ++iter) { 226 animated_properties.insert((*iter)->properties().begin(), 227 (*iter)->properties().end()); 228 } 229 230 // Scheduling a zero duration pause that affects all the animated properties 231 // will prevent any of the sequences from animating until there are no 232 // running animations that affect any of these properties. 233 ScheduleAnimation(new LayerAnimationSequence( 234 LayerAnimationElement::CreatePauseElement(animated_properties, 235 base::TimeDelta()))); 236 237 bool wait_for_group_start = false; 238 for (iter = animations.begin(); iter != animations.end(); ++iter) 239 wait_for_group_start |= (*iter)->IsFirstElementThreaded(); 240 241 int group_id = cc::AnimationIdProvider::NextGroupId(); 242 243 // These animations (provided they don't animate any common properties) will 244 // now animate together if trivially scheduled. 245 for (iter = animations.begin(); iter != animations.end(); ++iter) { 246 (*iter)->set_animation_group_id(group_id); 247 (*iter)->set_waiting_for_group_start(wait_for_group_start); 248 ScheduleAnimation(*iter); 249 } 250 251 UpdateAnimationState(); 252 } 253 254 void LayerAnimator::SchedulePauseForProperties( 255 base::TimeDelta duration, 256 LayerAnimationElement::AnimatableProperty property, 257 ...) { 258 ui::LayerAnimationElement::AnimatableProperties properties_to_pause; 259 va_list marker; 260 va_start(marker, property); 261 for (int p = static_cast<int>(property); p != -1; p = va_arg(marker, int)) { 262 properties_to_pause.insert( 263 static_cast<LayerAnimationElement::AnimatableProperty>(p)); 264 } 265 va_end(marker); 266 ScheduleAnimation(new ui::LayerAnimationSequence( 267 ui::LayerAnimationElement::CreatePauseElement( 268 properties_to_pause, duration))); 269 } 270 271 bool LayerAnimator::IsAnimatingProperty( 272 LayerAnimationElement::AnimatableProperty property) const { 273 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin(); 274 queue_iter != animation_queue_.end(); ++queue_iter) { 275 if ((*queue_iter)->properties().find(property) != 276 (*queue_iter)->properties().end()) { 277 return true; 278 } 279 } 280 return false; 281 } 282 283 void LayerAnimator::StopAnimatingProperty( 284 LayerAnimationElement::AnimatableProperty property) { 285 scoped_refptr<LayerAnimator> retain(this); 286 while (true) { 287 // GetRunningAnimation purges deleted animations before searching, so we are 288 // guaranteed to find a live animation if any is returned at all. 289 RunningAnimation* running = GetRunningAnimation(property); 290 if (!running) 291 break; 292 // As was mentioned above, this sequence must be alive. 293 DCHECK(running->is_sequence_alive()); 294 FinishAnimation(running->sequence(), false); 295 } 296 } 297 298 void LayerAnimator::AddObserver(LayerAnimationObserver* observer) { 299 if (!observers_.HasObserver(observer)) 300 observers_.AddObserver(observer); 301 } 302 303 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) { 304 observers_.RemoveObserver(observer); 305 // Remove the observer from all sequences as well. 306 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 307 queue_iter != animation_queue_.end(); ++queue_iter) { 308 (*queue_iter)->RemoveObserver(observer); 309 } 310 } 311 312 void LayerAnimator::OnThreadedAnimationStarted( 313 const cc::AnimationEvent& event) { 314 LayerAnimationElement::AnimatableProperty property = 315 LayerAnimationElement::ToAnimatableProperty(event.target_property); 316 317 RunningAnimation* running = GetRunningAnimation(property); 318 if (!running) 319 return; 320 DCHECK(running->is_sequence_alive()); 321 322 if (running->sequence()->animation_group_id() != event.group_id) 323 return; 324 325 running->sequence()->OnThreadedAnimationStarted(event); 326 if (!running->sequence()->waiting_for_group_start()) 327 return; 328 329 base::TimeTicks start_time = base::TimeTicks::FromInternalValue( 330 event.monotonic_time * base::Time::kMicrosecondsPerSecond); 331 332 running->sequence()->set_waiting_for_group_start(false); 333 334 // The call to GetRunningAnimation made above already purged deleted 335 // animations, so we are guaranteed that all the animations we iterate 336 // over now are alive. 337 for (RunningAnimations::iterator iter = running_animations_.begin(); 338 iter != running_animations_.end(); ++iter) { 339 // Ensure that each sequence is only Started once, regardless of the 340 // number of sequences in the group that have threaded first elements. 341 if (((*iter).sequence()->animation_group_id() == event.group_id) && 342 !(*iter).sequence()->IsFirstElementThreaded() && 343 (*iter).sequence()->waiting_for_group_start()) { 344 (*iter).sequence()->set_start_time(start_time); 345 (*iter).sequence()->set_waiting_for_group_start(false); 346 (*iter).sequence()->Start(delegate()); 347 } 348 } 349 } 350 351 // LayerAnimator protected ----------------------------------------------------- 352 353 void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence, 354 base::TimeTicks now) { 355 if (!delegate() || sequence->waiting_for_group_start()) 356 return; 357 358 sequence->Progress(now, delegate()); 359 } 360 361 void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) { 362 if (!delegate()) 363 return; 364 365 sequence->ProgressToEnd(delegate()); 366 } 367 368 bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const { 369 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin(); 370 queue_iter != animation_queue_.end(); ++queue_iter) { 371 if ((*queue_iter).get() == sequence) 372 return true; 373 } 374 return false; 375 } 376 377 // LayerAnimator private ------------------------------------------------------- 378 379 void LayerAnimator::Step(base::TimeTicks now) { 380 TRACE_EVENT0("ui", "LayerAnimator::Step"); 381 scoped_refptr<LayerAnimator> retain(this); 382 383 last_step_time_ = now; 384 385 PurgeDeletedAnimations(); 386 387 // We need to make a copy of the running animations because progressing them 388 // and finishing them may indirectly affect the collection of running 389 // animations. 390 RunningAnimations running_animations_copy = running_animations_; 391 for (size_t i = 0; i < running_animations_copy.size(); ++i) { 392 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i])) 393 continue; 394 395 if (running_animations_copy[i].sequence()->IsFinished(now)) { 396 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false); 397 } else { 398 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now); 399 } 400 } 401 } 402 403 void LayerAnimator::SetStartTime(base::TimeTicks start_time) { 404 // Do nothing. 405 } 406 407 base::TimeDelta LayerAnimator::GetTimerInterval() const { 408 return base::TimeDelta::FromMilliseconds(kTimerIntervalMs); 409 } 410 411 void LayerAnimator::StopAnimatingInternal(bool abort) { 412 scoped_refptr<LayerAnimator> retain(this); 413 while (is_animating()) { 414 // We're going to attempt to finish the first running animation. Let's 415 // ensure that it's valid. 416 PurgeDeletedAnimations(); 417 418 // If we've purged all running animations, attempt to start one up. 419 if (running_animations_.empty()) 420 ProcessQueue(); 421 422 DCHECK(!running_animations_.empty()); 423 424 // Still no luck, let's just bail and clear all animations. 425 if (running_animations_.empty()) { 426 ClearAnimationsInternal(); 427 break; 428 } 429 430 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort); 431 } 432 } 433 434 void LayerAnimator::UpdateAnimationState() { 435 if (disable_timer_for_test_) 436 return; 437 438 const bool should_start = is_animating(); 439 if (should_start && !is_started_) 440 GetAnimationContainer()->Start(this); 441 else if (!should_start && is_started_) 442 GetAnimationContainer()->Stop(this); 443 444 is_started_ = should_start; 445 } 446 447 LayerAnimationSequence* LayerAnimator::RemoveAnimation( 448 LayerAnimationSequence* sequence) { 449 linked_ptr<LayerAnimationSequence> to_return; 450 451 bool is_running = false; 452 453 // First remove from running animations 454 for (RunningAnimations::iterator iter = running_animations_.begin(); 455 iter != running_animations_.end(); ++iter) { 456 if ((*iter).sequence() == sequence) { 457 running_animations_.erase(iter); 458 is_running = true; 459 break; 460 } 461 } 462 463 // Then remove from the queue 464 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 465 queue_iter != animation_queue_.end(); ++queue_iter) { 466 if ((*queue_iter) == sequence) { 467 to_return = *queue_iter; 468 animation_queue_.erase(queue_iter); 469 break; 470 } 471 } 472 473 if (!to_return.get() || 474 !to_return->waiting_for_group_start() || 475 !to_return->IsFirstElementThreaded()) 476 return to_return.release(); 477 478 // The removed sequence may have been responsible for making other sequences 479 // wait for a group start. If no other sequences in the group have a 480 // threaded first element, the group no longer needs the additional wait. 481 bool is_wait_still_needed = false; 482 int group_id = to_return->animation_group_id(); 483 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 484 queue_iter != animation_queue_.end(); ++queue_iter) { 485 if (((*queue_iter)->animation_group_id() == group_id) && 486 (*queue_iter)->IsFirstElementThreaded()) { 487 is_wait_still_needed = true; 488 break; 489 } 490 } 491 492 if (is_wait_still_needed) 493 return to_return.release(); 494 495 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 496 queue_iter != animation_queue_.end(); ++queue_iter) { 497 if ((*queue_iter)->animation_group_id() == group_id && 498 (*queue_iter)->waiting_for_group_start()) { 499 (*queue_iter)->set_waiting_for_group_start(false); 500 if (is_running) { 501 (*queue_iter)->set_start_time(last_step_time_); 502 (*queue_iter)->Start(delegate()); 503 } 504 } 505 } 506 return to_return.release(); 507 } 508 509 void LayerAnimator::FinishAnimation( 510 LayerAnimationSequence* sequence, bool abort) { 511 scoped_refptr<LayerAnimator> retain(this); 512 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence)); 513 if (abort) 514 sequence->Abort(delegate()); 515 else 516 ProgressAnimationToEnd(sequence); 517 ProcessQueue(); 518 UpdateAnimationState(); 519 } 520 521 void LayerAnimator::FinishAnyAnimationWithZeroDuration() { 522 scoped_refptr<LayerAnimator> retain(this); 523 // Special case: if we've started a 0 duration animation, just finish it now 524 // and get rid of it. We need to make a copy because Progress may indirectly 525 // cause new animations to start running. 526 RunningAnimations running_animations_copy = running_animations_; 527 for (size_t i = 0; i < running_animations_copy.size(); ++i) { 528 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i])) 529 continue; 530 531 if (running_animations_copy[i].sequence()->IsFinished( 532 running_animations_copy[i].sequence()->start_time())) { 533 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]); 534 scoped_ptr<LayerAnimationSequence> removed( 535 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i])); 536 } 537 } 538 ProcessQueue(); 539 UpdateAnimationState(); 540 } 541 542 void LayerAnimator::ClearAnimations() { 543 scoped_refptr<LayerAnimator> retain(this); 544 ClearAnimationsInternal(); 545 } 546 547 LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation( 548 LayerAnimationElement::AnimatableProperty property) { 549 PurgeDeletedAnimations(); 550 for (RunningAnimations::iterator iter = running_animations_.begin(); 551 iter != running_animations_.end(); ++iter) { 552 if ((*iter).sequence()->properties().find(property) != 553 (*iter).sequence()->properties().end()) 554 return &(*iter); 555 } 556 return NULL; 557 } 558 559 void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) { 560 // If we don't have the animation in the queue yet, add it. 561 bool found_sequence = false; 562 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 563 queue_iter != animation_queue_.end(); ++queue_iter) { 564 if ((*queue_iter) == animation) { 565 found_sequence = true; 566 break; 567 } 568 } 569 570 if (!found_sequence) 571 animation_queue_.push_front(make_linked_ptr(animation)); 572 } 573 574 void LayerAnimator::RemoveAllAnimationsWithACommonProperty( 575 LayerAnimationSequence* sequence, bool abort) { 576 // For all the running animations, if they animate the same property, 577 // progress them to the end and remove them. Note, Aborting or Progressing 578 // animations may affect the collection of running animations, so we need to 579 // operate on a copy. 580 RunningAnimations running_animations_copy = running_animations_; 581 for (size_t i = 0; i < running_animations_copy.size(); ++i) { 582 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i])) 583 continue; 584 585 if (running_animations_copy[i].sequence()->HasConflictingProperty( 586 sequence->properties())) { 587 scoped_ptr<LayerAnimationSequence> removed( 588 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i])); 589 if (abort) 590 running_animations_copy[i].sequence()->Abort(delegate()); 591 else 592 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]); 593 } 594 } 595 596 // Same for the queued animations that haven't been started. Again, we'll 597 // need to operate on a copy. 598 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences; 599 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 600 queue_iter != animation_queue_.end(); ++queue_iter) 601 sequences.push_back((*queue_iter)->AsWeakPtr()); 602 603 for (size_t i = 0; i < sequences.size(); ++i) { 604 if (!sequences[i].get() || !HasAnimation(sequences[i].get())) 605 continue; 606 607 if (sequences[i]->HasConflictingProperty(sequence->properties())) { 608 scoped_ptr<LayerAnimationSequence> removed( 609 RemoveAnimation(sequences[i].get())); 610 if (abort) 611 sequences[i]->Abort(delegate()); 612 else 613 ProgressAnimationToEnd(sequences[i].get()); 614 } 615 } 616 } 617 618 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) { 619 // Need to detect if our sequence gets destroyed. 620 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr = 621 sequence->AsWeakPtr(); 622 623 const bool abort = false; 624 RemoveAllAnimationsWithACommonProperty(sequence, abort); 625 if (!weak_sequence_ptr.get()) 626 return; 627 628 LayerAnimationSequence* removed = RemoveAnimation(sequence); 629 DCHECK(removed == NULL || removed == sequence); 630 if (!weak_sequence_ptr.get()) 631 return; 632 633 ProgressAnimationToEnd(sequence); 634 if (!weak_sequence_ptr.get()) 635 return; 636 637 delete sequence; 638 } 639 640 void LayerAnimator::ImmediatelyAnimateToNewTarget( 641 LayerAnimationSequence* sequence) { 642 // Need to detect if our sequence gets destroyed. 643 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr = 644 sequence->AsWeakPtr(); 645 646 const bool abort = true; 647 RemoveAllAnimationsWithACommonProperty(sequence, abort); 648 if (!weak_sequence_ptr.get()) 649 return; 650 651 AddToQueueIfNotPresent(sequence); 652 if (!weak_sequence_ptr.get()) 653 return; 654 655 StartSequenceImmediately(sequence); 656 } 657 658 void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) { 659 // It is assumed that if there was no conflicting animation, we would 660 // not have been called. No need to check for a collision; just 661 // add to the queue. 662 animation_queue_.push_back(make_linked_ptr(sequence)); 663 ProcessQueue(); 664 } 665 666 void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) { 667 // Need to detect if our sequence gets destroyed. 668 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr = 669 sequence->AsWeakPtr(); 670 671 // Remove all animations that aren't running. Note: at each iteration i is 672 // incremented or an element is removed from the queue, so 673 // animation_queue_.size() - i is always decreasing and we are always making 674 // progress towards the loop terminating. 675 for (size_t i = 0; i < animation_queue_.size();) { 676 if (!weak_sequence_ptr.get()) 677 break; 678 679 PurgeDeletedAnimations(); 680 681 bool is_running = false; 682 for (RunningAnimations::const_iterator iter = running_animations_.begin(); 683 iter != running_animations_.end(); ++iter) { 684 if ((*iter).sequence() == animation_queue_[i].get()) { 685 is_running = true; 686 break; 687 } 688 } 689 690 if (!is_running) 691 delete RemoveAnimation(animation_queue_[i].get()); 692 else 693 ++i; 694 } 695 animation_queue_.push_back(make_linked_ptr(sequence)); 696 ProcessQueue(); 697 } 698 699 void LayerAnimator::ProcessQueue() { 700 bool started_sequence = false; 701 do { 702 started_sequence = false; 703 // Build a list of all currently animated properties. 704 LayerAnimationElement::AnimatableProperties animated; 705 for (RunningAnimations::const_iterator iter = running_animations_.begin(); 706 iter != running_animations_.end(); ++iter) { 707 if (!(*iter).is_sequence_alive()) 708 continue; 709 animated.insert((*iter).sequence()->properties().begin(), 710 (*iter).sequence()->properties().end()); 711 } 712 713 // Try to find an animation that doesn't conflict with an animated 714 // property or a property that will be animated before it. Note: starting 715 // the animation may indirectly cause more animations to be started, so we 716 // need to operate on a copy. 717 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences; 718 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 719 queue_iter != animation_queue_.end(); ++queue_iter) 720 sequences.push_back((*queue_iter)->AsWeakPtr()); 721 722 for (size_t i = 0; i < sequences.size(); ++i) { 723 if (!sequences[i].get() || !HasAnimation(sequences[i].get())) 724 continue; 725 726 if (!sequences[i]->HasConflictingProperty(animated)) { 727 StartSequenceImmediately(sequences[i].get()); 728 started_sequence = true; 729 break; 730 } 731 732 // Animation couldn't be started. Add its properties to the collection so 733 // that we don't start a conflicting animation. For example, if our queue 734 // has the elements { {T,B}, {B} } (that is, an element that animates both 735 // the transform and the bounds followed by an element that animates the 736 // bounds), and we're currently animating the transform, we can't start 737 // the first element because it animates the transform, too. We cannot 738 // start the second element, either, because the first element animates 739 // bounds too, and needs to go first. 740 animated.insert(sequences[i]->properties().begin(), 741 sequences[i]->properties().end()); 742 } 743 744 // If we started a sequence, try again. We may be able to start several. 745 } while (started_sequence); 746 } 747 748 bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) { 749 PurgeDeletedAnimations(); 750 751 // Ensure that no one is animating one of the sequence's properties already. 752 for (RunningAnimations::const_iterator iter = running_animations_.begin(); 753 iter != running_animations_.end(); ++iter) { 754 if ((*iter).sequence()->HasConflictingProperty(sequence->properties())) 755 return false; 756 } 757 758 // All clear, actually start the sequence. Note: base::TimeTicks::Now has 759 // a resolution that can be as bad as 15ms. If this causes glitches in the 760 // animations, this can be switched to HighResNow() (animation uses Now() 761 // internally). 762 // All LayerAnimators share the same AnimationContainer. Use the 763 // last_tick_time() from there to ensure animations started during the same 764 // event complete at the same time. 765 base::TimeTicks start_time; 766 if (is_animating() || adding_animations_) 767 start_time = last_step_time_; 768 else if (GetAnimationContainer()->is_running()) 769 start_time = GetAnimationContainer()->last_tick_time(); 770 else 771 start_time = base::TimeTicks::Now(); 772 773 if (!sequence->animation_group_id()) 774 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId()); 775 if (!sequence->waiting_for_group_start() || 776 sequence->IsFirstElementThreaded()) { 777 sequence->set_start_time(start_time); 778 sequence->Start(delegate()); 779 } 780 running_animations_.push_back( 781 RunningAnimation(sequence->AsWeakPtr())); 782 783 // Need to keep a reference to the animation. 784 AddToQueueIfNotPresent(sequence); 785 786 // Ensure that animations get stepped at their start time. 787 Step(start_time); 788 789 return true; 790 } 791 792 void LayerAnimator::GetTargetValue( 793 LayerAnimationElement::TargetValue* target) const { 794 for (AnimationQueue::const_iterator iter = animation_queue_.begin(); 795 iter != animation_queue_.end(); ++iter) { 796 (*iter)->GetTargetValue(target); 797 } 798 } 799 800 void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) { 801 if (observers_.might_have_observers()) { 802 ObserverListBase<LayerAnimationObserver>::Iterator it(observers_); 803 LayerAnimationObserver* obs; 804 while ((obs = it.GetNext()) != NULL) { 805 sequence->AddObserver(obs); 806 } 807 } 808 sequence->OnScheduled(); 809 } 810 811 base::TimeDelta LayerAnimator::GetTransitionDuration() const { 812 return transition_duration_; 813 } 814 815 void LayerAnimator::ClearAnimationsInternal() { 816 PurgeDeletedAnimations(); 817 818 // Abort should never affect the set of running animations, but just in case 819 // clients are badly behaved, we will use a copy of the running animations. 820 RunningAnimations running_animations_copy = running_animations_; 821 for (size_t i = 0; i < running_animations_copy.size(); ++i) { 822 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i])) 823 continue; 824 825 scoped_ptr<LayerAnimationSequence> removed( 826 RemoveAnimation(running_animations_copy[i].sequence())); 827 if (removed.get()) 828 removed->Abort(delegate()); 829 } 830 // This *should* have cleared the list of running animations. 831 DCHECK(running_animations_.empty()); 832 running_animations_.clear(); 833 animation_queue_.clear(); 834 UpdateAnimationState(); 835 } 836 837 void LayerAnimator::PurgeDeletedAnimations() { 838 for (size_t i = 0; i < running_animations_.size();) { 839 if (!running_animations_[i].is_sequence_alive()) 840 running_animations_.erase(running_animations_.begin() + i); 841 else 842 i++; 843 } 844 } 845 846 LayerAnimator::RunningAnimation::RunningAnimation( 847 const base::WeakPtr<LayerAnimationSequence>& sequence) 848 : sequence_(sequence) { 849 } 850 851 LayerAnimator::RunningAnimation::~RunningAnimation() { } 852 853 } // namespace ui 854