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