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

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

Issue 11896017: Thread ui opacity animations (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix ash_unittests Created 7 years, 10 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
« no previous file with comments | « ui/compositor/layer_animator.h ('k') | ui/compositor/layer_animator_unittest.cc » ('j') | 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 "cc/animation_id_provider.h"
10 #include "ui/base/animation/animation_container.h" 11 #include "ui/base/animation/animation_container.h"
11 #include "ui/compositor/compositor.h" 12 #include "ui/compositor/compositor.h"
12 #include "ui/compositor/layer.h" 13 #include "ui/compositor/layer.h"
13 #include "ui/compositor/layer_animation_delegate.h" 14 #include "ui/compositor/layer_animation_delegate.h"
14 #include "ui/compositor/layer_animation_observer.h" 15 #include "ui/compositor/layer_animation_observer.h"
15 #include "ui/compositor/layer_animation_sequence.h" 16 #include "ui/compositor/layer_animation_sequence.h"
16 17
17 #define SAFE_INVOKE_VOID(function, running_anim, ...) \ 18 #define SAFE_INVOKE_VOID(function, running_anim, ...) \
18 if (running_anim.is_sequence_alive()) \ 19 if (running_anim.is_sequence_alive()) \
19 function(running_anim.sequence(), ##__VA_ARGS__) 20 function(running_anim.sequence(), ##__VA_ARGS__)
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 } 196 }
196 197
197 // Starting a zero duration pause that affects all the animated properties 198 // Starting a zero duration pause that affects all the animated properties
198 // will prevent any of the sequences from animating until there are no 199 // will prevent any of the sequences from animating until there are no
199 // running animations that affect any of these properties, as well as 200 // running animations that affect any of these properties, as well as
200 // handle preemption strategy. 201 // handle preemption strategy.
201 StartAnimation(new LayerAnimationSequence( 202 StartAnimation(new LayerAnimationSequence(
202 LayerAnimationElement::CreatePauseElement(animated_properties, 203 LayerAnimationElement::CreatePauseElement(animated_properties,
203 base::TimeDelta()))); 204 base::TimeDelta())));
204 205
206 bool wait_for_group_start = false;
207 for (iter = animations.begin(); iter != animations.end(); ++iter)
208 wait_for_group_start |= (*iter)->IsFirstElementThreaded();
209
210 int group_id = cc::AnimationIdProvider::NextGroupId();
211
205 // These animations (provided they don't animate any common properties) will 212 // These animations (provided they don't animate any common properties) will
206 // now animate together if trivially scheduled. 213 // now animate together if trivially scheduled.
207 for (iter = animations.begin(); iter != animations.end(); ++iter) { 214 for (iter = animations.begin(); iter != animations.end(); ++iter) {
215 (*iter)->set_animation_group_id(group_id);
216 (*iter)->set_waiting_for_group_start(wait_for_group_start);
208 ScheduleAnimation(*iter); 217 ScheduleAnimation(*iter);
209 } 218 }
210 219
211 adding_animations_ = false; 220 adding_animations_ = false;
212 UpdateAnimationState(); 221 UpdateAnimationState();
213 } 222 }
214 223
215 224
216 void LayerAnimator::ScheduleTogether( 225 void LayerAnimator::ScheduleTogether(
217 const std::vector<LayerAnimationSequence*>& animations) { 226 const std::vector<LayerAnimationSequence*>& animations) {
218 scoped_refptr<LayerAnimator> retain(this); 227 scoped_refptr<LayerAnimator> retain(this);
219 228
220 // Collect all the affected properties. 229 // Collect all the affected properties.
221 LayerAnimationElement::AnimatableProperties animated_properties; 230 LayerAnimationElement::AnimatableProperties animated_properties;
222 std::vector<LayerAnimationSequence*>::const_iterator iter; 231 std::vector<LayerAnimationSequence*>::const_iterator iter;
223 for (iter = animations.begin(); iter != animations.end(); ++iter) { 232 for (iter = animations.begin(); iter != animations.end(); ++iter) {
224 animated_properties.insert((*iter)->properties().begin(), 233 animated_properties.insert((*iter)->properties().begin(),
225 (*iter)->properties().end()); 234 (*iter)->properties().end());
226 } 235 }
227 236
228 // Scheduling a zero duration pause that affects all the animated properties 237 // Scheduling a zero duration pause that affects all the animated properties
229 // will prevent any of the sequences from animating until there are no 238 // will prevent any of the sequences from animating until there are no
230 // running animations that affect any of these properties. 239 // running animations that affect any of these properties.
231 ScheduleAnimation(new LayerAnimationSequence( 240 ScheduleAnimation(new LayerAnimationSequence(
232 LayerAnimationElement::CreatePauseElement(animated_properties, 241 LayerAnimationElement::CreatePauseElement(animated_properties,
233 base::TimeDelta()))); 242 base::TimeDelta())));
234 243
244 bool wait_for_group_start = false;
245 for (iter = animations.begin(); iter != animations.end(); ++iter)
246 wait_for_group_start |= (*iter)->IsFirstElementThreaded();
247
248 int group_id = cc::AnimationIdProvider::NextGroupId();
249
235 // These animations (provided they don't animate any common properties) will 250 // These animations (provided they don't animate any common properties) will
236 // now animate together if trivially scheduled. 251 // now animate together if trivially scheduled.
237 for (iter = animations.begin(); iter != animations.end(); ++iter) { 252 for (iter = animations.begin(); iter != animations.end(); ++iter) {
253 (*iter)->set_animation_group_id(group_id);
254 (*iter)->set_waiting_for_group_start(wait_for_group_start);
238 ScheduleAnimation(*iter); 255 ScheduleAnimation(*iter);
239 } 256 }
240 257
241 UpdateAnimationState(); 258 UpdateAnimationState();
242 } 259 }
243 260
244 void LayerAnimator::SchedulePauseForProperties( 261 void LayerAnimator::SchedulePauseForProperties(
245 base::TimeDelta duration, 262 base::TimeDelta duration,
246 LayerAnimationElement::AnimatableProperty property, 263 LayerAnimationElement::AnimatableProperty property,
247 ...) { 264 ...) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 309
293 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) { 310 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
294 observers_.RemoveObserver(observer); 311 observers_.RemoveObserver(observer);
295 // Remove the observer from all sequences as well. 312 // Remove the observer from all sequences as well.
296 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 313 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
297 queue_iter != animation_queue_.end(); ++queue_iter) { 314 queue_iter != animation_queue_.end(); ++queue_iter) {
298 (*queue_iter)->RemoveObserver(observer); 315 (*queue_iter)->RemoveObserver(observer);
299 } 316 }
300 } 317 }
301 318
319 void LayerAnimator::OnThreadedAnimationStarted(
320 const cc::AnimationEvent& event) {
321 LayerAnimationElement::AnimatableProperty property =
322 LayerAnimationElement::ToAnimatableProperty(event.targetProperty);
323
324 RunningAnimation* running = GetRunningAnimation(property);
325 if (!running)
326 return;
327 DCHECK(running->is_sequence_alive());
328
329 if (running->sequence()->animation_group_id() != event.groupId)
330 return;
331
332 running->sequence()->OnThreadedAnimationStarted(event);
333 if (!running->sequence()->waiting_for_group_start())
334 return;
335
336 base::TimeTicks start_time = base::TimeTicks::FromInternalValue(
337 event.monotonicTime * base::Time::kMicrosecondsPerSecond);
338
339 running->sequence()->set_waiting_for_group_start(false);
340
341 // The call to GetRunningAnimation made above already purged deleted
342 // animations, so we are guaranteed that all the animations we iterate
343 // over now are alive.
344 for (RunningAnimations::iterator iter = running_animations_.begin();
345 iter != running_animations_.end(); ++iter) {
346 // Ensure that each sequence is only Started once, regardless of the
347 // number of sequences in the group that have threaded first elements.
348 if (((*iter).sequence()->animation_group_id() == event.groupId) &&
349 !(*iter).sequence()->IsFirstElementThreaded() &&
350 (*iter).sequence()->waiting_for_group_start()) {
351 (*iter).sequence()->set_start_time(start_time);
352 (*iter).sequence()->set_waiting_for_group_start(false);
353 (*iter).sequence()->Start(delegate());
354 }
355 }
356 }
357
302 // LayerAnimator protected ----------------------------------------------------- 358 // LayerAnimator protected -----------------------------------------------------
303 359
304 void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence, 360 void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
305 base::TimeTicks now) { 361 base::TimeTicks now) {
306 if (!delegate()) 362 if (!delegate() || sequence->waiting_for_group_start())
307 return; 363 return;
308 364
309 sequence->Progress(now, delegate()); 365 sequence->Progress(now, delegate());
310 } 366 }
311 367
312 void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) { 368 void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
313 if (!delegate()) 369 if (!delegate())
314 return; 370 return;
315 371
316 sequence->ProgressToEnd(delegate()); 372 sequence->ProgressToEnd(delegate());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 else if (!should_start && is_started_) 448 else if (!should_start && is_started_)
393 GetAnimationContainer()->Stop(this); 449 GetAnimationContainer()->Stop(this);
394 450
395 is_started_ = should_start; 451 is_started_ = should_start;
396 } 452 }
397 453
398 LayerAnimationSequence* LayerAnimator::RemoveAnimation( 454 LayerAnimationSequence* LayerAnimator::RemoveAnimation(
399 LayerAnimationSequence* sequence) { 455 LayerAnimationSequence* sequence) {
400 linked_ptr<LayerAnimationSequence> to_return; 456 linked_ptr<LayerAnimationSequence> to_return;
401 457
458 bool is_running = false;
459
402 // First remove from running animations 460 // First remove from running animations
403 for (RunningAnimations::iterator iter = running_animations_.begin(); 461 for (RunningAnimations::iterator iter = running_animations_.begin();
404 iter != running_animations_.end(); ++iter) { 462 iter != running_animations_.end(); ++iter) {
405 if ((*iter).sequence() == sequence) { 463 if ((*iter).sequence() == sequence) {
406 running_animations_.erase(iter); 464 running_animations_.erase(iter);
465 is_running = true;
407 break; 466 break;
408 } 467 }
409 } 468 }
410 469
411 // Then remove from the queue 470 // Then remove from the queue
412 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 471 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
413 queue_iter != animation_queue_.end(); ++queue_iter) { 472 queue_iter != animation_queue_.end(); ++queue_iter) {
414 if ((*queue_iter) == sequence) { 473 if ((*queue_iter) == sequence) {
415 to_return = *queue_iter; 474 to_return = *queue_iter;
416 animation_queue_.erase(queue_iter); 475 animation_queue_.erase(queue_iter);
417 break; 476 break;
418 } 477 }
419 } 478 }
420 479
480 if (!to_return.get() ||
481 !to_return->waiting_for_group_start() ||
482 !to_return->IsFirstElementThreaded())
483 return to_return.release();
484
485 // The removed sequence may have been responsible for making other sequences
486 // wait for a group start. If no other sequences in the group have a
487 // threaded first element, the group no longer needs the additional wait.
488 bool is_wait_still_needed = false;
489 int group_id = to_return->animation_group_id();
490 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
491 queue_iter != animation_queue_.end(); ++queue_iter) {
492 if (((*queue_iter)->animation_group_id() == group_id) &&
493 (*queue_iter)->IsFirstElementThreaded()) {
494 is_wait_still_needed = true;
495 break;
496 }
497 }
498
499 if (is_wait_still_needed)
500 return to_return.release();
501
502 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
503 queue_iter != animation_queue_.end(); ++queue_iter) {
504 if ((*queue_iter)->animation_group_id() == group_id &&
505 (*queue_iter)->waiting_for_group_start()) {
506 (*queue_iter)->set_waiting_for_group_start(false);
507 if (is_running) {
508 (*queue_iter)->set_start_time(last_step_time_);
509 (*queue_iter)->Start(delegate());
510 }
511 }
512 }
421 return to_return.release(); 513 return to_return.release();
422 } 514 }
423 515
424 void LayerAnimator::FinishAnimation( 516 void LayerAnimator::FinishAnimation(
425 LayerAnimationSequence* sequence, bool abort) { 517 LayerAnimationSequence* sequence, bool abort) {
426 scoped_refptr<LayerAnimator> retain(this); 518 scoped_refptr<LayerAnimator> retain(this);
427 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence)); 519 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
428 if (abort) 520 if (abort)
429 sequence->Abort(); 521 sequence->Abort(delegate());
430 else 522 else
431 ProgressAnimationToEnd(sequence); 523 ProgressAnimationToEnd(sequence);
432 ProcessQueue(); 524 ProcessQueue();
433 UpdateAnimationState(); 525 UpdateAnimationState();
434 } 526 }
435 527
436 void LayerAnimator::FinishAnyAnimationWithZeroDuration() { 528 void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
437 scoped_refptr<LayerAnimator> retain(this); 529 scoped_refptr<LayerAnimator> retain(this);
438 // Special case: if we've started a 0 duration animation, just finish it now 530 // Special case: if we've started a 0 duration animation, just finish it now
439 // and get rid of it. We need to make a copy because Progress may indirectly 531 // and get rid of it. We need to make a copy because Progress may indirectly
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 RunningAnimations running_animations_copy = running_animations_; 587 RunningAnimations running_animations_copy = running_animations_;
496 for (size_t i = 0; i < running_animations_copy.size(); ++i) { 588 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
497 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i])) 589 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
498 continue; 590 continue;
499 591
500 if (running_animations_copy[i].sequence()->HasCommonProperty( 592 if (running_animations_copy[i].sequence()->HasCommonProperty(
501 sequence->properties())) { 593 sequence->properties())) {
502 scoped_ptr<LayerAnimationSequence> removed( 594 scoped_ptr<LayerAnimationSequence> removed(
503 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i])); 595 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
504 if (abort) 596 if (abort)
505 running_animations_copy[i].sequence()->Abort(); 597 running_animations_copy[i].sequence()->Abort(delegate());
506 else 598 else
507 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]); 599 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
508 } 600 }
509 } 601 }
510 602
511 // Same for the queued animations that haven't been started. Again, we'll 603 // Same for the queued animations that haven't been started. Again, we'll
512 // need to operate on a copy. 604 // need to operate on a copy.
513 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences; 605 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
514 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); 606 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
515 queue_iter != animation_queue_.end(); ++queue_iter) 607 queue_iter != animation_queue_.end(); ++queue_iter)
516 sequences.push_back((*queue_iter)->AsWeakPtr()); 608 sequences.push_back((*queue_iter)->AsWeakPtr());
517 609
518 for (size_t i = 0; i < sequences.size(); ++i) { 610 for (size_t i = 0; i < sequences.size(); ++i) {
519 if (!sequences[i] || !HasAnimation(sequences[i])) 611 if (!sequences[i] || !HasAnimation(sequences[i]))
520 continue; 612 continue;
521 613
522 if (sequences[i]->HasCommonProperty(sequence->properties())) { 614 if (sequences[i]->HasCommonProperty(sequence->properties())) {
523 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequences[i])); 615 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequences[i]));
524 if (abort) 616 if (abort)
525 sequences[i]->Abort(); 617 sequences[i]->Abort(delegate());
526 else 618 else
527 ProgressAnimationToEnd(sequences[i]); 619 ProgressAnimationToEnd(sequences[i]);
528 } 620 }
529 } 621 }
530 } 622 }
531 623
532 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) { 624 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
533 // Need to detect if our sequence gets destroyed. 625 // Need to detect if our sequence gets destroyed.
534 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr = 626 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
535 sequence->AsWeakPtr(); 627 sequence->AsWeakPtr();
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 // last_tick_time() from there to ensure animations started during the same 769 // last_tick_time() from there to ensure animations started during the same
678 // event complete at the same time. 770 // event complete at the same time.
679 base::TimeTicks start_time; 771 base::TimeTicks start_time;
680 if (is_animating() || adding_animations_) 772 if (is_animating() || adding_animations_)
681 start_time = last_step_time_; 773 start_time = last_step_time_;
682 else if (GetAnimationContainer()->is_running()) 774 else if (GetAnimationContainer()->is_running())
683 start_time = GetAnimationContainer()->last_tick_time(); 775 start_time = GetAnimationContainer()->last_tick_time();
684 else 776 else
685 start_time = base::TimeTicks::Now(); 777 start_time = base::TimeTicks::Now();
686 778
687 sequence->set_start_time(start_time); 779 if (!sequence->animation_group_id())
780 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
781 if (!sequence->waiting_for_group_start() ||
782 sequence->IsFirstElementThreaded()) {
783 sequence->set_start_time(start_time);
784 sequence->Start(delegate());
785 }
688 running_animations_.push_back( 786 running_animations_.push_back(
689 RunningAnimation(sequence->AsWeakPtr())); 787 RunningAnimation(sequence->AsWeakPtr()));
690 788
691 // Need to keep a reference to the animation. 789 // Need to keep a reference to the animation.
692 AddToQueueIfNotPresent(sequence); 790 AddToQueueIfNotPresent(sequence);
693 791
694 // Ensure that animations get stepped at their start time. 792 // Ensure that animations get stepped at their start time.
695 Step(start_time); 793 Step(start_time);
696 794
697 return true; 795 return true;
(...skipping 28 matching lines...) Expand all
726 // Abort should never affect the set of running animations, but just in case 824 // Abort should never affect the set of running animations, but just in case
727 // clients are badly behaved, we will use a copy of the running animations. 825 // clients are badly behaved, we will use a copy of the running animations.
728 RunningAnimations running_animations_copy = running_animations_; 826 RunningAnimations running_animations_copy = running_animations_;
729 for (size_t i = 0; i < running_animations_copy.size(); ++i) { 827 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
730 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i])) 828 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
731 continue; 829 continue;
732 830
733 scoped_ptr<LayerAnimationSequence> removed( 831 scoped_ptr<LayerAnimationSequence> removed(
734 RemoveAnimation(running_animations_copy[i].sequence())); 832 RemoveAnimation(running_animations_copy[i].sequence()));
735 if (removed.get()) 833 if (removed.get())
736 removed->Abort(); 834 removed->Abort(delegate());
737 } 835 }
738 // This *should* have cleared the list of running animations. 836 // This *should* have cleared the list of running animations.
739 DCHECK(running_animations_.empty()); 837 DCHECK(running_animations_.empty());
740 running_animations_.clear(); 838 running_animations_.clear();
741 animation_queue_.clear(); 839 animation_queue_.clear();
742 UpdateAnimationState(); 840 UpdateAnimationState();
743 } 841 }
744 842
745 void LayerAnimator::PurgeDeletedAnimations() { 843 void LayerAnimator::PurgeDeletedAnimations() {
746 for (size_t i = 0; i < running_animations_.size();) { 844 for (size_t i = 0; i < running_animations_.size();) {
747 if (!running_animations_[i].is_sequence_alive()) 845 if (!running_animations_[i].is_sequence_alive())
748 running_animations_.erase(running_animations_.begin() + i); 846 running_animations_.erase(running_animations_.begin() + i);
749 else 847 else
750 i++; 848 i++;
751 } 849 }
752 } 850 }
753 851
754 LayerAnimator::RunningAnimation::RunningAnimation( 852 LayerAnimator::RunningAnimation::RunningAnimation(
755 const base::WeakPtr<LayerAnimationSequence>& sequence) 853 const base::WeakPtr<LayerAnimationSequence>& sequence)
756 : sequence_(sequence) { 854 : sequence_(sequence) {
757 } 855 }
758 856
759 LayerAnimator::RunningAnimation::~RunningAnimation() { } 857 LayerAnimator::RunningAnimation::~RunningAnimation() { }
760 858
761 } // namespace ui 859 } // namespace ui
OLDNEW
« no previous file with comments | « ui/compositor/layer_animator.h ('k') | ui/compositor/layer_animator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698