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

Unified 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: Correctly deal with sequences meant to start together Created 7 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: ui/compositor/layer_animator.cc
diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc
index e6e663d5811ea6f315041d06bc3bebd921e7f160..ddcc0d21b5c0670ff16964c7a3fbd9943896e0a0 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,43 @@ 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 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 +448,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 +470,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 +508,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 +584,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 +604,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 +766,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 +820,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());

Powered by Google App Engine
This is Rietveld 408576698