Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Side by Side Diff: ui/compositor/layer_animator.cc

Issue 10869066: Attempt 2 at Fixes crash introduced @ 153047 (you can hit crash by maximizing a (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Better fix Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/compositor/layer_animator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « ui/compositor/layer_animator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698