Index: cc/trees/layer_tree_host_unittest_damage.cc |
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a66b798a107b30c0041201479a2cea7e384763ea |
--- /dev/null |
+++ b/cc/trees/layer_tree_host_unittest_damage.cc |
@@ -0,0 +1,275 @@ |
+// Copyright 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "cc/trees/layer_tree_host.h" |
+ |
+#include "cc/test/fake_content_layer.h" |
+#include "cc/test/fake_content_layer_client.h" |
+#include "cc/test/layer_tree_test.h" |
+#include "cc/trees/damage_tracker.h" |
+#include "cc/trees/layer_tree_impl.h" |
+ |
+namespace cc { |
+namespace { |
+ |
+// These tests deal with damage tracking. |
+class LayerTreeHostDamageTest : public LayerTreeTest {}; |
+ |
+class LayerTreeHostDamageTestNoDamageDoesNotSwap |
+ : public LayerTreeHostDamageTest { |
+ virtual void BeginTest() OVERRIDE { |
+ expect_swap_and_succeed_ = 0; |
+ did_swaps_ = 0; |
+ did_swap_and_succeed_ = 0; |
+ PostSetNeedsCommitToMainThread(); |
+ } |
+ |
+ virtual void SetupTree() OVERRIDE { |
+ scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_); |
+ root->SetBounds(gfx::Size(10, 10)); |
+ |
+ // Most of the layer isn't visible. |
+ content_ = FakeContentLayer::Create(&client_); |
+ content_->SetBounds(gfx::Size(100, 100)); |
+ root->AddChild(content_); |
+ |
+ layer_tree_host()->SetRootLayer(root); |
+ LayerTreeHostDamageTest::SetupTree(); |
+ } |
+ |
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
+ LayerTreeHostImpl::FrameData* frame_data, |
+ bool result) OVERRIDE { |
+ EXPECT_TRUE(result); |
+ |
+ int source_frame = host_impl->active_tree()->source_frame_number(); |
+ switch (source_frame) { |
+ case 0: |
+ // The first frame has damage, so we should draw and swap. |
+ ++expect_swap_and_succeed_; |
+ break; |
+ case 1: |
+ // The second frame has no damage, so we should not draw and swap. |
+ break; |
+ case 2: |
+ // The third frame has damage again, so we should draw and swap. |
+ ++expect_swap_and_succeed_; |
+ break; |
+ case 3: |
+ // The fourth frame has no visible damage, so we should not draw and |
+ // swap. |
+ EndTest(); |
+ break; |
+ } |
+ return result; |
+ } |
+ |
+ virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, |
+ bool result) OVERRIDE { |
+ ++did_swaps_; |
+ if (result) |
+ ++did_swap_and_succeed_; |
+ EXPECT_EQ(expect_swap_and_succeed_, did_swap_and_succeed_); |
+ } |
+ |
+ virtual void DidCommit() OVERRIDE { |
+ int next_frame = layer_tree_host()->commit_number(); |
+ switch (next_frame) { |
+ case 1: |
+ layer_tree_host()->SetNeedsCommit(); |
+ break; |
+ case 2: |
+ // Cause visible damage. |
+ content_->SetNeedsDisplayRect( |
+ gfx::Rect(layer_tree_host()->layout_viewport_size())); |
+ break; |
+ case 3: |
+ // Cause non-visible damage. |
+ content_->SetNeedsDisplayRect(gfx::Rect(90, 90, 10, 10)); |
+ break; |
+ } |
+ } |
+ |
+ virtual void AfterTest() OVERRIDE { |
+ EXPECT_EQ(4, did_swaps_); |
+ EXPECT_EQ(2, expect_swap_and_succeed_); |
+ EXPECT_EQ(expect_swap_and_succeed_, did_swap_and_succeed_); |
+ } |
+ |
+ FakeContentLayerClient client_; |
+ scoped_refptr<FakeContentLayer> content_; |
+ int expect_swap_and_succeed_; |
+ int did_swaps_; |
+ int did_swap_and_succeed_; |
+}; |
+ |
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestNoDamageDoesNotSwap); |
+ |
+class LayerTreeHostDamageTestNoDamageReadbackDoesDraw |
+ : public LayerTreeHostDamageTest { |
+ virtual void BeginTest() OVERRIDE { |
+ PostSetNeedsCommitToMainThread(); |
+ } |
+ |
+ virtual void SetupTree() OVERRIDE { |
+ scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_); |
+ root->SetBounds(gfx::Size(10, 10)); |
+ |
+ // Most of the layer isn't visible. |
+ content_ = FakeContentLayer::Create(&client_); |
+ content_->SetBounds(gfx::Size(100, 100)); |
+ root->AddChild(content_); |
+ |
+ layer_tree_host()->SetRootLayer(root); |
+ LayerTreeHostDamageTest::SetupTree(); |
+ } |
+ |
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
+ LayerTreeHostImpl::FrameData* frame_data, |
+ bool result) OVERRIDE { |
+ EXPECT_TRUE(result); |
+ |
+ int source_frame = host_impl->active_tree()->source_frame_number(); |
+ switch (source_frame) { |
+ case 0: |
+ // The first frame draws and clears any damage. |
+ break; |
+ case 1: { |
+ // The second frame is a readback, we should have damage in the readback |
+ // rect, but not swap. |
+ RenderSurfaceImpl* root_surface = |
+ host_impl->active_tree()->root_layer()->render_surface(); |
+ gfx::RectF root_damage = |
+ root_surface->damage_tracker()->current_damage_rect(); |
+ root_damage.Intersect(root_surface->content_rect()); |
+ EXPECT_TRUE(root_damage.Contains(gfx::Rect(3, 3, 1, 1))); |
+ break; |
+ } |
+ case 2: |
+ NOTREACHED(); |
+ break; |
+ } |
+ return result; |
+ } |
+ |
+ virtual void DidCommitAndDrawFrame() OVERRIDE { |
+ int next_frame = layer_tree_host()->commit_number(); |
+ switch (next_frame) { |
+ case 1: { |
+ char pixels[4]; |
+ layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels), |
+ gfx::Rect(3, 3, 1, 1)); |
+ EndTest(); |
+ break; |
+ } |
+ } |
+ } |
+ |
+ virtual void AfterTest() OVERRIDE {} |
+ |
+ FakeContentLayerClient client_; |
+ scoped_refptr<FakeContentLayer> content_; |
+}; |
+ |
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestNoDamageReadbackDoesDraw); |
+ |
+class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { |
+ virtual void BeginTest() OVERRIDE { |
+ PostSetNeedsCommitToMainThread(); |
+ } |
+ |
+ virtual void SetupTree() OVERRIDE { |
+ root_ = FakeContentLayer::Create(&client_); |
+ child_ = FakeContentLayer::Create(&client_); |
+ |
+ root_->SetBounds(gfx::Size(500, 500)); |
+ child_->SetPosition(gfx::Point(100, 100)); |
+ child_->SetBounds(gfx::Size(30, 30)); |
+ |
+ root_->AddChild(child_); |
+ layer_tree_host()->SetRootLayer(root_); |
+ LayerTreeHostDamageTest::SetupTree(); |
+ } |
+ |
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
+ LayerTreeHostImpl::FrameData* frame_data, |
+ bool result) OVERRIDE { |
+ EXPECT_TRUE(result); |
+ |
+ RenderSurfaceImpl* root_surface = |
+ host_impl->active_tree()->root_layer()->render_surface(); |
+ gfx::RectF root_damage = |
+ root_surface->damage_tracker()->current_damage_rect(); |
+ root_damage.Intersect(root_surface->content_rect()); |
+ |
+ int source_frame = host_impl->active_tree()->source_frame_number(); |
+ switch (source_frame) { |
+ case 0: |
+ // The first frame draws and clears any damage. |
+ EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(), |
+ root_damage.ToString()); |
+ EXPECT_FALSE(frame_data->has_no_damage); |
+ break; |
+ case 1: |
+ // If we get a frame without damage then we don't draw. |
+ EXPECT_EQ(gfx::RectF().ToString(), root_damage.ToString()); |
+ EXPECT_TRUE(frame_data->has_no_damage); |
+ |
+ // Then we set full damage for the next frame. |
+ host_impl->SetFullRootLayerDamage(); |
+ break; |
+ case 2: |
+ // The whole frame should be damaged as requested. |
+ EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(), |
+ root_damage.ToString()); |
+ EXPECT_FALSE(frame_data->has_no_damage); |
+ |
+ // Just a part of the next frame should be damaged. |
+ child_damage_rect_ = gfx::RectF(10, 11, 12, 13); |
+ break; |
+ case 3: |
+ // The update rect in the child should be damaged. |
+ EXPECT_EQ(gfx::RectF(100+10, 100+11, 12, 13).ToString(), |
+ root_damage.ToString()); |
+ EXPECT_FALSE(frame_data->has_no_damage); |
+ |
+ // If we damage part of the frame, but also damage the full |
+ // frame, then the whole frame should be damaged. |
+ child_damage_rect_ = gfx::RectF(10, 11, 12, 13); |
+ host_impl->SetFullRootLayerDamage(); |
+ break; |
+ case 4: |
+ // The whole frame is damaged. |
+ EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(), |
+ root_damage.ToString()); |
+ EXPECT_FALSE(frame_data->has_no_damage); |
+ |
+ EndTest(); |
+ break; |
+ } |
+ return result; |
+ } |
+ |
+ virtual void DidCommitAndDrawFrame() OVERRIDE { |
+ if (!TestEnded()) |
+ layer_tree_host()->SetNeedsCommit(); |
+ |
+ if (!child_damage_rect_.IsEmpty()) { |
+ child_->SetNeedsDisplayRect(child_damage_rect_); |
+ child_damage_rect_ = gfx::RectF(); |
+ } |
+ } |
+ |
+ virtual void AfterTest() OVERRIDE {} |
+ |
+ FakeContentLayerClient client_; |
+ scoped_refptr<FakeContentLayer> root_; |
+ scoped_refptr<FakeContentLayer> child_; |
+ gfx::RectF child_damage_rect_; |
+}; |
+ |
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestForcedFullDamage); |
+ |
+} // namespace |
+} // namespace cc |