Commit 04063aa4 authored by ajuma's avatar ajuma Committed by Commit bot

cc: Make re-added animations get pushed to the compositor thread

When a layer with an animation is removed from the tree but later
re-added (this can happen, for example, when an iframe containing
an animation is set to display:none and later set back to
display:block), the animation should continue. Currently, the
animation is prevented from getting re-pushed to the compositor
thread since it already has a start time. This logic used to be
needed to prevent incorrectly re-pushing an animation that had
already been deleted  on the compositor thread, but is no longer
needed for that purpose since we now always delete animations on
the main thread before deleting them on the compositor thread.
This CL removes this logic.

BUG=409649

Review URL: https://codereview.chromium.org/1148333002

Cr-Commit-Position: refs/heads/master@{#330938}
parent 11fb72d7
......@@ -584,15 +584,6 @@ void LayerAnimationController::PushNewAnimationsToImplThread(
if (controller_impl->GetAnimationById(animations_[i]->id()))
continue;
// If the animation is not running on the impl thread, it does not
// necessarily mean that it needs to be copied over and started; it may
// have already finished. In this case, the impl thread animation will
// have already notified that it has started and the main thread animation
// will no longer need
// a synchronized start time.
if (!animations_[i]->needs_synchronized_start_time())
continue;
// Scroll animations always start at the current scroll offset.
if (animations_[i]->target_property() == Animation::SCROLL_OFFSET) {
gfx::ScrollOffset current_scroll_offset;
......
......@@ -298,12 +298,13 @@ TEST(LayerAnimationControllerTest, DoNotSyncFinishedAnimation) {
scoped_refptr<LayerAnimationController> controller(
LayerAnimationController::Create(0));
controller->AddValueObserver(&dummy);
scoped_ptr<AnimationEventsVector> events(
make_scoped_ptr(new AnimationEventsVector));
EXPECT_FALSE(controller_impl->GetAnimation(Animation::OPACITY));
int animation_id =
AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
int group_id = controller->GetAnimationById(animation_id)->group();
controller->PushAnimationUpdatesTo(controller_impl.get());
controller_impl->ActivateAnimations();
......@@ -312,21 +313,30 @@ TEST(LayerAnimationControllerTest, DoNotSyncFinishedAnimation) {
EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY,
controller_impl->GetAnimationById(animation_id)->run_state());
events.reset(new AnimationEventsVector);
controller_impl->Animate(kInitialTickTime);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(1u, events->size());
EXPECT_EQ(AnimationEvent::STARTED, (*events)[0].type);
// Notify main thread controller that the animation has started.
AnimationEvent animation_started_event(AnimationEvent::STARTED, 0, group_id,
Animation::OPACITY, kInitialTickTime);
controller->NotifyAnimationStarted(animation_started_event);
controller->NotifyAnimationStarted((*events)[0]);
// Force animation to complete on impl thread.
controller_impl->RemoveAnimation(animation_id);
// Complete animation on impl thread.
events.reset(new AnimationEventsVector);
controller_impl->Animate(kInitialTickTime + TimeDelta::FromSeconds(1));
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(1u, events->size());
EXPECT_EQ(AnimationEvent::FINISHED, (*events)[0].type);
EXPECT_FALSE(controller_impl->GetAnimationById(animation_id));
controller->NotifyAnimationFinished((*events)[0]);
controller->Animate(kInitialTickTime + TimeDelta::FromSeconds(2));
controller->UpdateState(true, nullptr);
controller->PushAnimationUpdatesTo(controller_impl.get());
controller_impl->ActivateAnimations();
// Even though the main thread has a 'new' animation, it should not be pushed
// because the animation has already completed on the impl thread.
EXPECT_FALSE(controller->GetAnimationById(animation_id));
EXPECT_FALSE(controller_impl->GetAnimationById(animation_id));
}
......
......@@ -928,6 +928,58 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
// When a layer with an animation is removed from the tree and later re-added,
// the animation should resume.
class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
: public LayerTreeHostAnimationTest {
public:
LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {}
void SetupTree() override {
LayerTreeHostAnimationTest::SetupTree();
content_ = Layer::Create();
content_->SetBounds(gfx::Size(4, 4));
layer_tree_host()->root_layer()->AddChild(content_);
AddOpacityTransitionToLayer(content_.get(), 10000.0, 0.1f, 0.9f, true);
}
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void DidCommit() override {
switch (layer_tree_host()->source_frame_number()) {
case 1:
content_->RemoveFromParent();
break;
case 2:
layer_tree_host()->root_layer()->AddChild(content_);
break;
}
}
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
switch (host_impl->active_tree()->source_frame_number()) {
case 0:
EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
break;
case 1:
EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
break;
case 2:
EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
EndTest();
break;
}
}
void AfterTest() override {}
private:
scoped_refptr<Layer> content_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
class LayerTreeHostAnimationTestAddAnimationAfterAnimating
: public LayerTreeHostAnimationTest {
public:
......
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