Chromium Code Reviews| Index: ui/compositor/layer_animator.cc |
| diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc |
| index e6e663d5811ea6f315041d06bc3bebd921e7f160..8ff636bbcac306dbace2ef86aeac2b689f4cc46b 100644 |
| --- a/ui/compositor/layer_animator.cc |
| +++ b/ui/compositor/layer_animator.cc |
| @@ -7,6 +7,7 @@ |
| #include "base/debug/trace_event.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "cc/animation_id_provider.h" |
| #include "ui/base/animation/animation_container.h" |
| #include "ui/compositor/compositor.h" |
| #include "ui/compositor/layer.h" |
| @@ -202,9 +203,17 @@ void LayerAnimator::StartTogether( |
| LayerAnimationElement::CreatePauseElement(animated_properties, |
| base::TimeDelta()))); |
| + bool wait_for_group_start = false; |
| + for (iter = animations.begin(); iter != animations.end(); ++iter) |
| + wait_for_group_start |= (*iter)->IsFirstElementThreaded(); |
| + |
| + int group_id = cc::AnimationIdProvider::NextGroupId(); |
| + |
| // These animations (provided they don't animate any common properties) will |
| // now animate together if trivially scheduled. |
| for (iter = animations.begin(); iter != animations.end(); ++iter) { |
| + (*iter)->set_animation_group_id(group_id); |
| + (*iter)->set_waiting_for_group_start(wait_for_group_start); |
| ScheduleAnimation(*iter); |
| } |
| @@ -232,9 +241,17 @@ void LayerAnimator::ScheduleTogether( |
| LayerAnimationElement::CreatePauseElement(animated_properties, |
| base::TimeDelta()))); |
| + bool wait_for_group_start = false; |
| + for (iter = animations.begin(); iter != animations.end(); ++iter) |
| + wait_for_group_start |= (*iter)->IsFirstElementThreaded(); |
| + |
| + int group_id = cc::AnimationIdProvider::NextGroupId(); |
| + |
| // These animations (provided they don't animate any common properties) will |
| // now animate together if trivially scheduled. |
| for (iter = animations.begin(); iter != animations.end(); ++iter) { |
| + (*iter)->set_animation_group_id(group_id); |
| + (*iter)->set_waiting_for_group_start(wait_for_group_start); |
| ScheduleAnimation(*iter); |
| } |
| @@ -299,11 +316,61 @@ void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) { |
| } |
| } |
| +void LayerAnimator::OnThreadedAnimationStarted( |
| + const cc::AnimationEvent& event) { |
| + LayerAnimationElement::AnimatableProperty property = |
| + LayerAnimationElement::ToAnimatableProperty(event.targetProperty); |
| + |
| + RunningAnimation* running = GetRunningAnimation(property); |
| + if (!running) |
| + return; |
| + DCHECK(running->is_sequence_alive()); |
| + |
| + if (running->sequence()->animation_group_id() != event.groupId) |
| + return; |
| + |
| + running->sequence()->OnThreadedAnimationStarted(event); |
| + if (!running->sequence()->waiting_for_group_start()) |
| + return; |
| + |
| + base::TimeTicks start_time = base::TimeTicks::FromInternalValue( |
| + event.monotonicTime * base::Time::kMicrosecondsPerSecond); |
| + |
| + // The call to GetRunningAnimation made above already purged deleted |
| + // animations, so we are guaranteed that all the animations we iterate |
| + // over now are alive. |
| + for (RunningAnimations::iterator iter = running_animations_.begin(); |
| + iter != running_animations_.end(); ++iter) { |
| + if ((*iter).sequence()->animation_group_id() == event.groupId) { |
| + (*iter).sequence()->set_start_time(start_time); |
| + (*iter).sequence()->set_waiting_for_group_start(false); |
| + } |
| + } |
| +} |
| + |
| +LayerAnimator::TestController::TestController( |
| + scoped_refptr<LayerAnimator> animator) |
| + : animator_(animator) { |
|
sky
2013/02/19 17:06:56
too many spaces here.
ajuma
2013/02/20 16:09:10
Done and moved to ui/compositor/test/layer_animato
|
| +} |
| + |
| +LayerAnimator::TestController::~TestController() { |
| +} |
| + |
| +LayerAnimationSequence* LayerAnimator::TestController::GetRunningSequence( |
| + LayerAnimationElement::AnimatableProperty property) { |
| + RunningAnimation* running_animation = |
| + animator_->GetRunningAnimation(property); |
| + if (running_animation) |
| + return running_animation->sequence(); |
| + else |
| + return NULL; |
| +} |
| + |
| // LayerAnimator protected ----------------------------------------------------- |
| void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence, |
| base::TimeTicks now) { |
| - if (!delegate()) |
| + if (!delegate() || sequence->waiting_for_group_start()) |
| return; |
| sequence->Progress(now, delegate()); |
| @@ -399,11 +466,14 @@ LayerAnimationSequence* LayerAnimator::RemoveAnimation( |
| LayerAnimationSequence* sequence) { |
| linked_ptr<LayerAnimationSequence> to_return; |
| + bool is_running = false; |
| + |
| // First remove from running animations |
| for (RunningAnimations::iterator iter = running_animations_.begin(); |
| iter != running_animations_.end(); ++iter) { |
| if ((*iter).sequence() == sequence) { |
| running_animations_.erase(iter); |
| + is_running = true; |
| break; |
| } |
| } |
| @@ -418,6 +488,36 @@ LayerAnimationSequence* LayerAnimator::RemoveAnimation( |
| } |
| } |
| + if (!to_return.get() || |
| + !to_return->waiting_for_group_start() || |
| + !to_return->IsFirstElementThreaded()) |
| + return to_return.release(); |
| + |
| + // The removed sequence may have been responsible for making other sequences |
| + // wait for a group start. If no other sequences in the group have a |
| + // threaded first element, the group no longer needs the additional wait. |
| + bool is_wait_still_needed = false; |
| + int group_id = to_return->animation_group_id(); |
| + for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); |
| + queue_iter != animation_queue_.end(); ++queue_iter) { |
| + if (((*queue_iter)->animation_group_id() == group_id) && |
| + (*queue_iter)->IsFirstElementThreaded()) { |
| + is_wait_still_needed = true; |
| + break; |
| + } |
| + } |
| + |
| + if (is_wait_still_needed) |
| + return to_return.release(); |
| + |
| + for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); |
| + queue_iter != animation_queue_.end(); ++queue_iter) { |
| + if ((*queue_iter)->animation_group_id() == group_id) { |
| + (*queue_iter)->set_waiting_for_group_start(false); |
| + if (is_running) |
| + (*queue_iter)->set_start_time(last_step_time_); |
| + } |
| + } |
| return to_return.release(); |
| } |
| @@ -426,7 +526,7 @@ void LayerAnimator::FinishAnimation( |
| scoped_refptr<LayerAnimator> retain(this); |
| scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence)); |
| if (abort) |
| - sequence->Abort(); |
| + sequence->Abort(delegate()); |
| else |
| ProgressAnimationToEnd(sequence); |
| ProcessQueue(); |
| @@ -502,7 +602,7 @@ void LayerAnimator::RemoveAllAnimationsWithACommonProperty( |
| scoped_ptr<LayerAnimationSequence> removed( |
| SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i])); |
| if (abort) |
| - running_animations_copy[i].sequence()->Abort(); |
| + running_animations_copy[i].sequence()->Abort(delegate()); |
| else |
| SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]); |
| } |
| @@ -522,7 +622,7 @@ void LayerAnimator::RemoveAllAnimationsWithACommonProperty( |
| if (sequences[i]->HasCommonProperty(sequence->properties())) { |
| scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequences[i])); |
| if (abort) |
| - sequences[i]->Abort(); |
| + sequences[i]->Abort(delegate()); |
| else |
| ProgressAnimationToEnd(sequences[i]); |
| } |
| @@ -684,7 +784,12 @@ bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) { |
| else |
| start_time = base::TimeTicks::Now(); |
| - sequence->set_start_time(start_time); |
| + if (!sequence->animation_group_id()) |
| + sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId()); |
| + if (sequence->waiting_for_group_start()) |
| + sequence->ProgressToEffectiveStart(delegate()); |
| + else |
| + sequence->set_start_time(start_time); |
| running_animations_.push_back( |
| RunningAnimation(sequence->AsWeakPtr())); |
| @@ -733,7 +838,7 @@ void LayerAnimator::ClearAnimationsInternal() { |
| scoped_ptr<LayerAnimationSequence> removed( |
| RemoveAnimation(running_animations_copy[i].sequence())); |
| if (removed.get()) |
| - removed->Abort(); |
| + removed->Abort(delegate()); |
| } |
| // This *should* have cleared the list of running animations. |
| DCHECK(running_animations_.empty()); |