OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/compositor/layer_animator.h" | 5 #include "ui/compositor/layer_animator.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "ui/base/animation/animation_container.h" | 10 #include "ui/base/animation/animation_container.h" |
(...skipping 10 matching lines...) Expand all Loading... | |
21 namespace { | 21 namespace { |
22 | 22 |
23 static const base::TimeDelta kDefaultTransitionDuration = | 23 static const base::TimeDelta kDefaultTransitionDuration = |
24 base::TimeDelta::FromMilliseconds(120); | 24 base::TimeDelta::FromMilliseconds(120); |
25 | 25 |
26 static const base::TimeDelta kTimerInterval = | 26 static const base::TimeDelta kTimerInterval = |
27 base::TimeDelta::FromMilliseconds(10); | 27 base::TimeDelta::FromMilliseconds(10); |
28 | 28 |
29 } // namespace | 29 } // namespace |
30 | 30 |
31 class LayerAnimator::DestroyedTracker | |
32 : public base::RefCounted<LayerAnimator::DestroyedTracker> { | |
33 public: | |
34 DestroyedTracker() : is_alive_(true) {} | |
35 virtual ~DestroyedTracker() { | |
36 DCHECK(!is_alive_); | |
37 } | |
38 | |
39 // Returns true if the animator is still alive. | |
40 bool is_alive() const { return is_alive_; } | |
41 | |
42 // Invoked when the animator is destroyed. | |
43 void AnimatorDeleted() { | |
44 DCHECK(is_alive_); | |
45 is_alive_ = false; | |
46 } | |
47 | |
48 private: | |
49 bool is_alive_; | |
50 | |
51 DISALLOW_COPY_AND_ASSIGN(DestroyedTracker); | |
52 }; | |
53 | |
31 // static | 54 // static |
32 bool LayerAnimator::disable_animations_for_test_ = false; | 55 bool LayerAnimator::disable_animations_for_test_ = false; |
33 // static | 56 // static |
34 bool LayerAnimator::slow_animation_mode_ = false; | 57 bool LayerAnimator::slow_animation_mode_ = false; |
35 // static | 58 // static |
36 int LayerAnimator::slow_animation_scale_factor_ = 4; | 59 int LayerAnimator::slow_animation_scale_factor_ = 4; |
37 | 60 |
38 // LayerAnimator public -------------------------------------------------------- | 61 // LayerAnimator public -------------------------------------------------------- |
39 | 62 |
40 LayerAnimator::LayerAnimator(base::TimeDelta transition_duration) | 63 LayerAnimator::LayerAnimator(base::TimeDelta transition_duration) |
41 : delegate_(NULL), | 64 : delegate_(NULL), |
42 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET), | 65 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET), |
43 transition_duration_(transition_duration), | 66 transition_duration_(transition_duration), |
44 tween_type_(Tween::LINEAR), | 67 tween_type_(Tween::LINEAR), |
45 is_started_(false), | 68 is_started_(false), |
46 disable_timer_for_test_(false) { | 69 disable_timer_for_test_(false), |
70 destroyed_tracker_(new DestroyedTracker) { | |
47 } | 71 } |
48 | 72 |
49 LayerAnimator::~LayerAnimator() { | 73 LayerAnimator::~LayerAnimator() { |
50 for (size_t i = 0; i < running_animations_.size(); ++i) | 74 for (size_t i = 0; i < running_animations_.size(); ++i) |
51 running_animations_[i].sequence->OnAnimatorDestroyed(); | 75 running_animations_[i].sequence->OnAnimatorDestroyed(); |
52 ClearAnimations(); | 76 ClearAnimations(); |
77 destroyed_tracker_->AnimatorDeleted(); | |
53 } | 78 } |
54 | 79 |
55 // static | 80 // static |
56 LayerAnimator* LayerAnimator::CreateDefaultAnimator() { | 81 LayerAnimator* LayerAnimator::CreateDefaultAnimator() { |
57 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0)); | 82 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0)); |
58 } | 83 } |
59 | 84 |
60 // static | 85 // static |
61 LayerAnimator* LayerAnimator::CreateImplicitAnimator() { | 86 LayerAnimator* LayerAnimator::CreateImplicitAnimator() { |
62 return new LayerAnimator(kDefaultTransitionDuration); | 87 return new LayerAnimator(kDefaultTransitionDuration); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 } | 270 } |
246 return false; | 271 return false; |
247 } | 272 } |
248 | 273 |
249 void LayerAnimator::StopAnimatingProperty( | 274 void LayerAnimator::StopAnimatingProperty( |
250 LayerAnimationElement::AnimatableProperty property) { | 275 LayerAnimationElement::AnimatableProperty property) { |
251 while (true) { | 276 while (true) { |
252 RunningAnimation* running = GetRunningAnimation(property); | 277 RunningAnimation* running = GetRunningAnimation(property); |
253 if (!running) | 278 if (!running) |
254 break; | 279 break; |
255 FinishAnimation(running->sequence); | 280 if (FinishAnimation(running->sequence) == DESTROYED) |
281 return; | |
256 } | 282 } |
257 } | 283 } |
258 | 284 |
259 void LayerAnimator::StopAnimating() { | 285 void LayerAnimator::StopAnimating() { |
260 while (is_animating()) | 286 while (is_animating()) { |
261 FinishAnimation(running_animations_[0].sequence); | 287 if (FinishAnimation(running_animations_[0].sequence) == DESTROYED) |
288 return; | |
289 } | |
262 } | 290 } |
263 | 291 |
264 void LayerAnimator::AddObserver(LayerAnimationObserver* observer) { | 292 void LayerAnimator::AddObserver(LayerAnimationObserver* observer) { |
265 if (!observers_.HasObserver(observer)) | 293 if (!observers_.HasObserver(observer)) |
266 observers_.AddObserver(observer); | 294 observers_.AddObserver(observer); |
267 } | 295 } |
268 | 296 |
269 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) { | 297 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) { |
270 observers_.RemoveObserver(observer); | 298 observers_.RemoveObserver(observer); |
271 // Remove the observer from all sequences as well. | 299 // Remove the observer from all sequences as well. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 // animations. | 331 // animations. |
304 RunningAnimations running_animations_copy = running_animations_; | 332 RunningAnimations running_animations_copy = running_animations_; |
305 bool needs_redraw = false; | 333 bool needs_redraw = false; |
306 for (size_t i = 0; i < running_animations_copy.size(); ++i) { | 334 for (size_t i = 0; i < running_animations_copy.size(); ++i) { |
307 if (!HasAnimation(running_animations_copy[i].sequence)) | 335 if (!HasAnimation(running_animations_copy[i].sequence)) |
308 continue; | 336 continue; |
309 | 337 |
310 base::TimeDelta delta = now - running_animations_copy[i].start_time; | 338 base::TimeDelta delta = now - running_animations_copy[i].start_time; |
311 if (delta >= running_animations_copy[i].sequence->duration() && | 339 if (delta >= running_animations_copy[i].sequence->duration() && |
312 !running_animations_copy[i].sequence->is_cyclic()) { | 340 !running_animations_copy[i].sequence->is_cyclic()) { |
313 FinishAnimation(running_animations_copy[i].sequence); | 341 if (FinishAnimation(running_animations_copy[i].sequence) == DESTROYED) |
314 } else if (ProgressAnimation(running_animations_copy[i].sequence, delta)) | 342 return; |
315 needs_redraw = true; | 343 needs_redraw = true; |
344 } else { | |
345 scoped_refptr<DestroyedTracker> tracker(destroyed_tracker_); | |
346 const bool progress_result = | |
347 ProgressAnimation(running_animations_copy[i].sequence, delta); | |
348 if (!tracker->is_alive()) | |
349 return; | |
350 if (progress_result) | |
351 needs_redraw = true; | |
352 } | |
316 } | 353 } |
317 | 354 |
318 if (needs_redraw && delegate()) | 355 if (needs_redraw && delegate()) |
319 delegate()->ScheduleDrawForAnimation(); | 356 delegate()->ScheduleDrawForAnimation(); |
320 } | 357 } |
321 | 358 |
322 void LayerAnimator::SetStartTime(base::TimeTicks start_time) { | 359 void LayerAnimator::SetStartTime(base::TimeTicks start_time) { |
323 // Do nothing. | 360 // Do nothing. |
324 } | 361 } |
325 | 362 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 if ((*queue_iter) == sequence) { | 402 if ((*queue_iter) == sequence) { |
366 to_return = *queue_iter; | 403 to_return = *queue_iter; |
367 animation_queue_.erase(queue_iter); | 404 animation_queue_.erase(queue_iter); |
368 break; | 405 break; |
369 } | 406 } |
370 } | 407 } |
371 | 408 |
372 return to_return.release(); | 409 return to_return.release(); |
373 } | 410 } |
374 | 411 |
375 void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) { | 412 LayerAnimator::DestroyedType LayerAnimator::FinishAnimation( |
413 LayerAnimationSequence* sequence) { | |
376 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence)); | 414 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence)); |
377 sequence->Progress(sequence->duration(), delegate()); | 415 { |
416 scoped_refptr<DestroyedTracker> tracker(destroyed_tracker_); | |
417 sequence->Progress(sequence->duration(), delegate()); | |
418 if (!tracker->is_alive()) | |
419 return DESTROYED; | |
420 } | |
378 ProcessQueue(); | 421 ProcessQueue(); |
379 UpdateAnimationState(); | 422 UpdateAnimationState(); |
423 return NOT_DESTROYED; | |
380 } | 424 } |
381 | 425 |
382 void LayerAnimator::FinishAnyAnimationWithZeroDuration() { | 426 void LayerAnimator::FinishAnyAnimationWithZeroDuration() { |
383 // Special case: if we've started a 0 duration animation, just finish it now | 427 // Special case: if we've started a 0 duration animation, just finish it now |
384 // and get rid of it. We need to make a copy because Progress may indirectly | 428 // and get rid of it. We need to make a copy because Progress may indirectly |
385 // cause new animations to start running. | 429 // cause new animations to start running. |
386 RunningAnimations running_animations_copy = running_animations_; | 430 RunningAnimations running_animations_copy = running_animations_; |
387 for (size_t i = 0; i < running_animations_copy.size(); ++i) { | 431 for (size_t i = 0; i < running_animations_copy.size(); ++i) { |
388 if (!HasAnimation(running_animations_copy[i].sequence)) | 432 if (!HasAnimation(running_animations_copy[i].sequence)) |
389 continue; | 433 continue; |
390 | 434 |
391 if (running_animations_copy[i].sequence->duration() == base::TimeDelta()) { | 435 if (running_animations_copy[i].sequence->duration() == base::TimeDelta()) { |
392 running_animations_copy[i].sequence->Progress( | 436 running_animations_copy[i].sequence->Progress( |
393 running_animations_copy[i].sequence->duration(), delegate()); | 437 running_animations_copy[i].sequence->duration(), delegate()); |
Ian Vollick
2012/09/06 00:57:35
Seems like there's a chance we could delete 'this'
| |
394 scoped_ptr<LayerAnimationSequence> removed( | 438 scoped_ptr<LayerAnimationSequence> removed( |
395 RemoveAnimation(running_animations_copy[i].sequence)); | 439 RemoveAnimation(running_animations_copy[i].sequence)); |
396 } | 440 } |
397 } | 441 } |
398 ProcessQueue(); | 442 ProcessQueue(); |
399 UpdateAnimationState(); | 443 UpdateAnimationState(); |
400 } | 444 } |
401 | 445 |
402 void LayerAnimator::ClearAnimations() { | 446 void LayerAnimator::ClearAnimations() { |
403 // Abort should never affect the set of running animations, but just in case | 447 // Abort should never affect the set of running animations, but just in case |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 continue; | 501 continue; |
458 | 502 |
459 if (running_animations_copy[i].sequence->HasCommonProperty( | 503 if (running_animations_copy[i].sequence->HasCommonProperty( |
460 sequence->properties())) { | 504 sequence->properties())) { |
461 scoped_ptr<LayerAnimationSequence> removed( | 505 scoped_ptr<LayerAnimationSequence> removed( |
462 RemoveAnimation(running_animations_copy[i].sequence)); | 506 RemoveAnimation(running_animations_copy[i].sequence)); |
463 if (abort) | 507 if (abort) |
464 running_animations_copy[i].sequence->Abort(); | 508 running_animations_copy[i].sequence->Abort(); |
465 else | 509 else |
466 running_animations_copy[i].sequence->Progress( | 510 running_animations_copy[i].sequence->Progress( |
467 running_animations_copy[i].sequence->duration(), delegate()); | 511 running_animations_copy[i].sequence->duration(), delegate()); |
Ian Vollick
2012/09/06 00:57:35
This seems like another place we can bail early if
| |
468 } | 512 } |
469 } | 513 } |
470 | 514 |
471 // Same for the queued animations that haven't been started. Again, we'll | 515 // Same for the queued animations that haven't been started. Again, we'll |
472 // need to operate on a copy. | 516 // need to operate on a copy. |
473 std::vector<LayerAnimationSequence*> sequences; | 517 std::vector<LayerAnimationSequence*> sequences; |
474 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); | 518 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); |
475 queue_iter != animation_queue_.end(); ++queue_iter) | 519 queue_iter != animation_queue_.end(); ++queue_iter) |
476 sequences.push_back((*queue_iter).get()); | 520 sequences.push_back((*queue_iter).get()); |
477 | 521 |
478 for (size_t i = 0; i < sequences.size(); ++i) { | 522 for (size_t i = 0; i < sequences.size(); ++i) { |
479 if (!HasAnimation(sequences[i])) | 523 if (!HasAnimation(sequences[i])) |
480 continue; | 524 continue; |
481 | 525 |
482 if (sequences[i]->HasCommonProperty(sequence->properties())) { | 526 if (sequences[i]->HasCommonProperty(sequence->properties())) { |
483 scoped_ptr<LayerAnimationSequence> removed( | 527 scoped_ptr<LayerAnimationSequence> removed( |
484 RemoveAnimation(sequences[i])); | 528 RemoveAnimation(sequences[i])); |
485 if (abort) | 529 if (abort) |
486 sequences[i]->Abort(); | 530 sequences[i]->Abort(); |
487 else | 531 else |
488 sequences[i]->Progress(sequences[i]->duration(), delegate()); | 532 sequences[i]->Progress(sequences[i]->duration(), delegate()); |
Ian Vollick
2012/09/06 00:57:35
Same here.
| |
489 } | 533 } |
490 } | 534 } |
491 } | 535 } |
492 | 536 |
493 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) { | 537 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) { |
494 // Ensure that sequence is disposed of when this function completes. | 538 // Ensure that sequence is disposed of when this function completes. |
495 scoped_ptr<LayerAnimationSequence> to_dispose(sequence); | 539 scoped_ptr<LayerAnimationSequence> to_dispose(sequence); |
496 const bool abort = false; | 540 const bool abort = false; |
497 RemoveAllAnimationsWithACommonProperty(sequence, abort); | 541 RemoveAllAnimationsWithACommonProperty(sequence, abort); |
498 LayerAnimationSequence* removed = RemoveAnimation(sequence); | 542 LayerAnimationSequence* removed = RemoveAnimation(sequence); |
499 DCHECK(removed == NULL || removed == sequence); | 543 DCHECK(removed == NULL || removed == sequence); |
500 sequence->Progress(sequence->duration(), delegate()); | 544 sequence->Progress(sequence->duration(), delegate()); |
Ian Vollick
2012/09/06 00:57:35
Same here.
| |
501 } | 545 } |
502 | 546 |
503 void LayerAnimator::ImmediatelyAnimateToNewTarget( | 547 void LayerAnimator::ImmediatelyAnimateToNewTarget( |
504 LayerAnimationSequence* sequence) { | 548 LayerAnimationSequence* sequence) { |
505 const bool abort = true; | 549 const bool abort = true; |
506 RemoveAllAnimationsWithACommonProperty(sequence, abort); | 550 RemoveAllAnimationsWithACommonProperty(sequence, abort); |
507 AddToQueueIfNotPresent(sequence); | 551 AddToQueueIfNotPresent(sequence); |
508 StartSequenceImmediately(sequence); | 552 StartSequenceImmediately(sequence); |
509 } | 553 } |
510 | 554 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
627 } | 671 } |
628 } | 672 } |
629 sequence->OnScheduled(); | 673 sequence->OnScheduled(); |
630 } | 674 } |
631 | 675 |
632 base::TimeDelta LayerAnimator::GetTransitionDuration() const { | 676 base::TimeDelta LayerAnimator::GetTransitionDuration() const { |
633 return transition_duration_; | 677 return transition_duration_; |
634 } | 678 } |
635 | 679 |
636 } // namespace ui | 680 } // namespace ui |
OLD | NEW |