Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / cc / trees / layer_tree_host_unittest_animation.cc
index aeeb4f5..70610f7 100644 (file)
@@ -1244,5 +1244,148 @@ 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);
+
+class LayerTreeHostAnimationTestAddAnimationAfterAnimating
+    : public LayerTreeHostAnimationTest {
+ public:
+  LayerTreeHostAnimationTestAddAnimationAfterAnimating()
+      : num_swap_buffers_(0) {}
+
+  virtual void SetupTree() OVERRIDE {
+    LayerTreeHostAnimationTest::SetupTree();
+    content_ = Layer::Create();
+    content_->SetBounds(gfx::Size(4, 4));
+    layer_tree_host()->root_layer()->AddChild(content_);
+  }
+
+  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+  virtual void DidCommit() OVERRIDE {
+    switch (layer_tree_host()->source_frame_number()) {
+      case 1:
+        // First frame: add an animation to the root layer.
+        AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
+        break;
+      case 2:
+        // Second frame: add an animation to the content layer. The root layer
+        // animation has caused us to animate already during this frame.
+        AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false);
+        break;
+    }
+  }
+
+  virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
+                                   bool result) OVERRIDE {
+    // The third frame is when both animations have started. Check that both
+    // have a valid start time.
+    if (++num_swap_buffers_ == 3) {
+      EndTest();
+      AnimationRegistrar::AnimationControllerMap copy =
+          host_impl->animation_registrar()->active_animation_controllers();
+      EXPECT_EQ(2u, copy.size());
+      for (AnimationRegistrar::AnimationControllerMap::iterator iter =
+               copy.begin();
+           iter != copy.end();
+           ++iter) {
+        int id = ((*iter).second->id());
+        if (id == host_impl->RootLayer()->id()) {
+          Animation* anim = (*iter).second->GetAnimation(Animation::Transform);
+          EXPECT_GT(anim->start_time(), 0);
+        } else if (id == host_impl->RootLayer()->children()[0]->id()) {
+          Animation* anim = (*iter).second->GetAnimation(Animation::Opacity);
+          EXPECT_GT(anim->start_time(), 0);
+        }
+      }
+    }
+  }
+
+  virtual void AfterTest() OVERRIDE {}
+
+ private:
+  scoped_refptr<Layer> content_;
+  int num_swap_buffers_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+    LayerTreeHostAnimationTestAddAnimationAfterAnimating);
+
 }  // namespace
 }  // namespace cc