summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
Diffstat (limited to 'cc')
-rw-r--r--cc/test/layer_tree_test.cc5
-rw-r--r--cc/test/layer_tree_test.h1
-rw-r--r--cc/trees/layer_tree_host_impl.cc16
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc97
-rw-r--r--cc/trees/layer_tree_host_unittest_animation.cc77
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());