Commit 638ef703 authored by loyso's avatar loyso Committed by Commit bot

CC Animation: Activate/deactivate ElementAnimations on Layer addition/removal.

This is a CC-side fix which can be useful for all CC clients.

Blink side: We will need to fix the race in CompositedLayerMapping destruction vs. CompositorAnimationPlayer detachment separately.

BUG=615471
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel

Review-Url: https://codereview.chromium.org/2042713002
Cr-Commit-Position: refs/heads/master@{#398209}
parent cf1b7e12
...@@ -89,6 +89,9 @@ void ElementAnimations::ElementRegistered(ElementId element_id, ...@@ -89,6 +89,9 @@ void ElementAnimations::ElementRegistered(ElementId element_id,
ElementListType list_type) { ElementListType list_type) {
DCHECK_EQ(element_id_, element_id); DCHECK_EQ(element_id_, element_id);
if (!has_element_in_any_list())
UpdateActivation(FORCE_ACTIVATION);
if (list_type == ElementListType::ACTIVE) if (list_type == ElementListType::ACTIVE)
set_has_element_in_active_list(true); set_has_element_in_active_list(true);
else else
...@@ -102,6 +105,9 @@ void ElementAnimations::ElementUnregistered(ElementId element_id, ...@@ -102,6 +105,9 @@ void ElementAnimations::ElementUnregistered(ElementId element_id,
set_has_element_in_active_list(false); set_has_element_in_active_list(false);
else else
set_has_element_in_pending_list(false); set_has_element_in_pending_list(false);
if (!has_element_in_any_list())
animation_host_->DidDeactivateElementAnimations(this);
} }
void ElementAnimations::AddPlayer(AnimationPlayer* player) { void ElementAnimations::AddPlayer(AnimationPlayer* player) {
......
...@@ -125,6 +125,9 @@ class CC_EXPORT ElementAnimations : public base::RefCounted<ElementAnimations> { ...@@ -125,6 +125,9 @@ class CC_EXPORT ElementAnimations : public base::RefCounted<ElementAnimations> {
bool has_element_in_pending_list() const { bool has_element_in_pending_list() const {
return has_element_in_pending_list_; return has_element_in_pending_list_;
} }
bool has_element_in_any_list() const {
return has_element_in_active_list_ || has_element_in_pending_list_;
}
void set_has_element_in_active_list(bool has_element_in_active_list) { void set_has_element_in_active_list(bool has_element_in_active_list) {
has_element_in_active_list_ = has_element_in_active_list; has_element_in_active_list_ = has_element_in_active_list;
......
...@@ -1453,6 +1453,60 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { ...@@ -1453,6 +1453,60 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) {
host_impl_ = nullptr; host_impl_ = nullptr;
} }
TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) {
host_impl_->SetViewportSize(gfx::Size(50, 50));
host_impl_->active_tree()->SetRootLayer(
LayerImpl::Create(host_impl_->active_tree(), 1));
LayerImpl* root = host_impl_->active_tree()->root_layer();
root->SetBounds(gfx::Size(50, 50));
root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2));
LayerImpl* child = root->children()[0];
child->SetBounds(gfx::Size(10, 10));
child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
child->SetDrawsContent(true);
// Add a translate animation.
TransformOperations start;
start.AppendTranslate(6.f, 7.f, 0.f);
TransformOperations end;
end.AppendTranslate(8.f, 9.f, 0.f);
AddAnimatedTransformToLayerWithPlayer(child->id(), timeline(), 4.0, start,
end);
base::TimeTicks now = base::TimeTicks::Now();
host_impl_->WillBeginImplFrame(
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now));
EXPECT_TRUE(did_request_next_frame_);
did_request_next_frame_ = false;
host_impl_->ActivateAnimations();
// On activating an animation, we should request another frame so that we'll
// continue ticking the animation.
EXPECT_TRUE(did_request_next_frame_);
did_request_next_frame_ = false;
// The next frame after activating, we'll tick the animation again.
host_impl_->Animate();
// An animation exists on the active layer. Doing Animate() requests another
// frame after the current one.
EXPECT_TRUE(did_request_next_frame_);
did_request_next_frame_ = false;
// Destroy layer, unregister animation target (element).
child->SetParent(nullptr);
root->RemoveChildForTesting(child);
child = nullptr;
// Doing Animate() doesn't request another frame after the current one.
host_impl_->Animate();
EXPECT_FALSE(did_request_next_frame_);
host_impl_->Animate();
EXPECT_FALSE(did_request_next_frame_);
}
class MissingTilesLayer : public LayerImpl { class MissingTilesLayer : public LayerImpl {
public: public:
MissingTilesLayer(LayerTreeImpl* layer_tree_impl, int id) MissingTilesLayer(LayerTreeImpl* layer_tree_impl, int id)
......
...@@ -1250,7 +1250,7 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded ...@@ -1250,7 +1250,7 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
player_->element_animations()->has_element_in_active_list()); player_->element_animations()->has_element_in_active_list());
EXPECT_FALSE( EXPECT_FALSE(
player_->element_animations()->has_element_in_pending_list()); player_->element_animations()->has_element_in_pending_list());
EXPECT_TRUE(layer_tree_host()->animation_host()->NeedsAnimateLayers()); EXPECT_FALSE(layer_tree_host()->animation_host()->NeedsAnimateLayers());
break; break;
case 2: case 2:
layer_tree_host()->root_layer()->AddChild(layer_); layer_tree_host()->root_layer()->AddChild(layer_);
...@@ -1278,7 +1278,7 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded ...@@ -1278,7 +1278,7 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
case 1: case 1:
EXPECT_FALSE( EXPECT_FALSE(
player_impl->element_animations()->has_element_in_active_list()); player_impl->element_animations()->has_element_in_active_list());
EXPECT_TRUE(host_impl->animation_host()->NeedsAnimateLayers()); EXPECT_FALSE(host_impl->animation_host()->NeedsAnimateLayers());
break; break;
case 2: case 2:
EXPECT_TRUE( EXPECT_TRUE(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment