From b33348f4524c917d65e9ebb4d1cc6acc9b82bb39 Mon Sep 17 00:00:00 2001
From: "ajuma@chromium.org"
 <ajuma@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Wed, 30 Apr 2014 18:17:34 +0000
Subject: cc: Animations committed together should start together

This change makes newly-committed animations wait for tree
activation before they're able to affect the active tree, and
makes newly-deleted animations wait for tree activation before
they no longer affect the active tree. This is accomplished by
tracking whether each animation affects active observers,
inactive (pending) observers, or both.

As a result, animations committed together will start
together, after the next activation.

BUG=225643

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267269 0039d316-1c4b-4281-b951-d872f2087c98
---
 cc/trees/layer_tree_host_unittest_animation.cc | 79 ++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

(limited to 'cc/trees/layer_tree_host_unittest_animation.cc')

diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index aeeb4f5..636c7b1 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1244,5 +1244,84 @@ class LayerTreeHostAnimationTestFrozenAnimationTickTime
 // Only the non-impl-paint multi-threaded compositor freezes animations.
 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostAnimationTestFrozenAnimationTickTime);
 
+// When animations are simultaneously added to an existing layer and to a new
+// layer, they should start at the same time, even when there's already a
+// running animation on the existing layer.
+class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
+    : public LayerTreeHostAnimationTest {
+ public:
+  LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
+      : frame_count_with_pending_tree_(0) {}
+
+  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+  virtual void DidCommit() OVERRIDE {
+    if (layer_tree_host()->source_frame_number() == 1) {
+      AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
+    } else if (layer_tree_host()->source_frame_number() == 2) {
+      AddOpacityTransitionToLayer(
+          layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
+
+      scoped_refptr<Layer> layer = Layer::Create();
+      layer_tree_host()->root_layer()->AddChild(layer);
+      layer->set_layer_animation_delegate(this);
+      layer->SetBounds(gfx::Size(4, 4));
+      AddOpacityTransitionToLayer(layer, 1, 0.f, 0.5f, true);
+    }
+  }
+
+  virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+    host_impl->BlockNotifyReadyToActivateForTesting(true);
+  }
+
+  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+    // For the commit that added animations to new and existing layers, keep
+    // blocking activation. We want to verify that even with activation blocked,
+    // the animation on the layer that's already in the active tree won't get a
+    // head start.
+    if (!host_impl->settings().impl_side_painting ||
+        host_impl->pending_tree()->source_frame_number() != 2)
+      host_impl->BlockNotifyReadyToActivateForTesting(false);
+  }
+
+  virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
+                                          const BeginFrameArgs& args) OVERRIDE {
+    if (!host_impl->pending_tree() ||
+        host_impl->pending_tree()->source_frame_number() != 2)
+      return;
+
+    frame_count_with_pending_tree_++;
+    if (frame_count_with_pending_tree_ == 2)
+      host_impl->BlockNotifyReadyToActivateForTesting(false);
+  }
+
+  virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl,
+                                    bool has_unfinished_animation) OVERRIDE {
+    Animation* root_animation = host_impl->active_tree()
+                                    ->root_layer()
+                                    ->layer_animation_controller()
+                                    ->GetAnimation(Animation::Opacity);
+    if (!root_animation || root_animation->run_state() != Animation::Running)
+      return;
+
+    Animation* child_animation = host_impl->active_tree()
+                                     ->root_layer()
+                                     ->children()[0]
+                                     ->layer_animation_controller()
+                                     ->GetAnimation(Animation::Opacity);
+    EXPECT_EQ(Animation::Running, child_animation->run_state());
+    EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
+    EndTest();
+  }
+
+  virtual void AfterTest() OVERRIDE {}
+
+ private:
+  int frame_count_with_pending_tree_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+    LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
+
 }  // namespace
 }  // namespace cc
-- 
cgit v1.1