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 "cc/animation/animation_id_provider.h" | 10 #include "cc/animation/animation_id_provider.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 181 |
182 adding_animations_ = true; | 182 adding_animations_ = true; |
183 if (!is_animating()) { | 183 if (!is_animating()) { |
184 if (GetAnimationContainer()->is_running()) | 184 if (GetAnimationContainer()->is_running()) |
185 last_step_time_ = GetAnimationContainer()->last_tick_time(); | 185 last_step_time_ = GetAnimationContainer()->last_tick_time(); |
186 else | 186 else |
187 last_step_time_ = gfx::FrameTime::Now(); | 187 last_step_time_ = gfx::FrameTime::Now(); |
188 } | 188 } |
189 | 189 |
190 // Collect all the affected properties. | 190 // Collect all the affected properties. |
191 LayerAnimationElement::AnimatableProperties animated_properties; | 191 LayerAnimationElement::AnimatableProperties animated_properties = |
| 192 LayerAnimationElement::UNKNOWN; |
| 193 |
192 std::vector<LayerAnimationSequence*>::const_iterator iter; | 194 std::vector<LayerAnimationSequence*>::const_iterator iter; |
193 for (iter = animations.begin(); iter != animations.end(); ++iter) { | 195 for (iter = animations.begin(); iter != animations.end(); ++iter) |
194 animated_properties.insert((*iter)->properties().begin(), | 196 animated_properties |= (*iter)->properties(); |
195 (*iter)->properties().end()); | |
196 } | |
197 | 197 |
198 // Starting a zero duration pause that affects all the animated properties | 198 // Starting a zero duration pause that affects all the animated properties |
199 // 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 |
200 // running animations that affect any of these properties, as well as | 200 // running animations that affect any of these properties, as well as |
201 // handle preemption strategy. | 201 // handle preemption strategy. |
202 StartAnimation(new LayerAnimationSequence( | 202 StartAnimation(new LayerAnimationSequence( |
203 LayerAnimationElement::CreatePauseElement(animated_properties, | 203 LayerAnimationElement::CreatePauseElement(animated_properties, |
204 base::TimeDelta()))); | 204 base::TimeDelta()))); |
205 | 205 |
206 bool wait_for_group_start = false; | 206 bool wait_for_group_start = false; |
(...skipping 13 matching lines...) Expand all Loading... |
220 adding_animations_ = false; | 220 adding_animations_ = false; |
221 UpdateAnimationState(); | 221 UpdateAnimationState(); |
222 } | 222 } |
223 | 223 |
224 | 224 |
225 void LayerAnimator::ScheduleTogether( | 225 void LayerAnimator::ScheduleTogether( |
226 const std::vector<LayerAnimationSequence*>& animations) { | 226 const std::vector<LayerAnimationSequence*>& animations) { |
227 scoped_refptr<LayerAnimator> retain(this); | 227 scoped_refptr<LayerAnimator> retain(this); |
228 | 228 |
229 // Collect all the affected properties. | 229 // Collect all the affected properties. |
230 LayerAnimationElement::AnimatableProperties animated_properties; | 230 LayerAnimationElement::AnimatableProperties animated_properties = |
| 231 LayerAnimationElement::UNKNOWN; |
| 232 |
231 std::vector<LayerAnimationSequence*>::const_iterator iter; | 233 std::vector<LayerAnimationSequence*>::const_iterator iter; |
232 for (iter = animations.begin(); iter != animations.end(); ++iter) { | 234 for (iter = animations.begin(); iter != animations.end(); ++iter) |
233 animated_properties.insert((*iter)->properties().begin(), | 235 animated_properties |= (*iter)->properties(); |
234 (*iter)->properties().end()); | |
235 } | |
236 | 236 |
237 // Scheduling a zero duration pause that affects all the animated properties | 237 // Scheduling a zero duration pause that affects all the animated properties |
238 // 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 |
239 // running animations that affect any of these properties. | 239 // running animations that affect any of these properties. |
240 ScheduleAnimation(new LayerAnimationSequence( | 240 ScheduleAnimation(new LayerAnimationSequence( |
241 LayerAnimationElement::CreatePauseElement(animated_properties, | 241 LayerAnimationElement::CreatePauseElement(animated_properties, |
242 base::TimeDelta()))); | 242 base::TimeDelta()))); |
243 | 243 |
244 bool wait_for_group_start = false; | 244 bool wait_for_group_start = false; |
245 for (iter = animations.begin(); iter != animations.end(); ++iter) | 245 for (iter = animations.begin(); iter != animations.end(); ++iter) |
246 wait_for_group_start |= (*iter)->IsFirstElementThreaded(); | 246 wait_for_group_start |= (*iter)->IsFirstElementThreaded(); |
247 | 247 |
248 int group_id = cc::AnimationIdProvider::NextGroupId(); | 248 int group_id = cc::AnimationIdProvider::NextGroupId(); |
249 | 249 |
250 // These animations (provided they don't animate any common properties) will | 250 // These animations (provided they don't animate any common properties) will |
251 // now animate together if trivially scheduled. | 251 // now animate together if trivially scheduled. |
252 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); | 253 (*iter)->set_animation_group_id(group_id); |
254 (*iter)->set_waiting_for_group_start(wait_for_group_start); | 254 (*iter)->set_waiting_for_group_start(wait_for_group_start); |
255 ScheduleAnimation(*iter); | 255 ScheduleAnimation(*iter); |
256 } | 256 } |
257 | 257 |
258 UpdateAnimationState(); | 258 UpdateAnimationState(); |
259 } | 259 } |
260 | 260 |
261 void LayerAnimator::SchedulePauseForProperties( | 261 void LayerAnimator::SchedulePauseForProperties( |
262 base::TimeDelta duration, | 262 base::TimeDelta duration, |
263 LayerAnimationElement::AnimatableProperty property, | 263 LayerAnimationElement::AnimatableProperties properties_to_pause) { |
264 ...) { | |
265 ui::LayerAnimationElement::AnimatableProperties properties_to_pause; | |
266 va_list marker; | |
267 va_start(marker, property); | |
268 for (int p = static_cast<int>(property); p != -1; p = va_arg(marker, int)) { | |
269 properties_to_pause.insert( | |
270 static_cast<LayerAnimationElement::AnimatableProperty>(p)); | |
271 } | |
272 va_end(marker); | |
273 ScheduleAnimation(new ui::LayerAnimationSequence( | 264 ScheduleAnimation(new ui::LayerAnimationSequence( |
274 ui::LayerAnimationElement::CreatePauseElement( | 265 ui::LayerAnimationElement::CreatePauseElement( |
275 properties_to_pause, duration))); | 266 properties_to_pause, duration))); |
276 } | 267 } |
277 | 268 |
278 bool LayerAnimator::IsAnimatingProperty( | 269 bool LayerAnimator::IsAnimatingProperty( |
279 LayerAnimationElement::AnimatableProperty property) const { | 270 LayerAnimationElement::AnimatableProperty property) const { |
280 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin(); | 271 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin(); |
281 queue_iter != animation_queue_.end(); ++queue_iter) { | 272 queue_iter != animation_queue_.end(); ++queue_iter) { |
282 if ((*queue_iter)->properties().find(property) != | 273 if ((*queue_iter)->properties() & property) |
283 (*queue_iter)->properties().end()) { | |
284 return true; | 274 return true; |
285 } | |
286 } | 275 } |
287 return false; | 276 return false; |
288 } | 277 } |
289 | 278 |
290 void LayerAnimator::StopAnimatingProperty( | 279 void LayerAnimator::StopAnimatingProperty( |
291 LayerAnimationElement::AnimatableProperty property) { | 280 LayerAnimationElement::AnimatableProperty property) { |
292 scoped_refptr<LayerAnimator> retain(this); | 281 scoped_refptr<LayerAnimator> retain(this); |
293 while (true) { | 282 while (true) { |
294 // GetRunningAnimation purges deleted animations before searching, so we are | 283 // GetRunningAnimation purges deleted animations before searching, so we are |
295 // guaranteed to find a live animation if any is returned at all. | 284 // guaranteed to find a live animation if any is returned at all. |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 void LayerAnimator::ClearAnimations() { | 538 void LayerAnimator::ClearAnimations() { |
550 scoped_refptr<LayerAnimator> retain(this); | 539 scoped_refptr<LayerAnimator> retain(this); |
551 ClearAnimationsInternal(); | 540 ClearAnimationsInternal(); |
552 } | 541 } |
553 | 542 |
554 LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation( | 543 LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation( |
555 LayerAnimationElement::AnimatableProperty property) { | 544 LayerAnimationElement::AnimatableProperty property) { |
556 PurgeDeletedAnimations(); | 545 PurgeDeletedAnimations(); |
557 for (RunningAnimations::iterator iter = running_animations_.begin(); | 546 for (RunningAnimations::iterator iter = running_animations_.begin(); |
558 iter != running_animations_.end(); ++iter) { | 547 iter != running_animations_.end(); ++iter) { |
559 if ((*iter).sequence()->properties().find(property) != | 548 if ((*iter).sequence()->properties() & property) |
560 (*iter).sequence()->properties().end()) | |
561 return &(*iter); | 549 return &(*iter); |
562 } | 550 } |
563 return NULL; | 551 return NULL; |
564 } | 552 } |
565 | 553 |
566 void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) { | 554 void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) { |
567 // If we don't have the animation in the queue yet, add it. | 555 // If we don't have the animation in the queue yet, add it. |
568 bool found_sequence = false; | 556 bool found_sequence = false; |
569 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); | 557 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); |
570 queue_iter != animation_queue_.end(); ++queue_iter) { | 558 queue_iter != animation_queue_.end(); ++queue_iter) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 } | 689 } |
702 animation_queue_.push_back(make_linked_ptr(sequence)); | 690 animation_queue_.push_back(make_linked_ptr(sequence)); |
703 ProcessQueue(); | 691 ProcessQueue(); |
704 } | 692 } |
705 | 693 |
706 void LayerAnimator::ProcessQueue() { | 694 void LayerAnimator::ProcessQueue() { |
707 bool started_sequence = false; | 695 bool started_sequence = false; |
708 do { | 696 do { |
709 started_sequence = false; | 697 started_sequence = false; |
710 // Build a list of all currently animated properties. | 698 // Build a list of all currently animated properties. |
711 LayerAnimationElement::AnimatableProperties animated; | 699 LayerAnimationElement::AnimatableProperties animated = |
| 700 LayerAnimationElement::UNKNOWN; |
712 for (RunningAnimations::const_iterator iter = running_animations_.begin(); | 701 for (RunningAnimations::const_iterator iter = running_animations_.begin(); |
713 iter != running_animations_.end(); ++iter) { | 702 iter != running_animations_.end(); ++iter) { |
714 if (!(*iter).is_sequence_alive()) | 703 if (!(*iter).is_sequence_alive()) |
715 continue; | 704 continue; |
716 animated.insert((*iter).sequence()->properties().begin(), | 705 |
717 (*iter).sequence()->properties().end()); | 706 animated |= (*iter).sequence()->properties(); |
718 } | 707 } |
719 | 708 |
720 // Try to find an animation that doesn't conflict with an animated | 709 // Try to find an animation that doesn't conflict with an animated |
721 // property or a property that will be animated before it. Note: starting | 710 // property or a property that will be animated before it. Note: starting |
722 // the animation may indirectly cause more animations to be started, so we | 711 // the animation may indirectly cause more animations to be started, so we |
723 // need to operate on a copy. | 712 // need to operate on a copy. |
724 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences; | 713 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences; |
725 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); | 714 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); |
726 queue_iter != animation_queue_.end(); ++queue_iter) | 715 queue_iter != animation_queue_.end(); ++queue_iter) |
727 sequences.push_back((*queue_iter)->AsWeakPtr()); | 716 sequences.push_back((*queue_iter)->AsWeakPtr()); |
728 | 717 |
729 for (size_t i = 0; i < sequences.size(); ++i) { | 718 for (size_t i = 0; i < sequences.size(); ++i) { |
730 if (!sequences[i].get() || !HasAnimation(sequences[i].get())) | 719 if (!sequences[i].get() || !HasAnimation(sequences[i].get())) |
731 continue; | 720 continue; |
732 | 721 |
733 if (!sequences[i]->HasConflictingProperty(animated)) { | 722 if (!sequences[i]->HasConflictingProperty(animated)) { |
734 StartSequenceImmediately(sequences[i].get()); | 723 StartSequenceImmediately(sequences[i].get()); |
735 started_sequence = true; | 724 started_sequence = true; |
736 break; | 725 break; |
737 } | 726 } |
738 | 727 |
739 // Animation couldn't be started. Add its properties to the collection so | 728 // Animation couldn't be started. Add its properties to the collection so |
740 // that we don't start a conflicting animation. For example, if our queue | 729 // that we don't start a conflicting animation. For example, if our queue |
741 // has the elements { {T,B}, {B} } (that is, an element that animates both | 730 // has the elements { {T,B}, {B} } (that is, an element that animates both |
742 // the transform and the bounds followed by an element that animates the | 731 // the transform and the bounds followed by an element that animates the |
743 // bounds), and we're currently animating the transform, we can't start | 732 // bounds), and we're currently animating the transform, we can't start |
744 // the first element because it animates the transform, too. We cannot | 733 // the first element because it animates the transform, too. We cannot |
745 // start the second element, either, because the first element animates | 734 // start the second element, either, because the first element animates |
746 // bounds too, and needs to go first. | 735 // bounds too, and needs to go first. |
747 animated.insert(sequences[i]->properties().begin(), | 736 animated |= sequences[i]->properties(); |
748 sequences[i]->properties().end()); | |
749 } | 737 } |
750 | 738 |
751 // If we started a sequence, try again. We may be able to start several. | 739 // If we started a sequence, try again. We may be able to start several. |
752 } while (started_sequence); | 740 } while (started_sequence); |
753 } | 741 } |
754 | 742 |
755 bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) { | 743 bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) { |
756 PurgeDeletedAnimations(); | 744 PurgeDeletedAnimations(); |
757 | 745 |
758 // Ensure that no one is animating one of the sequence's properties already. | 746 // Ensure that no one is animating one of the sequence's properties already. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 } | 841 } |
854 | 842 |
855 LayerAnimator::RunningAnimation::RunningAnimation( | 843 LayerAnimator::RunningAnimation::RunningAnimation( |
856 const base::WeakPtr<LayerAnimationSequence>& sequence) | 844 const base::WeakPtr<LayerAnimationSequence>& sequence) |
857 : sequence_(sequence) { | 845 : sequence_(sequence) { |
858 } | 846 } |
859 | 847 |
860 LayerAnimator::RunningAnimation::~RunningAnimation() { } | 848 LayerAnimator::RunningAnimation::~RunningAnimation() { } |
861 | 849 |
862 } // namespace ui | 850 } // namespace ui |
OLD | NEW |