OLD | NEW |
(Empty) | |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "cc/trees/layer_tree_host.h" |
| 6 |
| 7 #include "cc/test/fake_content_layer.h" |
| 8 #include "cc/test/fake_content_layer_client.h" |
| 9 #include "cc/test/layer_tree_test.h" |
| 10 #include "cc/trees/damage_tracker.h" |
| 11 #include "cc/trees/layer_tree_impl.h" |
| 12 |
| 13 namespace cc { |
| 14 namespace { |
| 15 |
| 16 // These tests deal with damage tracking. |
| 17 class LayerTreeHostDamageTest : public LayerTreeTest {}; |
| 18 |
| 19 class LayerTreeHostDamageTestNoDamageDoesNotSwap |
| 20 : public LayerTreeHostDamageTest { |
| 21 virtual void BeginTest() OVERRIDE { |
| 22 expect_swap_and_succeed_ = 0; |
| 23 did_swaps_ = 0; |
| 24 did_swap_and_succeed_ = 0; |
| 25 PostSetNeedsCommitToMainThread(); |
| 26 } |
| 27 |
| 28 virtual void SetupTree() OVERRIDE { |
| 29 scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_); |
| 30 root->SetBounds(gfx::Size(10, 10)); |
| 31 |
| 32 // Most of the layer isn't visible. |
| 33 content_ = FakeContentLayer::Create(&client_); |
| 34 content_->SetBounds(gfx::Size(100, 100)); |
| 35 root->AddChild(content_); |
| 36 |
| 37 layer_tree_host()->SetRootLayer(root); |
| 38 LayerTreeHostDamageTest::SetupTree(); |
| 39 } |
| 40 |
| 41 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
| 42 LayerTreeHostImpl::FrameData* frame_data, |
| 43 bool result) OVERRIDE { |
| 44 EXPECT_TRUE(result); |
| 45 |
| 46 int source_frame = host_impl->active_tree()->source_frame_number(); |
| 47 switch (source_frame) { |
| 48 case 0: |
| 49 // The first frame has damage, so we should draw and swap. |
| 50 ++expect_swap_and_succeed_; |
| 51 break; |
| 52 case 1: |
| 53 // The second frame has no damage, so we should not draw and swap. |
| 54 break; |
| 55 case 2: |
| 56 // The third frame has damage again, so we should draw and swap. |
| 57 ++expect_swap_and_succeed_; |
| 58 break; |
| 59 case 3: |
| 60 // The fourth frame has no visible damage, so we should not draw and |
| 61 // swap. |
| 62 EndTest(); |
| 63 break; |
| 64 } |
| 65 return result; |
| 66 } |
| 67 |
| 68 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, |
| 69 bool result) OVERRIDE { |
| 70 ++did_swaps_; |
| 71 if (result) |
| 72 ++did_swap_and_succeed_; |
| 73 EXPECT_EQ(expect_swap_and_succeed_, did_swap_and_succeed_); |
| 74 } |
| 75 |
| 76 virtual void DidCommit() OVERRIDE { |
| 77 int next_frame = layer_tree_host()->commit_number(); |
| 78 switch (next_frame) { |
| 79 case 1: |
| 80 layer_tree_host()->SetNeedsCommit(); |
| 81 break; |
| 82 case 2: |
| 83 // Cause visible damage. |
| 84 content_->SetNeedsDisplayRect( |
| 85 gfx::Rect(layer_tree_host()->layout_viewport_size())); |
| 86 break; |
| 87 case 3: |
| 88 // Cause non-visible damage. |
| 89 content_->SetNeedsDisplayRect(gfx::Rect(90, 90, 10, 10)); |
| 90 break; |
| 91 } |
| 92 } |
| 93 |
| 94 virtual void AfterTest() OVERRIDE { |
| 95 EXPECT_EQ(4, did_swaps_); |
| 96 EXPECT_EQ(2, expect_swap_and_succeed_); |
| 97 EXPECT_EQ(expect_swap_and_succeed_, did_swap_and_succeed_); |
| 98 } |
| 99 |
| 100 FakeContentLayerClient client_; |
| 101 scoped_refptr<FakeContentLayer> content_; |
| 102 int expect_swap_and_succeed_; |
| 103 int did_swaps_; |
| 104 int did_swap_and_succeed_; |
| 105 }; |
| 106 |
| 107 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestNoDamageDoesNotSwap); |
| 108 |
| 109 class LayerTreeHostDamageTestNoDamageReadbackDoesDraw |
| 110 : public LayerTreeHostDamageTest { |
| 111 virtual void BeginTest() OVERRIDE { |
| 112 PostSetNeedsCommitToMainThread(); |
| 113 } |
| 114 |
| 115 virtual void SetupTree() OVERRIDE { |
| 116 scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_); |
| 117 root->SetBounds(gfx::Size(10, 10)); |
| 118 |
| 119 // Most of the layer isn't visible. |
| 120 content_ = FakeContentLayer::Create(&client_); |
| 121 content_->SetBounds(gfx::Size(100, 100)); |
| 122 root->AddChild(content_); |
| 123 |
| 124 layer_tree_host()->SetRootLayer(root); |
| 125 LayerTreeHostDamageTest::SetupTree(); |
| 126 } |
| 127 |
| 128 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
| 129 LayerTreeHostImpl::FrameData* frame_data, |
| 130 bool result) OVERRIDE { |
| 131 EXPECT_TRUE(result); |
| 132 |
| 133 int source_frame = host_impl->active_tree()->source_frame_number(); |
| 134 switch (source_frame) { |
| 135 case 0: |
| 136 // The first frame draws and clears any damage. |
| 137 break; |
| 138 case 1: { |
| 139 // The second frame is a readback, we should have damage in the readback |
| 140 // rect, but not swap. |
| 141 RenderSurfaceImpl* root_surface = |
| 142 host_impl->active_tree()->root_layer()->render_surface(); |
| 143 gfx::RectF root_damage = |
| 144 root_surface->damage_tracker()->current_damage_rect(); |
| 145 root_damage.Intersect(root_surface->content_rect()); |
| 146 EXPECT_TRUE(root_damage.Contains(gfx::Rect(3, 3, 1, 1))); |
| 147 break; |
| 148 } |
| 149 case 2: |
| 150 NOTREACHED(); |
| 151 break; |
| 152 } |
| 153 return result; |
| 154 } |
| 155 |
| 156 virtual void DidCommitAndDrawFrame() OVERRIDE { |
| 157 int next_frame = layer_tree_host()->commit_number(); |
| 158 switch (next_frame) { |
| 159 case 1: { |
| 160 char pixels[4]; |
| 161 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels), |
| 162 gfx::Rect(3, 3, 1, 1)); |
| 163 EndTest(); |
| 164 break; |
| 165 } |
| 166 } |
| 167 } |
| 168 |
| 169 virtual void AfterTest() OVERRIDE {} |
| 170 |
| 171 FakeContentLayerClient client_; |
| 172 scoped_refptr<FakeContentLayer> content_; |
| 173 }; |
| 174 |
| 175 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestNoDamageReadbackDoesDraw); |
| 176 |
| 177 class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { |
| 178 virtual void BeginTest() OVERRIDE { |
| 179 PostSetNeedsCommitToMainThread(); |
| 180 } |
| 181 |
| 182 virtual void SetupTree() OVERRIDE { |
| 183 root_ = FakeContentLayer::Create(&client_); |
| 184 child_ = FakeContentLayer::Create(&client_); |
| 185 |
| 186 root_->SetBounds(gfx::Size(500, 500)); |
| 187 child_->SetPosition(gfx::Point(100, 100)); |
| 188 child_->SetBounds(gfx::Size(30, 30)); |
| 189 |
| 190 root_->AddChild(child_); |
| 191 layer_tree_host()->SetRootLayer(root_); |
| 192 LayerTreeHostDamageTest::SetupTree(); |
| 193 } |
| 194 |
| 195 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
| 196 LayerTreeHostImpl::FrameData* frame_data, |
| 197 bool result) OVERRIDE { |
| 198 EXPECT_TRUE(result); |
| 199 |
| 200 RenderSurfaceImpl* root_surface = |
| 201 host_impl->active_tree()->root_layer()->render_surface(); |
| 202 gfx::RectF root_damage = |
| 203 root_surface->damage_tracker()->current_damage_rect(); |
| 204 root_damage.Intersect(root_surface->content_rect()); |
| 205 |
| 206 int source_frame = host_impl->active_tree()->source_frame_number(); |
| 207 switch (source_frame) { |
| 208 case 0: |
| 209 // The first frame draws and clears any damage. |
| 210 EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(), |
| 211 root_damage.ToString()); |
| 212 EXPECT_FALSE(frame_data->has_no_damage); |
| 213 break; |
| 214 case 1: |
| 215 // If we get a frame without damage then we don't draw. |
| 216 EXPECT_EQ(gfx::RectF().ToString(), root_damage.ToString()); |
| 217 EXPECT_TRUE(frame_data->has_no_damage); |
| 218 |
| 219 // Then we set full damage for the next frame. |
| 220 host_impl->SetFullRootLayerDamage(); |
| 221 break; |
| 222 case 2: |
| 223 // The whole frame should be damaged as requested. |
| 224 EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(), |
| 225 root_damage.ToString()); |
| 226 EXPECT_FALSE(frame_data->has_no_damage); |
| 227 |
| 228 // Just a part of the next frame should be damaged. |
| 229 child_damage_rect_ = gfx::RectF(10, 11, 12, 13); |
| 230 break; |
| 231 case 3: |
| 232 // The update rect in the child should be damaged. |
| 233 EXPECT_EQ(gfx::RectF(100+10, 100+11, 12, 13).ToString(), |
| 234 root_damage.ToString()); |
| 235 EXPECT_FALSE(frame_data->has_no_damage); |
| 236 |
| 237 // If we damage part of the frame, but also damage the full |
| 238 // frame, then the whole frame should be damaged. |
| 239 child_damage_rect_ = gfx::RectF(10, 11, 12, 13); |
| 240 host_impl->SetFullRootLayerDamage(); |
| 241 break; |
| 242 case 4: |
| 243 // The whole frame is damaged. |
| 244 EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(), |
| 245 root_damage.ToString()); |
| 246 EXPECT_FALSE(frame_data->has_no_damage); |
| 247 |
| 248 EndTest(); |
| 249 break; |
| 250 } |
| 251 return result; |
| 252 } |
| 253 |
| 254 virtual void DidCommitAndDrawFrame() OVERRIDE { |
| 255 if (!TestEnded()) |
| 256 layer_tree_host()->SetNeedsCommit(); |
| 257 |
| 258 if (!child_damage_rect_.IsEmpty()) { |
| 259 child_->SetNeedsDisplayRect(child_damage_rect_); |
| 260 child_damage_rect_ = gfx::RectF(); |
| 261 } |
| 262 } |
| 263 |
| 264 virtual void AfterTest() OVERRIDE {} |
| 265 |
| 266 FakeContentLayerClient client_; |
| 267 scoped_refptr<FakeContentLayer> root_; |
| 268 scoped_refptr<FakeContentLayer> child_; |
| 269 gfx::RectF child_damage_rect_; |
| 270 }; |
| 271 |
| 272 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestForcedFullDamage); |
| 273 |
| 274 } // namespace |
| 275 } // namespace cc |
OLD | NEW |