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

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

Issue 291843012: compositor: Tick the UI animations from cc, instead of from timer callbacks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 6 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
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/animation_id_provider.h" 10 #include "cc/animation/animation_id_provider.h"
11 #include "cc/output/begin_frame_args.h" 11 #include "cc/output/begin_frame_args.h"
12 #include "ui/compositor/compositor.h" 12 #include "ui/compositor/compositor.h"
13 #include "ui/compositor/layer.h" 13 #include "ui/compositor/layer.h"
14 #include "ui/compositor/layer_animation_delegate.h" 14 #include "ui/compositor/layer_animation_delegate.h"
15 #include "ui/compositor/layer_animation_observer.h" 15 #include "ui/compositor/layer_animation_observer.h"
16 #include "ui/compositor/layer_animation_sequence.h" 16 #include "ui/compositor/layer_animation_sequence.h"
17 #include "ui/gfx/animation/animation_container.h" 17 #include "ui/compositor/layer_animator_collection.h"
18 #include "ui/gfx/frame_time.h" 18 #include "ui/gfx/frame_time.h"
19 19
20 #define SAFE_INVOKE_VOID(function, running_anim, ...) \ 20 #define SAFE_INVOKE_VOID(function, running_anim, ...) \
21 if (running_anim.is_sequence_alive()) \ 21 if (running_anim.is_sequence_alive()) \
22 function(running_anim.sequence(), ##__VA_ARGS__) 22 function(running_anim.sequence(), ##__VA_ARGS__)
23 #define SAFE_INVOKE_BOOL(function, running_anim) \ 23 #define SAFE_INVOKE_BOOL(function, running_anim) \
24 ((running_anim.is_sequence_alive()) \ 24 ((running_anim.is_sequence_alive()) \
25 ? function(running_anim.sequence()) \ 25 ? function(running_anim.sequence()) \
26 : false) 26 : false)
27 #define SAFE_INVOKE_PTR(function, running_anim) \ 27 #define SAFE_INVOKE_PTR(function, running_anim) \
28 ((running_anim.is_sequence_alive()) \ 28 ((running_anim.is_sequence_alive()) \
29 ? function(running_anim.sequence()) \ 29 ? function(running_anim.sequence()) \
30 : NULL) 30 : NULL)
31 31
32 namespace ui { 32 namespace ui {
33 33
34 class LayerAnimator;
35
36 namespace { 34 namespace {
37 35
38 const int kDefaultTransitionDurationMs = 120; 36 const int kDefaultTransitionDurationMs = 120;
39 const int kTimerIntervalMs = 10;
40
41 // Returns the AnimationContainer we're added to.
42 gfx::AnimationContainer* GetAnimationContainer() {
43 static gfx::AnimationContainer* container = NULL;
44 if (!container) {
45 container = new gfx::AnimationContainer();
46 container->AddRef();
47 }
48 return container;
49 }
50 37
51 } // namespace 38 } // namespace
52 39
53 // LayerAnimator public -------------------------------------------------------- 40 // LayerAnimator public --------------------------------------------------------
54 41
55 LayerAnimator::LayerAnimator(base::TimeDelta transition_duration) 42 LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
56 : delegate_(NULL), 43 : delegate_(NULL),
57 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET), 44 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
58 is_transition_duration_locked_(false), 45 is_transition_duration_locked_(false),
59 transition_duration_(transition_duration), 46 transition_duration_(transition_duration),
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility); 104 ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility);
118 ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness); 105 ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness);
119 ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale); 106 ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale);
120 ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color); 107 ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color);
121 108
122 base::TimeDelta LayerAnimator::GetTransitionDuration() const { 109 base::TimeDelta LayerAnimator::GetTransitionDuration() const {
123 return transition_duration_; 110 return transition_duration_;
124 } 111 }
125 112
126 void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) { 113 void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
114 if (delegate_ && is_started_) {
115 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
116 if (collection)
117 collection->StopAnimator(this);
118 }
127 delegate_ = delegate; 119 delegate_ = delegate;
120 if (delegate_ && is_started_) {
121 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
122 if (collection)
123 collection->StartAnimator(this);
124 }
128 } 125 }
129 126
130 void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) { 127 void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
131 scoped_refptr<LayerAnimator> retain(this); 128 scoped_refptr<LayerAnimator> retain(this);
132 OnScheduled(animation); 129 OnScheduled(animation);
133 if (!StartSequenceImmediately(animation)) { 130 if (!StartSequenceImmediately(animation)) {
134 // Attempt to preempt a running animation. 131 // Attempt to preempt a running animation.
135 switch (preemption_strategy_) { 132 switch (preemption_strategy_) {
136 case IMMEDIATELY_SET_NEW_TARGET: 133 case IMMEDIATELY_SET_NEW_TARGET:
137 ImmediatelySetNewTarget(animation); 134 ImmediatelySetNewTarget(animation);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) { 171 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
175 std::vector<LayerAnimationSequence*>::const_iterator iter; 172 std::vector<LayerAnimationSequence*>::const_iterator iter;
176 for (iter = animations.begin(); iter != animations.end(); ++iter) { 173 for (iter = animations.begin(); iter != animations.end(); ++iter) {
177 StartAnimation(*iter); 174 StartAnimation(*iter);
178 } 175 }
179 return; 176 return;
180 } 177 }
181 178
182 adding_animations_ = true; 179 adding_animations_ = true;
183 if (!is_animating()) { 180 if (!is_animating()) {
184 if (GetAnimationContainer()->is_running()) 181 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
185 last_step_time_ = GetAnimationContainer()->last_tick_time(); 182 if (collection && collection->HasActiveAnimators())
183 last_step_time_ = collection->last_tick_time();
186 else 184 else
187 last_step_time_ = gfx::FrameTime::Now(); 185 last_step_time_ = gfx::FrameTime::Now();
188 } 186 }
189 187
190 // Collect all the affected properties. 188 // Collect all the affected properties.
191 LayerAnimationElement::AnimatableProperties animated_properties = 189 LayerAnimationElement::AnimatableProperties animated_properties =
192 LayerAnimationElement::UNKNOWN; 190 LayerAnimationElement::UNKNOWN;
193 191
194 std::vector<LayerAnimationSequence*>::const_iterator iter; 192 std::vector<LayerAnimationSequence*>::const_iterator iter;
195 for (iter = animations.begin(); iter != animations.end(); ++iter) 193 for (iter = animations.begin(); iter != animations.end(); ++iter)
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 continue; 386 continue;
389 387
390 if (running_animations_copy[i].sequence()->IsFinished(now)) { 388 if (running_animations_copy[i].sequence()->IsFinished(now)) {
391 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false); 389 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
392 } else { 390 } else {
393 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now); 391 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
394 } 392 }
395 } 393 }
396 } 394 }
397 395
398 void LayerAnimator::SetStartTime(base::TimeTicks start_time) {
399 // Do nothing.
400 }
401
402 base::TimeDelta LayerAnimator::GetTimerInterval() const {
403 return base::TimeDelta::FromMilliseconds(kTimerIntervalMs);
404 }
405
406 void LayerAnimator::StopAnimatingInternal(bool abort) { 396 void LayerAnimator::StopAnimatingInternal(bool abort) {
407 scoped_refptr<LayerAnimator> retain(this); 397 scoped_refptr<LayerAnimator> retain(this);
408 while (is_animating()) { 398 while (is_animating()) {
409 // We're going to attempt to finish the first running animation. Let's 399 // We're going to attempt to finish the first running animation. Let's
410 // ensure that it's valid. 400 // ensure that it's valid.
411 PurgeDeletedAnimations(); 401 PurgeDeletedAnimations();
412 402
413 // If we've purged all running animations, attempt to start one up. 403 // If we've purged all running animations, attempt to start one up.
414 if (running_animations_.empty()) 404 if (running_animations_.empty())
415 ProcessQueue(); 405 ProcessQueue();
416 406
417 DCHECK(!running_animations_.empty()); 407 DCHECK(!running_animations_.empty());
418 408
419 // Still no luck, let's just bail and clear all animations. 409 // Still no luck, let's just bail and clear all animations.
420 if (running_animations_.empty()) { 410 if (running_animations_.empty()) {
421 ClearAnimationsInternal(); 411 ClearAnimationsInternal();
422 break; 412 break;
423 } 413 }
424 414
425 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort); 415 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
426 } 416 }
427 } 417 }
428 418
429 void LayerAnimator::UpdateAnimationState() { 419 void LayerAnimator::UpdateAnimationState() {
430 if (disable_timer_for_test_) 420 if (disable_timer_for_test_)
431 return; 421 return;
432 422
433 const bool should_start = is_animating(); 423 const bool should_start = is_animating();
434 if (should_start && !is_started_) 424 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
435 GetAnimationContainer()->Start(this); 425 if (collection) {
436 else if (!should_start && is_started_) 426 if (should_start && !is_started_)
437 GetAnimationContainer()->Stop(this); 427 collection->StartAnimator(this);
438 428 else if (!should_start && is_started_)
439 is_started_ = should_start; 429 collection->StopAnimator(this);
430 is_started_ = should_start;
431 } else {
432 is_started_ = false;
433 }
440 } 434 }
441 435
442 LayerAnimationSequence* LayerAnimator::RemoveAnimation( 436 LayerAnimationSequence* LayerAnimator::RemoveAnimation(
443 LayerAnimationSequence* sequence) { 437 LayerAnimationSequence* sequence) {
444 linked_ptr<LayerAnimationSequence> to_return; 438 linked_ptr<LayerAnimationSequence> to_return;
445 439
446 bool is_running = false; 440 bool is_running = false;
447 441
448 // First remove from running animations 442 // First remove from running animations
449 for (RunningAnimations::iterator iter = running_animations_.begin(); 443 for (RunningAnimations::iterator iter = running_animations_.begin();
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 for (RunningAnimations::const_iterator iter = running_animations_.begin(); 740 for (RunningAnimations::const_iterator iter = running_animations_.begin();
747 iter != running_animations_.end(); ++iter) { 741 iter != running_animations_.end(); ++iter) {
748 if ((*iter).sequence()->HasConflictingProperty(sequence->properties())) 742 if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
749 return false; 743 return false;
750 } 744 }
751 745
752 // All clear, actually start the sequence. Note: base::TimeTicks::Now has 746 // All clear, actually start the sequence. Note: base::TimeTicks::Now has
753 // a resolution that can be as bad as 15ms. If this causes glitches in the 747 // a resolution that can be as bad as 15ms. If this causes glitches in the
754 // animations, this can be switched to HighResNow() (animation uses Now() 748 // animations, this can be switched to HighResNow() (animation uses Now()
755 // internally). 749 // internally).
756 // All LayerAnimators share the same AnimationContainer. Use the 750 // All LayerAnimators share the same LayerAnimatorCollection. Use the
757 // last_tick_time() from there to ensure animations started during the same 751 // last_tick_time() from there to ensure animations started during the same
758 // event complete at the same time. 752 // event complete at the same time.
759 base::TimeTicks start_time; 753 base::TimeTicks start_time;
754 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
760 if (is_animating() || adding_animations_) 755 if (is_animating() || adding_animations_)
761 start_time = last_step_time_; 756 start_time = last_step_time_;
762 else if (GetAnimationContainer()->is_running()) 757 else if (collection && collection->HasActiveAnimators())
763 start_time = GetAnimationContainer()->last_tick_time(); 758 start_time = collection->last_tick_time();
764 else 759 else
765 start_time = gfx::FrameTime::Now(); 760 start_time = gfx::FrameTime::Now();
766 761
767 if (!sequence->animation_group_id()) 762 if (!sequence->animation_group_id())
768 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId()); 763 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
769 if (!sequence->waiting_for_group_start() || 764 if (!sequence->waiting_for_group_start() ||
770 sequence->IsFirstElementThreaded()) { 765 sequence->IsFirstElementThreaded()) {
771 sequence->set_start_time(start_time); 766 sequence->set_start_time(start_time);
772 sequence->Start(delegate()); 767 sequence->Start(delegate());
773 } 768 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 827
833 void LayerAnimator::PurgeDeletedAnimations() { 828 void LayerAnimator::PurgeDeletedAnimations() {
834 for (size_t i = 0; i < running_animations_.size();) { 829 for (size_t i = 0; i < running_animations_.size();) {
835 if (!running_animations_[i].is_sequence_alive()) 830 if (!running_animations_[i].is_sequence_alive())
836 running_animations_.erase(running_animations_.begin() + i); 831 running_animations_.erase(running_animations_.begin() + i);
837 else 832 else
838 i++; 833 i++;
839 } 834 }
840 } 835 }
841 836
837 LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() {
838 return delegate_ ? delegate_->GetLayerAnimatorCollection() : NULL;
839 }
840
842 LayerAnimator::RunningAnimation::RunningAnimation( 841 LayerAnimator::RunningAnimation::RunningAnimation(
843 const base::WeakPtr<LayerAnimationSequence>& sequence) 842 const base::WeakPtr<LayerAnimationSequence>& sequence)
844 : sequence_(sequence) { 843 : sequence_(sequence) {
845 } 844 }
846 845
847 LayerAnimator::RunningAnimation::~RunningAnimation() { } 846 LayerAnimator::RunningAnimation::~RunningAnimation() { }
848 847
849 } // namespace ui 848 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698