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