diff options
Diffstat (limited to 'cc')
-rw-r--r-- | cc/test/layer_tree_test.cc | 5 | ||||
-rw-r--r-- | cc/test/layer_tree_test.h | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 16 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 97 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_animation.cc | 77 |
5 files changed, 182 insertions, 14 deletions
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 8bb46c88..c87c36b 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -338,6 +338,11 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl { test_hooks_->CommitCompleteOnThread(this); } + bool PrepareTiles() override { + test_hooks_->WillPrepareTiles(this); + return LayerTreeHostImpl::PrepareTiles(); + } + DrawResult PrepareToDraw(FrameData* frame) override { DrawResult draw_result = LayerTreeHostImpl::PrepareToDraw(frame); return test_hooks_->PrepareToDrawOnThread(this, frame, draw_result); diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index 9eaa8f4..5a22087 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h @@ -61,6 +61,7 @@ class TestHooks : public AnimationDelegate { virtual void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) {} virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, CommitEarlyOutReason reason) {} + virtual void WillPrepareTiles(LayerTreeHostImpl* host_impl) {} virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {} virtual void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) {} virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {} diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index f711cd9..fa3ba0e 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -322,6 +322,12 @@ void LayerTreeHostImpl::CommitComplete() { ActivateAnimations(); } + // Start animations before UpdateDrawProperties and PrepareTiles, as they can + // change the results. When doing commit to the active tree, this must happen + // after ActivateAnimations() in order for this ticking to be propogated to + // layers on the active tree. + Animate(); + // LayerTreeHost may have changed the GPU rasterization flags state, which // may require an update of the tree resources. UpdateTreeResourcesForGpuRasterizationIfNeeded(); @@ -3072,13 +3078,19 @@ void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) { if (!settings_.accelerated_animation_enabled) return; + bool animated = false; if (animation_host_) { if (animation_host_->AnimateLayers(monotonic_time)) - SetNeedsAnimate(); + animated = true; } else { if (animation_registrar_->AnimateLayers(monotonic_time)) - SetNeedsAnimate(); + animated = true; } + + // TODO(ajuma): Only do this if the animations are on the active tree, or if + // they are on the pending tree waiting for some future time to start. + if (animated) + SetNeedsAnimate(); } void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) { diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 06c5c83..db51dc9 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -14,6 +14,7 @@ #include "base/location.h" #include "base/thread_task_runner_handle.h" #include "cc/animation/scrollbar_animation_controller_thinning.h" +#include "cc/animation/transform_operations.h" #include "cc/base/math_util.h" #include "cc/input/page_scale_animation.h" #include "cc/input/top_controls_manager.h" @@ -1068,6 +1069,102 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset()); } +TEST_F(LayerTreeHostImplTest, AnimationSchedulingPendingTree) { + host_impl_->SetViewportSize(gfx::Size(50, 50)); + + host_impl_->CreatePendingTree(); + host_impl_->pending_tree()->SetRootLayer( + LayerImpl::Create(host_impl_->pending_tree(), 1)); + LayerImpl* root = host_impl_->pending_tree()->root_layer(); + root->SetBounds(gfx::Size(50, 50)); + root->SetHasRenderSurface(true); + + root->AddChild(LayerImpl::Create(host_impl_->pending_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); + AddAnimatedTransformToLayer(child, 10.0, 3, 0); + + EXPECT_FALSE(did_request_animate_); + EXPECT_FALSE(did_request_redraw_); + EXPECT_FALSE(did_request_commit_); + + host_impl_->Animate(); + + // An animation exists on the pending layer. Doing Animate() requests another + // frame. + // In reality, animations without has_set_start_time() == true do not need to + // be continuously ticked on the pending tree, so it should not request + // another animation frame here. But we currently do so blindly if any + // animation exists. + EXPECT_TRUE(did_request_animate_); + // The pending tree with an animation does not need to draw after animating. + EXPECT_FALSE(did_request_redraw_); + EXPECT_FALSE(did_request_commit_); + + did_request_animate_ = false; + did_request_redraw_ = false; + did_request_commit_ = false; + + host_impl_->ActivateSyncTree(); + + // When the animation activates, we should request another animation frame + // to keep the animation moving. + EXPECT_TRUE(did_request_animate_); + // On activation we don't need to request a redraw for the animation, + // activating will draw on its own when it's ready. + EXPECT_FALSE(did_request_redraw_); + EXPECT_FALSE(did_request_commit_); +} + +TEST_F(LayerTreeHostImplTest, AnimationSchedulingActiveTree) { + 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->SetHasRenderSurface(true); + + 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 from 6,7 to 8,9. + TransformOperations start; + start.AppendTranslate(6.f, 7.f, 0.f); + TransformOperations end; + end.AppendTranslate(8.f, 9.f, 0.f); + AddAnimatedTransformToLayer(child, 4.0, start, end); + + base::TimeTicks now = base::TimeTicks::Now(); + host_impl_->WillBeginImplFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now)); + + EXPECT_FALSE(did_request_animate_); + EXPECT_FALSE(did_request_redraw_); + EXPECT_FALSE(did_request_commit_); + + host_impl_->ActivateAnimations(); + did_request_animate_ = false; + did_request_redraw_ = false; + did_request_commit_ = false; + + host_impl_->Animate(); + + // An animation exists on the active layer. Doing Animate() requests another + // frame after the current one. + EXPECT_TRUE(did_request_animate_); + // TODO(danakj): We also need to draw in the current frame if something + // animated, but this is currently handled by + // SchedulerStateMachine::WillAnimate. + EXPECT_FALSE(did_request_redraw_); + EXPECT_FALSE(did_request_commit_); +} + TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->SetViewportSize(gfx::Size(50, 50)); diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index 5587d6d..b41005a 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc @@ -8,6 +8,7 @@ #include "cc/animation/layer_animation_controller.h" #include "cc/animation/scroll_offset_animation_curve.h" #include "cc/animation/timing_function.h" +#include "cc/animation/transform_operations.h" #include "cc/base/completion_event.h" #include "cc/base/time_util.h" #include "cc/layers/layer.h" @@ -228,8 +229,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); class LayerTreeHostAnimationTestAddAnimationWithTimingFunction : public LayerTreeHostAnimationTest { public: - LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} - void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); picture_ = FakePictureLayer::Create(layer_settings(), &client_); @@ -241,6 +240,10 @@ class LayerTreeHostAnimationTestAddAnimationWithTimingFunction void AnimateLayers(LayerTreeHostImpl* host_impl, base::TimeTicks monotonic_time) override { + // TODO(ajuma): This test only checks the active tree. Add checks for + // pending tree too. + if (!host_impl->active_tree()->root_layer()) + return; LayerAnimationController* controller_impl = host_impl->active_tree()->root_layer()->children()[0]-> layer_animation_controller(); @@ -277,8 +280,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes : public LayerTreeHostAnimationTest { public: - LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {} - void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); picture_ = FakePictureLayer::Create(layer_settings(), &client_); @@ -332,8 +333,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostAnimationTestAnimationFinishedEvents : public LayerTreeHostAnimationTest { public: - LayerTreeHostAnimationTestAnimationFinishedEvents() {} - void BeginTest() override { PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); } @@ -405,8 +404,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostAnimationTestLayerAddedWithAnimation : public LayerTreeHostAnimationTest { public: - LayerTreeHostAnimationTestLayerAddedWithAnimation() {} - void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DidCommit() override { @@ -635,8 +632,6 @@ MULTI_THREAD_TEST_F( class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated : public LayerTreeHostAnimationTest { public: - LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {} - void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); @@ -879,13 +874,71 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers MULTI_THREAD_BLOCKNOTIFY_TEST_F( LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers); +class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit + : public LayerTreeHostAnimationTest { + public: + void SetupTree() override { + LayerTreeHostAnimationTest::SetupTree(); + + layer_ = FakePictureLayer::Create(layer_settings(), &client_); + layer_->SetBounds(gfx::Size(2, 2)); + // Transform the layer to 4,4 to start. + gfx::Transform start_transform; + start_transform.Translate(4.0, 4.0); + layer_->SetTransform(start_transform); + + layer_tree_host()->root_layer()->AddChild(layer_); + } + + void BeginTest() override { + // Add a translate from 6,7 to 8,9. + TransformOperations start; + start.AppendTranslate(6.f, 7.f, 0.f); + TransformOperations end; + end.AppendTranslate(8.f, 9.f, 0.f); + AddAnimatedTransformToLayer(layer_.get(), 4.0, start, end); + + PostSetNeedsCommitToMainThread(); + } + + void WillPrepareTiles(LayerTreeHostImpl* host_impl) override { + if (host_impl->sync_tree()->source_frame_number() != 0) + return; + LayerImpl* root = host_impl->sync_tree()->root_layer(); + LayerImpl* child = root->children()[0]; + LayerAnimationController* controller_impl = + child->layer_animation_controller(); + Animation* animation = controller_impl->GetAnimation(Animation::TRANSFORM); + + // The animation should be starting for the first frame. + EXPECT_EQ(Animation::STARTING, animation->run_state()); + + // And the transform should be propogated to the sync tree layer, at its + // starting state which is 6,7. + gfx::Transform expected_transform; + expected_transform.Translate(6.0, 7.0); + EXPECT_EQ(expected_transform, child->draw_transform()); + // And the sync tree layer should know it is animating. + EXPECT_TRUE(child->screen_space_transform_is_animating()); + + controller_impl->AbortAnimations(Animation::TRANSFORM); + EndTest(); + } + + void AfterTest() override {} + + FakeContentLayerClient client_; + scoped_refptr<Layer> layer_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit); + // 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(); layer_ = Layer::Create(layer_settings()); |