Don't PushProperties every commit for animating layers
This removes the need to PushProperties every commit during an animation.
Instead, a single PushProperties is needed whenever there are animations
waiting for deletion.
This also removes LayerAnimationController::set_force_sync, which no
longer had any non-test callers and wasn't actually needed by its test
callers.
BUG=259088
Review URL: https://codereview.chromium.org/60083018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235845 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index 3bac4a9..5279591 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -19,8 +19,7 @@
namespace cc {
LayerAnimationController::LayerAnimationController(int id)
- : force_sync_(false),
- registrar_(0),
+ : registrar_(0),
id_(id),
is_active_(false),
last_tick_time_(0),
@@ -106,20 +105,17 @@
void LayerAnimationController::PushAnimationUpdatesTo(
LayerAnimationController* controller_impl) {
DCHECK(this != controller_impl);
- if (force_sync_) {
- ReplaceImplThreadAnimations(controller_impl);
- force_sync_ = false;
- } else {
- PurgeAnimationsMarkedForDeletion();
- PushNewAnimationsToImplThread(controller_impl);
+ if (!has_any_animation() && !controller_impl->has_any_animation())
+ return;
+ PurgeAnimationsMarkedForDeletion();
+ PushNewAnimationsToImplThread(controller_impl);
- // Remove finished impl side animations only after pushing,
- // and only after the animations are deleted on the main thread
- // this insures we will never push an animation twice.
- RemoveAnimationsCompletedOnMainThread(controller_impl);
+ // Remove finished impl side animations only after pushing,
+ // and only after the animations are deleted on the main thread
+ // this insures we will never push an animation twice.
+ RemoveAnimationsCompletedOnMainThread(controller_impl);
- PushPropertiesToImplThread(controller_impl);
- }
+ PushPropertiesToImplThread(controller_impl);
controller_impl->UpdateActivation(NormalActivation);
UpdateActivation(NormalActivation);
}
@@ -601,6 +597,8 @@
void LayerAnimationController::MarkAnimationsForDeletion(
double monotonic_time, AnimationEventsVector* events) {
+ bool marked_animations_for_deletions = false;
+
// Non-aborted animations are marked for deletion after a corresponding
// AnimationEvent::Finished event is sent or received. This means that if
// we don't have an events vector, we must ensure that non-aborted animations
@@ -619,6 +617,7 @@
}
active_animations_[i]->SetRunState(Animation::WaitingForDeletion,
monotonic_time);
+ marked_animations_for_deletions = true;
continue;
}
@@ -667,8 +666,11 @@
monotonic_time);
}
}
+ marked_animations_for_deletions = true;
}
}
+ if (marked_animations_for_deletions)
+ NotifyObserversAnimationWaitingForDeletion();
}
static bool IsWaitingForDeletion(Animation* animation) {
@@ -684,27 +686,6 @@
animations.end());
}
-void LayerAnimationController::ReplaceImplThreadAnimations(
- LayerAnimationController* controller_impl) const {
- controller_impl->active_animations_.clear();
- for (size_t i = 0; i < active_animations_.size(); ++i) {
- scoped_ptr<Animation> to_add;
- if (active_animations_[i]->needs_synchronized_start_time()) {
- // We haven't received an animation started notification yet, so it
- // is important that we add it in a 'waiting' and not 'running' state.
- Animation::RunState initial_run_state =
- Animation::WaitingForTargetAvailability;
- double start_time = 0;
- to_add = active_animations_[i]->CloneAndInitialize(
- initial_run_state, start_time).Pass();
- } else {
- to_add = active_animations_[i]->Clone().Pass();
- }
-
- controller_impl->AddAnimation(to_add.Pass());
- }
-}
-
void LayerAnimationController::TickAnimations(double monotonic_time) {
for (size_t i = 0; i < active_animations_.size(); ++i) {
if (active_animations_[i]->run_state() == Animation::Starting ||
@@ -792,6 +773,12 @@
OnFilterAnimated(filters));
}
+void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
+ FOR_EACH_OBSERVER(LayerAnimationValueObserver,
+ value_observers_,
+ OnAnimationWaitingForDeletion());
+}
+
bool LayerAnimationController::HasValueObserver() {
if (value_observers_.might_have_observers()) {
ObserverListBase<LayerAnimationValueObserver>::Iterator it(
diff --git a/cc/animation/layer_animation_controller.h b/cc/animation/layer_animation_controller.h
index d48951f..6df5c05 100644
--- a/cc/animation/layer_animation_controller.h
+++ b/cc/animation/layer_animation_controller.h
@@ -79,10 +79,6 @@
// the future.
bool IsAnimatingProperty(Animation::TargetProperty target_property) const;
- // If a sync is forced, then the next time animation updates are pushed to the
- // impl thread, all animations will be transferred.
- void set_force_sync() { force_sync_ = true; }
-
void SetAnimationRegistrar(AnimationRegistrar* registrar);
AnimationRegistrar* animation_registrar() { return registrar_; }
@@ -120,8 +116,6 @@
LayerAnimationController* controller_impl) const;
void PushPropertiesToImplThread(
LayerAnimationController* controller_impl) const;
- void ReplaceImplThreadAnimations(
- LayerAnimationController* controller_impl) const;
void StartAnimationsWaitingForNextTick(double monotonic_time);
void StartAnimationsWaitingForStartTime(double monotonic_time);
@@ -146,12 +140,11 @@
void NotifyObserversTransformAnimated(const gfx::Transform& transform);
void NotifyObserversFilterAnimated(const FilterOperations& filter);
+ void NotifyObserversAnimationWaitingForDeletion();
+
bool HasValueObserver();
bool HasActiveValueObserver();
- // If this is true, we force a sync to the impl thread.
- bool force_sync_;
-
AnimationRegistrar* registrar_;
int id_;
ScopedPtrVector<Animation> active_animations_;
diff --git a/cc/animation/layer_animation_controller_unittest.cc b/cc/animation/layer_animation_controller_unittest.cc
index a1dd9a2..6b77cd2 100644
--- a/cc/animation/layer_animation_controller_unittest.cc
+++ b/cc/animation/layer_animation_controller_unittest.cc
@@ -293,10 +293,15 @@
controller->Animate(1.0);
controller->UpdateState(true, NULL);
+ EXPECT_FALSE(dummy.animation_waiting_for_deletion());
+ EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion());
+
events.reset(new AnimationEventsVector);
controller_impl->Animate(2.0);
controller_impl->UpdateState(true, events.get());
+ EXPECT_TRUE(dummy_impl.animation_waiting_for_deletion());
+
// There should be a Finished event for the animation.
EXPECT_EQ(1u, events->size());
EXPECT_EQ(AnimationEvent::Finished, (*events)[0].type);
@@ -309,6 +314,7 @@
controller->Animate(3.0);
controller->UpdateState(true, NULL);
+ EXPECT_TRUE(dummy.animation_waiting_for_deletion());
controller->PushAnimationUpdatesTo(controller_impl.get());
@@ -1140,7 +1146,7 @@
EXPECT_EQ(0.75f, dummy.opacity());
}
-TEST(LayerAnimationControllerTest, ForceSyncWhenSynchronizedStartTimeNeeded) {
+TEST(LayerAnimationControllerTest, PushUpdatesWhenSynchronizedStartTimeNeeded) {
FakeLayerAnimationValueObserver dummy_impl;
scoped_refptr<LayerAnimationController> controller_impl(
LayerAnimationController::Create(0));
@@ -1166,8 +1172,6 @@
EXPECT_TRUE(active_animation);
EXPECT_TRUE(active_animation->needs_synchronized_start_time());
- controller->set_force_sync();
-
controller->PushAnimationUpdatesTo(controller_impl.get());
active_animation = controller_impl->GetAnimation(0, Animation::Opacity);
@@ -1437,9 +1441,12 @@
controller->AbortAnimations(Animation::Opacity);
EXPECT_EQ(Animation::Aborted,
controller->GetAnimation(Animation::Opacity)->run_state());
+ EXPECT_FALSE(dummy.animation_waiting_for_deletion());
+ EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion());
controller->Animate(1.0);
controller->UpdateState(true, NULL);
+ EXPECT_TRUE(dummy.animation_waiting_for_deletion());
EXPECT_EQ(Animation::WaitingForDeletion,
controller->GetAnimation(Animation::Opacity)->run_state());
@@ -1468,10 +1475,13 @@
controller_impl->AbortAnimations(Animation::Opacity);
EXPECT_EQ(Animation::Aborted,
controller_impl->GetAnimation(Animation::Opacity)->run_state());
+ EXPECT_FALSE(dummy.animation_waiting_for_deletion());
+ EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion());
AnimationEventsVector events;
controller_impl->Animate(1.0);
controller_impl->UpdateState(true, &events);
+ EXPECT_TRUE(dummy_impl.animation_waiting_for_deletion());
EXPECT_EQ(1u, events.size());
EXPECT_EQ(AnimationEvent::Aborted, events[0].type);
EXPECT_EQ(Animation::WaitingForDeletion,
@@ -1483,6 +1493,7 @@
controller->Animate(1.5);
controller->UpdateState(true, NULL);
+ EXPECT_TRUE(dummy.animation_waiting_for_deletion());
EXPECT_EQ(Animation::WaitingForDeletion,
controller->GetAnimation(Animation::Opacity)->run_state());
diff --git a/cc/animation/layer_animation_value_observer.h b/cc/animation/layer_animation_value_observer.h
index adaf9c7..cc6219d 100644
--- a/cc/animation/layer_animation_value_observer.h
+++ b/cc/animation/layer_animation_value_observer.h
@@ -16,6 +16,7 @@
virtual void OnFilterAnimated(const FilterOperations& filters) = 0;
virtual void OnOpacityAnimated(float opacity) = 0;
virtual void OnTransformAnimated(const gfx::Transform& transform) = 0;
+ virtual void OnAnimationWaitingForDeletion() = 0;
virtual bool IsActive() const = 0;
};
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 8d07366..e0ffb5cd 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -927,9 +927,7 @@
stacking_order_changed_ = false;
update_rect_ = gfx::RectF();
- // Animating layers require further push properties to clean up the animation.
- // crbug.com/259088
- needs_push_properties_ = layer_animation_controller_->has_any_animation();
+ needs_push_properties_ = false;
num_dependents_need_push_properties_ = 0;
}
@@ -998,6 +996,11 @@
transform_ = transform;
}
+void Layer::OnAnimationWaitingForDeletion() {
+ // Animations are only deleted during PushProperties.
+ SetNeedsPushProperties();
+}
+
bool Layer::IsActive() const {
return true;
}
@@ -1027,7 +1030,6 @@
scoped_refptr<LayerAnimationController> controller) {
layer_animation_controller_->RemoveValueObserver(this);
layer_animation_controller_ = controller;
- layer_animation_controller_->set_force_sync();
layer_animation_controller_->AddValueObserver(this);
SetNeedsCommit();
}
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 889e09ba..b552a35 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -522,6 +522,7 @@
virtual void OnFilterAnimated(const FilterOperations& filters) OVERRIDE;
virtual void OnOpacityAnimated(float opacity) OVERRIDE;
virtual void OnTransformAnimated(const gfx::Transform& transform) OVERRIDE;
+ virtual void OnAnimationWaitingForDeletion() OVERRIDE;
virtual bool IsActive() const OVERRIDE;
LayerList children_;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 1033b61..99f9502 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -694,6 +694,8 @@
SetTransform(transform);
}
+void LayerImpl::OnAnimationWaitingForDeletion() {}
+
bool LayerImpl::IsActive() const {
return layer_tree_impl_->IsActiveTree();
}
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index e774dfac..6d06b6d2 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -76,6 +76,7 @@
virtual void OnFilterAnimated(const FilterOperations& filters) OVERRIDE;
virtual void OnOpacityAnimated(float opacity) OVERRIDE;
virtual void OnTransformAnimated(const gfx::Transform& transform) OVERRIDE;
+ virtual void OnAnimationWaitingForDeletion() OVERRIDE;
virtual bool IsActive() const OVERRIDE;
// Tree structure.
diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc
index 22b7793..7ab26a5 100644
--- a/cc/test/animation_test_common.cc
+++ b/cc/test/animation_test_common.cc
@@ -186,7 +186,8 @@
}
FakeLayerAnimationValueObserver::FakeLayerAnimationValueObserver()
- : opacity_(0.0f) {}
+ : opacity_(0.0f),
+ animation_waiting_for_deletion_(false) {}
FakeLayerAnimationValueObserver::~FakeLayerAnimationValueObserver() {}
@@ -204,6 +205,10 @@
transform_ = transform;
}
+void FakeLayerAnimationValueObserver::OnAnimationWaitingForDeletion() {
+ animation_waiting_for_deletion_ = true;
+}
+
bool FakeLayerAnimationValueObserver::IsActive() const {
return true;
}
diff --git a/cc/test/animation_test_common.h b/cc/test/animation_test_common.h
index a686b46..008af87 100644
--- a/cc/test/animation_test_common.h
+++ b/cc/test/animation_test_common.h
@@ -73,16 +73,22 @@
virtual void OnFilterAnimated(const FilterOperations& filters) OVERRIDE;
virtual void OnOpacityAnimated(float opacity) OVERRIDE;
virtual void OnTransformAnimated(const gfx::Transform& transform) OVERRIDE;
+ virtual void OnAnimationWaitingForDeletion() OVERRIDE;
virtual bool IsActive() const OVERRIDE;
const FilterOperations& filters() const { return filters_; }
float opacity() const { return opacity_; }
const gfx::Transform& transform() const { return transform_; }
+ bool animation_waiting_for_deletion() {
+ return animation_waiting_for_deletion_;
+ }
+
private:
FilterOperations filters_;
float opacity_;
gfx::Transform transform_;
+ bool animation_waiting_for_deletion_;
};
class FakeInactiveLayerAnimationValueObserver