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

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
« no previous file with comments | « ui/compositor/layer_animator.h ('k') | ui/compositor/layer_animator_collection.h » ('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/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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 if (((*iter).sequence()->animation_group_id() == event.group_id) && 334 if (((*iter).sequence()->animation_group_id() == event.group_id) &&
337 !(*iter).sequence()->IsFirstElementThreaded() && 335 !(*iter).sequence()->IsFirstElementThreaded() &&
338 (*iter).sequence()->waiting_for_group_start()) { 336 (*iter).sequence()->waiting_for_group_start()) {
339 (*iter).sequence()->set_start_time(start_time); 337 (*iter).sequence()->set_start_time(start_time);
340 (*iter).sequence()->set_waiting_for_group_start(false); 338 (*iter).sequence()->set_waiting_for_group_start(false);
341 (*iter).sequence()->Start(delegate()); 339 (*iter).sequence()->Start(delegate());
342 } 340 }
343 } 341 }
344 } 342 }
345 343
344 void LayerAnimator::AddToCollection(LayerAnimatorCollection* collection) {
345 if (is_animating() && !is_started_) {
346 collection->StartAnimator(this);
347 is_started_ = true;
348 }
349 }
350
351 void LayerAnimator::RemoveFromCollection(LayerAnimatorCollection* collection) {
352 if (is_animating() && is_started_) {
353 collection->StopAnimator(this);
354 is_started_ = false;
355 }
356 }
357
346 // LayerAnimator protected ----------------------------------------------------- 358 // LayerAnimator protected -----------------------------------------------------
347 359
348 void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence, 360 void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
349 base::TimeTicks now) { 361 base::TimeTicks now) {
350 if (!delegate() || sequence->waiting_for_group_start()) 362 if (!delegate() || sequence->waiting_for_group_start())
351 return; 363 return;
352 364
353 sequence->Progress(now, delegate()); 365 sequence->Progress(now, delegate());
354 } 366 }
355 367
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 continue; 400 continue;
389 401
390 if (running_animations_copy[i].sequence()->IsFinished(now)) { 402 if (running_animations_copy[i].sequence()->IsFinished(now)) {
391 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false); 403 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
392 } else { 404 } else {
393 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now); 405 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
394 } 406 }
395 } 407 }
396 } 408 }
397 409
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) { 410 void LayerAnimator::StopAnimatingInternal(bool abort) {
407 scoped_refptr<LayerAnimator> retain(this); 411 scoped_refptr<LayerAnimator> retain(this);
408 while (is_animating()) { 412 while (is_animating()) {
409 // We're going to attempt to finish the first running animation. Let's 413 // We're going to attempt to finish the first running animation. Let's
410 // ensure that it's valid. 414 // ensure that it's valid.
411 PurgeDeletedAnimations(); 415 PurgeDeletedAnimations();
412 416
413 // If we've purged all running animations, attempt to start one up. 417 // If we've purged all running animations, attempt to start one up.
414 if (running_animations_.empty()) 418 if (running_animations_.empty())
415 ProcessQueue(); 419 ProcessQueue();
416 420
417 DCHECK(!running_animations_.empty()); 421 DCHECK(!running_animations_.empty());
418 422
419 // Still no luck, let's just bail and clear all animations. 423 // Still no luck, let's just bail and clear all animations.
420 if (running_animations_.empty()) { 424 if (running_animations_.empty()) {
421 ClearAnimationsInternal(); 425 ClearAnimationsInternal();
422 break; 426 break;
423 } 427 }
424 428
425 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort); 429 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
426 } 430 }
427 } 431 }
428 432
429 void LayerAnimator::UpdateAnimationState() { 433 void LayerAnimator::UpdateAnimationState() {
430 if (disable_timer_for_test_) 434 if (disable_timer_for_test_)
431 return; 435 return;
432 436
433 const bool should_start = is_animating(); 437 const bool should_start = is_animating();
434 if (should_start && !is_started_) 438 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
435 GetAnimationContainer()->Start(this); 439 if (collection) {
436 else if (!should_start && is_started_) 440 if (should_start && !is_started_)
437 GetAnimationContainer()->Stop(this); 441 collection->StartAnimator(this);
438 442 else if (!should_start && is_started_)
439 is_started_ = should_start; 443 collection->StopAnimator(this);
444 is_started_ = should_start;
445 } else {
446 is_started_ = false;
447 }
440 } 448 }
441 449
442 LayerAnimationSequence* LayerAnimator::RemoveAnimation( 450 LayerAnimationSequence* LayerAnimator::RemoveAnimation(
443 LayerAnimationSequence* sequence) { 451 LayerAnimationSequence* sequence) {
444 linked_ptr<LayerAnimationSequence> to_return; 452 linked_ptr<LayerAnimationSequence> to_return;
445 453
446 bool is_running = false; 454 bool is_running = false;
447 455
448 // First remove from running animations 456 // First remove from running animations
449 for (RunningAnimations::iterator iter = running_animations_.begin(); 457 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(); 754 for (RunningAnimations::const_iterator iter = running_animations_.begin();
747 iter != running_animations_.end(); ++iter) { 755 iter != running_animations_.end(); ++iter) {
748 if ((*iter).sequence()->HasConflictingProperty(sequence->properties())) 756 if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
749 return false; 757 return false;
750 } 758 }
751 759
752 // All clear, actually start the sequence. Note: base::TimeTicks::Now has 760 // 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 761 // 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() 762 // animations, this can be switched to HighResNow() (animation uses Now()
755 // internally). 763 // internally).
756 // All LayerAnimators share the same AnimationContainer. Use the 764 // All LayerAnimators share the same LayerAnimatorCollection. Use the
757 // last_tick_time() from there to ensure animations started during the same 765 // last_tick_time() from there to ensure animations started during the same
758 // event complete at the same time. 766 // event complete at the same time.
759 base::TimeTicks start_time; 767 base::TimeTicks start_time;
768 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
760 if (is_animating() || adding_animations_) 769 if (is_animating() || adding_animations_)
761 start_time = last_step_time_; 770 start_time = last_step_time_;
762 else if (GetAnimationContainer()->is_running()) 771 else if (collection && collection->HasActiveAnimators())
763 start_time = GetAnimationContainer()->last_tick_time(); 772 start_time = collection->last_tick_time();
764 else 773 else
765 start_time = gfx::FrameTime::Now(); 774 start_time = gfx::FrameTime::Now();
766 775
767 if (!sequence->animation_group_id()) 776 if (!sequence->animation_group_id())
768 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId()); 777 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
769 if (!sequence->waiting_for_group_start() || 778 if (!sequence->waiting_for_group_start() ||
770 sequence->IsFirstElementThreaded()) { 779 sequence->IsFirstElementThreaded()) {
771 sequence->set_start_time(start_time); 780 sequence->set_start_time(start_time);
772 sequence->Start(delegate()); 781 sequence->Start(delegate());
773 } 782 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 841
833 void LayerAnimator::PurgeDeletedAnimations() { 842 void LayerAnimator::PurgeDeletedAnimations() {
834 for (size_t i = 0; i < running_animations_.size();) { 843 for (size_t i = 0; i < running_animations_.size();) {
835 if (!running_animations_[i].is_sequence_alive()) 844 if (!running_animations_[i].is_sequence_alive())
836 running_animations_.erase(running_animations_.begin() + i); 845 running_animations_.erase(running_animations_.begin() + i);
837 else 846 else
838 i++; 847 i++;
839 } 848 }
840 } 849 }
841 850
851 LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() {
852 return delegate_ ? delegate_->GetLayerAnimatorCollection() : NULL;
853 }
854
842 LayerAnimator::RunningAnimation::RunningAnimation( 855 LayerAnimator::RunningAnimation::RunningAnimation(
843 const base::WeakPtr<LayerAnimationSequence>& sequence) 856 const base::WeakPtr<LayerAnimationSequence>& sequence)
844 : sequence_(sequence) { 857 : sequence_(sequence) {
845 } 858 }
846 859
847 LayerAnimator::RunningAnimation::~RunningAnimation() { } 860 LayerAnimator::RunningAnimation::~RunningAnimation() { }
848 861
849 } // namespace ui 862 } // namespace ui
OLDNEW
« no previous file with comments | « ui/compositor/layer_animator.h ('k') | ui/compositor/layer_animator_collection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698