| OLD | NEW |
| (Empty) |
| 1 // Copyright 2011 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 <algorithm> | |
| 8 | |
| 9 #include "base/auto_reset.h" | |
| 10 #include "base/synchronization/lock.h" | |
| 11 #include "cc/animation/timing_function.h" | |
| 12 #include "cc/debug/frame_rate_counter.h" | |
| 13 #include "cc/layers/content_layer.h" | |
| 14 #include "cc/layers/content_layer_client.h" | |
| 15 #include "cc/layers/io_surface_layer.h" | |
| 16 #include "cc/layers/layer_impl.h" | |
| 17 #include "cc/layers/painted_scrollbar_layer.h" | |
| 18 #include "cc/layers/picture_layer.h" | |
| 19 #include "cc/layers/solid_color_layer.h" | |
| 20 #include "cc/output/begin_frame_args.h" | |
| 21 #include "cc/output/compositor_frame_ack.h" | |
| 22 #include "cc/output/copy_output_request.h" | |
| 23 #include "cc/output/copy_output_result.h" | |
| 24 #include "cc/output/output_surface.h" | |
| 25 #include "cc/output/swap_promise.h" | |
| 26 #include "cc/quads/draw_quad.h" | |
| 27 #include "cc/quads/io_surface_draw_quad.h" | |
| 28 #include "cc/quads/tile_draw_quad.h" | |
| 29 #include "cc/resources/prioritized_resource.h" | |
| 30 #include "cc/resources/prioritized_resource_manager.h" | |
| 31 #include "cc/resources/resource_update_queue.h" | |
| 32 #include "cc/test/fake_content_layer.h" | |
| 33 #include "cc/test/fake_content_layer_client.h" | |
| 34 #include "cc/test/fake_content_layer_impl.h" | |
| 35 #include "cc/test/fake_layer_tree_host_client.h" | |
| 36 #include "cc/test/fake_output_surface.h" | |
| 37 #include "cc/test/fake_painted_scrollbar_layer.h" | |
| 38 #include "cc/test/fake_picture_layer.h" | |
| 39 #include "cc/test/fake_picture_layer_impl.h" | |
| 40 #include "cc/test/fake_picture_pile.h" | |
| 41 #include "cc/test/fake_proxy.h" | |
| 42 #include "cc/test/fake_scoped_ui_resource.h" | |
| 43 #include "cc/test/geometry_test_utils.h" | |
| 44 #include "cc/test/impl_side_painting_settings.h" | |
| 45 #include "cc/test/layer_tree_test.h" | |
| 46 #include "cc/test/test_shared_bitmap_manager.h" | |
| 47 #include "cc/test/test_web_graphics_context_3d.h" | |
| 48 #include "cc/trees/layer_tree_host_impl.h" | |
| 49 #include "cc/trees/layer_tree_impl.h" | |
| 50 #include "cc/trees/single_thread_proxy.h" | |
| 51 #include "cc/trees/thread_proxy.h" | |
| 52 #include "gpu/GLES2/gl2extchromium.h" | |
| 53 #include "skia/ext/refptr.h" | |
| 54 #include "testing/gmock/include/gmock/gmock.h" | |
| 55 #include "third_party/khronos/GLES2/gl2.h" | |
| 56 #include "third_party/khronos/GLES2/gl2ext.h" | |
| 57 #include "third_party/skia/include/core/SkPicture.h" | |
| 58 #include "ui/gfx/frame_time.h" | |
| 59 #include "ui/gfx/geometry/point_conversions.h" | |
| 60 #include "ui/gfx/geometry/size_conversions.h" | |
| 61 #include "ui/gfx/geometry/vector2d_conversions.h" | |
| 62 | |
| 63 using testing::_; | |
| 64 using testing::AnyNumber; | |
| 65 using testing::AtLeast; | |
| 66 using testing::Mock; | |
| 67 | |
| 68 namespace cc { | |
| 69 namespace { | |
| 70 | |
| 71 class LayerTreeHostTest : public LayerTreeTest { | |
| 72 public: | |
| 73 LayerTreeHostTest() : contents_texture_manager_(nullptr) {} | |
| 74 | |
| 75 void DidInitializeOutputSurface() override { | |
| 76 contents_texture_manager_ = layer_tree_host()->contents_texture_manager(); | |
| 77 } | |
| 78 | |
| 79 protected: | |
| 80 PrioritizedResourceManager* contents_texture_manager_; | |
| 81 }; | |
| 82 | |
| 83 // Test if the LTHI receives ReadyToActivate notifications from the TileManager | |
| 84 // when no raster tasks get scheduled. | |
| 85 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest { | |
| 86 public: | |
| 87 LayerTreeHostTestReadyToActivateEmpty() | |
| 88 : did_notify_ready_to_activate_(false), | |
| 89 all_tiles_required_for_activation_are_ready_to_draw_(false), | |
| 90 required_for_activation_count_(0) {} | |
| 91 | |
| 92 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 93 | |
| 94 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 95 const std::vector<PictureLayerImpl*>& layers = | |
| 96 impl->sync_tree()->picture_layers(); | |
| 97 required_for_activation_count_ = 0; | |
| 98 for (const auto& layer : layers) { | |
| 99 FakePictureLayerImpl* fake_layer = | |
| 100 static_cast<FakePictureLayerImpl*>(layer); | |
| 101 required_for_activation_count_ += | |
| 102 fake_layer->CountTilesRequiredForActivation(); | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { | |
| 107 did_notify_ready_to_activate_ = true; | |
| 108 all_tiles_required_for_activation_are_ready_to_draw_ = | |
| 109 impl->tile_manager()->IsReadyToActivate(); | |
| 110 EndTest(); | |
| 111 } | |
| 112 | |
| 113 void AfterTest() override { | |
| 114 EXPECT_TRUE(did_notify_ready_to_activate_); | |
| 115 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_); | |
| 116 EXPECT_EQ(size_t(0), required_for_activation_count_); | |
| 117 } | |
| 118 | |
| 119 protected: | |
| 120 bool did_notify_ready_to_activate_; | |
| 121 bool all_tiles_required_for_activation_are_ready_to_draw_; | |
| 122 size_t required_for_activation_count_; | |
| 123 }; | |
| 124 | |
| 125 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty); | |
| 126 | |
| 127 // Test if the LTHI receives ReadyToActivate notifications from the TileManager | |
| 128 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled. | |
| 129 class LayerTreeHostTestReadyToActivateNonEmpty | |
| 130 : public LayerTreeHostTestReadyToActivateEmpty { | |
| 131 public: | |
| 132 void SetupTree() override { | |
| 133 client_.set_fill_with_nonsolid_color(true); | |
| 134 scoped_refptr<FakePictureLayer> root_layer = | |
| 135 FakePictureLayer::Create(&client_); | |
| 136 root_layer->SetBounds(gfx::Size(1024, 1024)); | |
| 137 root_layer->SetIsDrawable(true); | |
| 138 | |
| 139 layer_tree_host()->SetRootLayer(root_layer); | |
| 140 LayerTreeHostTest::SetupTree(); | |
| 141 } | |
| 142 | |
| 143 void AfterTest() override { | |
| 144 EXPECT_TRUE(did_notify_ready_to_activate_); | |
| 145 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_); | |
| 146 EXPECT_LE(size_t(1), required_for_activation_count_); | |
| 147 } | |
| 148 | |
| 149 private: | |
| 150 FakeContentLayerClient client_; | |
| 151 }; | |
| 152 | |
| 153 // Multi-thread only because in single thread the commit goes directly to the | |
| 154 // active tree, so notify ready to activate is skipped. | |
| 155 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty); | |
| 156 | |
| 157 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when | |
| 158 // no raster tasks get scheduled. | |
| 159 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest { | |
| 160 public: | |
| 161 LayerTreeHostTestReadyToDrawEmpty() | |
| 162 : did_notify_ready_to_draw_(false), | |
| 163 all_tiles_required_for_draw_are_ready_to_draw_(false), | |
| 164 required_for_draw_count_(0) {} | |
| 165 | |
| 166 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 167 | |
| 168 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override { | |
| 169 did_notify_ready_to_draw_ = true; | |
| 170 const std::vector<PictureLayerImpl*>& layers = | |
| 171 impl->active_tree()->picture_layers(); | |
| 172 all_tiles_required_for_draw_are_ready_to_draw_ = | |
| 173 impl->tile_manager()->IsReadyToDraw(); | |
| 174 for (const auto& layer : layers) { | |
| 175 FakePictureLayerImpl* fake_layer = | |
| 176 static_cast<FakePictureLayerImpl*>(layer); | |
| 177 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw(); | |
| 178 } | |
| 179 | |
| 180 EndTest(); | |
| 181 } | |
| 182 | |
| 183 void AfterTest() override { | |
| 184 EXPECT_TRUE(did_notify_ready_to_draw_); | |
| 185 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_); | |
| 186 EXPECT_EQ(size_t(0), required_for_draw_count_); | |
| 187 } | |
| 188 | |
| 189 protected: | |
| 190 bool did_notify_ready_to_draw_; | |
| 191 bool all_tiles_required_for_draw_are_ready_to_draw_; | |
| 192 size_t required_for_draw_count_; | |
| 193 }; | |
| 194 | |
| 195 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty); | |
| 196 | |
| 197 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when | |
| 198 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled. | |
| 199 class LayerTreeHostTestReadyToDrawNonEmpty | |
| 200 : public LayerTreeHostTestReadyToDrawEmpty { | |
| 201 public: | |
| 202 void SetupTree() override { | |
| 203 client_.set_fill_with_nonsolid_color(true); | |
| 204 scoped_refptr<FakePictureLayer> root_layer = | |
| 205 FakePictureLayer::Create(&client_); | |
| 206 root_layer->SetBounds(gfx::Size(1024, 1024)); | |
| 207 root_layer->SetIsDrawable(true); | |
| 208 | |
| 209 layer_tree_host()->SetRootLayer(root_layer); | |
| 210 LayerTreeHostTest::SetupTree(); | |
| 211 } | |
| 212 | |
| 213 void AfterTest() override { | |
| 214 EXPECT_TRUE(did_notify_ready_to_draw_); | |
| 215 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_); | |
| 216 EXPECT_LE(size_t(1), required_for_draw_count_); | |
| 217 } | |
| 218 | |
| 219 private: | |
| 220 FakeContentLayerClient client_; | |
| 221 }; | |
| 222 | |
| 223 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in | |
| 224 // single threaded mode. | |
| 225 SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty); | |
| 226 | |
| 227 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1 | |
| 228 // draw with frame 0. | |
| 229 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest { | |
| 230 public: | |
| 231 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {} | |
| 232 | |
| 233 void BeginTest() override { | |
| 234 PostSetNeedsCommitToMainThread(); | |
| 235 PostSetNeedsCommitToMainThread(); | |
| 236 } | |
| 237 | |
| 238 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 239 num_draws_++; | |
| 240 if (!impl->active_tree()->source_frame_number()) | |
| 241 EndTest(); | |
| 242 } | |
| 243 | |
| 244 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 245 num_commits_++; | |
| 246 } | |
| 247 | |
| 248 void AfterTest() override { | |
| 249 EXPECT_LE(1, num_commits_); | |
| 250 EXPECT_LE(1, num_draws_); | |
| 251 } | |
| 252 | |
| 253 private: | |
| 254 int num_commits_; | |
| 255 int num_draws_; | |
| 256 }; | |
| 257 | |
| 258 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1); | |
| 259 | |
| 260 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that | |
| 261 // first committed frame draws should lead to another commit. | |
| 262 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest { | |
| 263 public: | |
| 264 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {} | |
| 265 | |
| 266 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 267 | |
| 268 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; } | |
| 269 | |
| 270 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 271 ++num_commits_; | |
| 272 switch (num_commits_) { | |
| 273 case 1: | |
| 274 PostSetNeedsCommitToMainThread(); | |
| 275 break; | |
| 276 case 2: | |
| 277 EndTest(); | |
| 278 break; | |
| 279 default: | |
| 280 NOTREACHED(); | |
| 281 } | |
| 282 } | |
| 283 | |
| 284 void AfterTest() override { | |
| 285 EXPECT_EQ(2, num_commits_); | |
| 286 EXPECT_LE(1, num_draws_); | |
| 287 } | |
| 288 | |
| 289 private: | |
| 290 int num_commits_; | |
| 291 int num_draws_; | |
| 292 }; | |
| 293 | |
| 294 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2); | |
| 295 | |
| 296 // Verify that we pass property values in PushPropertiesTo. | |
| 297 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { | |
| 298 protected: | |
| 299 void SetupTree() override { | |
| 300 scoped_refptr<Layer> root = Layer::Create(); | |
| 301 root->CreateRenderSurface(); | |
| 302 root->SetBounds(gfx::Size(10, 10)); | |
| 303 layer_tree_host()->SetRootLayer(root); | |
| 304 LayerTreeHostTest::SetupTree(); | |
| 305 } | |
| 306 | |
| 307 enum Properties { | |
| 308 STARTUP, | |
| 309 BOUNDS, | |
| 310 HIDE_LAYER_AND_SUBTREE, | |
| 311 DRAWS_CONTENT, | |
| 312 DONE, | |
| 313 }; | |
| 314 | |
| 315 void BeginTest() override { | |
| 316 index_ = STARTUP; | |
| 317 PostSetNeedsCommitToMainThread(); | |
| 318 } | |
| 319 | |
| 320 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 321 VerifyAfterValues(impl->active_tree()->root_layer()); | |
| 322 } | |
| 323 | |
| 324 void DidCommitAndDrawFrame() override { | |
| 325 SetBeforeValues(layer_tree_host()->root_layer()); | |
| 326 VerifyBeforeValues(layer_tree_host()->root_layer()); | |
| 327 | |
| 328 ++index_; | |
| 329 if (index_ == DONE) { | |
| 330 EndTest(); | |
| 331 return; | |
| 332 } | |
| 333 | |
| 334 SetAfterValues(layer_tree_host()->root_layer()); | |
| 335 } | |
| 336 | |
| 337 void AfterTest() override {} | |
| 338 | |
| 339 void VerifyBeforeValues(Layer* layer) { | |
| 340 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString()); | |
| 341 EXPECT_FALSE(layer->hide_layer_and_subtree()); | |
| 342 EXPECT_FALSE(layer->DrawsContent()); | |
| 343 } | |
| 344 | |
| 345 void SetBeforeValues(Layer* layer) { | |
| 346 layer->SetBounds(gfx::Size(10, 10)); | |
| 347 layer->SetHideLayerAndSubtree(false); | |
| 348 layer->SetIsDrawable(false); | |
| 349 } | |
| 350 | |
| 351 void VerifyAfterValues(LayerImpl* layer) { | |
| 352 switch (static_cast<Properties>(index_)) { | |
| 353 case STARTUP: | |
| 354 case DONE: | |
| 355 break; | |
| 356 case BOUNDS: | |
| 357 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString()); | |
| 358 break; | |
| 359 case HIDE_LAYER_AND_SUBTREE: | |
| 360 EXPECT_TRUE(layer->hide_layer_and_subtree()); | |
| 361 break; | |
| 362 case DRAWS_CONTENT: | |
| 363 EXPECT_TRUE(layer->DrawsContent()); | |
| 364 break; | |
| 365 } | |
| 366 } | |
| 367 | |
| 368 void SetAfterValues(Layer* layer) { | |
| 369 switch (static_cast<Properties>(index_)) { | |
| 370 case STARTUP: | |
| 371 case DONE: | |
| 372 break; | |
| 373 case BOUNDS: | |
| 374 layer->SetBounds(gfx::Size(20, 20)); | |
| 375 break; | |
| 376 case HIDE_LAYER_AND_SUBTREE: | |
| 377 layer->SetHideLayerAndSubtree(true); | |
| 378 break; | |
| 379 case DRAWS_CONTENT: | |
| 380 layer->SetIsDrawable(true); | |
| 381 break; | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 int index_; | |
| 386 }; | |
| 387 | |
| 388 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo); | |
| 389 | |
| 390 // 1 setNeedsRedraw after the first commit has completed should lead to 1 | |
| 391 // additional draw. | |
| 392 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest { | |
| 393 public: | |
| 394 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {} | |
| 395 | |
| 396 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 397 | |
| 398 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 399 EXPECT_EQ(0, impl->active_tree()->source_frame_number()); | |
| 400 if (!num_draws_) { | |
| 401 // Redraw again to verify that the second redraw doesn't commit. | |
| 402 PostSetNeedsRedrawToMainThread(); | |
| 403 } else { | |
| 404 EndTest(); | |
| 405 } | |
| 406 num_draws_++; | |
| 407 } | |
| 408 | |
| 409 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 410 EXPECT_EQ(0, num_draws_); | |
| 411 num_commits_++; | |
| 412 } | |
| 413 | |
| 414 void AfterTest() override { | |
| 415 EXPECT_GE(2, num_draws_); | |
| 416 EXPECT_EQ(1, num_commits_); | |
| 417 } | |
| 418 | |
| 419 private: | |
| 420 int num_commits_; | |
| 421 int num_draws_; | |
| 422 }; | |
| 423 | |
| 424 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw); | |
| 425 | |
| 426 // After setNeedsRedrawRect(invalid_rect) the final damage_rect | |
| 427 // must contain invalid_rect. | |
| 428 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { | |
| 429 public: | |
| 430 LayerTreeHostTestSetNeedsRedrawRect() | |
| 431 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {} | |
| 432 | |
| 433 void BeginTest() override { | |
| 434 if (layer_tree_host()->settings().impl_side_painting) | |
| 435 root_layer_ = FakePictureLayer::Create(&client_); | |
| 436 else | |
| 437 root_layer_ = ContentLayer::Create(&client_); | |
| 438 root_layer_->SetIsDrawable(true); | |
| 439 root_layer_->SetBounds(bounds_); | |
| 440 layer_tree_host()->SetRootLayer(root_layer_); | |
| 441 layer_tree_host()->SetViewportSize(bounds_); | |
| 442 PostSetNeedsCommitToMainThread(); | |
| 443 } | |
| 444 | |
| 445 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 446 LayerTreeHostImpl::FrameData* frame_data, | |
| 447 DrawResult draw_result) override { | |
| 448 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
| 449 | |
| 450 gfx::RectF root_damage_rect; | |
| 451 if (!frame_data->render_passes.empty()) | |
| 452 root_damage_rect = frame_data->render_passes.back()->damage_rect; | |
| 453 | |
| 454 if (!num_draws_) { | |
| 455 // If this is the first frame, expect full frame damage. | |
| 456 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_)); | |
| 457 } else { | |
| 458 // Check that invalid_rect_ is indeed repainted. | |
| 459 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_)); | |
| 460 } | |
| 461 | |
| 462 return draw_result; | |
| 463 } | |
| 464 | |
| 465 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 466 if (!num_draws_) { | |
| 467 PostSetNeedsRedrawRectToMainThread(invalid_rect_); | |
| 468 } else { | |
| 469 EndTest(); | |
| 470 } | |
| 471 num_draws_++; | |
| 472 } | |
| 473 | |
| 474 void AfterTest() override { EXPECT_EQ(2, num_draws_); } | |
| 475 | |
| 476 private: | |
| 477 int num_draws_; | |
| 478 const gfx::Size bounds_; | |
| 479 const gfx::Rect invalid_rect_; | |
| 480 FakeContentLayerClient client_; | |
| 481 scoped_refptr<Layer> root_layer_; | |
| 482 }; | |
| 483 | |
| 484 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect); | |
| 485 | |
| 486 // Ensure the texture size of the pending and active trees are identical when a | |
| 487 // layer is not in the viewport and a resize happens on the viewport | |
| 488 class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest { | |
| 489 public: | |
| 490 LayerTreeHostTestGpuRasterDeviceSizeChanged() | |
| 491 : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {} | |
| 492 | |
| 493 void BeginTest() override { | |
| 494 client_.set_fill_with_nonsolid_color(true); | |
| 495 root_layer_ = FakePictureLayer::Create(&client_); | |
| 496 root_layer_->SetIsDrawable(true); | |
| 497 gfx::Transform transform; | |
| 498 // Translate the layer out of the viewport to force it to not update its | |
| 499 // tile size via PushProperties. | |
| 500 transform.Translate(10000.0, 10000.0); | |
| 501 root_layer_->SetTransform(transform); | |
| 502 root_layer_->SetBounds(bounds_); | |
| 503 layer_tree_host()->SetRootLayer(root_layer_); | |
| 504 layer_tree_host()->SetViewportSize(bounds_); | |
| 505 | |
| 506 PostSetNeedsCommitToMainThread(); | |
| 507 } | |
| 508 | |
| 509 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 510 settings->gpu_rasterization_enabled = true; | |
| 511 settings->gpu_rasterization_forced = true; | |
| 512 } | |
| 513 | |
| 514 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 515 // Perform 2 commits. | |
| 516 if (!num_draws_) { | |
| 517 PostSetNeedsRedrawRectToMainThread(invalid_rect_); | |
| 518 } else { | |
| 519 EndTest(); | |
| 520 } | |
| 521 num_draws_++; | |
| 522 } | |
| 523 | |
| 524 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 525 if (num_draws_ == 2) { | |
| 526 auto pending_tree = host_impl->pending_tree(); | |
| 527 auto pending_layer_impl = | |
| 528 static_cast<FakePictureLayerImpl*>(pending_tree->root_layer()); | |
| 529 EXPECT_NE(pending_layer_impl, nullptr); | |
| 530 | |
| 531 auto active_tree = host_impl->pending_tree(); | |
| 532 auto active_layer_impl = | |
| 533 static_cast<FakePictureLayerImpl*>(active_tree->root_layer()); | |
| 534 EXPECT_NE(pending_layer_impl, nullptr); | |
| 535 | |
| 536 auto active_tiling_set = active_layer_impl->picture_layer_tiling_set(); | |
| 537 auto active_tiling = active_tiling_set->tiling_at(0); | |
| 538 auto pending_tiling_set = pending_layer_impl->picture_layer_tiling_set(); | |
| 539 auto pending_tiling = pending_tiling_set->tiling_at(0); | |
| 540 EXPECT_EQ( | |
| 541 pending_tiling->TilingDataForTesting().max_texture_size().width(), | |
| 542 active_tiling->TilingDataForTesting().max_texture_size().width()); | |
| 543 } | |
| 544 } | |
| 545 | |
| 546 void DidCommitAndDrawFrame() override { | |
| 547 // On the second commit, resize the viewport. | |
| 548 if (num_draws_ == 1) { | |
| 549 layer_tree_host()->SetViewportSize(gfx::Size(400, 64)); | |
| 550 } | |
| 551 } | |
| 552 | |
| 553 void AfterTest() override {} | |
| 554 | |
| 555 private: | |
| 556 int num_draws_; | |
| 557 const gfx::Size bounds_; | |
| 558 const gfx::Rect invalid_rect_; | |
| 559 FakeContentLayerClient client_; | |
| 560 scoped_refptr<FakePictureLayer> root_layer_; | |
| 561 }; | |
| 562 | |
| 563 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F( | |
| 564 LayerTreeHostTestGpuRasterDeviceSizeChanged); | |
| 565 | |
| 566 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { | |
| 567 public: | |
| 568 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 569 settings->layer_transforms_should_scale_layer_contents = true; | |
| 570 } | |
| 571 | |
| 572 void SetupTree() override { | |
| 573 root_layer_ = Layer::Create(); | |
| 574 root_layer_->SetBounds(gfx::Size(10, 20)); | |
| 575 root_layer_->CreateRenderSurface(); | |
| 576 | |
| 577 if (layer_tree_host()->settings().impl_side_painting) | |
| 578 scaled_layer_ = FakePictureLayer::Create(&client_); | |
| 579 else | |
| 580 scaled_layer_ = FakeContentLayer::Create(&client_); | |
| 581 scaled_layer_->SetBounds(gfx::Size(1, 1)); | |
| 582 root_layer_->AddChild(scaled_layer_); | |
| 583 | |
| 584 layer_tree_host()->SetRootLayer(root_layer_); | |
| 585 LayerTreeHostTest::SetupTree(); | |
| 586 } | |
| 587 | |
| 588 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 589 | |
| 590 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 591 if (host_impl->active_tree()->source_frame_number() == 1) | |
| 592 EndTest(); | |
| 593 } | |
| 594 | |
| 595 void DidCommit() override { | |
| 596 switch (layer_tree_host()->source_frame_number()) { | |
| 597 case 1: | |
| 598 // SetBounds grows the layer and exposes new content. | |
| 599 if (layer_tree_host()->settings().impl_side_painting) { | |
| 600 scaled_layer_->SetBounds(gfx::Size(4, 4)); | |
| 601 } else { | |
| 602 // Changing the device scale factor causes a commit. It also changes | |
| 603 // the content bounds of |scaled_layer_|, which should not generate | |
| 604 // a second commit as a result. | |
| 605 layer_tree_host()->SetDeviceScaleFactor(4.f); | |
| 606 } | |
| 607 break; | |
| 608 default: | |
| 609 // No extra commits. | |
| 610 EXPECT_EQ(2, layer_tree_host()->source_frame_number()); | |
| 611 } | |
| 612 } | |
| 613 | |
| 614 void AfterTest() override { | |
| 615 EXPECT_EQ(gfx::Size(4, 4).ToString(), | |
| 616 scaled_layer_->content_bounds().ToString()); | |
| 617 } | |
| 618 | |
| 619 private: | |
| 620 FakeContentLayerClient client_; | |
| 621 scoped_refptr<Layer> root_layer_; | |
| 622 scoped_refptr<Layer> scaled_layer_; | |
| 623 }; | |
| 624 | |
| 625 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate); | |
| 626 | |
| 627 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate | |
| 628 : public LayerTreeHostTest { | |
| 629 public: | |
| 630 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 631 settings->layer_transforms_should_scale_layer_contents = true; | |
| 632 } | |
| 633 | |
| 634 void SetupTree() override { | |
| 635 root_layer_ = Layer::Create(); | |
| 636 root_layer_->SetBounds(gfx::Size(10, 20)); | |
| 637 root_layer_->CreateRenderSurface(); | |
| 638 | |
| 639 bool paint_scrollbar = true; | |
| 640 bool has_thumb = false; | |
| 641 scrollbar_ = FakePaintedScrollbarLayer::Create( | |
| 642 paint_scrollbar, has_thumb, root_layer_->id()); | |
| 643 scrollbar_->SetPosition(gfx::Point(0, 10)); | |
| 644 scrollbar_->SetBounds(gfx::Size(10, 10)); | |
| 645 | |
| 646 root_layer_->AddChild(scrollbar_); | |
| 647 | |
| 648 layer_tree_host()->SetRootLayer(root_layer_); | |
| 649 LayerTreeHostTest::SetupTree(); | |
| 650 } | |
| 651 | |
| 652 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 653 | |
| 654 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 655 if (host_impl->active_tree()->source_frame_number() == 1) | |
| 656 EndTest(); | |
| 657 } | |
| 658 | |
| 659 void DidCommit() override { | |
| 660 switch (layer_tree_host()->source_frame_number()) { | |
| 661 case 1: | |
| 662 // Changing the device scale factor causes a commit. It also changes | |
| 663 // the content bounds of |scrollbar_|, which should not generate | |
| 664 // a second commit as a result. | |
| 665 layer_tree_host()->SetDeviceScaleFactor(4.f); | |
| 666 break; | |
| 667 default: | |
| 668 // No extra commits. | |
| 669 EXPECT_EQ(2, layer_tree_host()->source_frame_number()); | |
| 670 } | |
| 671 } | |
| 672 | |
| 673 void AfterTest() override { | |
| 674 EXPECT_EQ(gfx::Size(40, 40).ToString(), | |
| 675 scrollbar_->internal_content_bounds().ToString()); | |
| 676 } | |
| 677 | |
| 678 private: | |
| 679 FakeContentLayerClient client_; | |
| 680 scoped_refptr<Layer> root_layer_; | |
| 681 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; | |
| 682 }; | |
| 683 | |
| 684 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 685 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate); | |
| 686 | |
| 687 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { | |
| 688 public: | |
| 689 LayerTreeHostTestSetNextCommitForcesRedraw() | |
| 690 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {} | |
| 691 | |
| 692 void BeginTest() override { | |
| 693 if (layer_tree_host()->settings().impl_side_painting) | |
| 694 root_layer_ = FakePictureLayer::Create(&client_); | |
| 695 else | |
| 696 root_layer_ = ContentLayer::Create(&client_); | |
| 697 root_layer_->SetIsDrawable(true); | |
| 698 root_layer_->SetBounds(bounds_); | |
| 699 layer_tree_host()->SetRootLayer(root_layer_); | |
| 700 layer_tree_host()->SetViewportSize(bounds_); | |
| 701 PostSetNeedsCommitToMainThread(); | |
| 702 } | |
| 703 | |
| 704 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 705 if (num_draws_ == 3 && host_impl->settings().impl_side_painting) | |
| 706 host_impl->SetNeedsRedrawRect(invalid_rect_); | |
| 707 } | |
| 708 | |
| 709 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 710 LayerTreeHostImpl::FrameData* frame_data, | |
| 711 DrawResult draw_result) override { | |
| 712 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
| 713 | |
| 714 gfx::RectF root_damage_rect; | |
| 715 if (!frame_data->render_passes.empty()) | |
| 716 root_damage_rect = frame_data->render_passes.back()->damage_rect; | |
| 717 | |
| 718 switch (num_draws_) { | |
| 719 case 0: | |
| 720 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect); | |
| 721 break; | |
| 722 case 1: | |
| 723 case 2: | |
| 724 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect); | |
| 725 break; | |
| 726 case 3: | |
| 727 EXPECT_EQ(invalid_rect_, root_damage_rect); | |
| 728 break; | |
| 729 case 4: | |
| 730 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect); | |
| 731 break; | |
| 732 default: | |
| 733 NOTREACHED(); | |
| 734 } | |
| 735 | |
| 736 return draw_result; | |
| 737 } | |
| 738 | |
| 739 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 740 switch (num_draws_) { | |
| 741 case 0: | |
| 742 case 1: | |
| 743 // Cycle through a couple of empty commits to ensure we're observing the | |
| 744 // right behavior | |
| 745 PostSetNeedsCommitToMainThread(); | |
| 746 break; | |
| 747 case 2: | |
| 748 // Should force full frame damage on the next commit | |
| 749 PostSetNextCommitForcesRedrawToMainThread(); | |
| 750 PostSetNeedsCommitToMainThread(); | |
| 751 if (host_impl->settings().impl_side_painting) | |
| 752 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
| 753 else | |
| 754 num_draws_++; | |
| 755 break; | |
| 756 case 3: | |
| 757 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
| 758 break; | |
| 759 default: | |
| 760 EndTest(); | |
| 761 break; | |
| 762 } | |
| 763 num_draws_++; | |
| 764 } | |
| 765 | |
| 766 void AfterTest() override { EXPECT_EQ(5, num_draws_); } | |
| 767 | |
| 768 private: | |
| 769 int num_draws_; | |
| 770 const gfx::Size bounds_; | |
| 771 const gfx::Rect invalid_rect_; | |
| 772 FakeContentLayerClient client_; | |
| 773 scoped_refptr<Layer> root_layer_; | |
| 774 }; | |
| 775 | |
| 776 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( | |
| 777 LayerTreeHostTestSetNextCommitForcesRedraw); | |
| 778 | |
| 779 // Tests that if a layer is not drawn because of some reason in the parent then | |
| 780 // its damage is preserved until the next time it is drawn. | |
| 781 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { | |
| 782 public: | |
| 783 LayerTreeHostTestUndrawnLayersDamageLater() {} | |
| 784 | |
| 785 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 786 // If we don't set the minimum contents scale, it's harder to verify whether | |
| 787 // the damage we get is correct. For other scale amounts, please see | |
| 788 // LayerTreeHostTestDamageWithScale. | |
| 789 settings->minimum_contents_scale = 1.f; | |
| 790 } | |
| 791 | |
| 792 void SetupTree() override { | |
| 793 if (layer_tree_host()->settings().impl_side_painting) | |
| 794 root_layer_ = FakePictureLayer::Create(&client_); | |
| 795 else | |
| 796 root_layer_ = ContentLayer::Create(&client_); | |
| 797 root_layer_->SetIsDrawable(true); | |
| 798 root_layer_->SetBounds(gfx::Size(50, 50)); | |
| 799 layer_tree_host()->SetRootLayer(root_layer_); | |
| 800 | |
| 801 // The initially transparent layer has a larger child layer, which is | |
| 802 // not initially drawn because of the this (parent) layer. | |
| 803 if (layer_tree_host()->settings().impl_side_painting) | |
| 804 parent_layer_ = FakePictureLayer::Create(&client_); | |
| 805 else | |
| 806 parent_layer_ = FakeContentLayer::Create(&client_); | |
| 807 parent_layer_->SetBounds(gfx::Size(15, 15)); | |
| 808 parent_layer_->SetOpacity(0.0f); | |
| 809 root_layer_->AddChild(parent_layer_); | |
| 810 | |
| 811 if (layer_tree_host()->settings().impl_side_painting) | |
| 812 child_layer_ = FakePictureLayer::Create(&client_); | |
| 813 else | |
| 814 child_layer_ = FakeContentLayer::Create(&client_); | |
| 815 child_layer_->SetBounds(gfx::Size(25, 25)); | |
| 816 parent_layer_->AddChild(child_layer_); | |
| 817 | |
| 818 LayerTreeHostTest::SetupTree(); | |
| 819 } | |
| 820 | |
| 821 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 822 | |
| 823 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 824 LayerTreeHostImpl::FrameData* frame_data, | |
| 825 DrawResult draw_result) override { | |
| 826 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
| 827 | |
| 828 gfx::RectF root_damage_rect; | |
| 829 if (!frame_data->render_passes.empty()) | |
| 830 root_damage_rect = frame_data->render_passes.back()->damage_rect; | |
| 831 | |
| 832 // The first time, the whole view needs be drawn. | |
| 833 // Afterwards, just the opacity of surface_layer1 is changed a few times, | |
| 834 // and each damage should be the bounding box of it and its child. If this | |
| 835 // was working improperly, the damage might not include its childs bounding | |
| 836 // box. | |
| 837 switch (host_impl->active_tree()->source_frame_number()) { | |
| 838 case 0: | |
| 839 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect); | |
| 840 break; | |
| 841 case 1: | |
| 842 case 2: | |
| 843 case 3: | |
| 844 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect); | |
| 845 break; | |
| 846 default: | |
| 847 NOTREACHED(); | |
| 848 } | |
| 849 | |
| 850 return draw_result; | |
| 851 } | |
| 852 | |
| 853 void DidCommitAndDrawFrame() override { | |
| 854 switch (layer_tree_host()->source_frame_number()) { | |
| 855 case 1: | |
| 856 // Test not owning the surface. | |
| 857 parent_layer_->SetOpacity(1.0f); | |
| 858 break; | |
| 859 case 2: | |
| 860 parent_layer_->SetOpacity(0.0f); | |
| 861 break; | |
| 862 case 3: | |
| 863 // Test owning the surface. | |
| 864 parent_layer_->SetOpacity(0.5f); | |
| 865 parent_layer_->SetForceRenderSurface(true); | |
| 866 break; | |
| 867 case 4: | |
| 868 EndTest(); | |
| 869 break; | |
| 870 default: | |
| 871 NOTREACHED(); | |
| 872 } | |
| 873 } | |
| 874 | |
| 875 void AfterTest() override {} | |
| 876 | |
| 877 private: | |
| 878 FakeContentLayerClient client_; | |
| 879 scoped_refptr<Layer> root_layer_; | |
| 880 scoped_refptr<Layer> parent_layer_; | |
| 881 scoped_refptr<Layer> child_layer_; | |
| 882 }; | |
| 883 | |
| 884 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater); | |
| 885 | |
| 886 // Tests that if a layer is not drawn because of some reason in the parent then | |
| 887 // its damage is preserved until the next time it is drawn. | |
| 888 class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest { | |
| 889 public: | |
| 890 LayerTreeHostTestDamageWithScale() {} | |
| 891 | |
| 892 void SetupTree() override { | |
| 893 client_.set_fill_with_nonsolid_color(true); | |
| 894 | |
| 895 scoped_ptr<FakePicturePile> pile( | |
| 896 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
| 897 ImplSidePaintingSettings().default_tile_grid_size)); | |
| 898 root_layer_ = | |
| 899 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
| 900 root_layer_->SetBounds(gfx::Size(50, 50)); | |
| 901 | |
| 902 pile.reset( | |
| 903 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
| 904 ImplSidePaintingSettings().default_tile_grid_size)); | |
| 905 child_layer_ = | |
| 906 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
| 907 child_layer_->SetBounds(gfx::Size(25, 25)); | |
| 908 child_layer_->SetIsDrawable(true); | |
| 909 child_layer_->SetContentsOpaque(true); | |
| 910 root_layer_->AddChild(child_layer_); | |
| 911 | |
| 912 layer_tree_host()->SetRootLayer(root_layer_); | |
| 913 LayerTreeHostTest::SetupTree(); | |
| 914 } | |
| 915 | |
| 916 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 917 // Force the layer to have a tiling at 1.3f scale. Note that if we simply | |
| 918 // add tiling, it will be gone by the time we draw because of aggressive | |
| 919 // cleanup. AddTilingUntilNextDraw ensures that it remains there during | |
| 920 // damage calculation. | |
| 921 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>( | |
| 922 host_impl->active_tree()->LayerById(child_layer_->id())); | |
| 923 child_layer_impl->AddTilingUntilNextDraw(1.3f); | |
| 924 } | |
| 925 | |
| 926 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 927 | |
| 928 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 929 LayerTreeHostImpl::FrameData* frame_data, | |
| 930 DrawResult draw_result) override { | |
| 931 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
| 932 | |
| 933 gfx::RectF root_damage_rect; | |
| 934 if (!frame_data->render_passes.empty()) | |
| 935 root_damage_rect = frame_data->render_passes.back()->damage_rect; | |
| 936 | |
| 937 // The first time, the whole view needs be drawn. | |
| 938 // Afterwards, just the opacity of surface_layer1 is changed a few times, | |
| 939 // and each damage should be the bounding box of it and its child. If this | |
| 940 // was working improperly, the damage might not include its childs bounding | |
| 941 // box. | |
| 942 switch (host_impl->active_tree()->source_frame_number()) { | |
| 943 case 0: | |
| 944 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect); | |
| 945 break; | |
| 946 case 1: { | |
| 947 FakePictureLayerImpl* child_layer_impl = | |
| 948 static_cast<FakePictureLayerImpl*>( | |
| 949 host_impl->active_tree()->LayerById(child_layer_->id())); | |
| 950 // We remove tilings pretty aggressively if they are not ideal. Add this | |
| 951 // back in so that we can compare | |
| 952 // child_layer_impl->GetEnclosingRectInTargetSpace to the damage. | |
| 953 child_layer_impl->AddTilingUntilNextDraw(1.3f); | |
| 954 | |
| 955 EXPECT_EQ(gfx::Rect(26, 26), root_damage_rect); | |
| 956 EXPECT_EQ(child_layer_impl->GetEnclosingRectInTargetSpace(), | |
| 957 root_damage_rect); | |
| 958 EXPECT_TRUE(child_layer_impl->GetEnclosingRectInTargetSpace().Contains( | |
| 959 gfx::Rect(child_layer_->bounds()))); | |
| 960 break; | |
| 961 } | |
| 962 default: | |
| 963 NOTREACHED(); | |
| 964 } | |
| 965 | |
| 966 return draw_result; | |
| 967 } | |
| 968 | |
| 969 void DidCommitAndDrawFrame() override { | |
| 970 switch (layer_tree_host()->source_frame_number()) { | |
| 971 case 1: { | |
| 972 // Test not owning the surface. | |
| 973 child_layer_->SetOpacity(0.5f); | |
| 974 break; | |
| 975 } | |
| 976 case 2: | |
| 977 EndTest(); | |
| 978 break; | |
| 979 default: | |
| 980 NOTREACHED(); | |
| 981 } | |
| 982 } | |
| 983 | |
| 984 void AfterTest() override {} | |
| 985 | |
| 986 private: | |
| 987 FakeContentLayerClient client_; | |
| 988 scoped_refptr<Layer> root_layer_; | |
| 989 scoped_refptr<Layer> child_layer_; | |
| 990 }; | |
| 991 | |
| 992 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestDamageWithScale); | |
| 993 | |
| 994 // Tests that if a layer is not drawn because of some reason in the parent, | |
| 995 // causing its content bounds to not be computed, then when it is later drawn, | |
| 996 // its content bounds get pushed. | |
| 997 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater | |
| 998 : public LayerTreeHostTest { | |
| 999 public: | |
| 1000 LayerTreeHostTestUndrawnLayersPushContentBoundsLater() | |
| 1001 : root_layer_(Layer::Create()) {} | |
| 1002 | |
| 1003 void SetupTree() override { | |
| 1004 root_layer_->CreateRenderSurface(); | |
| 1005 root_layer_->SetIsDrawable(true); | |
| 1006 root_layer_->SetBounds(gfx::Size(20, 20)); | |
| 1007 layer_tree_host()->SetRootLayer(root_layer_); | |
| 1008 | |
| 1009 parent_layer_ = Layer::Create(); | |
| 1010 parent_layer_->SetBounds(gfx::Size(20, 20)); | |
| 1011 parent_layer_->SetOpacity(0.0f); | |
| 1012 root_layer_->AddChild(parent_layer_); | |
| 1013 | |
| 1014 child_layer_ = Layer::Create(); | |
| 1015 child_layer_->SetBounds(gfx::Size(15, 15)); | |
| 1016 parent_layer_->AddChild(child_layer_); | |
| 1017 | |
| 1018 LayerTreeHostTest::SetupTree(); | |
| 1019 } | |
| 1020 | |
| 1021 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1022 | |
| 1023 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1024 LayerImpl* root = host_impl->active_tree()->root_layer(); | |
| 1025 LayerImpl* parent = root->children()[0]; | |
| 1026 LayerImpl* child = parent->children()[0]; | |
| 1027 | |
| 1028 switch (host_impl->active_tree()->source_frame_number()) { | |
| 1029 case 0: | |
| 1030 EXPECT_EQ(0.f, parent->opacity()); | |
| 1031 EXPECT_EQ(gfx::SizeF(), child->content_bounds()); | |
| 1032 break; | |
| 1033 case 1: | |
| 1034 EXPECT_EQ(1.f, parent->opacity()); | |
| 1035 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds()); | |
| 1036 EndTest(); | |
| 1037 break; | |
| 1038 default: | |
| 1039 NOTREACHED(); | |
| 1040 } | |
| 1041 } | |
| 1042 | |
| 1043 void DidCommit() override { | |
| 1044 switch (layer_tree_host()->source_frame_number()) { | |
| 1045 case 1: | |
| 1046 parent_layer_->SetOpacity(1.0f); | |
| 1047 break; | |
| 1048 case 2: | |
| 1049 break; | |
| 1050 default: | |
| 1051 NOTREACHED(); | |
| 1052 } | |
| 1053 } | |
| 1054 | |
| 1055 void AfterTest() override {} | |
| 1056 | |
| 1057 private: | |
| 1058 scoped_refptr<Layer> root_layer_; | |
| 1059 scoped_refptr<Layer> parent_layer_; | |
| 1060 scoped_refptr<Layer> child_layer_; | |
| 1061 }; | |
| 1062 | |
| 1063 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 1064 LayerTreeHostTestUndrawnLayersPushContentBoundsLater); | |
| 1065 | |
| 1066 // This test verifies that properties on the layer tree host are commited | |
| 1067 // to the impl side. | |
| 1068 class LayerTreeHostTestCommit : public LayerTreeHostTest { | |
| 1069 public: | |
| 1070 LayerTreeHostTestCommit() {} | |
| 1071 | |
| 1072 void BeginTest() override { | |
| 1073 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); | |
| 1074 layer_tree_host()->set_background_color(SK_ColorGRAY); | |
| 1075 | |
| 1076 PostSetNeedsCommitToMainThread(); | |
| 1077 } | |
| 1078 | |
| 1079 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 1080 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize()); | |
| 1081 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color()); | |
| 1082 | |
| 1083 EndTest(); | |
| 1084 } | |
| 1085 | |
| 1086 void AfterTest() override {} | |
| 1087 }; | |
| 1088 | |
| 1089 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit); | |
| 1090 | |
| 1091 // This test verifies that LayerTreeHostImpl's current frame time gets | |
| 1092 // updated in consecutive frames when it doesn't draw due to tree | |
| 1093 // activation failure. | |
| 1094 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails | |
| 1095 : public LayerTreeHostTest { | |
| 1096 public: | |
| 1097 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails() | |
| 1098 : frame_count_with_pending_tree_(0) {} | |
| 1099 | |
| 1100 void BeginTest() override { | |
| 1101 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); | |
| 1102 layer_tree_host()->set_background_color(SK_ColorGRAY); | |
| 1103 | |
| 1104 PostSetNeedsCommitToMainThread(); | |
| 1105 } | |
| 1106 | |
| 1107 void BeginCommitOnThread(LayerTreeHostImpl* impl) override { | |
| 1108 EXPECT_EQ(frame_count_with_pending_tree_, 0); | |
| 1109 if (impl->settings().impl_side_painting) | |
| 1110 impl->BlockNotifyReadyToActivateForTesting(true); | |
| 1111 } | |
| 1112 | |
| 1113 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl, | |
| 1114 const BeginFrameArgs& args) override { | |
| 1115 if (impl->pending_tree()) | |
| 1116 frame_count_with_pending_tree_++; | |
| 1117 | |
| 1118 if (frame_count_with_pending_tree_ == 1) { | |
| 1119 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0); | |
| 1120 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time; | |
| 1121 } else if (frame_count_with_pending_tree_ == 2 && | |
| 1122 impl->settings().impl_side_painting) { | |
| 1123 impl->BlockNotifyReadyToActivateForTesting(false); | |
| 1124 } | |
| 1125 } | |
| 1126 | |
| 1127 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 1128 if (frame_count_with_pending_tree_ > 1) { | |
| 1129 EXPECT_NE(first_frame_time_.ToInternalValue(), 0); | |
| 1130 EXPECT_NE(first_frame_time_.ToInternalValue(), | |
| 1131 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue()); | |
| 1132 EndTest(); | |
| 1133 return; | |
| 1134 } | |
| 1135 | |
| 1136 EXPECT_FALSE(impl->settings().impl_side_painting); | |
| 1137 EndTest(); | |
| 1138 } | |
| 1139 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 1140 if (impl->settings().impl_side_painting) | |
| 1141 EXPECT_NE(frame_count_with_pending_tree_, 1); | |
| 1142 } | |
| 1143 | |
| 1144 void AfterTest() override {} | |
| 1145 | |
| 1146 private: | |
| 1147 int frame_count_with_pending_tree_; | |
| 1148 base::TimeTicks first_frame_time_; | |
| 1149 }; | |
| 1150 | |
| 1151 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( | |
| 1152 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails); | |
| 1153 | |
| 1154 // This test verifies that LayerTreeHostImpl's current frame time gets | |
| 1155 // updated in consecutive frames when it draws in each frame. | |
| 1156 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { | |
| 1157 public: | |
| 1158 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {} | |
| 1159 | |
| 1160 void BeginTest() override { | |
| 1161 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); | |
| 1162 layer_tree_host()->set_background_color(SK_ColorGRAY); | |
| 1163 | |
| 1164 PostSetNeedsCommitToMainThread(); | |
| 1165 } | |
| 1166 | |
| 1167 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 1168 frame_++; | |
| 1169 if (frame_ == 1) { | |
| 1170 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time; | |
| 1171 impl->SetNeedsRedraw(); | |
| 1172 | |
| 1173 // Since we might use a low-resolution clock on Windows, we need to | |
| 1174 // make sure that the clock has incremented past first_frame_time_. | |
| 1175 while (first_frame_time_ == gfx::FrameTime::Now()) { | |
| 1176 } | |
| 1177 | |
| 1178 return; | |
| 1179 } | |
| 1180 | |
| 1181 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time); | |
| 1182 EndTest(); | |
| 1183 } | |
| 1184 | |
| 1185 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1186 // Ensure there isn't a commit between the two draws, to ensure that a | |
| 1187 // commit isn't required for updating the current frame time. We can | |
| 1188 // only check for this in the multi-threaded case, since in the single- | |
| 1189 // threaded case there will always be a commit between consecutive draws. | |
| 1190 if (HasImplThread()) | |
| 1191 EXPECT_EQ(0, frame_); | |
| 1192 } | |
| 1193 | |
| 1194 void AfterTest() override {} | |
| 1195 | |
| 1196 private: | |
| 1197 int frame_; | |
| 1198 base::TimeTicks first_frame_time_; | |
| 1199 }; | |
| 1200 | |
| 1201 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw); | |
| 1202 | |
| 1203 // Verifies that StartPageScaleAnimation events propagate correctly | |
| 1204 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor. | |
| 1205 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { | |
| 1206 public: | |
| 1207 LayerTreeHostTestStartPageScaleAnimation() {} | |
| 1208 | |
| 1209 void SetupTree() override { | |
| 1210 LayerTreeHostTest::SetupTree(); | |
| 1211 | |
| 1212 if (layer_tree_host()->settings().impl_side_painting) { | |
| 1213 scoped_refptr<FakePictureLayer> layer = | |
| 1214 FakePictureLayer::Create(&client_); | |
| 1215 layer->set_always_update_resources(true); | |
| 1216 scroll_layer_ = layer; | |
| 1217 } else { | |
| 1218 scroll_layer_ = FakeContentLayer::Create(&client_); | |
| 1219 } | |
| 1220 | |
| 1221 Layer* root_layer = layer_tree_host()->root_layer(); | |
| 1222 scroll_layer_->SetScrollClipLayerId(root_layer->id()); | |
| 1223 scroll_layer_->SetIsContainerForFixedPositionLayers(true); | |
| 1224 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(), | |
| 1225 2 * root_layer->bounds().height())); | |
| 1226 scroll_layer_->SetScrollOffset(gfx::ScrollOffset()); | |
| 1227 layer_tree_host()->root_layer()->AddChild(scroll_layer_); | |
| 1228 // This test requires the page_scale and inner viewport layers to be | |
| 1229 // identified. | |
| 1230 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, | |
| 1231 scroll_layer_.get(), NULL); | |
| 1232 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f); | |
| 1233 } | |
| 1234 | |
| 1235 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1236 | |
| 1237 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, | |
| 1238 float scale, | |
| 1239 float) override { | |
| 1240 gfx::ScrollOffset offset = scroll_layer_->scroll_offset(); | |
| 1241 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset, | |
| 1242 scroll_delta)); | |
| 1243 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f); | |
| 1244 } | |
| 1245 | |
| 1246 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 1247 // We get one commit before the first draw, and the animation doesn't happen | |
| 1248 // until the second draw. | |
| 1249 switch (impl->active_tree()->source_frame_number()) { | |
| 1250 case 0: | |
| 1251 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); | |
| 1252 // We'll start an animation when we get back to the main thread. | |
| 1253 break; | |
| 1254 case 1: | |
| 1255 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); | |
| 1256 break; | |
| 1257 case 2: | |
| 1258 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor()); | |
| 1259 EndTest(); | |
| 1260 break; | |
| 1261 default: | |
| 1262 NOTREACHED(); | |
| 1263 } | |
| 1264 } | |
| 1265 | |
| 1266 void DidCommitAndDrawFrame() override { | |
| 1267 switch (layer_tree_host()->source_frame_number()) { | |
| 1268 case 1: | |
| 1269 layer_tree_host()->StartPageScaleAnimation( | |
| 1270 gfx::Vector2d(), false, 1.25f, base::TimeDelta()); | |
| 1271 break; | |
| 1272 } | |
| 1273 } | |
| 1274 | |
| 1275 void AfterTest() override {} | |
| 1276 | |
| 1277 FakeContentLayerClient client_; | |
| 1278 scoped_refptr<Layer> scroll_layer_; | |
| 1279 }; | |
| 1280 | |
| 1281 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation); | |
| 1282 | |
| 1283 class LayerTreeHostTestSetVisible : public LayerTreeHostTest { | |
| 1284 public: | |
| 1285 LayerTreeHostTestSetVisible() : num_draws_(0) {} | |
| 1286 | |
| 1287 void BeginTest() override { | |
| 1288 PostSetNeedsCommitToMainThread(); | |
| 1289 PostSetVisibleToMainThread(false); | |
| 1290 // This is suppressed while we're invisible. | |
| 1291 PostSetNeedsRedrawToMainThread(); | |
| 1292 // Triggers the redraw. | |
| 1293 PostSetVisibleToMainThread(true); | |
| 1294 } | |
| 1295 | |
| 1296 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 1297 EXPECT_TRUE(impl->visible()); | |
| 1298 ++num_draws_; | |
| 1299 EndTest(); | |
| 1300 } | |
| 1301 | |
| 1302 void AfterTest() override { EXPECT_EQ(1, num_draws_); } | |
| 1303 | |
| 1304 private: | |
| 1305 int num_draws_; | |
| 1306 }; | |
| 1307 | |
| 1308 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible); | |
| 1309 | |
| 1310 class TestOpacityChangeLayerDelegate : public ContentLayerClient { | |
| 1311 public: | |
| 1312 TestOpacityChangeLayerDelegate() : test_layer_(0) {} | |
| 1313 | |
| 1314 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; } | |
| 1315 | |
| 1316 void PaintContents(SkCanvas* canvas, | |
| 1317 const gfx::Rect& clip, | |
| 1318 PaintingControlSetting picture_control) override { | |
| 1319 // Set layer opacity to 0. | |
| 1320 if (test_layer_) | |
| 1321 test_layer_->SetOpacity(0.f); | |
| 1322 } | |
| 1323 scoped_refptr<DisplayItemList> PaintContentsToDisplayList( | |
| 1324 const gfx::Rect& clip, | |
| 1325 PaintingControlSetting picture_control) override { | |
| 1326 NOTIMPLEMENTED(); | |
| 1327 return DisplayItemList::Create(); | |
| 1328 } | |
| 1329 bool FillsBoundsCompletely() const override { return false; } | |
| 1330 | |
| 1331 private: | |
| 1332 Layer* test_layer_; | |
| 1333 }; | |
| 1334 | |
| 1335 class ContentLayerWithUpdateTracking : public ContentLayer { | |
| 1336 public: | |
| 1337 static scoped_refptr<ContentLayerWithUpdateTracking> Create( | |
| 1338 ContentLayerClient* client) { | |
| 1339 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client)); | |
| 1340 } | |
| 1341 | |
| 1342 int PaintContentsCount() { return paint_contents_count_; } | |
| 1343 void ResetPaintContentsCount() { paint_contents_count_ = 0; } | |
| 1344 | |
| 1345 bool Update(ResourceUpdateQueue* queue, | |
| 1346 const OcclusionTracker<Layer>* occlusion) override { | |
| 1347 bool updated = ContentLayer::Update(queue, occlusion); | |
| 1348 paint_contents_count_++; | |
| 1349 return updated; | |
| 1350 } | |
| 1351 | |
| 1352 private: | |
| 1353 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client) | |
| 1354 : ContentLayer(client), paint_contents_count_(0) { | |
| 1355 SetBounds(gfx::Size(10, 10)); | |
| 1356 SetIsDrawable(true); | |
| 1357 } | |
| 1358 ~ContentLayerWithUpdateTracking() override {} | |
| 1359 | |
| 1360 int paint_contents_count_; | |
| 1361 }; | |
| 1362 | |
| 1363 // Layer opacity change during paint should not prevent compositor resources | |
| 1364 // from being updated during commit. | |
| 1365 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest { | |
| 1366 public: | |
| 1367 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {} | |
| 1368 | |
| 1369 void BeginTest() override { | |
| 1370 if (layer_tree_host()->settings().impl_side_painting) { | |
| 1371 update_check_picture_layer_ = | |
| 1372 FakePictureLayer::Create(&test_opacity_change_delegate_); | |
| 1373 test_opacity_change_delegate_.SetTestLayer( | |
| 1374 update_check_picture_layer_.get()); | |
| 1375 is_impl_paint_ = true; | |
| 1376 } else { | |
| 1377 update_check_content_layer_ = ContentLayerWithUpdateTracking::Create( | |
| 1378 &test_opacity_change_delegate_); | |
| 1379 test_opacity_change_delegate_.SetTestLayer( | |
| 1380 update_check_content_layer_.get()); | |
| 1381 is_impl_paint_ = false; | |
| 1382 } | |
| 1383 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); | |
| 1384 if (layer_tree_host()->settings().impl_side_painting) | |
| 1385 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_); | |
| 1386 else | |
| 1387 layer_tree_host()->root_layer()->AddChild(update_check_content_layer_); | |
| 1388 | |
| 1389 PostSetNeedsCommitToMainThread(); | |
| 1390 } | |
| 1391 | |
| 1392 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); } | |
| 1393 | |
| 1394 void AfterTest() override { | |
| 1395 // Update() should have been called once. | |
| 1396 if (is_impl_paint_) | |
| 1397 EXPECT_EQ(1u, update_check_picture_layer_->update_count()); | |
| 1398 else | |
| 1399 EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount()); | |
| 1400 } | |
| 1401 | |
| 1402 private: | |
| 1403 TestOpacityChangeLayerDelegate test_opacity_change_delegate_; | |
| 1404 scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_; | |
| 1405 scoped_refptr<FakePictureLayer> update_check_picture_layer_; | |
| 1406 bool is_impl_paint_; | |
| 1407 }; | |
| 1408 | |
| 1409 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange); | |
| 1410 | |
| 1411 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers | |
| 1412 : public LayerTreeHostTest { | |
| 1413 public: | |
| 1414 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {} | |
| 1415 | |
| 1416 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 1417 // PictureLayer can only be used with impl side painting enabled. | |
| 1418 settings->impl_side_painting = true; | |
| 1419 } | |
| 1420 | |
| 1421 void BeginTest() override { | |
| 1422 client_.set_fill_with_nonsolid_color(true); | |
| 1423 root_layer_ = FakePictureLayer::Create(&client_); | |
| 1424 child_layer_ = FakePictureLayer::Create(&client_); | |
| 1425 | |
| 1426 layer_tree_host()->SetViewportSize(gfx::Size(60, 60)); | |
| 1427 layer_tree_host()->SetDeviceScaleFactor(1.5); | |
| 1428 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size()); | |
| 1429 | |
| 1430 root_layer_->AddChild(child_layer_); | |
| 1431 | |
| 1432 root_layer_->SetIsDrawable(true); | |
| 1433 root_layer_->SetBounds(gfx::Size(30, 30)); | |
| 1434 | |
| 1435 child_layer_->SetIsDrawable(true); | |
| 1436 child_layer_->SetPosition(gfx::Point(2, 2)); | |
| 1437 child_layer_->SetBounds(gfx::Size(10, 10)); | |
| 1438 | |
| 1439 layer_tree_host()->SetRootLayer(root_layer_); | |
| 1440 | |
| 1441 PostSetNeedsCommitToMainThread(); | |
| 1442 } | |
| 1443 | |
| 1444 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 1445 // Should only do one commit. | |
| 1446 EXPECT_EQ(0, impl->active_tree()->source_frame_number()); | |
| 1447 // Device scale factor should come over to impl. | |
| 1448 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f); | |
| 1449 | |
| 1450 // Both layers are on impl. | |
| 1451 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size()); | |
| 1452 | |
| 1453 // Device viewport is scaled. | |
| 1454 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize()); | |
| 1455 | |
| 1456 FakePictureLayerImpl* root = | |
| 1457 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); | |
| 1458 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>( | |
| 1459 impl->active_tree()->root_layer()->children()[0]); | |
| 1460 | |
| 1461 // Positions remain in layout pixels. | |
| 1462 EXPECT_EQ(gfx::Point(0, 0), root->position()); | |
| 1463 EXPECT_EQ(gfx::Point(2, 2), child->position()); | |
| 1464 | |
| 1465 // Compute all the layer transforms for the frame. | |
| 1466 LayerTreeHostImpl::FrameData frame_data; | |
| 1467 impl->PrepareToDraw(&frame_data); | |
| 1468 impl->DidDrawAllLayers(frame_data); | |
| 1469 | |
| 1470 const LayerImplList& render_surface_layer_list = | |
| 1471 *frame_data.render_surface_layer_list; | |
| 1472 | |
| 1473 // Both layers should be drawing into the root render surface. | |
| 1474 ASSERT_EQ(1u, render_surface_layer_list.size()); | |
| 1475 ASSERT_EQ(root->render_surface(), | |
| 1476 render_surface_layer_list[0]->render_surface()); | |
| 1477 ASSERT_EQ(2u, root->render_surface()->layer_list().size()); | |
| 1478 | |
| 1479 // The root render surface is the size of the viewport. | |
| 1480 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect()); | |
| 1481 | |
| 1482 // The max tiling scale of the child should be scaled. | |
| 1483 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale()); | |
| 1484 | |
| 1485 gfx::Transform scale_transform; | |
| 1486 scale_transform.Scale(impl->device_scale_factor(), | |
| 1487 impl->device_scale_factor()); | |
| 1488 | |
| 1489 // The root layer is scaled by 2x. | |
| 1490 gfx::Transform root_screen_space_transform = scale_transform; | |
| 1491 gfx::Transform root_draw_transform = scale_transform; | |
| 1492 | |
| 1493 EXPECT_EQ(root_draw_transform, root->draw_transform()); | |
| 1494 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform()); | |
| 1495 | |
| 1496 // The child is at position 2,2, which is transformed to 3,3 after the scale | |
| 1497 gfx::Transform child_transform; | |
| 1498 child_transform.Translate(3.f, 3.f); | |
| 1499 child_transform.Scale(child->MaximumTilingContentsScale(), | |
| 1500 child->MaximumTilingContentsScale()); | |
| 1501 | |
| 1502 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform()); | |
| 1503 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, | |
| 1504 child->screen_space_transform()); | |
| 1505 | |
| 1506 EndTest(); | |
| 1507 } | |
| 1508 | |
| 1509 void AfterTest() override {} | |
| 1510 | |
| 1511 private: | |
| 1512 FakeContentLayerClient client_; | |
| 1513 scoped_refptr<FakePictureLayer> root_layer_; | |
| 1514 scoped_refptr<FakePictureLayer> child_layer_; | |
| 1515 }; | |
| 1516 | |
| 1517 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); | |
| 1518 | |
| 1519 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere. | |
| 1520 // Verify atomicity of commits and reuse of textures. | |
| 1521 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { | |
| 1522 public: | |
| 1523 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 1524 settings->renderer_settings.texture_id_allocation_chunk_size = 1; | |
| 1525 // Make sure partial texture updates are turned off. | |
| 1526 settings->max_partial_texture_updates = 0; | |
| 1527 // Linear fade animator prevents scrollbars from drawing immediately. | |
| 1528 settings->scrollbar_animator = LayerTreeSettings::NO_ANIMATOR; | |
| 1529 } | |
| 1530 | |
| 1531 void SetupTree() override { | |
| 1532 layer_ = FakeContentLayer::Create(&client_); | |
| 1533 layer_->SetBounds(gfx::Size(10, 20)); | |
| 1534 | |
| 1535 bool paint_scrollbar = true; | |
| 1536 bool has_thumb = false; | |
| 1537 scrollbar_ = FakePaintedScrollbarLayer::Create( | |
| 1538 paint_scrollbar, has_thumb, layer_->id()); | |
| 1539 scrollbar_->SetPosition(gfx::Point(0, 10)); | |
| 1540 scrollbar_->SetBounds(gfx::Size(10, 10)); | |
| 1541 | |
| 1542 layer_->AddChild(scrollbar_); | |
| 1543 | |
| 1544 layer_tree_host()->SetRootLayer(layer_); | |
| 1545 LayerTreeHostTest::SetupTree(); | |
| 1546 } | |
| 1547 | |
| 1548 void BeginTest() override { | |
| 1549 drew_frame_ = -1; | |
| 1550 PostSetNeedsCommitToMainThread(); | |
| 1551 } | |
| 1552 | |
| 1553 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 1554 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates); | |
| 1555 | |
| 1556 TestWebGraphicsContext3D* context = TestContext(); | |
| 1557 | |
| 1558 switch (impl->active_tree()->source_frame_number()) { | |
| 1559 case 0: | |
| 1560 // Number of textures should be one for each layer | |
| 1561 ASSERT_EQ(2u, context->NumTextures()); | |
| 1562 // Number of textures used for commit should be one for each layer. | |
| 1563 EXPECT_EQ(2u, context->NumUsedTextures()); | |
| 1564 // Verify that used texture is correct. | |
| 1565 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
| 1566 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
| 1567 | |
| 1568 context->ResetUsedTextures(); | |
| 1569 break; | |
| 1570 case 1: | |
| 1571 // Number of textures should be one for scrollbar layer since it was | |
| 1572 // requested and deleted on the impl-thread, and double for the content | |
| 1573 // layer since its first texture is used by impl thread and cannot by | |
| 1574 // used for update. | |
| 1575 ASSERT_EQ(3u, context->NumTextures()); | |
| 1576 // Number of textures used for commit should be one for each layer. | |
| 1577 EXPECT_EQ(2u, context->NumUsedTextures()); | |
| 1578 // First textures should not have been used. | |
| 1579 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); | |
| 1580 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
| 1581 // New textures should have been used. | |
| 1582 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); | |
| 1583 context->ResetUsedTextures(); | |
| 1584 break; | |
| 1585 case 2: | |
| 1586 EndTest(); | |
| 1587 break; | |
| 1588 default: | |
| 1589 NOTREACHED(); | |
| 1590 break; | |
| 1591 } | |
| 1592 } | |
| 1593 | |
| 1594 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 1595 TestWebGraphicsContext3D* context = TestContext(); | |
| 1596 | |
| 1597 if (drew_frame_ == impl->active_tree()->source_frame_number()) { | |
| 1598 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_; | |
| 1599 return; | |
| 1600 } | |
| 1601 drew_frame_ = impl->active_tree()->source_frame_number(); | |
| 1602 | |
| 1603 // We draw/ship one texture each frame for each layer. | |
| 1604 EXPECT_EQ(2u, context->NumUsedTextures()); | |
| 1605 context->ResetUsedTextures(); | |
| 1606 | |
| 1607 if (!TestEnded()) | |
| 1608 PostSetNeedsCommitToMainThread(); | |
| 1609 } | |
| 1610 | |
| 1611 void Layout() override { | |
| 1612 layer_->SetNeedsDisplay(); | |
| 1613 scrollbar_->SetNeedsDisplay(); | |
| 1614 } | |
| 1615 | |
| 1616 void AfterTest() override {} | |
| 1617 | |
| 1618 protected: | |
| 1619 FakeContentLayerClient client_; | |
| 1620 scoped_refptr<FakeContentLayer> layer_; | |
| 1621 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; | |
| 1622 int drew_frame_; | |
| 1623 }; | |
| 1624 | |
| 1625 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( | |
| 1626 LayerTreeHostTestDirectRendererAtomicCommit); | |
| 1627 | |
| 1628 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere. | |
| 1629 class LayerTreeHostTestDelegatingRendererAtomicCommit | |
| 1630 : public LayerTreeHostTestDirectRendererAtomicCommit { | |
| 1631 public: | |
| 1632 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 1633 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates); | |
| 1634 | |
| 1635 TestWebGraphicsContext3D* context = TestContext(); | |
| 1636 | |
| 1637 switch (impl->active_tree()->source_frame_number()) { | |
| 1638 case 0: | |
| 1639 // Number of textures should be one for each layer | |
| 1640 ASSERT_EQ(2u, context->NumTextures()); | |
| 1641 // Number of textures used for commit should be one for each layer. | |
| 1642 EXPECT_EQ(2u, context->NumUsedTextures()); | |
| 1643 // Verify that used texture is correct. | |
| 1644 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
| 1645 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
| 1646 break; | |
| 1647 case 1: | |
| 1648 // Number of textures should be doubled as the first context layer | |
| 1649 // texture is being used by the impl-thread and cannot be used for | |
| 1650 // update. The scrollbar behavior is different direct renderer because | |
| 1651 // UI resource deletion with delegating renderer occurs after tree | |
| 1652 // activation. | |
| 1653 ASSERT_EQ(4u, context->NumTextures()); | |
| 1654 // Number of textures used for commit should still be | |
| 1655 // one for each layer. | |
| 1656 EXPECT_EQ(2u, context->NumUsedTextures()); | |
| 1657 // First textures should not have been used. | |
| 1658 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); | |
| 1659 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); | |
| 1660 // New textures should have been used. | |
| 1661 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); | |
| 1662 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); | |
| 1663 break; | |
| 1664 case 2: | |
| 1665 EndTest(); | |
| 1666 break; | |
| 1667 default: | |
| 1668 NOTREACHED(); | |
| 1669 break; | |
| 1670 } | |
| 1671 } | |
| 1672 }; | |
| 1673 | |
| 1674 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F( | |
| 1675 LayerTreeHostTestDelegatingRendererAtomicCommit); | |
| 1676 | |
| 1677 static void SetLayerPropertiesForTesting(Layer* layer, | |
| 1678 Layer* parent, | |
| 1679 const gfx::Transform& transform, | |
| 1680 const gfx::Point3F& transform_origin, | |
| 1681 const gfx::PointF& position, | |
| 1682 const gfx::Size& bounds, | |
| 1683 bool opaque) { | |
| 1684 layer->RemoveAllChildren(); | |
| 1685 if (parent) | |
| 1686 parent->AddChild(layer); | |
| 1687 layer->SetTransform(transform); | |
| 1688 layer->SetTransformOrigin(transform_origin); | |
| 1689 layer->SetPosition(position); | |
| 1690 layer->SetBounds(bounds); | |
| 1691 layer->SetContentsOpaque(opaque); | |
| 1692 } | |
| 1693 | |
| 1694 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere. | |
| 1695 class LayerTreeHostTestAtomicCommitWithPartialUpdate | |
| 1696 : public LayerTreeHostTest { | |
| 1697 public: | |
| 1698 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 1699 settings->renderer_settings.texture_id_allocation_chunk_size = 1; | |
| 1700 // Allow one partial texture update. | |
| 1701 settings->max_partial_texture_updates = 1; | |
| 1702 // No partial updates when impl side painting is enabled. | |
| 1703 settings->impl_side_painting = false; | |
| 1704 } | |
| 1705 | |
| 1706 void SetupTree() override { | |
| 1707 parent_ = FakeContentLayer::Create(&client_); | |
| 1708 parent_->SetBounds(gfx::Size(10, 20)); | |
| 1709 | |
| 1710 child_ = FakeContentLayer::Create(&client_); | |
| 1711 child_->SetPosition(gfx::Point(0, 10)); | |
| 1712 child_->SetBounds(gfx::Size(3, 10)); | |
| 1713 | |
| 1714 parent_->AddChild(child_); | |
| 1715 | |
| 1716 layer_tree_host()->SetRootLayer(parent_); | |
| 1717 LayerTreeHostTest::SetupTree(); | |
| 1718 } | |
| 1719 | |
| 1720 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1721 | |
| 1722 void DidCommitAndDrawFrame() override { | |
| 1723 switch (layer_tree_host()->source_frame_number()) { | |
| 1724 case 1: | |
| 1725 parent_->SetNeedsDisplay(); | |
| 1726 child_->SetNeedsDisplay(); | |
| 1727 break; | |
| 1728 case 2: | |
| 1729 // Damage part of layers. | |
| 1730 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5)); | |
| 1731 child_->SetNeedsDisplayRect(gfx::Rect(5, 5)); | |
| 1732 break; | |
| 1733 case 3: | |
| 1734 child_->SetNeedsDisplay(); | |
| 1735 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); | |
| 1736 break; | |
| 1737 case 4: | |
| 1738 layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); | |
| 1739 break; | |
| 1740 case 5: | |
| 1741 EndTest(); | |
| 1742 break; | |
| 1743 default: | |
| 1744 NOTREACHED() << layer_tree_host()->source_frame_number(); | |
| 1745 break; | |
| 1746 } | |
| 1747 } | |
| 1748 | |
| 1749 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 1750 ASSERT_EQ(1u, impl->settings().max_partial_texture_updates); | |
| 1751 | |
| 1752 TestWebGraphicsContext3D* context = TestContext(); | |
| 1753 | |
| 1754 switch (impl->active_tree()->source_frame_number()) { | |
| 1755 case 0: | |
| 1756 // Number of textures should be one for each layer. | |
| 1757 ASSERT_EQ(2u, context->NumTextures()); | |
| 1758 // Number of textures used for commit should be one for each layer. | |
| 1759 EXPECT_EQ(2u, context->NumUsedTextures()); | |
| 1760 // Verify that used textures are correct. | |
| 1761 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
| 1762 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
| 1763 context->ResetUsedTextures(); | |
| 1764 break; | |
| 1765 case 1: | |
| 1766 if (HasImplThread()) { | |
| 1767 // Number of textures should be two for each content layer. | |
| 1768 ASSERT_EQ(4u, context->NumTextures()); | |
| 1769 } else { | |
| 1770 // In single thread we can always do partial updates, so the limit has | |
| 1771 // no effect. | |
| 1772 ASSERT_EQ(2u, context->NumTextures()); | |
| 1773 } | |
| 1774 // Number of textures used for commit should be one for each content | |
| 1775 // layer. | |
| 1776 EXPECT_EQ(2u, context->NumUsedTextures()); | |
| 1777 | |
| 1778 if (HasImplThread()) { | |
| 1779 // First content textures should not have been used. | |
| 1780 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); | |
| 1781 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); | |
| 1782 // New textures should have been used. | |
| 1783 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); | |
| 1784 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); | |
| 1785 } else { | |
| 1786 // In single thread we can always do partial updates, so the limit has | |
| 1787 // no effect. | |
| 1788 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
| 1789 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
| 1790 } | |
| 1791 | |
| 1792 context->ResetUsedTextures(); | |
| 1793 break; | |
| 1794 case 2: | |
| 1795 if (HasImplThread()) { | |
| 1796 // Number of textures should be two for each content layer. | |
| 1797 ASSERT_EQ(4u, context->NumTextures()); | |
| 1798 } else { | |
| 1799 // In single thread we can always do partial updates, so the limit has | |
| 1800 // no effect. | |
| 1801 ASSERT_EQ(2u, context->NumTextures()); | |
| 1802 } | |
| 1803 // Number of textures used for commit should be one for each content | |
| 1804 // layer. | |
| 1805 EXPECT_EQ(2u, context->NumUsedTextures()); | |
| 1806 | |
| 1807 if (HasImplThread()) { | |
| 1808 // One content layer does a partial update also. | |
| 1809 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); | |
| 1810 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3))); | |
| 1811 } else { | |
| 1812 // In single thread we can always do partial updates, so the limit has | |
| 1813 // no effect. | |
| 1814 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
| 1815 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
| 1816 } | |
| 1817 | |
| 1818 context->ResetUsedTextures(); | |
| 1819 break; | |
| 1820 case 3: | |
| 1821 // No textures should be used for commit. | |
| 1822 EXPECT_EQ(0u, context->NumUsedTextures()); | |
| 1823 | |
| 1824 context->ResetUsedTextures(); | |
| 1825 break; | |
| 1826 case 4: | |
| 1827 // Number of textures used for commit should be one, for the | |
| 1828 // content layer. | |
| 1829 EXPECT_EQ(1u, context->NumUsedTextures()); | |
| 1830 | |
| 1831 context->ResetUsedTextures(); | |
| 1832 break; | |
| 1833 default: | |
| 1834 NOTREACHED(); | |
| 1835 break; | |
| 1836 } | |
| 1837 } | |
| 1838 | |
| 1839 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 1840 EXPECT_LT(impl->active_tree()->source_frame_number(), 5); | |
| 1841 | |
| 1842 TestWebGraphicsContext3D* context = TestContext(); | |
| 1843 | |
| 1844 // Number of textures used for drawing should one per layer except for | |
| 1845 // frame 3 where the viewport only contains one layer. | |
| 1846 if (impl->active_tree()->source_frame_number() == 3) { | |
| 1847 EXPECT_EQ(1u, context->NumUsedTextures()); | |
| 1848 } else { | |
| 1849 EXPECT_EQ(2u, context->NumUsedTextures()) | |
| 1850 << "For frame " << impl->active_tree()->source_frame_number(); | |
| 1851 } | |
| 1852 | |
| 1853 context->ResetUsedTextures(); | |
| 1854 } | |
| 1855 | |
| 1856 void AfterTest() override {} | |
| 1857 | |
| 1858 private: | |
| 1859 FakeContentLayerClient client_; | |
| 1860 scoped_refptr<FakeContentLayer> parent_; | |
| 1861 scoped_refptr<FakeContentLayer> child_; | |
| 1862 }; | |
| 1863 | |
| 1864 // Partial updates are not possible with a delegating renderer. | |
| 1865 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( | |
| 1866 LayerTreeHostTestAtomicCommitWithPartialUpdate); | |
| 1867 | |
| 1868 // TODO(sohanjg) : Make it work with impl-side painting. | |
| 1869 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit | |
| 1870 : public LayerTreeHostTest { | |
| 1871 protected: | |
| 1872 void SetupTree() override { | |
| 1873 root_layer_ = FakeContentLayer::Create(&client_); | |
| 1874 root_layer_->SetBounds(gfx::Size(100, 100)); | |
| 1875 | |
| 1876 surface_layer1_ = FakeContentLayer::Create(&client_); | |
| 1877 surface_layer1_->SetBounds(gfx::Size(100, 100)); | |
| 1878 surface_layer1_->SetForceRenderSurface(true); | |
| 1879 surface_layer1_->SetOpacity(0.5f); | |
| 1880 root_layer_->AddChild(surface_layer1_); | |
| 1881 | |
| 1882 surface_layer2_ = FakeContentLayer::Create(&client_); | |
| 1883 surface_layer2_->SetBounds(gfx::Size(100, 100)); | |
| 1884 surface_layer2_->SetForceRenderSurface(true); | |
| 1885 surface_layer2_->SetOpacity(0.5f); | |
| 1886 surface_layer1_->AddChild(surface_layer2_); | |
| 1887 | |
| 1888 replica_layer1_ = FakeContentLayer::Create(&client_); | |
| 1889 surface_layer1_->SetReplicaLayer(replica_layer1_.get()); | |
| 1890 | |
| 1891 replica_layer2_ = FakeContentLayer::Create(&client_); | |
| 1892 surface_layer2_->SetReplicaLayer(replica_layer2_.get()); | |
| 1893 | |
| 1894 layer_tree_host()->SetRootLayer(root_layer_); | |
| 1895 LayerTreeHostTest::SetupTree(); | |
| 1896 } | |
| 1897 | |
| 1898 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1899 | |
| 1900 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1901 Renderer* renderer = host_impl->renderer(); | |
| 1902 RenderPassId surface1_render_pass_id = host_impl->active_tree() | |
| 1903 ->root_layer() | |
| 1904 ->children()[0] | |
| 1905 ->render_surface() | |
| 1906 ->GetRenderPassId(); | |
| 1907 RenderPassId surface2_render_pass_id = host_impl->active_tree() | |
| 1908 ->root_layer() | |
| 1909 ->children()[0] | |
| 1910 ->children()[0] | |
| 1911 ->render_surface() | |
| 1912 ->GetRenderPassId(); | |
| 1913 | |
| 1914 switch (host_impl->active_tree()->source_frame_number()) { | |
| 1915 case 0: | |
| 1916 EXPECT_TRUE( | |
| 1917 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id)); | |
| 1918 EXPECT_TRUE( | |
| 1919 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id)); | |
| 1920 | |
| 1921 // Reduce the memory limit to only fit the root layer and one render | |
| 1922 // surface. This prevents any contents drawing into surfaces | |
| 1923 // from being allocated. | |
| 1924 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2)); | |
| 1925 break; | |
| 1926 case 1: | |
| 1927 EXPECT_FALSE( | |
| 1928 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id)); | |
| 1929 EXPECT_FALSE( | |
| 1930 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id)); | |
| 1931 | |
| 1932 EndTest(); | |
| 1933 break; | |
| 1934 } | |
| 1935 } | |
| 1936 | |
| 1937 void DidCommitAndDrawFrame() override { | |
| 1938 if (layer_tree_host()->source_frame_number() < 2) | |
| 1939 root_layer_->SetNeedsDisplay(); | |
| 1940 } | |
| 1941 | |
| 1942 void AfterTest() override { | |
| 1943 EXPECT_LE(2u, root_layer_->update_count()); | |
| 1944 EXPECT_LE(2u, surface_layer1_->update_count()); | |
| 1945 EXPECT_LE(2u, surface_layer2_->update_count()); | |
| 1946 } | |
| 1947 | |
| 1948 FakeContentLayerClient client_; | |
| 1949 scoped_refptr<FakeContentLayer> root_layer_; | |
| 1950 scoped_refptr<FakeContentLayer> surface_layer1_; | |
| 1951 scoped_refptr<FakeContentLayer> replica_layer1_; | |
| 1952 scoped_refptr<FakeContentLayer> surface_layer2_; | |
| 1953 scoped_refptr<FakeContentLayer> replica_layer2_; | |
| 1954 }; | |
| 1955 | |
| 1956 // Surfaces don't exist with a delegated renderer. | |
| 1957 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( | |
| 1958 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit); | |
| 1959 | |
| 1960 class EvictionTestLayer : public Layer { | |
| 1961 public: | |
| 1962 static scoped_refptr<EvictionTestLayer> Create() { | |
| 1963 return make_scoped_refptr(new EvictionTestLayer()); | |
| 1964 } | |
| 1965 | |
| 1966 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override; | |
| 1967 bool DrawsContent() const override { return true; } | |
| 1968 | |
| 1969 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; | |
| 1970 void PushPropertiesTo(LayerImpl* impl) override; | |
| 1971 void SetTexturePriorities(const PriorityCalculator&) override; | |
| 1972 | |
| 1973 bool HaveBackingTexture() const { | |
| 1974 return texture_.get() ? texture_->have_backing_texture() : false; | |
| 1975 } | |
| 1976 | |
| 1977 private: | |
| 1978 EvictionTestLayer() : Layer() {} | |
| 1979 ~EvictionTestLayer() override {} | |
| 1980 | |
| 1981 void CreateTextureIfNeeded() { | |
| 1982 if (texture_) | |
| 1983 return; | |
| 1984 texture_ = PrioritizedResource::Create( | |
| 1985 layer_tree_host()->contents_texture_manager()); | |
| 1986 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888); | |
| 1987 bitmap_.allocN32Pixels(10, 10); | |
| 1988 } | |
| 1989 | |
| 1990 scoped_ptr<PrioritizedResource> texture_; | |
| 1991 SkBitmap bitmap_; | |
| 1992 }; | |
| 1993 | |
| 1994 class EvictionTestLayerImpl : public LayerImpl { | |
| 1995 public: | |
| 1996 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl, | |
| 1997 int id) { | |
| 1998 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id)); | |
| 1999 } | |
| 2000 ~EvictionTestLayerImpl() override {} | |
| 2001 | |
| 2002 void AppendQuads(RenderPass* render_pass, | |
| 2003 AppendQuadsData* append_quads_data) override { | |
| 2004 ASSERT_TRUE(has_texture_); | |
| 2005 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources()); | |
| 2006 } | |
| 2007 | |
| 2008 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; } | |
| 2009 | |
| 2010 private: | |
| 2011 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id) | |
| 2012 : LayerImpl(tree_impl, id), has_texture_(false) {} | |
| 2013 | |
| 2014 bool has_texture_; | |
| 2015 }; | |
| 2016 | |
| 2017 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) { | |
| 2018 CreateTextureIfNeeded(); | |
| 2019 if (!texture_) | |
| 2020 return; | |
| 2021 texture_->set_request_priority(PriorityCalculator::UIPriority(true)); | |
| 2022 } | |
| 2023 | |
| 2024 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue, | |
| 2025 const OcclusionTracker<Layer>* occlusion) { | |
| 2026 CreateTextureIfNeeded(); | |
| 2027 if (!texture_) | |
| 2028 return false; | |
| 2029 | |
| 2030 gfx::Rect full_rect(0, 0, 10, 10); | |
| 2031 ResourceUpdate upload = ResourceUpdate::Create( | |
| 2032 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d()); | |
| 2033 queue->AppendFullUpload(upload); | |
| 2034 return true; | |
| 2035 } | |
| 2036 | |
| 2037 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl( | |
| 2038 LayerTreeImpl* tree_impl) { | |
| 2039 return EvictionTestLayerImpl::Create(tree_impl, layer_id_); | |
| 2040 } | |
| 2041 | |
| 2042 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) { | |
| 2043 Layer::PushPropertiesTo(layer_impl); | |
| 2044 | |
| 2045 EvictionTestLayerImpl* test_layer_impl = | |
| 2046 static_cast<EvictionTestLayerImpl*>(layer_impl); | |
| 2047 test_layer_impl->SetHasTexture(texture_->have_backing_texture()); | |
| 2048 } | |
| 2049 | |
| 2050 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { | |
| 2051 public: | |
| 2052 LayerTreeHostTestEvictTextures() | |
| 2053 : layer_(EvictionTestLayer::Create()), | |
| 2054 impl_for_evict_textures_(0), | |
| 2055 num_commits_(0) {} | |
| 2056 | |
| 2057 void BeginTest() override { | |
| 2058 layer_tree_host()->SetRootLayer(layer_); | |
| 2059 layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); | |
| 2060 | |
| 2061 gfx::Transform identity_matrix; | |
| 2062 SetLayerPropertiesForTesting(layer_.get(), | |
| 2063 0, | |
| 2064 identity_matrix, | |
| 2065 gfx::Point3F(0.f, 0.f, 0.f), | |
| 2066 gfx::PointF(0.f, 0.f), | |
| 2067 gfx::Size(10, 20), | |
| 2068 true); | |
| 2069 | |
| 2070 PostSetNeedsCommitToMainThread(); | |
| 2071 } | |
| 2072 | |
| 2073 void PostEvictTextures() { | |
| 2074 ImplThreadTaskRunner()->PostTask( | |
| 2075 FROM_HERE, | |
| 2076 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread, | |
| 2077 base::Unretained(this))); | |
| 2078 } | |
| 2079 | |
| 2080 void EvictTexturesOnImplThread() { | |
| 2081 DCHECK(impl_for_evict_textures_); | |
| 2082 impl_for_evict_textures_->EvictTexturesForTesting(); | |
| 2083 } | |
| 2084 | |
| 2085 // Commit 1: Just commit and draw normally, then post an eviction at the end | |
| 2086 // that will trigger a commit. | |
| 2087 // Commit 2: Triggered by the eviction, let it go through and then set | |
| 2088 // needsCommit. | |
| 2089 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction | |
| 2090 // task, which will be handled before the commit. Don't set needsCommit, it | |
| 2091 // should have been posted. A frame should not be drawn (note, | |
| 2092 // didCommitAndDrawFrame may be called anyway). | |
| 2093 // Commit 4: Triggered by the eviction, let it go through and then set | |
| 2094 // needsCommit. | |
| 2095 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in | |
| 2096 // Layout(), a frame should not be drawn but a commit will be posted. | |
| 2097 // Commit 6: Triggered by the eviction, post an eviction task in | |
| 2098 // Layout(), which will be a noop, letting the commit (which recreates the | |
| 2099 // textures) go through and draw a frame, then end the test. | |
| 2100 // | |
| 2101 // Commits 1+2 test the eviction recovery path where eviction happens outside | |
| 2102 // of the beginFrame/commit pair. | |
| 2103 // Commits 3+4 test the eviction recovery path where eviction happens inside | |
| 2104 // the beginFrame/commit pair. | |
| 2105 // Commits 5+6 test the path where an eviction happens during the eviction | |
| 2106 // recovery path. | |
| 2107 void DidCommit() override { | |
| 2108 switch (num_commits_) { | |
| 2109 case 1: | |
| 2110 EXPECT_TRUE(layer_->HaveBackingTexture()); | |
| 2111 PostEvictTextures(); | |
| 2112 break; | |
| 2113 case 2: | |
| 2114 EXPECT_TRUE(layer_->HaveBackingTexture()); | |
| 2115 layer_tree_host()->SetNeedsCommit(); | |
| 2116 break; | |
| 2117 case 3: | |
| 2118 break; | |
| 2119 case 4: | |
| 2120 EXPECT_TRUE(layer_->HaveBackingTexture()); | |
| 2121 layer_tree_host()->SetNeedsCommit(); | |
| 2122 break; | |
| 2123 case 5: | |
| 2124 break; | |
| 2125 case 6: | |
| 2126 EXPECT_TRUE(layer_->HaveBackingTexture()); | |
| 2127 EndTest(); | |
| 2128 break; | |
| 2129 default: | |
| 2130 NOTREACHED(); | |
| 2131 break; | |
| 2132 } | |
| 2133 } | |
| 2134 | |
| 2135 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 2136 impl_for_evict_textures_ = impl; | |
| 2137 } | |
| 2138 | |
| 2139 void Layout() override { | |
| 2140 ++num_commits_; | |
| 2141 switch (num_commits_) { | |
| 2142 case 1: | |
| 2143 case 2: | |
| 2144 break; | |
| 2145 case 3: | |
| 2146 PostEvictTextures(); | |
| 2147 break; | |
| 2148 case 4: | |
| 2149 // We couldn't check in didCommitAndDrawFrame on commit 3, | |
| 2150 // so check here. | |
| 2151 EXPECT_FALSE(layer_->HaveBackingTexture()); | |
| 2152 break; | |
| 2153 case 5: | |
| 2154 PostEvictTextures(); | |
| 2155 break; | |
| 2156 case 6: | |
| 2157 // We couldn't check in didCommitAndDrawFrame on commit 5, | |
| 2158 // so check here. | |
| 2159 EXPECT_FALSE(layer_->HaveBackingTexture()); | |
| 2160 PostEvictTextures(); | |
| 2161 break; | |
| 2162 default: | |
| 2163 NOTREACHED(); | |
| 2164 break; | |
| 2165 } | |
| 2166 } | |
| 2167 | |
| 2168 void AfterTest() override {} | |
| 2169 | |
| 2170 private: | |
| 2171 FakeContentLayerClient client_; | |
| 2172 scoped_refptr<EvictionTestLayer> layer_; | |
| 2173 LayerTreeHostImpl* impl_for_evict_textures_; | |
| 2174 int num_commits_; | |
| 2175 }; | |
| 2176 | |
| 2177 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures); | |
| 2178 | |
| 2179 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { | |
| 2180 public: | |
| 2181 LayerTreeHostTestContinuousInvalidate() | |
| 2182 : num_commit_complete_(0), num_draw_layers_(0) {} | |
| 2183 | |
| 2184 void BeginTest() override { | |
| 2185 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); | |
| 2186 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); | |
| 2187 | |
| 2188 if (layer_tree_host()->settings().impl_side_painting) | |
| 2189 layer_ = FakePictureLayer::Create(&client_); | |
| 2190 else | |
| 2191 layer_ = FakeContentLayer::Create(&client_); | |
| 2192 | |
| 2193 layer_->SetBounds(gfx::Size(10, 10)); | |
| 2194 layer_->SetPosition(gfx::PointF(0.f, 0.f)); | |
| 2195 layer_->SetIsDrawable(true); | |
| 2196 layer_tree_host()->root_layer()->AddChild(layer_); | |
| 2197 | |
| 2198 PostSetNeedsCommitToMainThread(); | |
| 2199 } | |
| 2200 | |
| 2201 void DidCommitAndDrawFrame() override { | |
| 2202 if (num_draw_layers_ == 2) | |
| 2203 return; | |
| 2204 layer_->SetNeedsDisplay(); | |
| 2205 } | |
| 2206 | |
| 2207 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 2208 if (num_draw_layers_ == 1) | |
| 2209 num_commit_complete_++; | |
| 2210 } | |
| 2211 | |
| 2212 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 2213 num_draw_layers_++; | |
| 2214 if (num_draw_layers_ == 2) | |
| 2215 EndTest(); | |
| 2216 } | |
| 2217 | |
| 2218 void AfterTest() override { | |
| 2219 // Check that we didn't commit twice between first and second draw. | |
| 2220 EXPECT_EQ(1, num_commit_complete_); | |
| 2221 } | |
| 2222 | |
| 2223 private: | |
| 2224 FakeContentLayerClient client_; | |
| 2225 scoped_refptr<Layer> layer_; | |
| 2226 int num_commit_complete_; | |
| 2227 int num_draw_layers_; | |
| 2228 }; | |
| 2229 | |
| 2230 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate); | |
| 2231 | |
| 2232 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { | |
| 2233 public: | |
| 2234 LayerTreeHostTestDeferCommits() | |
| 2235 : num_will_begin_impl_frame_(0), | |
| 2236 num_send_begin_main_frame_(0) {} | |
| 2237 | |
| 2238 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 2239 | |
| 2240 void WillBeginImplFrame(const BeginFrameArgs& args) override { | |
| 2241 num_will_begin_impl_frame_++; | |
| 2242 switch (num_will_begin_impl_frame_) { | |
| 2243 case 1: | |
| 2244 break; | |
| 2245 case 2: | |
| 2246 PostSetNeedsCommitToMainThread(); | |
| 2247 break; | |
| 2248 case 3: | |
| 2249 PostSetDeferCommitsToMainThread(false); | |
| 2250 break; | |
| 2251 default: | |
| 2252 // Sometimes |num_will_begin_impl_frame_| will be greater than 3 if the | |
| 2253 // main thread is slow to respond. | |
| 2254 break; | |
| 2255 } | |
| 2256 } | |
| 2257 | |
| 2258 void ScheduledActionSendBeginMainFrame() override { | |
| 2259 num_send_begin_main_frame_++; | |
| 2260 switch (num_send_begin_main_frame_) { | |
| 2261 case 1: | |
| 2262 PostSetDeferCommitsToMainThread(true); | |
| 2263 break; | |
| 2264 case 2: | |
| 2265 EndTest(); | |
| 2266 break; | |
| 2267 default: | |
| 2268 NOTREACHED(); | |
| 2269 break; | |
| 2270 } | |
| 2271 } | |
| 2272 | |
| 2273 void AfterTest() override { | |
| 2274 EXPECT_GE(num_will_begin_impl_frame_, 3); | |
| 2275 EXPECT_EQ(2, num_send_begin_main_frame_); | |
| 2276 } | |
| 2277 | |
| 2278 private: | |
| 2279 int num_will_begin_impl_frame_; | |
| 2280 int num_send_begin_main_frame_; | |
| 2281 }; | |
| 2282 | |
| 2283 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); | |
| 2284 | |
| 2285 class LayerTreeHostWithProxy : public LayerTreeHost { | |
| 2286 public: | |
| 2287 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client, | |
| 2288 const LayerTreeSettings& settings, | |
| 2289 scoped_ptr<FakeProxy> proxy) | |
| 2290 : LayerTreeHost(client, NULL, NULL, NULL, settings) { | |
| 2291 proxy->SetLayerTreeHost(this); | |
| 2292 client->SetLayerTreeHost(this); | |
| 2293 InitializeForTesting(proxy.Pass()); | |
| 2294 } | |
| 2295 }; | |
| 2296 | |
| 2297 TEST(LayerTreeHostTest, LimitPartialUpdates) { | |
| 2298 // When partial updates are not allowed, max updates should be 0. | |
| 2299 { | |
| 2300 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
| 2301 | |
| 2302 scoped_ptr<FakeProxy> proxy(new FakeProxy); | |
| 2303 proxy->GetRendererCapabilities().allow_partial_texture_updates = false; | |
| 2304 proxy->SetMaxPartialTextureUpdates(5); | |
| 2305 | |
| 2306 LayerTreeSettings settings; | |
| 2307 settings.impl_side_painting = false; | |
| 2308 settings.max_partial_texture_updates = 10; | |
| 2309 | |
| 2310 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); | |
| 2311 | |
| 2312 EXPECT_EQ(0u, host.MaxPartialTextureUpdates()); | |
| 2313 } | |
| 2314 | |
| 2315 // When partial updates are allowed, | |
| 2316 // max updates should be limited by the proxy. | |
| 2317 { | |
| 2318 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
| 2319 | |
| 2320 scoped_ptr<FakeProxy> proxy(new FakeProxy); | |
| 2321 proxy->GetRendererCapabilities().allow_partial_texture_updates = true; | |
| 2322 proxy->SetMaxPartialTextureUpdates(5); | |
| 2323 | |
| 2324 LayerTreeSettings settings; | |
| 2325 settings.impl_side_painting = false; | |
| 2326 settings.max_partial_texture_updates = 10; | |
| 2327 | |
| 2328 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); | |
| 2329 | |
| 2330 EXPECT_EQ(5u, host.MaxPartialTextureUpdates()); | |
| 2331 } | |
| 2332 | |
| 2333 // When partial updates are allowed, | |
| 2334 // max updates should also be limited by the settings. | |
| 2335 { | |
| 2336 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
| 2337 | |
| 2338 scoped_ptr<FakeProxy> proxy(new FakeProxy); | |
| 2339 proxy->GetRendererCapabilities().allow_partial_texture_updates = true; | |
| 2340 proxy->SetMaxPartialTextureUpdates(20); | |
| 2341 | |
| 2342 LayerTreeSettings settings; | |
| 2343 settings.impl_side_painting = false; | |
| 2344 settings.max_partial_texture_updates = 10; | |
| 2345 | |
| 2346 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); | |
| 2347 | |
| 2348 EXPECT_EQ(10u, host.MaxPartialTextureUpdates()); | |
| 2349 } | |
| 2350 } | |
| 2351 | |
| 2352 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) { | |
| 2353 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
| 2354 | |
| 2355 LayerTreeSettings settings; | |
| 2356 settings.max_partial_texture_updates = 4; | |
| 2357 settings.single_thread_proxy_scheduler = false; | |
| 2358 settings.impl_side_painting = false; | |
| 2359 | |
| 2360 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
| 2361 new TestSharedBitmapManager()); | |
| 2362 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( | |
| 2363 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
| 2364 base::MessageLoopProxy::current(), nullptr); | |
| 2365 client.SetLayerTreeHost(host.get()); | |
| 2366 host->Composite(base::TimeTicks::Now()); | |
| 2367 | |
| 2368 EXPECT_EQ(4u, host->settings().max_partial_texture_updates); | |
| 2369 } | |
| 2370 | |
| 2371 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) { | |
| 2372 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE); | |
| 2373 | |
| 2374 LayerTreeSettings settings; | |
| 2375 settings.max_partial_texture_updates = 4; | |
| 2376 settings.single_thread_proxy_scheduler = false; | |
| 2377 settings.impl_side_painting = false; | |
| 2378 | |
| 2379 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
| 2380 new TestSharedBitmapManager()); | |
| 2381 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( | |
| 2382 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
| 2383 base::MessageLoopProxy::current(), nullptr); | |
| 2384 client.SetLayerTreeHost(host.get()); | |
| 2385 host->Composite(base::TimeTicks::Now()); | |
| 2386 | |
| 2387 EXPECT_EQ(4u, host->settings().max_partial_texture_updates); | |
| 2388 } | |
| 2389 | |
| 2390 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) { | |
| 2391 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D); | |
| 2392 | |
| 2393 LayerTreeSettings settings; | |
| 2394 settings.max_partial_texture_updates = 4; | |
| 2395 settings.single_thread_proxy_scheduler = false; | |
| 2396 settings.impl_side_painting = false; | |
| 2397 | |
| 2398 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
| 2399 new TestSharedBitmapManager()); | |
| 2400 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( | |
| 2401 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
| 2402 base::MessageLoopProxy::current(), nullptr); | |
| 2403 client.SetLayerTreeHost(host.get()); | |
| 2404 host->Composite(base::TimeTicks::Now()); | |
| 2405 | |
| 2406 EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); | |
| 2407 } | |
| 2408 | |
| 2409 TEST(LayerTreeHostTest, | |
| 2410 PartialUpdatesWithDelegatingRendererAndSoftwareContent) { | |
| 2411 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE); | |
| 2412 | |
| 2413 LayerTreeSettings settings; | |
| 2414 settings.max_partial_texture_updates = 4; | |
| 2415 settings.single_thread_proxy_scheduler = false; | |
| 2416 settings.impl_side_painting = false; | |
| 2417 | |
| 2418 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
| 2419 new TestSharedBitmapManager()); | |
| 2420 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( | |
| 2421 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
| 2422 base::MessageLoopProxy::current(), nullptr); | |
| 2423 client.SetLayerTreeHost(host.get()); | |
| 2424 host->Composite(base::TimeTicks::Now()); | |
| 2425 | |
| 2426 EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); | |
| 2427 } | |
| 2428 | |
| 2429 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere. | |
| 2430 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted | |
| 2431 : public LayerTreeHostTest { | |
| 2432 public: | |
| 2433 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted() | |
| 2434 : root_layer_(FakeContentLayer::Create(&client_)), | |
| 2435 child_layer1_(FakeContentLayer::Create(&client_)), | |
| 2436 child_layer2_(FakeContentLayer::Create(&client_)), | |
| 2437 num_commits_(0) {} | |
| 2438 | |
| 2439 void BeginTest() override { | |
| 2440 layer_tree_host()->SetViewportSize(gfx::Size(100, 100)); | |
| 2441 root_layer_->SetBounds(gfx::Size(100, 100)); | |
| 2442 child_layer1_->SetBounds(gfx::Size(100, 100)); | |
| 2443 child_layer2_->SetBounds(gfx::Size(100, 100)); | |
| 2444 root_layer_->AddChild(child_layer1_); | |
| 2445 root_layer_->AddChild(child_layer2_); | |
| 2446 layer_tree_host()->SetRootLayer(root_layer_); | |
| 2447 PostSetNeedsCommitToMainThread(); | |
| 2448 } | |
| 2449 | |
| 2450 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, | |
| 2451 bool visible) override { | |
| 2452 if (visible) { | |
| 2453 // One backing should remain unevicted. | |
| 2454 EXPECT_EQ(100u * 100u * 4u * 1u, | |
| 2455 contents_texture_manager_->MemoryUseBytes()); | |
| 2456 } else { | |
| 2457 EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes()); | |
| 2458 } | |
| 2459 | |
| 2460 // Make sure that contents textures are marked as having been | |
| 2461 // purged. | |
| 2462 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged()); | |
| 2463 // End the test in this state. | |
| 2464 EndTest(); | |
| 2465 } | |
| 2466 | |
| 2467 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 2468 ++num_commits_; | |
| 2469 switch (num_commits_) { | |
| 2470 case 1: | |
| 2471 // All three backings should have memory. | |
| 2472 EXPECT_EQ(100u * 100u * 4u * 3u, | |
| 2473 contents_texture_manager_->MemoryUseBytes()); | |
| 2474 | |
| 2475 // Set a new policy that will kick out 1 of the 3 resources. | |
| 2476 // Because a resource was evicted, a commit will be kicked off. | |
| 2477 host_impl->SetMemoryPolicy( | |
| 2478 ManagedMemoryPolicy(100 * 100 * 4 * 2, | |
| 2479 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, | |
| 2480 1000)); | |
| 2481 break; | |
| 2482 case 2: | |
| 2483 // Only two backings should have memory. | |
| 2484 EXPECT_EQ(100u * 100u * 4u * 2u, | |
| 2485 contents_texture_manager_->MemoryUseBytes()); | |
| 2486 // Become backgrounded, which will cause 1 more resource to be | |
| 2487 // evicted. | |
| 2488 PostSetVisibleToMainThread(false); | |
| 2489 break; | |
| 2490 default: | |
| 2491 // No further commits should happen because this is not visible | |
| 2492 // anymore. | |
| 2493 NOTREACHED(); | |
| 2494 break; | |
| 2495 } | |
| 2496 } | |
| 2497 | |
| 2498 void AfterTest() override {} | |
| 2499 | |
| 2500 private: | |
| 2501 FakeContentLayerClient client_; | |
| 2502 scoped_refptr<FakeContentLayer> root_layer_; | |
| 2503 scoped_refptr<FakeContentLayer> child_layer1_; | |
| 2504 scoped_refptr<FakeContentLayer> child_layer2_; | |
| 2505 int num_commits_; | |
| 2506 }; | |
| 2507 | |
| 2508 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F( | |
| 2509 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted); | |
| 2510 | |
| 2511 class LayerTreeHostTestLCDChange : public LayerTreeHostTest { | |
| 2512 public: | |
| 2513 void SetupTree() override { | |
| 2514 num_tiles_rastered_ = 0; | |
| 2515 | |
| 2516 scoped_refptr<Layer> root_layer = PictureLayer::Create(&client_); | |
| 2517 client_.set_fill_with_nonsolid_color(true); | |
| 2518 root_layer->SetIsDrawable(true); | |
| 2519 root_layer->SetBounds(gfx::Size(10, 10)); | |
| 2520 root_layer->SetContentsOpaque(true); | |
| 2521 | |
| 2522 layer_tree_host()->SetRootLayer(root_layer); | |
| 2523 | |
| 2524 // The expectations are based on the assumption that the default | |
| 2525 // LCD settings are: | |
| 2526 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text); | |
| 2527 | |
| 2528 LayerTreeHostTest::SetupTree(); | |
| 2529 } | |
| 2530 | |
| 2531 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 2532 | |
| 2533 void DidCommitAndDrawFrame() override { | |
| 2534 switch (layer_tree_host()->source_frame_number()) { | |
| 2535 case 1: | |
| 2536 PostSetNeedsCommitToMainThread(); | |
| 2537 break; | |
| 2538 case 2: | |
| 2539 // Change layer opacity that should trigger lcd change. | |
| 2540 layer_tree_host()->root_layer()->SetOpacity(.5f); | |
| 2541 break; | |
| 2542 case 3: | |
| 2543 // Change layer opacity that should not trigger lcd change. | |
| 2544 layer_tree_host()->root_layer()->SetOpacity(1.f); | |
| 2545 break; | |
| 2546 case 4: | |
| 2547 EndTest(); | |
| 2548 break; | |
| 2549 } | |
| 2550 } | |
| 2551 | |
| 2552 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, | |
| 2553 const Tile* tile) override { | |
| 2554 ++num_tiles_rastered_; | |
| 2555 } | |
| 2556 | |
| 2557 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 2558 PictureLayerImpl* root_layer = | |
| 2559 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer()); | |
| 2560 bool can_use_lcd_text = | |
| 2561 host_impl->active_tree()->root_layer()->can_use_lcd_text(); | |
| 2562 switch (host_impl->active_tree()->source_frame_number()) { | |
| 2563 case 0: | |
| 2564 // The first draw. | |
| 2565 EXPECT_EQ(1, num_tiles_rastered_); | |
| 2566 EXPECT_TRUE(can_use_lcd_text); | |
| 2567 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText()); | |
| 2568 break; | |
| 2569 case 1: | |
| 2570 // Nothing changed on the layer. | |
| 2571 EXPECT_EQ(1, num_tiles_rastered_); | |
| 2572 EXPECT_TRUE(can_use_lcd_text); | |
| 2573 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText()); | |
| 2574 break; | |
| 2575 case 2: | |
| 2576 // LCD text was disabled; it should be re-rastered with LCD text off. | |
| 2577 EXPECT_EQ(2, num_tiles_rastered_); | |
| 2578 EXPECT_FALSE(can_use_lcd_text); | |
| 2579 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText()); | |
| 2580 break; | |
| 2581 case 3: | |
| 2582 // LCD text was enabled, but it's sticky and stays off. | |
| 2583 EXPECT_EQ(2, num_tiles_rastered_); | |
| 2584 EXPECT_TRUE(can_use_lcd_text); | |
| 2585 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText()); | |
| 2586 break; | |
| 2587 } | |
| 2588 } | |
| 2589 | |
| 2590 void AfterTest() override {} | |
| 2591 | |
| 2592 private: | |
| 2593 FakeContentLayerClient client_; | |
| 2594 int num_tiles_rastered_; | |
| 2595 }; | |
| 2596 | |
| 2597 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange); | |
| 2598 | |
| 2599 // Verify that the BeginFrame notification is used to initiate rendering. | |
| 2600 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest { | |
| 2601 public: | |
| 2602 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 2603 settings->use_external_begin_frame_source = true; | |
| 2604 } | |
| 2605 | |
| 2606 void BeginTest() override { | |
| 2607 // This will trigger a SetNeedsBeginFrame which will trigger a | |
| 2608 // BeginFrame. | |
| 2609 PostSetNeedsCommitToMainThread(); | |
| 2610 } | |
| 2611 | |
| 2612 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 2613 LayerTreeHostImpl::FrameData* frame, | |
| 2614 DrawResult draw_result) override { | |
| 2615 EndTest(); | |
| 2616 return DRAW_SUCCESS; | |
| 2617 } | |
| 2618 | |
| 2619 void AfterTest() override {} | |
| 2620 | |
| 2621 private: | |
| 2622 base::TimeTicks frame_time_; | |
| 2623 }; | |
| 2624 | |
| 2625 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification); | |
| 2626 | |
| 2627 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled | |
| 2628 : public LayerTreeHostTest { | |
| 2629 public: | |
| 2630 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 2631 settings->use_external_begin_frame_source = true; | |
| 2632 settings->using_synchronous_renderer_compositor = true; | |
| 2633 } | |
| 2634 | |
| 2635 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 2636 | |
| 2637 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 2638 // The BeginFrame notification is turned off now but will get enabled | |
| 2639 // once we return. End test while it's enabled. | |
| 2640 ImplThreadTaskRunner()->PostTask( | |
| 2641 FROM_HERE, | |
| 2642 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest, | |
| 2643 base::Unretained(this))); | |
| 2644 } | |
| 2645 | |
| 2646 void AfterTest() override {} | |
| 2647 }; | |
| 2648 | |
| 2649 MULTI_THREAD_TEST_F( | |
| 2650 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled); | |
| 2651 | |
| 2652 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { | |
| 2653 protected: | |
| 2654 LayerTreeHostTestAbortedCommitDoesntStall() | |
| 2655 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {} | |
| 2656 | |
| 2657 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 2658 settings->use_external_begin_frame_source = true; | |
| 2659 } | |
| 2660 | |
| 2661 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 2662 | |
| 2663 void DidCommit() override { | |
| 2664 commit_count_++; | |
| 2665 if (commit_count_ == 4) { | |
| 2666 // After two aborted commits, request a real commit now to make sure a | |
| 2667 // real commit following an aborted commit will still complete and | |
| 2668 // end the test even when the Impl thread is idle. | |
| 2669 layer_tree_host()->SetNeedsCommit(); | |
| 2670 } | |
| 2671 } | |
| 2672 | |
| 2673 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, | |
| 2674 CommitEarlyOutReason reason) override { | |
| 2675 commit_abort_count_++; | |
| 2676 // Initiate another abortable commit. | |
| 2677 host_impl->SetNeedsCommit(); | |
| 2678 } | |
| 2679 | |
| 2680 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 2681 commit_complete_count_++; | |
| 2682 if (commit_complete_count_ == 1) { | |
| 2683 // Initiate an abortable commit after the first commit. | |
| 2684 host_impl->SetNeedsCommit(); | |
| 2685 } else { | |
| 2686 EndTest(); | |
| 2687 } | |
| 2688 } | |
| 2689 | |
| 2690 void AfterTest() override { | |
| 2691 EXPECT_EQ(commit_count_, 5); | |
| 2692 EXPECT_EQ(commit_abort_count_, 3); | |
| 2693 EXPECT_EQ(commit_complete_count_, 2); | |
| 2694 } | |
| 2695 | |
| 2696 int commit_count_; | |
| 2697 int commit_abort_count_; | |
| 2698 int commit_complete_count_; | |
| 2699 }; | |
| 2700 | |
| 2701 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor | |
| 2702 : public LayerTreeHostTestAbortedCommitDoesntStall { | |
| 2703 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 2704 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); | |
| 2705 settings->using_synchronous_renderer_compositor = true; | |
| 2706 } | |
| 2707 }; | |
| 2708 | |
| 2709 MULTI_THREAD_TEST_F( | |
| 2710 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor); | |
| 2711 | |
| 2712 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync | |
| 2713 : public LayerTreeHostTestAbortedCommitDoesntStall { | |
| 2714 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 2715 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); | |
| 2716 settings->throttle_frame_production = false; | |
| 2717 } | |
| 2718 }; | |
| 2719 | |
| 2720 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync); | |
| 2721 | |
| 2722 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation | |
| 2723 : public LayerTreeHostTest { | |
| 2724 protected: | |
| 2725 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 2726 settings->impl_side_painting = true; | |
| 2727 } | |
| 2728 | |
| 2729 void SetupTree() override { | |
| 2730 LayerTreeHostTest::SetupTree(); | |
| 2731 | |
| 2732 scoped_refptr<Layer> layer = PictureLayer::Create(&client_); | |
| 2733 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); | |
| 2734 layer->SetBounds(gfx::Size(10, 10)); | |
| 2735 layer_tree_host()->root_layer()->AddChild(layer); | |
| 2736 } | |
| 2737 | |
| 2738 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 2739 | |
| 2740 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 2741 EndTest(); | |
| 2742 } | |
| 2743 | |
| 2744 void AfterTest() override {} | |
| 2745 | |
| 2746 FakeContentLayerClient client_; | |
| 2747 }; | |
| 2748 | |
| 2749 MULTI_THREAD_TEST_F( | |
| 2750 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation); | |
| 2751 | |
| 2752 class LayerTreeHostTestChangeLayerPropertiesInPaintContents | |
| 2753 : public LayerTreeHostTest { | |
| 2754 public: | |
| 2755 class SetBoundsClient : public ContentLayerClient { | |
| 2756 public: | |
| 2757 SetBoundsClient() : layer_(0) {} | |
| 2758 | |
| 2759 void set_layer(Layer* layer) { layer_ = layer; } | |
| 2760 | |
| 2761 void PaintContents(SkCanvas* canvas, | |
| 2762 const gfx::Rect& clip, | |
| 2763 PaintingControlSetting picture_control) override { | |
| 2764 layer_->SetBounds(gfx::Size(2, 2)); | |
| 2765 } | |
| 2766 | |
| 2767 scoped_refptr<DisplayItemList> PaintContentsToDisplayList( | |
| 2768 const gfx::Rect& clip, | |
| 2769 PaintingControlSetting picture_control) override { | |
| 2770 NOTIMPLEMENTED(); | |
| 2771 return DisplayItemList::Create(); | |
| 2772 } | |
| 2773 | |
| 2774 bool FillsBoundsCompletely() const override { return false; } | |
| 2775 | |
| 2776 private: | |
| 2777 Layer* layer_; | |
| 2778 }; | |
| 2779 | |
| 2780 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {} | |
| 2781 | |
| 2782 void SetupTree() override { | |
| 2783 if (layer_tree_host()->settings().impl_side_painting) { | |
| 2784 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_); | |
| 2785 layer_tree_host()->SetRootLayer(root_layer); | |
| 2786 } else { | |
| 2787 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_); | |
| 2788 layer_tree_host()->SetRootLayer(root_layer); | |
| 2789 } | |
| 2790 Layer* root_layer = layer_tree_host()->root_layer(); | |
| 2791 root_layer->SetIsDrawable(true); | |
| 2792 root_layer->SetBounds(gfx::Size(1, 1)); | |
| 2793 | |
| 2794 client_.set_layer(root_layer); | |
| 2795 | |
| 2796 LayerTreeHostTest::SetupTree(); | |
| 2797 } | |
| 2798 | |
| 2799 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 2800 void AfterTest() override {} | |
| 2801 | |
| 2802 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 2803 num_commits_++; | |
| 2804 if (num_commits_ == 1) { | |
| 2805 LayerImpl* root_layer = host_impl->active_tree()->root_layer(); | |
| 2806 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds()); | |
| 2807 } else { | |
| 2808 LayerImpl* root_layer = host_impl->active_tree()->root_layer(); | |
| 2809 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds()); | |
| 2810 EndTest(); | |
| 2811 } | |
| 2812 } | |
| 2813 | |
| 2814 private: | |
| 2815 SetBoundsClient client_; | |
| 2816 int num_commits_; | |
| 2817 }; | |
| 2818 | |
| 2819 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 2820 LayerTreeHostTestChangeLayerPropertiesInPaintContents); | |
| 2821 | |
| 2822 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { | |
| 2823 public: | |
| 2824 MockIOSurfaceWebGraphicsContext3D() { | |
| 2825 test_capabilities_.gpu.iosurface = true; | |
| 2826 test_capabilities_.gpu.texture_rectangle = true; | |
| 2827 } | |
| 2828 | |
| 2829 GLuint createTexture() override { return 1; } | |
| 2830 MOCK_METHOD1(activeTexture, void(GLenum texture)); | |
| 2831 MOCK_METHOD2(bindTexture, void(GLenum target, | |
| 2832 GLuint texture_id)); | |
| 2833 MOCK_METHOD3(texParameteri, void(GLenum target, | |
| 2834 GLenum pname, | |
| 2835 GLint param)); | |
| 2836 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target, | |
| 2837 GLint width, | |
| 2838 GLint height, | |
| 2839 GLuint ioSurfaceId, | |
| 2840 GLuint plane)); | |
| 2841 MOCK_METHOD4(drawElements, void(GLenum mode, | |
| 2842 GLsizei count, | |
| 2843 GLenum type, | |
| 2844 GLintptr offset)); | |
| 2845 MOCK_METHOD1(deleteTexture, void(GLenum texture)); | |
| 2846 MOCK_METHOD3(produceTextureDirectCHROMIUM, | |
| 2847 void(GLuint texture, GLenum target, const GLbyte* mailbox)); | |
| 2848 }; | |
| 2849 | |
| 2850 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { | |
| 2851 protected: | |
| 2852 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
| 2853 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned( | |
| 2854 new MockIOSurfaceWebGraphicsContext3D); | |
| 2855 mock_context_ = mock_context_owned.get(); | |
| 2856 | |
| 2857 if (delegating_renderer()) | |
| 2858 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass()); | |
| 2859 else | |
| 2860 return FakeOutputSurface::Create3d(mock_context_owned.Pass()); | |
| 2861 } | |
| 2862 | |
| 2863 void SetupTree() override { | |
| 2864 LayerTreeHostTest::SetupTree(); | |
| 2865 | |
| 2866 layer_tree_host()->root_layer()->SetIsDrawable(false); | |
| 2867 | |
| 2868 io_surface_id_ = 9; | |
| 2869 io_surface_size_ = gfx::Size(6, 7); | |
| 2870 | |
| 2871 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create(); | |
| 2872 io_surface_layer->SetBounds(gfx::Size(10, 10)); | |
| 2873 io_surface_layer->SetIsDrawable(true); | |
| 2874 io_surface_layer->SetContentsOpaque(true); | |
| 2875 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); | |
| 2876 layer_tree_host()->root_layer()->AddChild(io_surface_layer); | |
| 2877 } | |
| 2878 | |
| 2879 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 2880 | |
| 2881 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 2882 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources()); | |
| 2883 // In WillDraw, the IOSurfaceLayer sets up the io surface texture. | |
| 2884 | |
| 2885 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0); | |
| 2886 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1)) | |
| 2887 .Times(AtLeast(1)); | |
| 2888 EXPECT_CALL(*mock_context_, | |
| 2889 texParameteri( | |
| 2890 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)) | |
| 2891 .Times(1); | |
| 2892 EXPECT_CALL(*mock_context_, | |
| 2893 texParameteri( | |
| 2894 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR)) | |
| 2895 .Times(1); | |
| 2896 EXPECT_CALL(*mock_context_, | |
| 2897 texParameteri(GL_TEXTURE_RECTANGLE_ARB, | |
| 2898 GL_TEXTURE_POOL_CHROMIUM, | |
| 2899 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1); | |
| 2900 EXPECT_CALL(*mock_context_, | |
| 2901 texParameteri(GL_TEXTURE_RECTANGLE_ARB, | |
| 2902 GL_TEXTURE_WRAP_S, | |
| 2903 GL_CLAMP_TO_EDGE)).Times(1); | |
| 2904 EXPECT_CALL(*mock_context_, | |
| 2905 texParameteri(GL_TEXTURE_RECTANGLE_ARB, | |
| 2906 GL_TEXTURE_WRAP_T, | |
| 2907 GL_CLAMP_TO_EDGE)).Times(1); | |
| 2908 | |
| 2909 EXPECT_CALL(*mock_context_, | |
| 2910 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, | |
| 2911 io_surface_size_.width(), | |
| 2912 io_surface_size_.height(), | |
| 2913 io_surface_id_, | |
| 2914 0)).Times(1); | |
| 2915 | |
| 2916 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber()); | |
| 2917 } | |
| 2918 | |
| 2919 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 2920 LayerTreeHostImpl::FrameData* frame, | |
| 2921 DrawResult draw_result) override { | |
| 2922 Mock::VerifyAndClearExpectations(&mock_context_); | |
| 2923 ResourceProvider* resource_provider = host_impl->resource_provider(); | |
| 2924 EXPECT_EQ(1u, resource_provider->num_resources()); | |
| 2925 CHECK_EQ(1u, frame->render_passes.size()); | |
| 2926 CHECK_LE(1u, frame->render_passes[0]->quad_list.size()); | |
| 2927 const DrawQuad* quad = frame->render_passes[0]->quad_list.front(); | |
| 2928 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material); | |
| 2929 const IOSurfaceDrawQuad* io_surface_draw_quad = | |
| 2930 IOSurfaceDrawQuad::MaterialCast(quad); | |
| 2931 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size); | |
| 2932 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id); | |
| 2933 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), | |
| 2934 resource_provider->TargetForTesting( | |
| 2935 io_surface_draw_quad->io_surface_resource_id)); | |
| 2936 | |
| 2937 if (delegating_renderer()) { | |
| 2938 // The io surface layer's resource should be sent to the parent. | |
| 2939 EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM( | |
| 2940 _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1); | |
| 2941 } else { | |
| 2942 // The io surface layer's texture is drawn. | |
| 2943 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1)); | |
| 2944 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _)) | |
| 2945 .Times(AtLeast(1)); | |
| 2946 } | |
| 2947 | |
| 2948 return draw_result; | |
| 2949 } | |
| 2950 | |
| 2951 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 2952 Mock::VerifyAndClearExpectations(&mock_context_); | |
| 2953 | |
| 2954 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1)); | |
| 2955 EndTest(); | |
| 2956 } | |
| 2957 | |
| 2958 void AfterTest() override {} | |
| 2959 | |
| 2960 int io_surface_id_; | |
| 2961 MockIOSurfaceWebGraphicsContext3D* mock_context_; | |
| 2962 gfx::Size io_surface_size_; | |
| 2963 }; | |
| 2964 | |
| 2965 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing); | |
| 2966 | |
| 2967 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { | |
| 2968 public: | |
| 2969 void BeginTest() override { | |
| 2970 frame_ = 0; | |
| 2971 PostSetNeedsCommitToMainThread(); | |
| 2972 } | |
| 2973 | |
| 2974 // Round 1: commit + draw | |
| 2975 // Round 2: commit only (no draw/swap) | |
| 2976 // Round 3: draw only (no commit) | |
| 2977 | |
| 2978 void DidCommit() override { | |
| 2979 int commit = layer_tree_host()->source_frame_number(); | |
| 2980 switch (commit) { | |
| 2981 case 2: | |
| 2982 // Round 2 done. | |
| 2983 EXPECT_EQ(1, frame_); | |
| 2984 layer_tree_host()->SetNeedsRedraw(); | |
| 2985 break; | |
| 2986 } | |
| 2987 } | |
| 2988 | |
| 2989 void DidCompleteSwapBuffers() override { | |
| 2990 int commit = layer_tree_host()->source_frame_number(); | |
| 2991 ++frame_; | |
| 2992 switch (frame_) { | |
| 2993 case 1: | |
| 2994 // Round 1 done. | |
| 2995 EXPECT_EQ(1, commit); | |
| 2996 layer_tree_host()->SetNeedsCommit(); | |
| 2997 break; | |
| 2998 case 2: | |
| 2999 // Round 3 done. | |
| 3000 EXPECT_EQ(2, commit); | |
| 3001 EndTest(); | |
| 3002 break; | |
| 3003 } | |
| 3004 } | |
| 3005 | |
| 3006 void AfterTest() override {} | |
| 3007 | |
| 3008 protected: | |
| 3009 int frame_; | |
| 3010 }; | |
| 3011 | |
| 3012 // Flaky on all platforms: http://crbug.com/327498 | |
| 3013 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) { | |
| 3014 RunTest(true, true, true); | |
| 3015 } | |
| 3016 | |
| 3017 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) { | |
| 3018 RunTest(true, false, true); | |
| 3019 } | |
| 3020 | |
| 3021 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { | |
| 3022 public: | |
| 3023 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 3024 // PictureLayer can only be used with impl side painting enabled. | |
| 3025 settings->impl_side_painting = true; | |
| 3026 } | |
| 3027 | |
| 3028 void SetupTree() override { | |
| 3029 layer_ = FakePictureLayer::Create(&client_); | |
| 3030 // Force commits to not be aborted so new frames get drawn, otherwise | |
| 3031 // the renderer gets deferred initialized but nothing new needs drawing. | |
| 3032 layer_->set_always_update_resources(true); | |
| 3033 layer_tree_host()->SetRootLayer(layer_); | |
| 3034 LayerTreeHostTest::SetupTree(); | |
| 3035 } | |
| 3036 | |
| 3037 void BeginTest() override { | |
| 3038 did_initialize_gl_ = false; | |
| 3039 did_release_gl_ = false; | |
| 3040 last_source_frame_number_drawn_ = -1; // Never drawn. | |
| 3041 PostSetNeedsCommitToMainThread(); | |
| 3042 } | |
| 3043 | |
| 3044 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
| 3045 scoped_ptr<TestWebGraphicsContext3D> context3d( | |
| 3046 TestWebGraphicsContext3D::Create()); | |
| 3047 | |
| 3048 return FakeOutputSurface::CreateDeferredGL( | |
| 3049 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice), | |
| 3050 delegating_renderer()); | |
| 3051 } | |
| 3052 | |
| 3053 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 3054 ASSERT_TRUE(host_impl->RootLayer()); | |
| 3055 FakePictureLayerImpl* layer_impl = | |
| 3056 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer()); | |
| 3057 | |
| 3058 // The same frame can be draw multiple times if new visible tiles are | |
| 3059 // rasterized. But we want to make sure we only post DeferredInitialize | |
| 3060 // and ReleaseGL once, so early out if the same frame is drawn again. | |
| 3061 if (last_source_frame_number_drawn_ == | |
| 3062 host_impl->active_tree()->source_frame_number()) | |
| 3063 return; | |
| 3064 | |
| 3065 last_source_frame_number_drawn_ = | |
| 3066 host_impl->active_tree()->source_frame_number(); | |
| 3067 | |
| 3068 if (!did_initialize_gl_) { | |
| 3069 EXPECT_LE(1u, layer_impl->append_quads_count()); | |
| 3070 ImplThreadTaskRunner()->PostTask( | |
| 3071 FROM_HERE, | |
| 3072 base::Bind( | |
| 3073 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw, | |
| 3074 base::Unretained(this), | |
| 3075 base::Unretained(host_impl))); | |
| 3076 } else if (did_initialize_gl_ && !did_release_gl_) { | |
| 3077 EXPECT_LE(2u, layer_impl->append_quads_count()); | |
| 3078 ImplThreadTaskRunner()->PostTask( | |
| 3079 FROM_HERE, | |
| 3080 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw, | |
| 3081 base::Unretained(this), | |
| 3082 base::Unretained(host_impl))); | |
| 3083 } else if (did_initialize_gl_ && did_release_gl_) { | |
| 3084 EXPECT_LE(3u, layer_impl->append_quads_count()); | |
| 3085 EndTest(); | |
| 3086 } | |
| 3087 } | |
| 3088 | |
| 3089 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) { | |
| 3090 EXPECT_FALSE(did_initialize_gl_); | |
| 3091 // SetAndInitializeContext3D calls SetNeedsCommit. | |
| 3092 FakeOutputSurface* fake_output_surface = | |
| 3093 static_cast<FakeOutputSurface*>(host_impl->output_surface()); | |
| 3094 scoped_refptr<TestContextProvider> context_provider = | |
| 3095 TestContextProvider::Create(); // Not bound to thread. | |
| 3096 scoped_refptr<TestContextProvider> worker_context_provider = | |
| 3097 TestContextProvider::Create(); // Not bound to thread. | |
| 3098 EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d( | |
| 3099 context_provider, worker_context_provider)); | |
| 3100 did_initialize_gl_ = true; | |
| 3101 } | |
| 3102 | |
| 3103 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) { | |
| 3104 EXPECT_TRUE(did_initialize_gl_); | |
| 3105 EXPECT_FALSE(did_release_gl_); | |
| 3106 // ReleaseGL calls SetNeedsCommit. | |
| 3107 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL(); | |
| 3108 did_release_gl_ = true; | |
| 3109 } | |
| 3110 | |
| 3111 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 3112 ASSERT_TRUE(result); | |
| 3113 DelegatedFrameData* delegated_frame_data = | |
| 3114 output_surface()->last_sent_frame().delegated_frame_data.get(); | |
| 3115 if (!delegated_frame_data) | |
| 3116 return; | |
| 3117 | |
| 3118 // Return all resources immediately. | |
| 3119 TransferableResourceArray resources_to_return = | |
| 3120 output_surface()->resources_held_by_parent(); | |
| 3121 | |
| 3122 CompositorFrameAck ack; | |
| 3123 for (size_t i = 0; i < resources_to_return.size(); ++i) | |
| 3124 output_surface()->ReturnResource(resources_to_return[i].id, &ack); | |
| 3125 host_impl->ReclaimResources(&ack); | |
| 3126 } | |
| 3127 | |
| 3128 void AfterTest() override { | |
| 3129 EXPECT_TRUE(did_initialize_gl_); | |
| 3130 EXPECT_TRUE(did_release_gl_); | |
| 3131 } | |
| 3132 | |
| 3133 private: | |
| 3134 FakeContentLayerClient client_; | |
| 3135 scoped_refptr<FakePictureLayer> layer_; | |
| 3136 bool did_initialize_gl_; | |
| 3137 bool did_release_gl_; | |
| 3138 int last_source_frame_number_drawn_; | |
| 3139 }; | |
| 3140 | |
| 3141 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize); | |
| 3142 | |
| 3143 class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { | |
| 3144 public: | |
| 3145 void SetupTree() override { | |
| 3146 root_layer_ = FakePictureLayer::Create(&client_); | |
| 3147 root_layer_->SetIsDrawable(true); | |
| 3148 root_layer_->SetBounds(gfx::Size(50, 50)); | |
| 3149 | |
| 3150 parent_layer_ = FakePictureLayer::Create(&client_); | |
| 3151 parent_layer_->SetIsDrawable(true); | |
| 3152 parent_layer_->SetBounds(gfx::Size(50, 50)); | |
| 3153 parent_layer_->SetForceRenderSurface(true); | |
| 3154 | |
| 3155 child_layer_ = FakePictureLayer::Create(&client_); | |
| 3156 child_layer_->SetIsDrawable(true); | |
| 3157 child_layer_->SetBounds(gfx::Size(50, 50)); | |
| 3158 | |
| 3159 root_layer_->AddChild(parent_layer_); | |
| 3160 parent_layer_->AddChild(child_layer_); | |
| 3161 layer_tree_host()->SetRootLayer(root_layer_); | |
| 3162 | |
| 3163 LayerTreeHostTest::SetupTree(); | |
| 3164 } | |
| 3165 | |
| 3166 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
| 3167 return FakeOutputSurface::CreateDeferredGL( | |
| 3168 make_scoped_ptr(new SoftwareOutputDevice), delegating_renderer()); | |
| 3169 } | |
| 3170 | |
| 3171 void BeginTest() override { | |
| 3172 PostSetNeedsCommitToMainThread(); | |
| 3173 swap_count_ = 0; | |
| 3174 } | |
| 3175 | |
| 3176 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 3177 LayerTreeHostImpl::FrameData* frame_data, | |
| 3178 DrawResult draw_result) override { | |
| 3179 if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) { | |
| 3180 EXPECT_EQ(1u, frame_data->render_passes.size()); | |
| 3181 // Has at least 3 quads for each layer. | |
| 3182 RenderPass* render_pass = frame_data->render_passes[0]; | |
| 3183 EXPECT_GE(render_pass->quad_list.size(), 3u); | |
| 3184 } else { | |
| 3185 EXPECT_EQ(2u, frame_data->render_passes.size()); | |
| 3186 | |
| 3187 // At least root layer quad in root render pass. | |
| 3188 EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u); | |
| 3189 // At least parent and child layer quads in parent render pass. | |
| 3190 EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u); | |
| 3191 } | |
| 3192 return draw_result; | |
| 3193 } | |
| 3194 | |
| 3195 void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 3196 swap_count_++; | |
| 3197 switch (swap_count_) { | |
| 3198 case 1: { | |
| 3199 gfx::Transform identity; | |
| 3200 gfx::Rect empty_rect; | |
| 3201 bool resourceless_software_draw = true; | |
| 3202 host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect, | |
| 3203 empty_rect, identity, | |
| 3204 resourceless_software_draw); | |
| 3205 host_impl->SetFullRootLayerDamage(); | |
| 3206 host_impl->SetNeedsRedraw(); | |
| 3207 break; | |
| 3208 } | |
| 3209 case 2: | |
| 3210 EndTest(); | |
| 3211 break; | |
| 3212 default: | |
| 3213 NOTREACHED(); | |
| 3214 } | |
| 3215 } | |
| 3216 | |
| 3217 void AfterTest() override {} | |
| 3218 | |
| 3219 private: | |
| 3220 FakeContentLayerClient client_; | |
| 3221 scoped_refptr<Layer> root_layer_; | |
| 3222 scoped_refptr<Layer> parent_layer_; | |
| 3223 scoped_refptr<Layer> child_layer_; | |
| 3224 int swap_count_; | |
| 3225 }; | |
| 3226 | |
| 3227 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw); | |
| 3228 | |
| 3229 class LayerTreeHostTestDeferredInitializeWithGpuRasterization | |
| 3230 : public LayerTreeHostTestDeferredInitialize { | |
| 3231 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 3232 // PictureLayer can only be used with impl side painting enabled. | |
| 3233 settings->impl_side_painting = true; | |
| 3234 settings->gpu_rasterization_enabled = true; | |
| 3235 settings->gpu_rasterization_forced = true; | |
| 3236 } | |
| 3237 }; | |
| 3238 | |
| 3239 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization); | |
| 3240 | |
| 3241 // Test for UI Resource management. | |
| 3242 class LayerTreeHostTestUIResource : public LayerTreeHostTest { | |
| 3243 public: | |
| 3244 LayerTreeHostTestUIResource() : num_ui_resources_(0) {} | |
| 3245 | |
| 3246 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 3247 settings->renderer_settings.texture_id_allocation_chunk_size = 1; | |
| 3248 } | |
| 3249 | |
| 3250 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 3251 | |
| 3252 void DidCommit() override { | |
| 3253 int frame = layer_tree_host()->source_frame_number(); | |
| 3254 switch (frame) { | |
| 3255 case 1: | |
| 3256 CreateResource(); | |
| 3257 CreateResource(); | |
| 3258 PostSetNeedsCommitToMainThread(); | |
| 3259 break; | |
| 3260 case 2: | |
| 3261 // Usually ScopedUIResource are deleted from the manager in their | |
| 3262 // destructor. Here we just want to test that a direct call to | |
| 3263 // DeleteUIResource works. | |
| 3264 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id()); | |
| 3265 PostSetNeedsCommitToMainThread(); | |
| 3266 break; | |
| 3267 case 3: | |
| 3268 // DeleteUIResource can be called with an invalid id. | |
| 3269 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id()); | |
| 3270 PostSetNeedsCommitToMainThread(); | |
| 3271 break; | |
| 3272 case 4: | |
| 3273 CreateResource(); | |
| 3274 CreateResource(); | |
| 3275 PostSetNeedsCommitToMainThread(); | |
| 3276 break; | |
| 3277 case 5: | |
| 3278 ClearResources(); | |
| 3279 EndTest(); | |
| 3280 break; | |
| 3281 } | |
| 3282 } | |
| 3283 | |
| 3284 void PerformTest(LayerTreeHostImpl* impl) { | |
| 3285 TestWebGraphicsContext3D* context = TestContext(); | |
| 3286 | |
| 3287 int frame = impl->active_tree()->source_frame_number(); | |
| 3288 switch (frame) { | |
| 3289 case 0: | |
| 3290 ASSERT_EQ(0u, context->NumTextures()); | |
| 3291 break; | |
| 3292 case 1: | |
| 3293 // Created two textures. | |
| 3294 ASSERT_EQ(2u, context->NumTextures()); | |
| 3295 break; | |
| 3296 case 2: | |
| 3297 // One texture left after one deletion. | |
| 3298 ASSERT_EQ(1u, context->NumTextures()); | |
| 3299 break; | |
| 3300 case 3: | |
| 3301 // Resource manager state should not change when delete is called on an | |
| 3302 // invalid id. | |
| 3303 ASSERT_EQ(1u, context->NumTextures()); | |
| 3304 break; | |
| 3305 case 4: | |
| 3306 // Creation after deletion: two more creates should total up to | |
| 3307 // three textures. | |
| 3308 ASSERT_EQ(3u, context->NumTextures()); | |
| 3309 break; | |
| 3310 } | |
| 3311 } | |
| 3312 | |
| 3313 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 3314 if (!impl->settings().impl_side_painting) | |
| 3315 PerformTest(impl); | |
| 3316 } | |
| 3317 | |
| 3318 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 3319 if (impl->settings().impl_side_painting) | |
| 3320 PerformTest(impl); | |
| 3321 } | |
| 3322 | |
| 3323 void AfterTest() override {} | |
| 3324 | |
| 3325 private: | |
| 3326 // Must clear all resources before exiting. | |
| 3327 void ClearResources() { | |
| 3328 for (int i = 0; i < num_ui_resources_; i++) | |
| 3329 ui_resources_[i] = nullptr; | |
| 3330 } | |
| 3331 | |
| 3332 void CreateResource() { | |
| 3333 ui_resources_[num_ui_resources_++] = | |
| 3334 FakeScopedUIResource::Create(layer_tree_host()); | |
| 3335 } | |
| 3336 | |
| 3337 scoped_ptr<FakeScopedUIResource> ui_resources_[5]; | |
| 3338 int num_ui_resources_; | |
| 3339 }; | |
| 3340 | |
| 3341 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource); | |
| 3342 | |
| 3343 class PushPropertiesCountingLayerImpl : public LayerImpl { | |
| 3344 public: | |
| 3345 static scoped_ptr<PushPropertiesCountingLayerImpl> Create( | |
| 3346 LayerTreeImpl* tree_impl, int id) { | |
| 3347 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id)); | |
| 3348 } | |
| 3349 | |
| 3350 ~PushPropertiesCountingLayerImpl() override {} | |
| 3351 | |
| 3352 void PushPropertiesTo(LayerImpl* layer) override { | |
| 3353 LayerImpl::PushPropertiesTo(layer); | |
| 3354 push_properties_count_++; | |
| 3355 // Push state to the active tree because we can only access it from there. | |
| 3356 static_cast<PushPropertiesCountingLayerImpl*>( | |
| 3357 layer)->push_properties_count_ = push_properties_count_; | |
| 3358 } | |
| 3359 | |
| 3360 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { | |
| 3361 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); | |
| 3362 } | |
| 3363 | |
| 3364 size_t push_properties_count() const { return push_properties_count_; } | |
| 3365 void reset_push_properties_count() { push_properties_count_ = 0; } | |
| 3366 | |
| 3367 private: | |
| 3368 size_t push_properties_count_; | |
| 3369 | |
| 3370 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id) | |
| 3371 : LayerImpl(tree_impl, id), | |
| 3372 push_properties_count_(0) { | |
| 3373 SetBounds(gfx::Size(1, 1)); | |
| 3374 } | |
| 3375 }; | |
| 3376 | |
| 3377 class PushPropertiesCountingLayer : public Layer { | |
| 3378 public: | |
| 3379 static scoped_refptr<PushPropertiesCountingLayer> Create() { | |
| 3380 return new PushPropertiesCountingLayer(); | |
| 3381 } | |
| 3382 | |
| 3383 void PushPropertiesTo(LayerImpl* layer) override { | |
| 3384 Layer::PushPropertiesTo(layer); | |
| 3385 push_properties_count_++; | |
| 3386 if (persist_needs_push_properties_) | |
| 3387 needs_push_properties_ = true; | |
| 3388 } | |
| 3389 | |
| 3390 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { | |
| 3391 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); | |
| 3392 } | |
| 3393 | |
| 3394 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); } | |
| 3395 | |
| 3396 size_t push_properties_count() const { return push_properties_count_; } | |
| 3397 void reset_push_properties_count() { push_properties_count_ = 0; } | |
| 3398 | |
| 3399 void set_persist_needs_push_properties(bool persist) { | |
| 3400 persist_needs_push_properties_ = persist; | |
| 3401 } | |
| 3402 | |
| 3403 private: | |
| 3404 PushPropertiesCountingLayer() | |
| 3405 : push_properties_count_(0), persist_needs_push_properties_(false) { | |
| 3406 SetBounds(gfx::Size(1, 1)); | |
| 3407 } | |
| 3408 ~PushPropertiesCountingLayer() override {} | |
| 3409 | |
| 3410 size_t push_properties_count_; | |
| 3411 bool persist_needs_push_properties_; | |
| 3412 }; | |
| 3413 | |
| 3414 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { | |
| 3415 protected: | |
| 3416 void BeginTest() override { | |
| 3417 num_commits_ = 0; | |
| 3418 expected_push_properties_root_ = 0; | |
| 3419 expected_push_properties_child_ = 0; | |
| 3420 expected_push_properties_grandchild_ = 0; | |
| 3421 expected_push_properties_child2_ = 0; | |
| 3422 expected_push_properties_other_root_ = 0; | |
| 3423 expected_push_properties_leaf_layer_ = 0; | |
| 3424 PostSetNeedsCommitToMainThread(); | |
| 3425 } | |
| 3426 | |
| 3427 void SetupTree() override { | |
| 3428 root_ = PushPropertiesCountingLayer::Create(); | |
| 3429 root_->CreateRenderSurface(); | |
| 3430 child_ = PushPropertiesCountingLayer::Create(); | |
| 3431 child2_ = PushPropertiesCountingLayer::Create(); | |
| 3432 grandchild_ = PushPropertiesCountingLayer::Create(); | |
| 3433 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create(); | |
| 3434 leaf_always_pushing_layer_->set_persist_needs_push_properties(true); | |
| 3435 | |
| 3436 root_->AddChild(child_); | |
| 3437 root_->AddChild(child2_); | |
| 3438 child_->AddChild(grandchild_); | |
| 3439 child2_->AddChild(leaf_always_pushing_layer_); | |
| 3440 | |
| 3441 other_root_ = PushPropertiesCountingLayer::Create(); | |
| 3442 other_root_->CreateRenderSurface(); | |
| 3443 | |
| 3444 // Don't set the root layer here. | |
| 3445 LayerTreeHostTest::SetupTree(); | |
| 3446 } | |
| 3447 | |
| 3448 void DidCommitAndDrawFrame() override { | |
| 3449 ++num_commits_; | |
| 3450 | |
| 3451 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count()); | |
| 3452 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count()); | |
| 3453 EXPECT_EQ(expected_push_properties_grandchild_, | |
| 3454 grandchild_->push_properties_count()); | |
| 3455 EXPECT_EQ(expected_push_properties_child2_, | |
| 3456 child2_->push_properties_count()); | |
| 3457 EXPECT_EQ(expected_push_properties_other_root_, | |
| 3458 other_root_->push_properties_count()); | |
| 3459 EXPECT_EQ(expected_push_properties_leaf_layer_, | |
| 3460 leaf_always_pushing_layer_->push_properties_count()); | |
| 3461 | |
| 3462 // The scrollbar layer always needs to be pushed. | |
| 3463 if (root_->layer_tree_host()) { | |
| 3464 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 3465 EXPECT_FALSE(root_->needs_push_properties()); | |
| 3466 } | |
| 3467 if (child2_->layer_tree_host()) { | |
| 3468 EXPECT_TRUE(child2_->descendant_needs_push_properties()); | |
| 3469 EXPECT_FALSE(child2_->needs_push_properties()); | |
| 3470 } | |
| 3471 if (leaf_always_pushing_layer_->layer_tree_host()) { | |
| 3472 EXPECT_FALSE( | |
| 3473 leaf_always_pushing_layer_->descendant_needs_push_properties()); | |
| 3474 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties()); | |
| 3475 } | |
| 3476 | |
| 3477 // child_ and grandchild_ don't persist their need to push properties. | |
| 3478 if (child_->layer_tree_host()) { | |
| 3479 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 3480 EXPECT_FALSE(child_->needs_push_properties()); | |
| 3481 } | |
| 3482 if (grandchild_->layer_tree_host()) { | |
| 3483 EXPECT_FALSE(grandchild_->descendant_needs_push_properties()); | |
| 3484 EXPECT_FALSE(grandchild_->needs_push_properties()); | |
| 3485 } | |
| 3486 | |
| 3487 if (other_root_->layer_tree_host()) { | |
| 3488 EXPECT_FALSE(other_root_->descendant_needs_push_properties()); | |
| 3489 EXPECT_FALSE(other_root_->needs_push_properties()); | |
| 3490 } | |
| 3491 | |
| 3492 switch (num_commits_) { | |
| 3493 case 1: | |
| 3494 layer_tree_host()->SetRootLayer(root_); | |
| 3495 // Layers added to the tree get committed. | |
| 3496 ++expected_push_properties_root_; | |
| 3497 ++expected_push_properties_child_; | |
| 3498 ++expected_push_properties_grandchild_; | |
| 3499 ++expected_push_properties_child2_; | |
| 3500 break; | |
| 3501 case 2: | |
| 3502 layer_tree_host()->SetNeedsCommit(); | |
| 3503 // No layers need commit. | |
| 3504 break; | |
| 3505 case 3: | |
| 3506 layer_tree_host()->SetRootLayer(other_root_); | |
| 3507 // Layers added to the tree get committed. | |
| 3508 ++expected_push_properties_other_root_; | |
| 3509 break; | |
| 3510 case 4: | |
| 3511 layer_tree_host()->SetRootLayer(root_); | |
| 3512 // Layers added to the tree get committed. | |
| 3513 ++expected_push_properties_root_; | |
| 3514 ++expected_push_properties_child_; | |
| 3515 ++expected_push_properties_grandchild_; | |
| 3516 ++expected_push_properties_child2_; | |
| 3517 break; | |
| 3518 case 5: | |
| 3519 layer_tree_host()->SetNeedsCommit(); | |
| 3520 // No layers need commit. | |
| 3521 break; | |
| 3522 case 6: | |
| 3523 child_->RemoveFromParent(); | |
| 3524 // No layers need commit. | |
| 3525 break; | |
| 3526 case 7: | |
| 3527 root_->AddChild(child_); | |
| 3528 // Layers added to the tree get committed. | |
| 3529 ++expected_push_properties_child_; | |
| 3530 ++expected_push_properties_grandchild_; | |
| 3531 break; | |
| 3532 case 8: | |
| 3533 grandchild_->RemoveFromParent(); | |
| 3534 // No layers need commit. | |
| 3535 break; | |
| 3536 case 9: | |
| 3537 child_->AddChild(grandchild_); | |
| 3538 // Layers added to the tree get committed. | |
| 3539 ++expected_push_properties_grandchild_; | |
| 3540 break; | |
| 3541 case 10: | |
| 3542 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); | |
| 3543 // No layers need commit. | |
| 3544 break; | |
| 3545 case 11: | |
| 3546 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f); | |
| 3547 // No layers need commit. | |
| 3548 break; | |
| 3549 case 12: | |
| 3550 child_->SetPosition(gfx::Point(1, 1)); | |
| 3551 // The modified layer needs commit | |
| 3552 ++expected_push_properties_child_; | |
| 3553 break; | |
| 3554 case 13: | |
| 3555 child2_->SetPosition(gfx::Point(1, 1)); | |
| 3556 // The modified layer needs commit | |
| 3557 ++expected_push_properties_child2_; | |
| 3558 break; | |
| 3559 case 14: | |
| 3560 child_->RemoveFromParent(); | |
| 3561 root_->AddChild(child_); | |
| 3562 // Layers added to the tree get committed. | |
| 3563 ++expected_push_properties_child_; | |
| 3564 ++expected_push_properties_grandchild_; | |
| 3565 break; | |
| 3566 case 15: | |
| 3567 grandchild_->SetPosition(gfx::Point(1, 1)); | |
| 3568 // The modified layer needs commit | |
| 3569 ++expected_push_properties_grandchild_; | |
| 3570 break; | |
| 3571 case 16: | |
| 3572 // SetNeedsDisplay does not always set needs commit (so call it | |
| 3573 // explicitly), but is a property change. | |
| 3574 child_->SetNeedsDisplay(); | |
| 3575 ++expected_push_properties_child_; | |
| 3576 layer_tree_host()->SetNeedsCommit(); | |
| 3577 break; | |
| 3578 case 17: | |
| 3579 EndTest(); | |
| 3580 break; | |
| 3581 } | |
| 3582 | |
| 3583 // The leaf layer always pushes. | |
| 3584 if (leaf_always_pushing_layer_->layer_tree_host()) | |
| 3585 ++expected_push_properties_leaf_layer_; | |
| 3586 } | |
| 3587 | |
| 3588 void AfterTest() override {} | |
| 3589 | |
| 3590 int num_commits_; | |
| 3591 FakeContentLayerClient client_; | |
| 3592 scoped_refptr<PushPropertiesCountingLayer> root_; | |
| 3593 scoped_refptr<PushPropertiesCountingLayer> child_; | |
| 3594 scoped_refptr<PushPropertiesCountingLayer> child2_; | |
| 3595 scoped_refptr<PushPropertiesCountingLayer> grandchild_; | |
| 3596 scoped_refptr<PushPropertiesCountingLayer> other_root_; | |
| 3597 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_; | |
| 3598 size_t expected_push_properties_root_; | |
| 3599 size_t expected_push_properties_child_; | |
| 3600 size_t expected_push_properties_child2_; | |
| 3601 size_t expected_push_properties_grandchild_; | |
| 3602 size_t expected_push_properties_other_root_; | |
| 3603 size_t expected_push_properties_leaf_layer_; | |
| 3604 }; | |
| 3605 | |
| 3606 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties); | |
| 3607 | |
| 3608 class LayerTreeHostTestImplLayersPushProperties | |
| 3609 : public LayerTreeHostTestLayersPushProperties { | |
| 3610 protected: | |
| 3611 void BeginTest() override { | |
| 3612 expected_push_properties_root_impl_ = 0; | |
| 3613 expected_push_properties_child_impl_ = 0; | |
| 3614 expected_push_properties_grandchild_impl_ = 0; | |
| 3615 expected_push_properties_child2_impl_ = 0; | |
| 3616 expected_push_properties_grandchild2_impl_ = 0; | |
| 3617 LayerTreeHostTestLayersPushProperties::BeginTest(); | |
| 3618 } | |
| 3619 | |
| 3620 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 3621 // These commits are in response to the changes made in | |
| 3622 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame() | |
| 3623 switch (num_commits_) { | |
| 3624 case 0: | |
| 3625 // Tree hasn't been setup yet don't bother to check anything. | |
| 3626 return; | |
| 3627 case 1: | |
| 3628 // Root gets set up, Everyone is initialized. | |
| 3629 ++expected_push_properties_root_impl_; | |
| 3630 ++expected_push_properties_child_impl_; | |
| 3631 ++expected_push_properties_grandchild_impl_; | |
| 3632 ++expected_push_properties_child2_impl_; | |
| 3633 ++expected_push_properties_grandchild2_impl_; | |
| 3634 break; | |
| 3635 case 2: | |
| 3636 // Tree doesn't change but the one leaf that always pushes is pushed. | |
| 3637 ++expected_push_properties_grandchild2_impl_; | |
| 3638 break; | |
| 3639 case 3: | |
| 3640 // Root is swapped here. | |
| 3641 // Clear the expected push properties the tree will be rebuilt. | |
| 3642 expected_push_properties_root_impl_ = 0; | |
| 3643 expected_push_properties_child_impl_ = 0; | |
| 3644 expected_push_properties_grandchild_impl_ = 0; | |
| 3645 expected_push_properties_child2_impl_ = 0; | |
| 3646 expected_push_properties_grandchild2_impl_ = 0; | |
| 3647 | |
| 3648 // Make sure the new root is pushed. | |
| 3649 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>( | |
| 3650 host_impl->RootLayer())->push_properties_count()); | |
| 3651 return; | |
| 3652 case 4: | |
| 3653 // Root is swapped back all of the layers in the tree get pushed. | |
| 3654 ++expected_push_properties_root_impl_; | |
| 3655 ++expected_push_properties_child_impl_; | |
| 3656 ++expected_push_properties_grandchild_impl_; | |
| 3657 ++expected_push_properties_child2_impl_; | |
| 3658 ++expected_push_properties_grandchild2_impl_; | |
| 3659 break; | |
| 3660 case 5: | |
| 3661 // Tree doesn't change but the one leaf that always pushes is pushed. | |
| 3662 ++expected_push_properties_grandchild2_impl_; | |
| 3663 break; | |
| 3664 case 6: | |
| 3665 // First child is removed. Structure of the tree changes here so swap | |
| 3666 // some of the values. child_impl becomes child2_impl. | |
| 3667 expected_push_properties_child_impl_ = | |
| 3668 expected_push_properties_child2_impl_; | |
| 3669 expected_push_properties_child2_impl_ = 0; | |
| 3670 // grandchild_impl becomes grandchild2_impl. | |
| 3671 expected_push_properties_grandchild_impl_ = | |
| 3672 expected_push_properties_grandchild2_impl_; | |
| 3673 expected_push_properties_grandchild2_impl_ = 0; | |
| 3674 | |
| 3675 // grandchild_impl is now the leaf that always pushes. It is pushed. | |
| 3676 ++expected_push_properties_grandchild_impl_; | |
| 3677 break; | |
| 3678 case 7: | |
| 3679 // The leaf that always pushes is pushed. | |
| 3680 ++expected_push_properties_grandchild_impl_; | |
| 3681 | |
| 3682 // Child is added back. New layers are initialized. | |
| 3683 ++expected_push_properties_grandchild2_impl_; | |
| 3684 ++expected_push_properties_child2_impl_; | |
| 3685 break; | |
| 3686 case 8: | |
| 3687 // Leaf is removed. | |
| 3688 expected_push_properties_grandchild2_impl_ = 0; | |
| 3689 | |
| 3690 // Always pushing. | |
| 3691 ++expected_push_properties_grandchild_impl_; | |
| 3692 break; | |
| 3693 case 9: | |
| 3694 // Leaf is added back | |
| 3695 ++expected_push_properties_grandchild2_impl_; | |
| 3696 | |
| 3697 // The leaf that always pushes is pushed. | |
| 3698 ++expected_push_properties_grandchild_impl_; | |
| 3699 break; | |
| 3700 case 10: | |
| 3701 // The leaf that always pushes is pushed. | |
| 3702 ++expected_push_properties_grandchild_impl_; | |
| 3703 break; | |
| 3704 case 11: | |
| 3705 // The leaf that always pushes is pushed. | |
| 3706 ++expected_push_properties_grandchild_impl_; | |
| 3707 break; | |
| 3708 case 12: | |
| 3709 // The leaf that always pushes is pushed. | |
| 3710 ++expected_push_properties_grandchild_impl_; | |
| 3711 | |
| 3712 // This child position was changed. | |
| 3713 ++expected_push_properties_child2_impl_; | |
| 3714 break; | |
| 3715 case 13: | |
| 3716 // The position of this child was changed. | |
| 3717 ++expected_push_properties_child_impl_; | |
| 3718 | |
| 3719 // The leaf that always pushes is pushed. | |
| 3720 ++expected_push_properties_grandchild_impl_; | |
| 3721 break; | |
| 3722 case 14: | |
| 3723 // Second child is removed from tree. Don't discard counts because | |
| 3724 // they are added back before commit. | |
| 3725 | |
| 3726 // The leaf that always pushes is pushed. | |
| 3727 ++expected_push_properties_grandchild_impl_; | |
| 3728 | |
| 3729 // Second child added back. | |
| 3730 ++expected_push_properties_child2_impl_; | |
| 3731 ++expected_push_properties_grandchild2_impl_; | |
| 3732 | |
| 3733 break; | |
| 3734 case 15: | |
| 3735 // The position of this child was changed. | |
| 3736 ++expected_push_properties_grandchild2_impl_; | |
| 3737 | |
| 3738 // The leaf that always pushes is pushed. | |
| 3739 ++expected_push_properties_grandchild_impl_; | |
| 3740 break; | |
| 3741 case 16: | |
| 3742 // Second child is invalidated with SetNeedsDisplay | |
| 3743 ++expected_push_properties_child2_impl_; | |
| 3744 | |
| 3745 // The leaf that always pushed is pushed. | |
| 3746 ++expected_push_properties_grandchild_impl_; | |
| 3747 break; | |
| 3748 } | |
| 3749 | |
| 3750 PushPropertiesCountingLayerImpl* root_impl_ = NULL; | |
| 3751 PushPropertiesCountingLayerImpl* child_impl_ = NULL; | |
| 3752 PushPropertiesCountingLayerImpl* child2_impl_ = NULL; | |
| 3753 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL; | |
| 3754 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL; | |
| 3755 | |
| 3756 // Pull the layers that we need from the tree assuming the same structure | |
| 3757 // as LayerTreeHostTestLayersPushProperties | |
| 3758 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( | |
| 3759 host_impl->RootLayer()); | |
| 3760 | |
| 3761 if (root_impl_ && root_impl_->children().size() > 0) { | |
| 3762 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( | |
| 3763 root_impl_->children()[0]); | |
| 3764 | |
| 3765 if (child_impl_ && child_impl_->children().size() > 0) | |
| 3766 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( | |
| 3767 child_impl_->children()[0]); | |
| 3768 } | |
| 3769 | |
| 3770 if (root_impl_ && root_impl_->children().size() > 1) { | |
| 3771 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( | |
| 3772 root_impl_->children()[1]); | |
| 3773 | |
| 3774 if (child2_impl_ && child2_impl_->children().size() > 0) | |
| 3775 leaf_always_pushing_layer_impl_ = | |
| 3776 static_cast<PushPropertiesCountingLayerImpl*>( | |
| 3777 child2_impl_->children()[0]); | |
| 3778 } | |
| 3779 | |
| 3780 if (root_impl_) | |
| 3781 EXPECT_EQ(expected_push_properties_root_impl_, | |
| 3782 root_impl_->push_properties_count()); | |
| 3783 if (child_impl_) | |
| 3784 EXPECT_EQ(expected_push_properties_child_impl_, | |
| 3785 child_impl_->push_properties_count()); | |
| 3786 if (grandchild_impl_) | |
| 3787 EXPECT_EQ(expected_push_properties_grandchild_impl_, | |
| 3788 grandchild_impl_->push_properties_count()); | |
| 3789 if (child2_impl_) | |
| 3790 EXPECT_EQ(expected_push_properties_child2_impl_, | |
| 3791 child2_impl_->push_properties_count()); | |
| 3792 if (leaf_always_pushing_layer_impl_) | |
| 3793 EXPECT_EQ(expected_push_properties_grandchild2_impl_, | |
| 3794 leaf_always_pushing_layer_impl_->push_properties_count()); | |
| 3795 } | |
| 3796 | |
| 3797 size_t expected_push_properties_root_impl_; | |
| 3798 size_t expected_push_properties_child_impl_; | |
| 3799 size_t expected_push_properties_child2_impl_; | |
| 3800 size_t expected_push_properties_grandchild_impl_; | |
| 3801 size_t expected_push_properties_grandchild2_impl_; | |
| 3802 }; | |
| 3803 | |
| 3804 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) { | |
| 3805 RunTestWithImplSidePainting(); | |
| 3806 } | |
| 3807 | |
| 3808 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed | |
| 3809 : public LayerTreeHostTest { | |
| 3810 protected: | |
| 3811 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 3812 | |
| 3813 void SetupTree() override { | |
| 3814 root_ = Layer::Create(); | |
| 3815 root_->CreateRenderSurface(); | |
| 3816 root_->SetBounds(gfx::Size(1, 1)); | |
| 3817 | |
| 3818 bool paint_scrollbar = true; | |
| 3819 bool has_thumb = false; | |
| 3820 scrollbar_layer_ = FakePaintedScrollbarLayer::Create( | |
| 3821 paint_scrollbar, has_thumb, root_->id()); | |
| 3822 | |
| 3823 root_->AddChild(scrollbar_layer_); | |
| 3824 | |
| 3825 layer_tree_host()->SetRootLayer(root_); | |
| 3826 LayerTreeHostTest::SetupTree(); | |
| 3827 } | |
| 3828 | |
| 3829 void DidCommitAndDrawFrame() override { | |
| 3830 switch (layer_tree_host()->source_frame_number()) { | |
| 3831 case 0: | |
| 3832 break; | |
| 3833 case 1: { | |
| 3834 // During update, the ignore_set_needs_commit_ bit is set to true to | |
| 3835 // avoid causing a second commit to be scheduled. If a property change | |
| 3836 // is made during this, however, it needs to be pushed in the upcoming | |
| 3837 // commit. | |
| 3838 scoped_ptr<base::AutoReset<bool>> ignore = | |
| 3839 scrollbar_layer_->IgnoreSetNeedsCommit(); | |
| 3840 | |
| 3841 scrollbar_layer_->SetBounds(gfx::Size(30, 30)); | |
| 3842 | |
| 3843 EXPECT_TRUE(scrollbar_layer_->needs_push_properties()); | |
| 3844 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 3845 layer_tree_host()->SetNeedsCommit(); | |
| 3846 | |
| 3847 scrollbar_layer_->reset_push_properties_count(); | |
| 3848 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count()); | |
| 3849 break; | |
| 3850 } | |
| 3851 case 2: | |
| 3852 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count()); | |
| 3853 EndTest(); | |
| 3854 break; | |
| 3855 } | |
| 3856 } | |
| 3857 | |
| 3858 void AfterTest() override {} | |
| 3859 | |
| 3860 scoped_refptr<Layer> root_; | |
| 3861 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_; | |
| 3862 }; | |
| 3863 | |
| 3864 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed); | |
| 3865 | |
| 3866 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest { | |
| 3867 protected: | |
| 3868 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 3869 | |
| 3870 void SetupTree() override { | |
| 3871 root_ = PushPropertiesCountingLayer::Create(); | |
| 3872 root_->CreateRenderSurface(); | |
| 3873 child_ = PushPropertiesCountingLayer::Create(); | |
| 3874 root_->AddChild(child_); | |
| 3875 | |
| 3876 layer_tree_host()->SetRootLayer(root_); | |
| 3877 LayerTreeHostTest::SetupTree(); | |
| 3878 } | |
| 3879 | |
| 3880 void DidCommitAndDrawFrame() override { | |
| 3881 switch (layer_tree_host()->source_frame_number()) { | |
| 3882 case 0: | |
| 3883 break; | |
| 3884 case 1: { | |
| 3885 // During update, the ignore_set_needs_commit_ bit is set to true to | |
| 3886 // avoid causing a second commit to be scheduled. If a property change | |
| 3887 // is made during this, however, it needs to be pushed in the upcoming | |
| 3888 // commit. | |
| 3889 EXPECT_FALSE(root_->needs_push_properties()); | |
| 3890 EXPECT_FALSE(child_->needs_push_properties()); | |
| 3891 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent()); | |
| 3892 root_->reset_push_properties_count(); | |
| 3893 child_->reset_push_properties_count(); | |
| 3894 child_->SetDrawsContent(true); | |
| 3895 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent()); | |
| 3896 EXPECT_EQ(0u, root_->push_properties_count()); | |
| 3897 EXPECT_EQ(0u, child_->push_properties_count()); | |
| 3898 EXPECT_TRUE(root_->needs_push_properties()); | |
| 3899 EXPECT_TRUE(child_->needs_push_properties()); | |
| 3900 break; | |
| 3901 } | |
| 3902 case 2: | |
| 3903 EXPECT_EQ(1u, root_->push_properties_count()); | |
| 3904 EXPECT_EQ(1u, child_->push_properties_count()); | |
| 3905 EXPECT_FALSE(root_->needs_push_properties()); | |
| 3906 EXPECT_FALSE(child_->needs_push_properties()); | |
| 3907 EndTest(); | |
| 3908 break; | |
| 3909 } | |
| 3910 } | |
| 3911 | |
| 3912 void AfterTest() override {} | |
| 3913 | |
| 3914 scoped_refptr<PushPropertiesCountingLayer> root_; | |
| 3915 scoped_refptr<PushPropertiesCountingLayer> child_; | |
| 3916 }; | |
| 3917 | |
| 3918 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit); | |
| 3919 | |
| 3920 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren | |
| 3921 : public LayerTreeHostTest { | |
| 3922 protected: | |
| 3923 void BeginTest() override { | |
| 3924 expected_push_properties_root_ = 0; | |
| 3925 expected_push_properties_child_ = 0; | |
| 3926 expected_push_properties_grandchild1_ = 0; | |
| 3927 expected_push_properties_grandchild2_ = 0; | |
| 3928 expected_push_properties_grandchild3_ = 0; | |
| 3929 PostSetNeedsCommitToMainThread(); | |
| 3930 } | |
| 3931 | |
| 3932 void SetupTree() override { | |
| 3933 root_ = PushPropertiesCountingLayer::Create(); | |
| 3934 root_->CreateRenderSurface(); | |
| 3935 child_ = PushPropertiesCountingLayer::Create(); | |
| 3936 grandchild1_ = PushPropertiesCountingLayer::Create(); | |
| 3937 grandchild2_ = PushPropertiesCountingLayer::Create(); | |
| 3938 grandchild3_ = PushPropertiesCountingLayer::Create(); | |
| 3939 | |
| 3940 root_->AddChild(child_); | |
| 3941 child_->AddChild(grandchild1_); | |
| 3942 child_->AddChild(grandchild2_); | |
| 3943 child_->AddChild(grandchild3_); | |
| 3944 | |
| 3945 // Don't set the root layer here. | |
| 3946 LayerTreeHostTest::SetupTree(); | |
| 3947 } | |
| 3948 | |
| 3949 void AfterTest() override {} | |
| 3950 | |
| 3951 FakeContentLayerClient client_; | |
| 3952 scoped_refptr<PushPropertiesCountingLayer> root_; | |
| 3953 scoped_refptr<PushPropertiesCountingLayer> child_; | |
| 3954 scoped_refptr<PushPropertiesCountingLayer> grandchild1_; | |
| 3955 scoped_refptr<PushPropertiesCountingLayer> grandchild2_; | |
| 3956 scoped_refptr<PushPropertiesCountingLayer> grandchild3_; | |
| 3957 size_t expected_push_properties_root_; | |
| 3958 size_t expected_push_properties_child_; | |
| 3959 size_t expected_push_properties_grandchild1_; | |
| 3960 size_t expected_push_properties_grandchild2_; | |
| 3961 size_t expected_push_properties_grandchild3_; | |
| 3962 }; | |
| 3963 | |
| 3964 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush | |
| 3965 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
| 3966 protected: | |
| 3967 void DidCommitAndDrawFrame() override { | |
| 3968 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
| 3969 switch (last_source_frame_number) { | |
| 3970 case 0: | |
| 3971 EXPECT_FALSE(root_->needs_push_properties()); | |
| 3972 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 3973 EXPECT_FALSE(child_->needs_push_properties()); | |
| 3974 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 3975 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
| 3976 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 3977 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
| 3978 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 3979 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 3980 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 3981 | |
| 3982 layer_tree_host()->SetRootLayer(root_); | |
| 3983 | |
| 3984 EXPECT_TRUE(root_->needs_push_properties()); | |
| 3985 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 3986 EXPECT_TRUE(child_->needs_push_properties()); | |
| 3987 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 3988 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
| 3989 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 3990 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
| 3991 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 3992 EXPECT_TRUE(grandchild3_->needs_push_properties()); | |
| 3993 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 3994 break; | |
| 3995 case 1: | |
| 3996 EndTest(); | |
| 3997 break; | |
| 3998 } | |
| 3999 } | |
| 4000 }; | |
| 4001 | |
| 4002 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush); | |
| 4003 | |
| 4004 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion | |
| 4005 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
| 4006 protected: | |
| 4007 void DidCommitAndDrawFrame() override { | |
| 4008 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
| 4009 switch (last_source_frame_number) { | |
| 4010 case 0: | |
| 4011 layer_tree_host()->SetRootLayer(root_); | |
| 4012 break; | |
| 4013 case 1: | |
| 4014 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4015 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4016 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4017 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4018 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
| 4019 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4020 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
| 4021 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4022 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4023 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4024 | |
| 4025 grandchild1_->RemoveFromParent(); | |
| 4026 grandchild1_->SetPosition(gfx::Point(1, 1)); | |
| 4027 | |
| 4028 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4029 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4030 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4031 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4032 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
| 4033 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4034 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4035 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4036 | |
| 4037 child_->AddChild(grandchild1_); | |
| 4038 | |
| 4039 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4040 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4041 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4042 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4043 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
| 4044 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4045 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
| 4046 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4047 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4048 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4049 | |
| 4050 grandchild2_->SetPosition(gfx::Point(1, 1)); | |
| 4051 | |
| 4052 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4053 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4054 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4055 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4056 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
| 4057 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4058 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
| 4059 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4060 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4061 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4062 | |
| 4063 // grandchild2_ will still need a push properties. | |
| 4064 grandchild1_->RemoveFromParent(); | |
| 4065 | |
| 4066 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4067 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4068 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4069 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4070 | |
| 4071 // grandchild3_ does not need a push properties, so recursing should | |
| 4072 // no longer be needed. | |
| 4073 grandchild2_->RemoveFromParent(); | |
| 4074 | |
| 4075 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4076 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4077 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4078 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4079 EndTest(); | |
| 4080 break; | |
| 4081 } | |
| 4082 } | |
| 4083 }; | |
| 4084 | |
| 4085 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion); | |
| 4086 | |
| 4087 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence | |
| 4088 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
| 4089 protected: | |
| 4090 void DidCommitAndDrawFrame() override { | |
| 4091 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
| 4092 switch (last_source_frame_number) { | |
| 4093 case 0: | |
| 4094 layer_tree_host()->SetRootLayer(root_); | |
| 4095 grandchild1_->set_persist_needs_push_properties(true); | |
| 4096 grandchild2_->set_persist_needs_push_properties(true); | |
| 4097 break; | |
| 4098 case 1: | |
| 4099 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4100 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4101 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4102 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4103 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
| 4104 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4105 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
| 4106 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4107 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4108 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4109 | |
| 4110 // grandchild2_ will still need a push properties. | |
| 4111 grandchild1_->RemoveFromParent(); | |
| 4112 | |
| 4113 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4114 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4115 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4116 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4117 | |
| 4118 // grandchild3_ does not need a push properties, so recursing should | |
| 4119 // no longer be needed. | |
| 4120 grandchild2_->RemoveFromParent(); | |
| 4121 | |
| 4122 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4123 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4124 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4125 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4126 EndTest(); | |
| 4127 break; | |
| 4128 } | |
| 4129 } | |
| 4130 }; | |
| 4131 | |
| 4132 MULTI_THREAD_TEST_F( | |
| 4133 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence); | |
| 4134 | |
| 4135 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree | |
| 4136 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
| 4137 protected: | |
| 4138 void DidCommitAndDrawFrame() override { | |
| 4139 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
| 4140 switch (last_source_frame_number) { | |
| 4141 case 0: | |
| 4142 layer_tree_host()->SetRootLayer(root_); | |
| 4143 break; | |
| 4144 case 1: | |
| 4145 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4146 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4147 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4148 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4149 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
| 4150 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4151 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
| 4152 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4153 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4154 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4155 | |
| 4156 // Change grandchildren while their parent is not in the tree. | |
| 4157 child_->RemoveFromParent(); | |
| 4158 grandchild1_->SetPosition(gfx::Point(1, 1)); | |
| 4159 grandchild2_->SetPosition(gfx::Point(1, 1)); | |
| 4160 root_->AddChild(child_); | |
| 4161 | |
| 4162 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4163 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4164 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4165 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4166 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
| 4167 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4168 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
| 4169 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4170 EXPECT_TRUE(grandchild3_->needs_push_properties()); | |
| 4171 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4172 | |
| 4173 grandchild1_->RemoveFromParent(); | |
| 4174 | |
| 4175 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4176 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4177 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4178 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4179 | |
| 4180 grandchild2_->RemoveFromParent(); | |
| 4181 | |
| 4182 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4183 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4184 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4185 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4186 | |
| 4187 grandchild3_->RemoveFromParent(); | |
| 4188 | |
| 4189 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4190 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4191 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4192 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4193 | |
| 4194 EndTest(); | |
| 4195 break; | |
| 4196 } | |
| 4197 } | |
| 4198 }; | |
| 4199 | |
| 4200 MULTI_THREAD_TEST_F( | |
| 4201 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree); | |
| 4202 | |
| 4203 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild | |
| 4204 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
| 4205 protected: | |
| 4206 void DidCommitAndDrawFrame() override { | |
| 4207 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
| 4208 switch (last_source_frame_number) { | |
| 4209 case 0: | |
| 4210 layer_tree_host()->SetRootLayer(root_); | |
| 4211 break; | |
| 4212 case 1: | |
| 4213 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4214 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4215 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4216 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4217 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
| 4218 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4219 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
| 4220 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4221 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4222 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4223 | |
| 4224 child_->SetPosition(gfx::Point(1, 1)); | |
| 4225 grandchild1_->SetPosition(gfx::Point(1, 1)); | |
| 4226 grandchild2_->SetPosition(gfx::Point(1, 1)); | |
| 4227 | |
| 4228 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4229 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4230 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4231 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4232 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
| 4233 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4234 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
| 4235 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4236 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4237 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4238 | |
| 4239 grandchild1_->RemoveFromParent(); | |
| 4240 | |
| 4241 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4242 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4243 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4244 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4245 | |
| 4246 grandchild2_->RemoveFromParent(); | |
| 4247 | |
| 4248 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4249 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4250 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4251 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4252 | |
| 4253 child_->RemoveFromParent(); | |
| 4254 | |
| 4255 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4256 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4257 | |
| 4258 EndTest(); | |
| 4259 break; | |
| 4260 } | |
| 4261 } | |
| 4262 }; | |
| 4263 | |
| 4264 MULTI_THREAD_TEST_F( | |
| 4265 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild); | |
| 4266 | |
| 4267 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent | |
| 4268 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
| 4269 protected: | |
| 4270 void DidCommitAndDrawFrame() override { | |
| 4271 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
| 4272 switch (last_source_frame_number) { | |
| 4273 case 0: | |
| 4274 layer_tree_host()->SetRootLayer(root_); | |
| 4275 break; | |
| 4276 case 1: | |
| 4277 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4278 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4279 EXPECT_FALSE(child_->needs_push_properties()); | |
| 4280 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4281 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
| 4282 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4283 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
| 4284 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4285 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4286 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4287 | |
| 4288 grandchild1_->SetPosition(gfx::Point(1, 1)); | |
| 4289 grandchild2_->SetPosition(gfx::Point(1, 1)); | |
| 4290 child_->SetPosition(gfx::Point(1, 1)); | |
| 4291 | |
| 4292 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4293 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4294 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4295 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4296 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
| 4297 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
| 4298 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
| 4299 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
| 4300 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
| 4301 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
| 4302 | |
| 4303 grandchild1_->RemoveFromParent(); | |
| 4304 | |
| 4305 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4306 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4307 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4308 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
| 4309 | |
| 4310 grandchild2_->RemoveFromParent(); | |
| 4311 | |
| 4312 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4313 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
| 4314 EXPECT_TRUE(child_->needs_push_properties()); | |
| 4315 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
| 4316 | |
| 4317 child_->RemoveFromParent(); | |
| 4318 | |
| 4319 EXPECT_FALSE(root_->needs_push_properties()); | |
| 4320 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
| 4321 | |
| 4322 EndTest(); | |
| 4323 break; | |
| 4324 } | |
| 4325 } | |
| 4326 }; | |
| 4327 | |
| 4328 MULTI_THREAD_TEST_F( | |
| 4329 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent); | |
| 4330 | |
| 4331 // This test verifies that the tree activation callback is invoked correctly. | |
| 4332 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest { | |
| 4333 public: | |
| 4334 LayerTreeHostTestTreeActivationCallback() | |
| 4335 : num_commits_(0), callback_count_(0) {} | |
| 4336 | |
| 4337 void BeginTest() override { | |
| 4338 EXPECT_TRUE(HasImplThread()); | |
| 4339 PostSetNeedsCommitToMainThread(); | |
| 4340 } | |
| 4341 | |
| 4342 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 4343 LayerTreeHostImpl::FrameData* frame_data, | |
| 4344 DrawResult draw_result) override { | |
| 4345 ++num_commits_; | |
| 4346 switch (num_commits_) { | |
| 4347 case 1: | |
| 4348 EXPECT_EQ(0, callback_count_); | |
| 4349 callback_count_ = 0; | |
| 4350 SetCallback(true); | |
| 4351 PostSetNeedsCommitToMainThread(); | |
| 4352 break; | |
| 4353 case 2: | |
| 4354 EXPECT_EQ(1, callback_count_); | |
| 4355 callback_count_ = 0; | |
| 4356 SetCallback(false); | |
| 4357 PostSetNeedsCommitToMainThread(); | |
| 4358 break; | |
| 4359 case 3: | |
| 4360 EXPECT_EQ(0, callback_count_); | |
| 4361 callback_count_ = 0; | |
| 4362 EndTest(); | |
| 4363 break; | |
| 4364 default: | |
| 4365 ADD_FAILURE() << num_commits_; | |
| 4366 EndTest(); | |
| 4367 break; | |
| 4368 } | |
| 4369 return LayerTreeHostTest::PrepareToDrawOnThread( | |
| 4370 host_impl, frame_data, draw_result); | |
| 4371 } | |
| 4372 | |
| 4373 void AfterTest() override { EXPECT_EQ(3, num_commits_); } | |
| 4374 | |
| 4375 void SetCallback(bool enable) { | |
| 4376 output_surface()->SetTreeActivationCallback( | |
| 4377 enable | |
| 4378 ? base::Bind( | |
| 4379 &LayerTreeHostTestTreeActivationCallback::ActivationCallback, | |
| 4380 base::Unretained(this)) | |
| 4381 : base::Closure()); | |
| 4382 } | |
| 4383 | |
| 4384 void ActivationCallback() { ++callback_count_; } | |
| 4385 | |
| 4386 int num_commits_; | |
| 4387 int callback_count_; | |
| 4388 }; | |
| 4389 | |
| 4390 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) { | |
| 4391 RunTest(true, false, true); | |
| 4392 } | |
| 4393 | |
| 4394 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) { | |
| 4395 RunTest(true, true, true); | |
| 4396 } | |
| 4397 | |
| 4398 class LayerInvalidateCausesDraw : public LayerTreeHostTest { | |
| 4399 public: | |
| 4400 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {} | |
| 4401 | |
| 4402 void BeginTest() override { | |
| 4403 ASSERT_TRUE(!!invalidate_layer_.get()) | |
| 4404 << "Derived tests must set this in SetupTree"; | |
| 4405 | |
| 4406 // One initial commit. | |
| 4407 PostSetNeedsCommitToMainThread(); | |
| 4408 } | |
| 4409 | |
| 4410 void DidCommitAndDrawFrame() override { | |
| 4411 // After commit, invalidate the layer. This should cause a commit. | |
| 4412 if (layer_tree_host()->source_frame_number() == 1) | |
| 4413 invalidate_layer_->SetNeedsDisplay(); | |
| 4414 } | |
| 4415 | |
| 4416 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 4417 num_draws_++; | |
| 4418 if (impl->active_tree()->source_frame_number() == 1) | |
| 4419 EndTest(); | |
| 4420 } | |
| 4421 | |
| 4422 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 4423 num_commits_++; | |
| 4424 } | |
| 4425 | |
| 4426 void AfterTest() override { | |
| 4427 EXPECT_GE(2, num_commits_); | |
| 4428 EXPECT_GE(2, num_draws_); | |
| 4429 } | |
| 4430 | |
| 4431 protected: | |
| 4432 scoped_refptr<Layer> invalidate_layer_; | |
| 4433 | |
| 4434 private: | |
| 4435 int num_commits_; | |
| 4436 int num_draws_; | |
| 4437 }; | |
| 4438 | |
| 4439 // IOSurfaceLayer must support being invalidated and then passing that along | |
| 4440 // to the compositor thread, even though no resources are updated in | |
| 4441 // response to that invalidation. | |
| 4442 class LayerTreeHostTestIOSurfaceLayerInvalidate | |
| 4443 : public LayerInvalidateCausesDraw { | |
| 4444 public: | |
| 4445 void SetupTree() override { | |
| 4446 LayerTreeHostTest::SetupTree(); | |
| 4447 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create(); | |
| 4448 layer->SetBounds(gfx::Size(10, 10)); | |
| 4449 uint32_t fake_io_surface_id = 7; | |
| 4450 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds()); | |
| 4451 layer->SetIsDrawable(true); | |
| 4452 layer_tree_host()->root_layer()->AddChild(layer); | |
| 4453 | |
| 4454 invalidate_layer_ = layer; | |
| 4455 } | |
| 4456 }; | |
| 4457 | |
| 4458 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335 | |
| 4459 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( | |
| 4460 LayerTreeHostTestIOSurfaceLayerInvalidate); | |
| 4461 | |
| 4462 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { | |
| 4463 protected: | |
| 4464 void SetupTree() override { | |
| 4465 root_layer_ = Layer::Create(); | |
| 4466 root_layer_->CreateRenderSurface(); | |
| 4467 root_layer_->SetPosition(gfx::Point()); | |
| 4468 root_layer_->SetBounds(gfx::Size(10, 10)); | |
| 4469 | |
| 4470 parent_layer_ = SolidColorLayer::Create(); | |
| 4471 parent_layer_->SetPosition(gfx::Point()); | |
| 4472 parent_layer_->SetBounds(gfx::Size(10, 10)); | |
| 4473 parent_layer_->SetIsDrawable(true); | |
| 4474 root_layer_->AddChild(parent_layer_); | |
| 4475 | |
| 4476 child_layer_ = SolidColorLayer::Create(); | |
| 4477 child_layer_->SetPosition(gfx::Point()); | |
| 4478 child_layer_->SetBounds(gfx::Size(10, 10)); | |
| 4479 child_layer_->SetIsDrawable(true); | |
| 4480 parent_layer_->AddChild(child_layer_); | |
| 4481 | |
| 4482 layer_tree_host()->SetRootLayer(root_layer_); | |
| 4483 LayerTreeHostTest::SetupTree(); | |
| 4484 } | |
| 4485 | |
| 4486 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 4487 | |
| 4488 void DidCommitAndDrawFrame() override { | |
| 4489 switch (layer_tree_host()->source_frame_number()) { | |
| 4490 case 1: | |
| 4491 // The layer type used does not need to push properties every frame. | |
| 4492 EXPECT_FALSE(child_layer_->needs_push_properties()); | |
| 4493 | |
| 4494 // Change the bounds of the child layer, but make it skipped | |
| 4495 // by CalculateDrawProperties. | |
| 4496 parent_layer_->SetOpacity(0.f); | |
| 4497 child_layer_->SetBounds(gfx::Size(5, 5)); | |
| 4498 break; | |
| 4499 case 2: | |
| 4500 // The bounds of the child layer were pushed to the impl side. | |
| 4501 EXPECT_FALSE(child_layer_->needs_push_properties()); | |
| 4502 | |
| 4503 EndTest(); | |
| 4504 break; | |
| 4505 } | |
| 4506 } | |
| 4507 | |
| 4508 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 4509 LayerImpl* root = impl->active_tree()->root_layer(); | |
| 4510 LayerImpl* parent = root->children()[0]; | |
| 4511 LayerImpl* child = parent->children()[0]; | |
| 4512 | |
| 4513 switch (impl->active_tree()->source_frame_number()) { | |
| 4514 case 1: | |
| 4515 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString()); | |
| 4516 break; | |
| 4517 } | |
| 4518 } | |
| 4519 | |
| 4520 void AfterTest() override {} | |
| 4521 | |
| 4522 scoped_refptr<Layer> root_layer_; | |
| 4523 scoped_refptr<SolidColorLayer> parent_layer_; | |
| 4524 scoped_refptr<SolidColorLayer> child_layer_; | |
| 4525 }; | |
| 4526 | |
| 4527 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer); | |
| 4528 | |
| 4529 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { | |
| 4530 protected: | |
| 4531 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 4532 settings->impl_side_painting = true; | |
| 4533 } | |
| 4534 | |
| 4535 void SetupTree() override { | |
| 4536 root_layer_ = FakePictureLayer::Create(&client_); | |
| 4537 root_layer_->SetBounds(gfx::Size(10, 10)); | |
| 4538 | |
| 4539 layer_tree_host()->SetRootLayer(root_layer_); | |
| 4540 LayerTreeHostTest::SetupTree(); | |
| 4541 } | |
| 4542 | |
| 4543 void BeginTest() override { | |
| 4544 // The viewport is empty, but we still need to update layers on the main | |
| 4545 // thread. | |
| 4546 layer_tree_host()->SetViewportSize(gfx::Size(0, 0)); | |
| 4547 PostSetNeedsCommitToMainThread(); | |
| 4548 } | |
| 4549 | |
| 4550 void DidCommit() override { | |
| 4551 // The layer should be updated even though the viewport is empty, so we | |
| 4552 // are capable of drawing it on the impl tree. | |
| 4553 EXPECT_GT(root_layer_->update_count(), 0u); | |
| 4554 EndTest(); | |
| 4555 } | |
| 4556 | |
| 4557 void AfterTest() override {} | |
| 4558 | |
| 4559 FakeContentLayerClient client_; | |
| 4560 scoped_refptr<FakePictureLayer> root_layer_; | |
| 4561 }; | |
| 4562 | |
| 4563 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); | |
| 4564 | |
| 4565 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest { | |
| 4566 public: | |
| 4567 LayerTreeHostTestAbortEvictedTextures() | |
| 4568 : num_will_begin_main_frames_(0), num_impl_commits_(0) {} | |
| 4569 | |
| 4570 protected: | |
| 4571 void SetupTree() override { | |
| 4572 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create(); | |
| 4573 root_layer->SetBounds(gfx::Size(200, 200)); | |
| 4574 root_layer->SetIsDrawable(true); | |
| 4575 root_layer->CreateRenderSurface(); | |
| 4576 | |
| 4577 layer_tree_host()->SetRootLayer(root_layer); | |
| 4578 LayerTreeHostTest::SetupTree(); | |
| 4579 } | |
| 4580 | |
| 4581 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 4582 | |
| 4583 void WillBeginMainFrame() override { | |
| 4584 num_will_begin_main_frames_++; | |
| 4585 switch (num_will_begin_main_frames_) { | |
| 4586 case 2: | |
| 4587 // Send a redraw to the compositor thread. This will (wrongly) be | |
| 4588 // ignored unless aborting resets the texture state. | |
| 4589 layer_tree_host()->SetNeedsRedraw(); | |
| 4590 break; | |
| 4591 } | |
| 4592 } | |
| 4593 | |
| 4594 void BeginCommitOnThread(LayerTreeHostImpl* impl) override { | |
| 4595 num_impl_commits_++; | |
| 4596 } | |
| 4597 | |
| 4598 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 4599 switch (impl->SourceAnimationFrameNumber()) { | |
| 4600 case 1: | |
| 4601 // Prevent draws until commit. | |
| 4602 impl->active_tree()->SetContentsTexturesPurged(); | |
| 4603 EXPECT_FALSE(impl->CanDraw()); | |
| 4604 // Trigger an abortable commit. | |
| 4605 impl->SetNeedsCommit(); | |
| 4606 break; | |
| 4607 case 2: | |
| 4608 EndTest(); | |
| 4609 break; | |
| 4610 } | |
| 4611 } | |
| 4612 | |
| 4613 void AfterTest() override { | |
| 4614 // Ensure that the commit was truly aborted. | |
| 4615 EXPECT_EQ(2, num_will_begin_main_frames_); | |
| 4616 EXPECT_EQ(1, num_impl_commits_); | |
| 4617 } | |
| 4618 | |
| 4619 private: | |
| 4620 int num_will_begin_main_frames_; | |
| 4621 int num_impl_commits_; | |
| 4622 }; | |
| 4623 | |
| 4624 // Commits can only be aborted when using the thread proxy. | |
| 4625 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures); | |
| 4626 | |
| 4627 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest { | |
| 4628 protected: | |
| 4629 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 4630 settings->impl_side_painting = true; | |
| 4631 settings->use_zero_copy = false; | |
| 4632 settings->use_one_copy = false; | |
| 4633 } | |
| 4634 | |
| 4635 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
| 4636 scoped_refptr<TestContextProvider> context_provider = | |
| 4637 TestContextProvider::Create(); | |
| 4638 context_provider->SetMaxTransferBufferUsageBytes(512 * 512); | |
| 4639 if (delegating_renderer()) | |
| 4640 return FakeOutputSurface::CreateDelegating3d(context_provider); | |
| 4641 else | |
| 4642 return FakeOutputSurface::Create3d(context_provider); | |
| 4643 } | |
| 4644 | |
| 4645 void SetupTree() override { | |
| 4646 client_.set_fill_with_nonsolid_color(true); | |
| 4647 scoped_refptr<FakePictureLayer> root_layer = | |
| 4648 FakePictureLayer::Create(&client_); | |
| 4649 root_layer->SetBounds(gfx::Size(1024, 1024)); | |
| 4650 root_layer->SetIsDrawable(true); | |
| 4651 | |
| 4652 layer_tree_host()->SetRootLayer(root_layer); | |
| 4653 LayerTreeHostTest::SetupTree(); | |
| 4654 } | |
| 4655 | |
| 4656 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 4657 | |
| 4658 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 4659 TestWebGraphicsContext3D* context = TestContext(); | |
| 4660 | |
| 4661 // Expect that the transfer buffer memory used is equal to the | |
| 4662 // MaxTransferBufferUsageBytes value set in CreateOutputSurface. | |
| 4663 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes()); | |
| 4664 EndTest(); | |
| 4665 } | |
| 4666 | |
| 4667 void AfterTest() override {} | |
| 4668 | |
| 4669 private: | |
| 4670 FakeContentLayerClient client_; | |
| 4671 }; | |
| 4672 | |
| 4673 // Impl-side painting is a multi-threaded compositor feature. | |
| 4674 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes); | |
| 4675 | |
| 4676 // Test ensuring that memory limits are sent to the prioritized resource | |
| 4677 // manager. | |
| 4678 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest { | |
| 4679 public: | |
| 4680 LayerTreeHostTestMemoryLimits() : num_commits_(0) {} | |
| 4681 | |
| 4682 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 4683 | |
| 4684 void WillCommit() override { | |
| 4685 // Some commits are aborted, so increment number of attempted commits here. | |
| 4686 num_commits_++; | |
| 4687 } | |
| 4688 | |
| 4689 void DidCommit() override { | |
| 4690 switch (num_commits_) { | |
| 4691 case 1: | |
| 4692 // Verify default values. | |
| 4693 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(), | |
| 4694 layer_tree_host() | |
| 4695 ->contents_texture_manager() | |
| 4696 ->MaxMemoryLimitBytes()); | |
| 4697 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(), | |
| 4698 layer_tree_host() | |
| 4699 ->contents_texture_manager() | |
| 4700 ->ExternalPriorityCutoff()); | |
| 4701 PostSetNeedsCommitToMainThread(); | |
| 4702 break; | |
| 4703 case 2: | |
| 4704 // The values should remain the same until the commit after the policy | |
| 4705 // is changed. | |
| 4706 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(), | |
| 4707 layer_tree_host() | |
| 4708 ->contents_texture_manager() | |
| 4709 ->MaxMemoryLimitBytes()); | |
| 4710 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(), | |
| 4711 layer_tree_host() | |
| 4712 ->contents_texture_manager() | |
| 4713 ->ExternalPriorityCutoff()); | |
| 4714 break; | |
| 4715 case 3: | |
| 4716 // Verify values were correctly passed. | |
| 4717 EXPECT_EQ(16u * 1024u * 1024u, | |
| 4718 layer_tree_host() | |
| 4719 ->contents_texture_manager() | |
| 4720 ->MaxMemoryLimitBytes()); | |
| 4721 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(), | |
| 4722 layer_tree_host() | |
| 4723 ->contents_texture_manager() | |
| 4724 ->ExternalPriorityCutoff()); | |
| 4725 EndTest(); | |
| 4726 break; | |
| 4727 case 4: | |
| 4728 // Make sure no extra commits happen. | |
| 4729 NOTREACHED(); | |
| 4730 break; | |
| 4731 } | |
| 4732 } | |
| 4733 | |
| 4734 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 4735 switch (num_commits_) { | |
| 4736 case 1: | |
| 4737 break; | |
| 4738 case 2: | |
| 4739 // This will trigger a commit because the priority cutoff has changed. | |
| 4740 impl->SetMemoryPolicy(ManagedMemoryPolicy( | |
| 4741 16u * 1024u * 1024u, | |
| 4742 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, | |
| 4743 1000)); | |
| 4744 break; | |
| 4745 case 3: | |
| 4746 // This will not trigger a commit because the priority cutoff has not | |
| 4747 // changed, and there is already enough memory for all allocations. | |
| 4748 impl->SetMemoryPolicy(ManagedMemoryPolicy( | |
| 4749 32u * 1024u * 1024u, | |
| 4750 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, | |
| 4751 1000)); | |
| 4752 break; | |
| 4753 case 4: | |
| 4754 NOTREACHED(); | |
| 4755 break; | |
| 4756 } | |
| 4757 } | |
| 4758 | |
| 4759 void AfterTest() override {} | |
| 4760 | |
| 4761 private: | |
| 4762 int num_commits_; | |
| 4763 }; | |
| 4764 | |
| 4765 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits); | |
| 4766 | |
| 4767 } // namespace | |
| 4768 | |
| 4769 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface | |
| 4770 : public LayerTreeHostTest { | |
| 4771 protected: | |
| 4772 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface() | |
| 4773 : first_output_surface_memory_limit_(4321234), | |
| 4774 second_output_surface_memory_limit_(1234321) {} | |
| 4775 | |
| 4776 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
| 4777 if (!first_context_provider_.get()) { | |
| 4778 first_context_provider_ = TestContextProvider::Create(); | |
| 4779 } else { | |
| 4780 EXPECT_FALSE(second_context_provider_.get()); | |
| 4781 second_context_provider_ = TestContextProvider::Create(); | |
| 4782 } | |
| 4783 | |
| 4784 scoped_refptr<TestContextProvider> provider(second_context_provider_.get() | |
| 4785 ? second_context_provider_ | |
| 4786 : first_context_provider_); | |
| 4787 scoped_ptr<FakeOutputSurface> output_surface; | |
| 4788 if (delegating_renderer()) | |
| 4789 output_surface = FakeOutputSurface::CreateDelegating3d(provider); | |
| 4790 else | |
| 4791 output_surface = FakeOutputSurface::Create3d(provider); | |
| 4792 output_surface->SetMemoryPolicyToSetAtBind( | |
| 4793 make_scoped_ptr(new ManagedMemoryPolicy( | |
| 4794 second_context_provider_.get() ? second_output_surface_memory_limit_ | |
| 4795 : first_output_surface_memory_limit_, | |
| 4796 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, | |
| 4797 ManagedMemoryPolicy::kDefaultNumResourcesLimit))); | |
| 4798 return output_surface.Pass(); | |
| 4799 } | |
| 4800 | |
| 4801 void SetupTree() override { | |
| 4802 if (layer_tree_host()->settings().impl_side_painting) | |
| 4803 root_ = FakePictureLayer::Create(&client_); | |
| 4804 else | |
| 4805 root_ = FakeContentLayer::Create(&client_); | |
| 4806 root_->SetBounds(gfx::Size(20, 20)); | |
| 4807 layer_tree_host()->SetRootLayer(root_); | |
| 4808 LayerTreeHostTest::SetupTree(); | |
| 4809 } | |
| 4810 | |
| 4811 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 4812 | |
| 4813 void DidCommitAndDrawFrame() override { | |
| 4814 // Lost context sometimes takes two frames to recreate. The third frame | |
| 4815 // is sometimes aborted, so wait until the fourth frame to verify that | |
| 4816 // the memory has been set, and the fifth frame to end the test. | |
| 4817 if (layer_tree_host()->source_frame_number() < 5) { | |
| 4818 layer_tree_host()->SetNeedsCommit(); | |
| 4819 } else if (layer_tree_host()->source_frame_number() == 5) { | |
| 4820 EndTest(); | |
| 4821 } | |
| 4822 } | |
| 4823 | |
| 4824 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override { | |
| 4825 switch (impl->active_tree()->source_frame_number()) { | |
| 4826 case 1: | |
| 4827 EXPECT_EQ(first_output_surface_memory_limit_, | |
| 4828 impl->memory_allocation_limit_bytes()); | |
| 4829 // Lose the output surface. | |
| 4830 first_context_provider_->TestContext3d()->loseContextCHROMIUM( | |
| 4831 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); | |
| 4832 break; | |
| 4833 case 4: | |
| 4834 EXPECT_EQ(second_output_surface_memory_limit_, | |
| 4835 impl->memory_allocation_limit_bytes()); | |
| 4836 break; | |
| 4837 } | |
| 4838 } | |
| 4839 | |
| 4840 void AfterTest() override {} | |
| 4841 | |
| 4842 scoped_refptr<TestContextProvider> first_context_provider_; | |
| 4843 scoped_refptr<TestContextProvider> second_context_provider_; | |
| 4844 size_t first_output_surface_memory_limit_; | |
| 4845 size_t second_output_surface_memory_limit_; | |
| 4846 FakeContentLayerClient client_; | |
| 4847 scoped_refptr<Layer> root_; | |
| 4848 }; | |
| 4849 | |
| 4850 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 4851 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface); | |
| 4852 | |
| 4853 struct TestSwapPromiseResult { | |
| 4854 TestSwapPromiseResult() | |
| 4855 : did_swap_called(false), | |
| 4856 did_not_swap_called(false), | |
| 4857 dtor_called(false), | |
| 4858 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {} | |
| 4859 | |
| 4860 bool did_swap_called; | |
| 4861 bool did_not_swap_called; | |
| 4862 bool dtor_called; | |
| 4863 SwapPromise::DidNotSwapReason reason; | |
| 4864 base::Lock lock; | |
| 4865 }; | |
| 4866 | |
| 4867 class TestSwapPromise : public SwapPromise { | |
| 4868 public: | |
| 4869 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {} | |
| 4870 | |
| 4871 ~TestSwapPromise() override { | |
| 4872 base::AutoLock lock(result_->lock); | |
| 4873 result_->dtor_called = true; | |
| 4874 } | |
| 4875 | |
| 4876 void DidSwap(CompositorFrameMetadata* metadata) override { | |
| 4877 base::AutoLock lock(result_->lock); | |
| 4878 EXPECT_FALSE(result_->did_swap_called); | |
| 4879 EXPECT_FALSE(result_->did_not_swap_called); | |
| 4880 result_->did_swap_called = true; | |
| 4881 } | |
| 4882 | |
| 4883 void DidNotSwap(DidNotSwapReason reason) override { | |
| 4884 base::AutoLock lock(result_->lock); | |
| 4885 EXPECT_FALSE(result_->did_swap_called); | |
| 4886 EXPECT_FALSE(result_->did_not_swap_called); | |
| 4887 result_->did_not_swap_called = true; | |
| 4888 result_->reason = reason; | |
| 4889 } | |
| 4890 | |
| 4891 int64 TraceId() const override { return 0; } | |
| 4892 | |
| 4893 private: | |
| 4894 // Not owned. | |
| 4895 TestSwapPromiseResult* result_; | |
| 4896 }; | |
| 4897 | |
| 4898 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { | |
| 4899 protected: | |
| 4900 LayerTreeHostTestBreakSwapPromise() | |
| 4901 : commit_count_(0), commit_complete_count_(0) {} | |
| 4902 | |
| 4903 void WillBeginMainFrame() override { | |
| 4904 ASSERT_LE(commit_count_, 2); | |
| 4905 scoped_ptr<SwapPromise> swap_promise( | |
| 4906 new TestSwapPromise(&swap_promise_result_[commit_count_])); | |
| 4907 layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); | |
| 4908 } | |
| 4909 | |
| 4910 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 4911 | |
| 4912 void DidCommit() override { | |
| 4913 commit_count_++; | |
| 4914 if (commit_count_ == 2) { | |
| 4915 // This commit will finish. | |
| 4916 layer_tree_host()->SetNeedsCommit(); | |
| 4917 } | |
| 4918 } | |
| 4919 | |
| 4920 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 4921 commit_complete_count_++; | |
| 4922 if (commit_complete_count_ == 1) { | |
| 4923 // This commit will be aborted because no actual update. | |
| 4924 PostSetNeedsUpdateLayersToMainThread(); | |
| 4925 } else { | |
| 4926 EndTest(); | |
| 4927 } | |
| 4928 } | |
| 4929 | |
| 4930 void AfterTest() override { | |
| 4931 // 3 commits are scheduled. 2 completes. 1 is aborted. | |
| 4932 EXPECT_EQ(commit_count_, 3); | |
| 4933 EXPECT_EQ(commit_complete_count_, 2); | |
| 4934 | |
| 4935 { | |
| 4936 // The first commit completes and causes swap buffer which finishes | |
| 4937 // the promise. | |
| 4938 base::AutoLock lock(swap_promise_result_[0].lock); | |
| 4939 EXPECT_TRUE(swap_promise_result_[0].did_swap_called); | |
| 4940 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called); | |
| 4941 EXPECT_TRUE(swap_promise_result_[0].dtor_called); | |
| 4942 } | |
| 4943 | |
| 4944 { | |
| 4945 // The second commit is aborted since it contains no updates. | |
| 4946 base::AutoLock lock(swap_promise_result_[1].lock); | |
| 4947 EXPECT_FALSE(swap_promise_result_[1].did_swap_called); | |
| 4948 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); | |
| 4949 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason); | |
| 4950 EXPECT_TRUE(swap_promise_result_[1].dtor_called); | |
| 4951 } | |
| 4952 | |
| 4953 { | |
| 4954 // The last commit completes but it does not cause swap buffer because | |
| 4955 // there is no damage in the frame data. | |
| 4956 base::AutoLock lock(swap_promise_result_[2].lock); | |
| 4957 EXPECT_FALSE(swap_promise_result_[2].did_swap_called); | |
| 4958 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called); | |
| 4959 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason); | |
| 4960 EXPECT_TRUE(swap_promise_result_[2].dtor_called); | |
| 4961 } | |
| 4962 } | |
| 4963 | |
| 4964 int commit_count_; | |
| 4965 int commit_complete_count_; | |
| 4966 TestSwapPromiseResult swap_promise_result_[3]; | |
| 4967 }; | |
| 4968 | |
| 4969 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); | |
| 4970 | |
| 4971 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest { | |
| 4972 public: | |
| 4973 LayerTreeHostTestKeepSwapPromise() {} | |
| 4974 | |
| 4975 void BeginTest() override { | |
| 4976 layer_ = SolidColorLayer::Create(); | |
| 4977 layer_->SetIsDrawable(true); | |
| 4978 layer_->SetBounds(gfx::Size(10, 10)); | |
| 4979 layer_tree_host()->SetRootLayer(layer_); | |
| 4980 gfx::Size bounds(100, 100); | |
| 4981 layer_tree_host()->SetViewportSize(bounds); | |
| 4982 PostSetNeedsCommitToMainThread(); | |
| 4983 } | |
| 4984 | |
| 4985 void DidCommit() override { | |
| 4986 MainThreadTaskRunner()->PostTask( | |
| 4987 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame, | |
| 4988 base::Unretained(this))); | |
| 4989 } | |
| 4990 | |
| 4991 void ChangeFrame() { | |
| 4992 switch (layer_tree_host()->source_frame_number()) { | |
| 4993 case 1: | |
| 4994 layer_->SetBounds(gfx::Size(10, 11)); | |
| 4995 layer_tree_host()->QueueSwapPromise( | |
| 4996 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_))); | |
| 4997 break; | |
| 4998 case 2: | |
| 4999 break; | |
| 5000 default: | |
| 5001 NOTREACHED(); | |
| 5002 break; | |
| 5003 } | |
| 5004 } | |
| 5005 | |
| 5006 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 5007 EXPECT_TRUE(result); | |
| 5008 if (host_impl->active_tree()->source_frame_number() >= 1) { | |
| 5009 // The commit changes layers so it should cause a swap. | |
| 5010 base::AutoLock lock(swap_promise_result_.lock); | |
| 5011 EXPECT_TRUE(swap_promise_result_.did_swap_called); | |
| 5012 EXPECT_FALSE(swap_promise_result_.did_not_swap_called); | |
| 5013 EXPECT_TRUE(swap_promise_result_.dtor_called); | |
| 5014 EndTest(); | |
| 5015 } | |
| 5016 } | |
| 5017 | |
| 5018 void AfterTest() override {} | |
| 5019 | |
| 5020 private: | |
| 5021 scoped_refptr<Layer> layer_; | |
| 5022 TestSwapPromiseResult swap_promise_result_; | |
| 5023 }; | |
| 5024 | |
| 5025 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise); | |
| 5026 | |
| 5027 class LayerTreeHostTestBreakSwapPromiseForVisibility | |
| 5028 : public LayerTreeHostTest { | |
| 5029 protected: | |
| 5030 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 5031 | |
| 5032 void SetVisibleFalseAndQueueSwapPromise() { | |
| 5033 layer_tree_host()->SetVisible(false); | |
| 5034 scoped_ptr<SwapPromise> swap_promise( | |
| 5035 new TestSwapPromise(&swap_promise_result_)); | |
| 5036 layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); | |
| 5037 } | |
| 5038 | |
| 5039 void ScheduledActionWillSendBeginMainFrame() override { | |
| 5040 MainThreadTaskRunner()->PostTask( | |
| 5041 FROM_HERE, | |
| 5042 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility | |
| 5043 ::SetVisibleFalseAndQueueSwapPromise, | |
| 5044 base::Unretained(this))); | |
| 5045 } | |
| 5046 | |
| 5047 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, | |
| 5048 CommitEarlyOutReason reason) override { | |
| 5049 EndTest(); | |
| 5050 } | |
| 5051 | |
| 5052 void AfterTest() override { | |
| 5053 { | |
| 5054 base::AutoLock lock(swap_promise_result_.lock); | |
| 5055 EXPECT_FALSE(swap_promise_result_.did_swap_called); | |
| 5056 EXPECT_TRUE(swap_promise_result_.did_not_swap_called); | |
| 5057 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); | |
| 5058 EXPECT_TRUE(swap_promise_result_.dtor_called); | |
| 5059 } | |
| 5060 } | |
| 5061 | |
| 5062 TestSwapPromiseResult swap_promise_result_; | |
| 5063 }; | |
| 5064 | |
| 5065 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility); | |
| 5066 | |
| 5067 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest { | |
| 5068 protected: | |
| 5069 LayerTreeHostTestBreakSwapPromiseForContext() | |
| 5070 : output_surface_lost_triggered_(false) { | |
| 5071 } | |
| 5072 | |
| 5073 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 5074 | |
| 5075 void LoseOutputSurfaceAndQueueSwapPromise() { | |
| 5076 layer_tree_host()->DidLoseOutputSurface(); | |
| 5077 scoped_ptr<SwapPromise> swap_promise( | |
| 5078 new TestSwapPromise(&swap_promise_result_)); | |
| 5079 layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); | |
| 5080 } | |
| 5081 | |
| 5082 void ScheduledActionWillSendBeginMainFrame() override { | |
| 5083 if (output_surface_lost_triggered_) | |
| 5084 return; | |
| 5085 output_surface_lost_triggered_ = true; | |
| 5086 | |
| 5087 MainThreadTaskRunner()->PostTask( | |
| 5088 FROM_HERE, | |
| 5089 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext | |
| 5090 ::LoseOutputSurfaceAndQueueSwapPromise, | |
| 5091 base::Unretained(this))); | |
| 5092 } | |
| 5093 | |
| 5094 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, | |
| 5095 CommitEarlyOutReason reason) override { | |
| 5096 // This is needed so that the impl-thread state matches main-thread state. | |
| 5097 host_impl->DidLoseOutputSurface(); | |
| 5098 EndTest(); | |
| 5099 } | |
| 5100 | |
| 5101 void AfterTest() override { | |
| 5102 { | |
| 5103 base::AutoLock lock(swap_promise_result_.lock); | |
| 5104 EXPECT_FALSE(swap_promise_result_.did_swap_called); | |
| 5105 EXPECT_TRUE(swap_promise_result_.did_not_swap_called); | |
| 5106 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); | |
| 5107 EXPECT_TRUE(swap_promise_result_.dtor_called); | |
| 5108 } | |
| 5109 } | |
| 5110 | |
| 5111 bool output_surface_lost_triggered_; | |
| 5112 TestSwapPromiseResult swap_promise_result_; | |
| 5113 }; | |
| 5114 | |
| 5115 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 5116 LayerTreeHostTestBreakSwapPromiseForContext); | |
| 5117 | |
| 5118 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { | |
| 5119 public: | |
| 5120 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, | |
| 5121 LayerTreeHostImpl* layer_tree_host_impl, | |
| 5122 int* set_needs_commit_count, | |
| 5123 int* set_needs_redraw_count) | |
| 5124 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl), | |
| 5125 set_needs_commit_count_(set_needs_commit_count) {} | |
| 5126 | |
| 5127 ~SimpleSwapPromiseMonitor() override {} | |
| 5128 | |
| 5129 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; } | |
| 5130 | |
| 5131 void OnSetNeedsRedrawOnImpl() override { | |
| 5132 ADD_FAILURE() << "Should not get called on main thread."; | |
| 5133 } | |
| 5134 | |
| 5135 void OnForwardScrollUpdateToMainThreadOnImpl() override { | |
| 5136 ADD_FAILURE() << "Should not get called on main thread."; | |
| 5137 } | |
| 5138 | |
| 5139 private: | |
| 5140 int* set_needs_commit_count_; | |
| 5141 }; | |
| 5142 | |
| 5143 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { | |
| 5144 public: | |
| 5145 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 5146 | |
| 5147 void WillBeginMainFrame() override { | |
| 5148 if (TestEnded()) | |
| 5149 return; | |
| 5150 | |
| 5151 int set_needs_commit_count = 0; | |
| 5152 int set_needs_redraw_count = 0; | |
| 5153 | |
| 5154 { | |
| 5155 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( | |
| 5156 new SimpleSwapPromiseMonitor(layer_tree_host(), | |
| 5157 NULL, | |
| 5158 &set_needs_commit_count, | |
| 5159 &set_needs_redraw_count)); | |
| 5160 layer_tree_host()->SetNeedsCommit(); | |
| 5161 EXPECT_EQ(1, set_needs_commit_count); | |
| 5162 EXPECT_EQ(0, set_needs_redraw_count); | |
| 5163 } | |
| 5164 | |
| 5165 // Now the monitor is destroyed, SetNeedsCommit() is no longer being | |
| 5166 // monitored. | |
| 5167 layer_tree_host()->SetNeedsCommit(); | |
| 5168 EXPECT_EQ(1, set_needs_commit_count); | |
| 5169 EXPECT_EQ(0, set_needs_redraw_count); | |
| 5170 | |
| 5171 { | |
| 5172 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( | |
| 5173 new SimpleSwapPromiseMonitor(layer_tree_host(), | |
| 5174 NULL, | |
| 5175 &set_needs_commit_count, | |
| 5176 &set_needs_redraw_count)); | |
| 5177 layer_tree_host()->SetNeedsUpdateLayers(); | |
| 5178 EXPECT_EQ(2, set_needs_commit_count); | |
| 5179 EXPECT_EQ(0, set_needs_redraw_count); | |
| 5180 } | |
| 5181 | |
| 5182 { | |
| 5183 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( | |
| 5184 new SimpleSwapPromiseMonitor(layer_tree_host(), | |
| 5185 NULL, | |
| 5186 &set_needs_commit_count, | |
| 5187 &set_needs_redraw_count)); | |
| 5188 layer_tree_host()->SetNeedsAnimate(); | |
| 5189 EXPECT_EQ(3, set_needs_commit_count); | |
| 5190 EXPECT_EQ(0, set_needs_redraw_count); | |
| 5191 } | |
| 5192 | |
| 5193 EndTest(); | |
| 5194 } | |
| 5195 | |
| 5196 void AfterTest() override {} | |
| 5197 }; | |
| 5198 | |
| 5199 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); | |
| 5200 | |
| 5201 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources | |
| 5202 : public LayerTreeHostTest { | |
| 5203 protected: | |
| 5204 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5205 settings->impl_side_painting = true; | |
| 5206 } | |
| 5207 | |
| 5208 void SetupTree() override { | |
| 5209 LayerTreeHostTest::SetupTree(); | |
| 5210 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); | |
| 5211 } | |
| 5212 | |
| 5213 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 5214 | |
| 5215 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5216 host_impl->EvictAllUIResources(); | |
| 5217 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY | |
| 5218 // mode. Active tree should require high-res to draw after entering this | |
| 5219 // mode to ensure that high-res tiles are also required for a pending tree | |
| 5220 // to be activated. | |
| 5221 EXPECT_TRUE(host_impl->RequiresHighResToDraw()); | |
| 5222 } | |
| 5223 | |
| 5224 void DidCommit() override { | |
| 5225 int frame = layer_tree_host()->source_frame_number(); | |
| 5226 switch (frame) { | |
| 5227 case 1: | |
| 5228 PostSetNeedsCommitToMainThread(); | |
| 5229 break; | |
| 5230 case 2: | |
| 5231 ui_resource_ = nullptr; | |
| 5232 EndTest(); | |
| 5233 break; | |
| 5234 } | |
| 5235 } | |
| 5236 | |
| 5237 void AfterTest() override {} | |
| 5238 | |
| 5239 FakeContentLayerClient client_; | |
| 5240 scoped_ptr<FakeScopedUIResource> ui_resource_; | |
| 5241 }; | |
| 5242 | |
| 5243 // This test is flaky, see http://crbug.com/386199 | |
| 5244 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources) | |
| 5245 | |
| 5246 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { | |
| 5247 protected: | |
| 5248 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5249 settings->impl_side_painting = true; | |
| 5250 | |
| 5251 EXPECT_FALSE(settings->gpu_rasterization_enabled); | |
| 5252 EXPECT_FALSE(settings->gpu_rasterization_forced); | |
| 5253 } | |
| 5254 | |
| 5255 void SetupTree() override { | |
| 5256 LayerTreeHostTest::SetupTree(); | |
| 5257 | |
| 5258 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); | |
| 5259 layer->SetBounds(gfx::Size(10, 10)); | |
| 5260 layer->SetIsDrawable(true); | |
| 5261 layer_tree_host()->root_layer()->AddChild(layer); | |
| 5262 } | |
| 5263 | |
| 5264 void BeginTest() override { | |
| 5265 Layer* root = layer_tree_host()->root_layer(); | |
| 5266 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); | |
| 5267 RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); | |
| 5268 | |
| 5269 // Verify default values. | |
| 5270 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); | |
| 5271 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); | |
| 5272 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); | |
| 5273 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
| 5274 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); | |
| 5275 | |
| 5276 // Setting gpu rasterization trigger does not enable gpu rasterization. | |
| 5277 layer_tree_host()->SetHasGpuRasterizationTrigger(true); | |
| 5278 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
| 5279 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); | |
| 5280 | |
| 5281 PostSetNeedsCommitToMainThread(); | |
| 5282 } | |
| 5283 | |
| 5284 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5285 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); | |
| 5286 EXPECT_FALSE(host_impl->use_gpu_rasterization()); | |
| 5287 } | |
| 5288 | |
| 5289 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5290 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); | |
| 5291 EXPECT_FALSE(host_impl->use_gpu_rasterization()); | |
| 5292 EndTest(); | |
| 5293 } | |
| 5294 | |
| 5295 void AfterTest() override {} | |
| 5296 | |
| 5297 FakeContentLayerClient layer_client_; | |
| 5298 }; | |
| 5299 | |
| 5300 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault); | |
| 5301 | |
| 5302 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { | |
| 5303 protected: | |
| 5304 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5305 settings->impl_side_painting = true; | |
| 5306 | |
| 5307 EXPECT_FALSE(settings->gpu_rasterization_enabled); | |
| 5308 settings->gpu_rasterization_enabled = true; | |
| 5309 } | |
| 5310 | |
| 5311 void SetupTree() override { | |
| 5312 LayerTreeHostTest::SetupTree(); | |
| 5313 | |
| 5314 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); | |
| 5315 layer->SetBounds(gfx::Size(10, 10)); | |
| 5316 layer->SetIsDrawable(true); | |
| 5317 layer_tree_host()->root_layer()->AddChild(layer); | |
| 5318 } | |
| 5319 | |
| 5320 void BeginTest() override { | |
| 5321 Layer* root = layer_tree_host()->root_layer(); | |
| 5322 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); | |
| 5323 RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); | |
| 5324 | |
| 5325 // Verify default values. | |
| 5326 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); | |
| 5327 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); | |
| 5328 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); | |
| 5329 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
| 5330 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); | |
| 5331 | |
| 5332 // Gpu rasterization trigger is relevant. | |
| 5333 layer_tree_host()->SetHasGpuRasterizationTrigger(true); | |
| 5334 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
| 5335 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); | |
| 5336 | |
| 5337 // Content-based veto is relevant as well. | |
| 5338 recording_source->SetUnsuitableForGpuRasterizationForTesting(); | |
| 5339 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization()); | |
| 5340 EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); | |
| 5341 // Veto will take effect when layers are updated. | |
| 5342 // The results will be verified after commit is completed below. | |
| 5343 // Since we are manually marking picture pile as unsuitable, | |
| 5344 // make sure that the layer gets a chance to update. | |
| 5345 layer->SetNeedsDisplay(); | |
| 5346 PostSetNeedsCommitToMainThread(); | |
| 5347 } | |
| 5348 | |
| 5349 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5350 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); | |
| 5351 EXPECT_FALSE(host_impl->use_gpu_rasterization()); | |
| 5352 } | |
| 5353 | |
| 5354 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5355 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); | |
| 5356 EXPECT_FALSE(host_impl->use_gpu_rasterization()); | |
| 5357 EndTest(); | |
| 5358 } | |
| 5359 | |
| 5360 void AfterTest() override {} | |
| 5361 | |
| 5362 FakeContentLayerClient layer_client_; | |
| 5363 }; | |
| 5364 | |
| 5365 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); | |
| 5366 | |
| 5367 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { | |
| 5368 protected: | |
| 5369 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5370 ASSERT_TRUE(settings->impl_side_painting); | |
| 5371 | |
| 5372 EXPECT_FALSE(settings->gpu_rasterization_forced); | |
| 5373 settings->gpu_rasterization_forced = true; | |
| 5374 } | |
| 5375 | |
| 5376 void SetupTree() override { | |
| 5377 LayerTreeHostTest::SetupTree(); | |
| 5378 | |
| 5379 scoped_refptr<FakePictureLayer> layer = | |
| 5380 FakePictureLayer::Create(&layer_client_); | |
| 5381 layer->SetBounds(gfx::Size(10, 10)); | |
| 5382 layer->SetIsDrawable(true); | |
| 5383 layer_tree_host()->root_layer()->AddChild(layer); | |
| 5384 } | |
| 5385 | |
| 5386 void BeginTest() override { | |
| 5387 Layer* root = layer_tree_host()->root_layer(); | |
| 5388 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); | |
| 5389 RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); | |
| 5390 | |
| 5391 // Verify default values. | |
| 5392 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); | |
| 5393 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); | |
| 5394 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); | |
| 5395 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
| 5396 | |
| 5397 // With gpu rasterization forced, gpu rasterization trigger is irrelevant. | |
| 5398 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); | |
| 5399 layer_tree_host()->SetHasGpuRasterizationTrigger(true); | |
| 5400 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
| 5401 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); | |
| 5402 | |
| 5403 // Content-based veto is irrelevant as well. | |
| 5404 recording_source->SetUnsuitableForGpuRasterizationForTesting(); | |
| 5405 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization()); | |
| 5406 EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); | |
| 5407 // Veto will take effect when layers are updated. | |
| 5408 // The results will be verified after commit is completed below. | |
| 5409 // Since we are manually marking picture pile as unsuitable, | |
| 5410 // make sure that the layer gets a chance to update. | |
| 5411 layer->SetNeedsDisplay(); | |
| 5412 PostSetNeedsCommitToMainThread(); | |
| 5413 } | |
| 5414 | |
| 5415 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5416 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization()); | |
| 5417 EXPECT_TRUE(host_impl->use_gpu_rasterization()); | |
| 5418 } | |
| 5419 | |
| 5420 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5421 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); | |
| 5422 EXPECT_TRUE(host_impl->use_gpu_rasterization()); | |
| 5423 EndTest(); | |
| 5424 } | |
| 5425 | |
| 5426 void AfterTest() override {} | |
| 5427 | |
| 5428 FakeContentLayerClient layer_client_; | |
| 5429 }; | |
| 5430 | |
| 5431 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced); | |
| 5432 | |
| 5433 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest { | |
| 5434 public: | |
| 5435 LayerTreeHostTestContinuousPainting() | |
| 5436 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {} | |
| 5437 | |
| 5438 protected: | |
| 5439 enum { kExpectedNumCommits = 10 }; | |
| 5440 | |
| 5441 void SetupTree() override { | |
| 5442 scoped_refptr<Layer> root_layer = Layer::Create(); | |
| 5443 root_layer->SetBounds(bounds_); | |
| 5444 root_layer->CreateRenderSurface(); | |
| 5445 | |
| 5446 if (layer_tree_host()->settings().impl_side_painting) { | |
| 5447 picture_layer_ = FakePictureLayer::Create(&client_); | |
| 5448 child_layer_ = picture_layer_.get(); | |
| 5449 } else { | |
| 5450 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_); | |
| 5451 child_layer_ = content_layer_.get(); | |
| 5452 } | |
| 5453 child_layer_->SetBounds(bounds_); | |
| 5454 child_layer_->SetIsDrawable(true); | |
| 5455 root_layer->AddChild(child_layer_); | |
| 5456 | |
| 5457 layer_tree_host()->SetRootLayer(root_layer); | |
| 5458 layer_tree_host()->SetViewportSize(bounds_); | |
| 5459 LayerTreeHostTest::SetupTree(); | |
| 5460 } | |
| 5461 | |
| 5462 void BeginTest() override { | |
| 5463 MainThreadTaskRunner()->PostTask( | |
| 5464 FROM_HERE, | |
| 5465 base::Bind( | |
| 5466 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting, | |
| 5467 base::Unretained(this))); | |
| 5468 // Wait 50x longer than expected. | |
| 5469 double milliseconds_per_frame = | |
| 5470 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate; | |
| 5471 MainThreadTaskRunner()->PostDelayedTask( | |
| 5472 FROM_HERE, | |
| 5473 base::Bind( | |
| 5474 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting, | |
| 5475 base::Unretained(this)), | |
| 5476 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits * | |
| 5477 milliseconds_per_frame)); | |
| 5478 } | |
| 5479 | |
| 5480 void BeginMainFrame(const BeginFrameArgs& args) override { | |
| 5481 child_layer_->SetNeedsDisplay(); | |
| 5482 } | |
| 5483 | |
| 5484 void AfterTest() override { | |
| 5485 EXPECT_LE(kExpectedNumCommits, num_commits_); | |
| 5486 EXPECT_LE(kExpectedNumCommits, num_draws_); | |
| 5487 int update_count = content_layer_.get() | |
| 5488 ? content_layer_->PaintContentsCount() | |
| 5489 : picture_layer_->update_count(); | |
| 5490 EXPECT_LE(kExpectedNumCommits, update_count); | |
| 5491 } | |
| 5492 | |
| 5493 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
| 5494 if (++num_draws_ == kExpectedNumCommits) | |
| 5495 EndTest(); | |
| 5496 } | |
| 5497 | |
| 5498 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
| 5499 ++num_commits_; | |
| 5500 } | |
| 5501 | |
| 5502 private: | |
| 5503 void EnableContinuousPainting() { | |
| 5504 LayerTreeDebugState debug_state = layer_tree_host()->debug_state(); | |
| 5505 debug_state.continuous_painting = true; | |
| 5506 layer_tree_host()->SetDebugState(debug_state); | |
| 5507 } | |
| 5508 | |
| 5509 void DisableContinuousPainting() { | |
| 5510 LayerTreeDebugState debug_state = layer_tree_host()->debug_state(); | |
| 5511 debug_state.continuous_painting = false; | |
| 5512 layer_tree_host()->SetDebugState(debug_state); | |
| 5513 EndTest(); | |
| 5514 } | |
| 5515 | |
| 5516 int num_commits_; | |
| 5517 int num_draws_; | |
| 5518 const gfx::Size bounds_; | |
| 5519 FakeContentLayerClient client_; | |
| 5520 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_; | |
| 5521 scoped_refptr<FakePictureLayer> picture_layer_; | |
| 5522 Layer* child_layer_; | |
| 5523 }; | |
| 5524 | |
| 5525 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting); | |
| 5526 | |
| 5527 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest { | |
| 5528 public: | |
| 5529 LayerTreeHostTestSendBeginFramesToChildren() | |
| 5530 : begin_frame_sent_to_children_(false) { | |
| 5531 } | |
| 5532 | |
| 5533 void BeginTest() override { | |
| 5534 // Kick off the test with a commit. | |
| 5535 PostSetNeedsCommitToMainThread(); | |
| 5536 } | |
| 5537 | |
| 5538 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | |
| 5539 begin_frame_sent_to_children_ = true; | |
| 5540 EndTest(); | |
| 5541 } | |
| 5542 | |
| 5543 void DidBeginMainFrame() override { | |
| 5544 // Children requested BeginFrames. | |
| 5545 layer_tree_host()->SetChildrenNeedBeginFrames(true); | |
| 5546 } | |
| 5547 | |
| 5548 void AfterTest() override { | |
| 5549 // Ensure that BeginFrame message is sent to children during parent | |
| 5550 // scheduler handles its BeginFrame. | |
| 5551 EXPECT_TRUE(begin_frame_sent_to_children_); | |
| 5552 } | |
| 5553 | |
| 5554 private: | |
| 5555 bool begin_frame_sent_to_children_; | |
| 5556 }; | |
| 5557 | |
| 5558 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren); | |
| 5559 | |
| 5560 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS | |
| 5561 : public LayerTreeHostTest { | |
| 5562 public: | |
| 5563 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS() | |
| 5564 : begin_frame_sent_to_children_(false) { | |
| 5565 } | |
| 5566 | |
| 5567 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5568 settings->use_external_begin_frame_source = true; | |
| 5569 } | |
| 5570 | |
| 5571 void BeginTest() override { | |
| 5572 // Kick off the test with a commit. | |
| 5573 PostSetNeedsCommitToMainThread(); | |
| 5574 } | |
| 5575 | |
| 5576 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | |
| 5577 begin_frame_sent_to_children_ = true; | |
| 5578 EndTest(); | |
| 5579 } | |
| 5580 | |
| 5581 void DidBeginMainFrame() override { | |
| 5582 // Children requested BeginFrames. | |
| 5583 layer_tree_host()->SetChildrenNeedBeginFrames(true); | |
| 5584 } | |
| 5585 | |
| 5586 void AfterTest() override { | |
| 5587 // Ensure that BeginFrame message is sent to children during parent | |
| 5588 // scheduler handles its BeginFrame. | |
| 5589 EXPECT_TRUE(begin_frame_sent_to_children_); | |
| 5590 } | |
| 5591 | |
| 5592 private: | |
| 5593 bool begin_frame_sent_to_children_; | |
| 5594 }; | |
| 5595 | |
| 5596 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS); | |
| 5597 | |
| 5598 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest { | |
| 5599 public: | |
| 5600 LayerTreeHostTestActivateOnInvisible() | |
| 5601 : activation_count_(0), visible_(true) {} | |
| 5602 | |
| 5603 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5604 settings->impl_side_painting = true; | |
| 5605 } | |
| 5606 | |
| 5607 void BeginTest() override { | |
| 5608 // Kick off the test with a commit. | |
| 5609 PostSetNeedsCommitToMainThread(); | |
| 5610 } | |
| 5611 | |
| 5612 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5613 // Make sure we don't activate using the notify signal from tile manager. | |
| 5614 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
| 5615 } | |
| 5616 | |
| 5617 void DidCommit() override { layer_tree_host()->SetVisible(false); } | |
| 5618 | |
| 5619 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, | |
| 5620 bool visible) override { | |
| 5621 visible_ = visible; | |
| 5622 | |
| 5623 // Once invisible, we can go visible again. | |
| 5624 if (!visible) { | |
| 5625 PostSetVisibleToMainThread(true); | |
| 5626 } else { | |
| 5627 EXPECT_TRUE(host_impl->RequiresHighResToDraw()); | |
| 5628 EndTest(); | |
| 5629 } | |
| 5630 } | |
| 5631 | |
| 5632 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 5633 ++activation_count_; | |
| 5634 EXPECT_FALSE(visible_); | |
| 5635 } | |
| 5636 | |
| 5637 void AfterTest() override { | |
| 5638 // Ensure we activated even though the signal was blocked. | |
| 5639 EXPECT_EQ(1, activation_count_); | |
| 5640 EXPECT_TRUE(visible_); | |
| 5641 } | |
| 5642 | |
| 5643 private: | |
| 5644 int activation_count_; | |
| 5645 bool visible_; | |
| 5646 | |
| 5647 FakeContentLayerClient client_; | |
| 5648 scoped_refptr<FakePictureLayer> picture_layer_; | |
| 5649 }; | |
| 5650 | |
| 5651 // TODO(vmpstr): Enable with single thread impl-side painting. | |
| 5652 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible); | |
| 5653 | |
| 5654 // Do a synchronous composite and assert that the swap promise succeeds. | |
| 5655 class LayerTreeHostTestSynchronousCompositeSwapPromise | |
| 5656 : public LayerTreeHostTest { | |
| 5657 public: | |
| 5658 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {} | |
| 5659 | |
| 5660 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5661 settings->single_thread_proxy_scheduler = false; | |
| 5662 } | |
| 5663 | |
| 5664 void BeginTest() override { | |
| 5665 // Successful composite. | |
| 5666 scoped_ptr<SwapPromise> swap_promise0( | |
| 5667 new TestSwapPromise(&swap_promise_result_[0])); | |
| 5668 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass()); | |
| 5669 layer_tree_host()->Composite(gfx::FrameTime::Now()); | |
| 5670 | |
| 5671 // Fail to swap (no damage). | |
| 5672 scoped_ptr<SwapPromise> swap_promise1( | |
| 5673 new TestSwapPromise(&swap_promise_result_[1])); | |
| 5674 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass()); | |
| 5675 layer_tree_host()->SetNeedsCommit(); | |
| 5676 layer_tree_host()->Composite(gfx::FrameTime::Now()); | |
| 5677 | |
| 5678 // Fail to draw (not visible). | |
| 5679 scoped_ptr<SwapPromise> swap_promise2( | |
| 5680 new TestSwapPromise(&swap_promise_result_[2])); | |
| 5681 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass()); | |
| 5682 layer_tree_host()->SetNeedsDisplayOnAllLayers(); | |
| 5683 layer_tree_host()->SetVisible(false); | |
| 5684 layer_tree_host()->Composite(gfx::FrameTime::Now()); | |
| 5685 | |
| 5686 EndTest(); | |
| 5687 } | |
| 5688 | |
| 5689 void DidCommit() override { | |
| 5690 commit_count_++; | |
| 5691 ASSERT_LE(commit_count_, 3); | |
| 5692 } | |
| 5693 | |
| 5694 void AfterTest() override { | |
| 5695 EXPECT_EQ(3, commit_count_); | |
| 5696 | |
| 5697 // Initial swap promise should have succeded. | |
| 5698 { | |
| 5699 base::AutoLock lock(swap_promise_result_[0].lock); | |
| 5700 EXPECT_TRUE(swap_promise_result_[0].did_swap_called); | |
| 5701 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called); | |
| 5702 EXPECT_TRUE(swap_promise_result_[0].dtor_called); | |
| 5703 } | |
| 5704 | |
| 5705 // Second swap promise fails to swap. | |
| 5706 { | |
| 5707 base::AutoLock lock(swap_promise_result_[1].lock); | |
| 5708 EXPECT_FALSE(swap_promise_result_[1].did_swap_called); | |
| 5709 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); | |
| 5710 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); | |
| 5711 EXPECT_TRUE(swap_promise_result_[1].dtor_called); | |
| 5712 } | |
| 5713 | |
| 5714 // Third swap promises also fails to swap (and draw). | |
| 5715 { | |
| 5716 base::AutoLock lock(swap_promise_result_[2].lock); | |
| 5717 EXPECT_FALSE(swap_promise_result_[2].did_swap_called); | |
| 5718 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called); | |
| 5719 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason); | |
| 5720 EXPECT_TRUE(swap_promise_result_[2].dtor_called); | |
| 5721 } | |
| 5722 } | |
| 5723 | |
| 5724 int commit_count_; | |
| 5725 TestSwapPromiseResult swap_promise_result_[3]; | |
| 5726 }; | |
| 5727 | |
| 5728 // Impl-side painting is not supported for synchronous compositing. | |
| 5729 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise); | |
| 5730 | |
| 5731 // Make sure page scale and top control deltas are applied to the client even | |
| 5732 // when the LayerTreeHost doesn't have a root layer. | |
| 5733 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer | |
| 5734 : public LayerTreeHostTest { | |
| 5735 public: | |
| 5736 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer() | |
| 5737 : deltas_sent_to_client_(false) {} | |
| 5738 | |
| 5739 void BeginTest() override { | |
| 5740 layer_tree_host()->SetRootLayer(nullptr); | |
| 5741 info_.page_scale_delta = 3.14f; | |
| 5742 info_.top_controls_delta = 2.73f; | |
| 5743 | |
| 5744 PostSetNeedsCommitToMainThread(); | |
| 5745 } | |
| 5746 | |
| 5747 void BeginMainFrame(const BeginFrameArgs& args) override { | |
| 5748 EXPECT_EQ(nullptr, layer_tree_host()->root_layer()); | |
| 5749 | |
| 5750 layer_tree_host()->ApplyScrollAndScale(&info_); | |
| 5751 EndTest(); | |
| 5752 } | |
| 5753 | |
| 5754 void ApplyViewportDeltas(const gfx::Vector2dF& inner, | |
| 5755 const gfx::Vector2dF& outer, | |
| 5756 const gfx::Vector2dF& elastic_overscroll_delta, | |
| 5757 float scale_delta, | |
| 5758 float top_controls_delta) override { | |
| 5759 EXPECT_EQ(info_.page_scale_delta, scale_delta); | |
| 5760 EXPECT_EQ(info_.top_controls_delta, top_controls_delta); | |
| 5761 deltas_sent_to_client_ = true; | |
| 5762 } | |
| 5763 | |
| 5764 void ApplyViewportDeltas( | |
| 5765 const gfx::Vector2d& scroll, | |
| 5766 float scale_delta, | |
| 5767 float top_controls_delta) override { | |
| 5768 EXPECT_EQ(info_.page_scale_delta, scale_delta); | |
| 5769 EXPECT_EQ(info_.top_controls_delta, top_controls_delta); | |
| 5770 deltas_sent_to_client_ = true; | |
| 5771 } | |
| 5772 | |
| 5773 void AfterTest() override { | |
| 5774 EXPECT_TRUE(deltas_sent_to_client_); | |
| 5775 } | |
| 5776 | |
| 5777 ScrollAndScaleSet info_; | |
| 5778 bool deltas_sent_to_client_; | |
| 5779 }; | |
| 5780 | |
| 5781 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer); | |
| 5782 | |
| 5783 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { | |
| 5784 protected: | |
| 5785 LayerTreeHostTestCrispUpAfterPinchEnds() | |
| 5786 : playback_allowed_event_(true, true) {} | |
| 5787 | |
| 5788 void SetupTree() override { | |
| 5789 frame_ = 1; | |
| 5790 posted_ = false; | |
| 5791 client_.set_fill_with_nonsolid_color(true); | |
| 5792 | |
| 5793 scoped_refptr<Layer> root = Layer::Create(); | |
| 5794 root->SetBounds(gfx::Size(500, 500)); | |
| 5795 | |
| 5796 scoped_refptr<Layer> pinch = Layer::Create(); | |
| 5797 pinch->SetBounds(gfx::Size(500, 500)); | |
| 5798 pinch->SetScrollClipLayerId(root->id()); | |
| 5799 pinch->SetIsContainerForFixedPositionLayers(true); | |
| 5800 root->AddChild(pinch); | |
| 5801 | |
| 5802 scoped_ptr<FakePicturePile> pile( | |
| 5803 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
| 5804 ImplSidePaintingSettings().default_tile_grid_size)); | |
| 5805 pile->SetPlaybackAllowedEvent(&playback_allowed_event_); | |
| 5806 scoped_refptr<FakePictureLayer> layer = | |
| 5807 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
| 5808 layer->SetBounds(gfx::Size(500, 500)); | |
| 5809 layer->SetContentsOpaque(true); | |
| 5810 // Avoid LCD text on the layer so we don't cause extra commits when we | |
| 5811 // pinch. | |
| 5812 layer->disable_lcd_text(); | |
| 5813 pinch->AddChild(layer); | |
| 5814 | |
| 5815 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch); | |
| 5816 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); | |
| 5817 layer_tree_host()->SetRootLayer(root); | |
| 5818 LayerTreeHostTest::SetupTree(); | |
| 5819 } | |
| 5820 | |
| 5821 // Returns the delta scale of all quads in the frame's root pass from their | |
| 5822 // ideal, or 0 if they are not all the same. | |
| 5823 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) { | |
| 5824 if (frame_data->has_no_damage) | |
| 5825 return 0.f; | |
| 5826 float frame_scale = 0.f; | |
| 5827 RenderPass* root_pass = frame_data->render_passes.back(); | |
| 5828 for (const auto& draw_quad : root_pass->quad_list) { | |
| 5829 // Checkerboards mean an incomplete frame. | |
| 5830 if (draw_quad->material != DrawQuad::TILED_CONTENT) | |
| 5831 return 0.f; | |
| 5832 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad); | |
| 5833 float quad_scale = | |
| 5834 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width()); | |
| 5835 float transform_scale = | |
| 5836 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0)); | |
| 5837 float scale = quad_scale / transform_scale; | |
| 5838 if (frame_scale != 0.f && frame_scale != scale) | |
| 5839 return 0.f; | |
| 5840 frame_scale = scale; | |
| 5841 } | |
| 5842 return frame_scale; | |
| 5843 } | |
| 5844 | |
| 5845 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 5846 | |
| 5847 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 5848 LayerTreeHostImpl::FrameData* frame_data, | |
| 5849 DrawResult draw_result) override { | |
| 5850 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data); | |
| 5851 switch (frame_) { | |
| 5852 case 1: | |
| 5853 // Drew at page scale 1 before any pinching. | |
| 5854 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
| 5855 EXPECT_EQ(1.f, quad_scale_delta); | |
| 5856 PostNextAfterDraw(host_impl); | |
| 5857 break; | |
| 5858 case 2: | |
| 5859 if (quad_scale_delta != 1.f) | |
| 5860 break; | |
| 5861 // Drew at page scale 1.5 after pinching in. | |
| 5862 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); | |
| 5863 EXPECT_EQ(1.f, quad_scale_delta); | |
| 5864 PostNextAfterDraw(host_impl); | |
| 5865 break; | |
| 5866 case 3: | |
| 5867 // By pinching out, we will create a new tiling and raster it. This may | |
| 5868 // cause some additional draws, though we should still be drawing with | |
| 5869 // the old 1.5 tiling. | |
| 5870 if (frame_data->has_no_damage) | |
| 5871 break; | |
| 5872 // Drew at page scale 1 with the 1.5 tiling while pinching out. | |
| 5873 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
| 5874 EXPECT_EQ(1.5f, quad_scale_delta); | |
| 5875 // We don't PostNextAfterDraw here, instead we wait for the new tiling | |
| 5876 // to finish rastering so we don't get any noise in further steps. | |
| 5877 break; | |
| 5878 case 4: | |
| 5879 // Drew at page scale 1 with the 1.5 tiling after pinching out completed | |
| 5880 // while waiting for texture uploads to complete. | |
| 5881 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
| 5882 // This frame will not have any damage, since it's actually the same as | |
| 5883 // the last frame, and should contain no incomplete tiles. We just want | |
| 5884 // to make sure we drew here at least once after the pinch ended to be | |
| 5885 // sure that drawing after pinch doesn't leave us at the wrong scale | |
| 5886 EXPECT_TRUE(frame_data->has_no_damage); | |
| 5887 PostNextAfterDraw(host_impl); | |
| 5888 break; | |
| 5889 case 5: | |
| 5890 if (quad_scale_delta != 1.f) | |
| 5891 break; | |
| 5892 // Drew at scale 1 after texture uploads are done. | |
| 5893 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
| 5894 EXPECT_EQ(1.f, quad_scale_delta); | |
| 5895 EndTest(); | |
| 5896 break; | |
| 5897 } | |
| 5898 return draw_result; | |
| 5899 } | |
| 5900 | |
| 5901 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) { | |
| 5902 if (posted_) | |
| 5903 return; | |
| 5904 posted_ = true; | |
| 5905 ImplThreadTaskRunner()->PostDelayedTask( | |
| 5906 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next, | |
| 5907 base::Unretained(this), host_impl), | |
| 5908 // Use a delay to allow raster/upload to happen in between frames. This | |
| 5909 // should cause flakiness if we fail to block raster/upload when | |
| 5910 // desired. | |
| 5911 base::TimeDelta::FromMilliseconds(16 * 4)); | |
| 5912 } | |
| 5913 | |
| 5914 void Next(LayerTreeHostImpl* host_impl) { | |
| 5915 ++frame_; | |
| 5916 posted_ = false; | |
| 5917 switch (frame_) { | |
| 5918 case 2: | |
| 5919 // Pinch zoom in. | |
| 5920 host_impl->PinchGestureBegin(); | |
| 5921 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100)); | |
| 5922 host_impl->PinchGestureEnd(); | |
| 5923 break; | |
| 5924 case 3: | |
| 5925 // Pinch zoom back to 1.f but don't end it. | |
| 5926 host_impl->PinchGestureBegin(); | |
| 5927 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100)); | |
| 5928 break; | |
| 5929 case 4: | |
| 5930 // End the pinch, but delay tile production. | |
| 5931 playback_allowed_event_.Reset(); | |
| 5932 host_impl->PinchGestureEnd(); | |
| 5933 break; | |
| 5934 case 5: | |
| 5935 // Let tiles complete. | |
| 5936 playback_allowed_event_.Signal(); | |
| 5937 break; | |
| 5938 } | |
| 5939 } | |
| 5940 | |
| 5941 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, | |
| 5942 const Tile* tile) override { | |
| 5943 if (frame_ == 3) { | |
| 5944 // On frame 3, we will have a lower res tile complete for the pinch-out | |
| 5945 // gesture even though it's not displayed. We wait for it here to prevent | |
| 5946 // flakiness. | |
| 5947 EXPECT_EQ(0.75f, tile->contents_scale()); | |
| 5948 PostNextAfterDraw(host_impl); | |
| 5949 } | |
| 5950 // On frame_ == 4, we are preventing texture uploads from completing, | |
| 5951 // so this verifies they are not completing before frame_ == 5. | |
| 5952 // Flaky failures here indicate we're failing to prevent uploads from | |
| 5953 // completing. | |
| 5954 EXPECT_NE(4, frame_) << tile->contents_scale(); | |
| 5955 } | |
| 5956 | |
| 5957 void AfterTest() override {} | |
| 5958 | |
| 5959 FakeContentLayerClient client_; | |
| 5960 int frame_; | |
| 5961 bool posted_; | |
| 5962 base::WaitableEvent playback_allowed_event_; | |
| 5963 }; | |
| 5964 | |
| 5965 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds); | |
| 5966 | |
| 5967 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy | |
| 5968 : public LayerTreeHostTestCrispUpAfterPinchEnds { | |
| 5969 protected: | |
| 5970 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5971 settings->use_one_copy = true; | |
| 5972 } | |
| 5973 | |
| 5974 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
| 5975 scoped_ptr<TestWebGraphicsContext3D> context3d = | |
| 5976 TestWebGraphicsContext3D::Create(); | |
| 5977 context3d->set_support_image(true); | |
| 5978 context3d->set_support_sync_query(true); | |
| 5979 #if defined(OS_MACOSX) | |
| 5980 context3d->set_support_texture_rectangle(true); | |
| 5981 #endif | |
| 5982 | |
| 5983 if (delegating_renderer()) | |
| 5984 return FakeOutputSurface::CreateDelegating3d(context3d.Pass()); | |
| 5985 else | |
| 5986 return FakeOutputSurface::Create3d(context3d.Pass()); | |
| 5987 } | |
| 5988 }; | |
| 5989 | |
| 5990 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy); | |
| 5991 | |
| 5992 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest { | |
| 5993 protected: | |
| 5994 RasterizeWithGpuRasterizationCreatesResources() {} | |
| 5995 | |
| 5996 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 5997 settings->impl_side_painting = true; | |
| 5998 settings->gpu_rasterization_forced = true; | |
| 5999 } | |
| 6000 | |
| 6001 void SetupTree() override { | |
| 6002 client_.set_fill_with_nonsolid_color(true); | |
| 6003 | |
| 6004 scoped_refptr<Layer> root = Layer::Create(); | |
| 6005 root->SetBounds(gfx::Size(500, 500)); | |
| 6006 | |
| 6007 scoped_ptr<FakePicturePile> pile( | |
| 6008 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
| 6009 ImplSidePaintingSettings().default_tile_grid_size)); | |
| 6010 scoped_refptr<FakePictureLayer> layer = | |
| 6011 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
| 6012 layer->SetBounds(gfx::Size(500, 500)); | |
| 6013 layer->SetContentsOpaque(true); | |
| 6014 root->AddChild(layer); | |
| 6015 | |
| 6016 layer_tree_host()->SetRootLayer(root); | |
| 6017 LayerTreeHostTest::SetupTree(); | |
| 6018 } | |
| 6019 | |
| 6020 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 6021 | |
| 6022 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 6023 LayerTreeHostImpl::FrameData* frame_data, | |
| 6024 DrawResult draw_result) override { | |
| 6025 EXPECT_NE(0u, host_impl->resource_provider()->num_resources()); | |
| 6026 EndTest(); | |
| 6027 return draw_result; | |
| 6028 } | |
| 6029 void AfterTest() override {} | |
| 6030 | |
| 6031 FakeContentLayerClient client_; | |
| 6032 }; | |
| 6033 | |
| 6034 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources); | |
| 6035 | |
| 6036 class SynchronousGpuRasterizationRasterizesVisibleOnly | |
| 6037 : public LayerTreeHostTest { | |
| 6038 protected: | |
| 6039 SynchronousGpuRasterizationRasterizesVisibleOnly() | |
| 6040 : viewport_size_(1024, 2048) {} | |
| 6041 | |
| 6042 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 6043 settings->impl_side_painting = true; | |
| 6044 settings->gpu_rasterization_enabled = true; | |
| 6045 settings->gpu_rasterization_forced = true; | |
| 6046 settings->threaded_gpu_rasterization_enabled = false; | |
| 6047 } | |
| 6048 | |
| 6049 void SetupTree() override { | |
| 6050 client_.set_fill_with_nonsolid_color(true); | |
| 6051 | |
| 6052 scoped_ptr<FakePicturePile> pile( | |
| 6053 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
| 6054 ImplSidePaintingSettings().default_tile_grid_size)); | |
| 6055 scoped_refptr<FakePictureLayer> root = | |
| 6056 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
| 6057 root->SetBounds(gfx::Size(viewport_size_.width(), 10000)); | |
| 6058 root->SetContentsOpaque(true); | |
| 6059 | |
| 6060 layer_tree_host()->SetRootLayer(root); | |
| 6061 LayerTreeHostTest::SetupTree(); | |
| 6062 layer_tree_host()->SetViewportSize(viewport_size_); | |
| 6063 } | |
| 6064 | |
| 6065 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 6066 | |
| 6067 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 6068 LayerTreeHostImpl::FrameData* frame_data, | |
| 6069 DrawResult draw_result) override { | |
| 6070 EXPECT_EQ(4u, host_impl->resource_provider()->num_resources()); | |
| 6071 | |
| 6072 // Verify which tiles got resources using an eviction iterator, which has to | |
| 6073 // return all tiles that have resources. | |
| 6074 scoped_ptr<EvictionTilePriorityQueue> eviction_queue( | |
| 6075 host_impl->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); | |
| 6076 int tile_count = 0; | |
| 6077 for (; !eviction_queue->IsEmpty(); eviction_queue->Pop()) { | |
| 6078 Tile* tile = eviction_queue->Top(); | |
| 6079 // Ensure this tile is within the viewport. | |
| 6080 EXPECT_TRUE(tile->content_rect().Intersects(gfx::Rect(viewport_size_))); | |
| 6081 // Ensure that the tile is 1/4 of the viewport tall (plus padding). | |
| 6082 EXPECT_EQ(tile->content_rect().height(), | |
| 6083 (viewport_size_.height() / 4) + 2); | |
| 6084 ++tile_count; | |
| 6085 } | |
| 6086 EXPECT_EQ(4, tile_count); | |
| 6087 EndTest(); | |
| 6088 return draw_result; | |
| 6089 } | |
| 6090 | |
| 6091 void AfterTest() override {} | |
| 6092 | |
| 6093 private: | |
| 6094 FakeContentLayerClient client_; | |
| 6095 gfx::Size viewport_size_; | |
| 6096 }; | |
| 6097 | |
| 6098 MULTI_THREAD_IMPL_TEST_F(SynchronousGpuRasterizationRasterizesVisibleOnly); | |
| 6099 | |
| 6100 class ThreadedGpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest { | |
| 6101 protected: | |
| 6102 ThreadedGpuRasterizationRasterizesBorderTiles() | |
| 6103 : viewport_size_(1024, 2048) {} | |
| 6104 | |
| 6105 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 6106 settings->impl_side_painting = true; | |
| 6107 settings->gpu_rasterization_enabled = true; | |
| 6108 settings->gpu_rasterization_forced = true; | |
| 6109 settings->threaded_gpu_rasterization_enabled = true; | |
| 6110 } | |
| 6111 | |
| 6112 void SetupTree() override { | |
| 6113 client_.set_fill_with_nonsolid_color(true); | |
| 6114 | |
| 6115 scoped_ptr<FakePicturePile> pile( | |
| 6116 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
| 6117 ImplSidePaintingSettings().default_tile_grid_size)); | |
| 6118 scoped_refptr<FakePictureLayer> root = | |
| 6119 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
| 6120 root->SetBounds(gfx::Size(10000, 10000)); | |
| 6121 root->SetContentsOpaque(true); | |
| 6122 | |
| 6123 layer_tree_host()->SetRootLayer(root); | |
| 6124 LayerTreeHostTest::SetupTree(); | |
| 6125 layer_tree_host()->SetViewportSize(viewport_size_); | |
| 6126 } | |
| 6127 | |
| 6128 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 6129 | |
| 6130 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 6131 LayerTreeHostImpl::FrameData* frame_data, | |
| 6132 DrawResult draw_result) override { | |
| 6133 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources()); | |
| 6134 EndTest(); | |
| 6135 return draw_result; | |
| 6136 } | |
| 6137 | |
| 6138 void AfterTest() override {} | |
| 6139 | |
| 6140 private: | |
| 6141 FakeContentLayerClient client_; | |
| 6142 gfx::Size viewport_size_; | |
| 6143 }; | |
| 6144 | |
| 6145 MULTI_THREAD_IMPL_TEST_F(ThreadedGpuRasterizationRasterizesBorderTiles); | |
| 6146 | |
| 6147 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles | |
| 6148 : public LayerTreeHostTest { | |
| 6149 protected: | |
| 6150 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles() | |
| 6151 : playback_allowed_event_(true, true) {} | |
| 6152 | |
| 6153 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 6154 settings->impl_side_painting = true; | |
| 6155 } | |
| 6156 | |
| 6157 void SetupTree() override { | |
| 6158 step_ = 1; | |
| 6159 continuous_draws_ = 0; | |
| 6160 client_.set_fill_with_nonsolid_color(true); | |
| 6161 | |
| 6162 scoped_refptr<Layer> root = Layer::Create(); | |
| 6163 root->SetBounds(gfx::Size(500, 500)); | |
| 6164 | |
| 6165 scoped_refptr<Layer> pinch = Layer::Create(); | |
| 6166 pinch->SetBounds(gfx::Size(500, 500)); | |
| 6167 pinch->SetScrollClipLayerId(root->id()); | |
| 6168 pinch->SetIsContainerForFixedPositionLayers(true); | |
| 6169 root->AddChild(pinch); | |
| 6170 | |
| 6171 scoped_ptr<FakePicturePile> pile( | |
| 6172 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
| 6173 ImplSidePaintingSettings().default_tile_grid_size)); | |
| 6174 pile->SetPlaybackAllowedEvent(&playback_allowed_event_); | |
| 6175 scoped_refptr<FakePictureLayer> layer = | |
| 6176 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
| 6177 layer->SetBounds(gfx::Size(500, 500)); | |
| 6178 layer->SetContentsOpaque(true); | |
| 6179 // Avoid LCD text on the layer so we don't cause extra commits when we | |
| 6180 // pinch. | |
| 6181 layer->disable_lcd_text(); | |
| 6182 pinch->AddChild(layer); | |
| 6183 | |
| 6184 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch); | |
| 6185 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); | |
| 6186 layer_tree_host()->SetRootLayer(root); | |
| 6187 LayerTreeHostTest::SetupTree(); | |
| 6188 } | |
| 6189 | |
| 6190 // Returns the delta scale of all quads in the frame's root pass from their | |
| 6191 // ideal, or 0 if they are not all the same. | |
| 6192 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) { | |
| 6193 if (frame_data->has_no_damage) | |
| 6194 return 0.f; | |
| 6195 float frame_scale = 0.f; | |
| 6196 RenderPass* root_pass = frame_data->render_passes.back(); | |
| 6197 for (const auto& draw_quad : root_pass->quad_list) { | |
| 6198 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad); | |
| 6199 float quad_scale = | |
| 6200 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width()); | |
| 6201 float transform_scale = | |
| 6202 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0)); | |
| 6203 float scale = quad_scale / transform_scale; | |
| 6204 if (frame_scale != 0.f && frame_scale != scale) | |
| 6205 return 0.f; | |
| 6206 frame_scale = scale; | |
| 6207 } | |
| 6208 return frame_scale; | |
| 6209 } | |
| 6210 | |
| 6211 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 6212 | |
| 6213 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 6214 LayerTreeHostImpl::FrameData* frame_data, | |
| 6215 DrawResult draw_result) override { | |
| 6216 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data); | |
| 6217 switch (step_) { | |
| 6218 case 1: | |
| 6219 // Drew at scale 1 before any pinching. | |
| 6220 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
| 6221 EXPECT_EQ(1.f, quad_scale_delta); | |
| 6222 break; | |
| 6223 case 2: | |
| 6224 if (quad_scale_delta != 1.f / 1.5f) | |
| 6225 break; | |
| 6226 // Drew at scale 1 still though the ideal is 1.5. | |
| 6227 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); | |
| 6228 EXPECT_EQ(1.f / 1.5f, quad_scale_delta); | |
| 6229 break; | |
| 6230 case 3: | |
| 6231 // Continuous draws are attempted. | |
| 6232 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); | |
| 6233 if (!frame_data->has_no_damage) | |
| 6234 EXPECT_EQ(1.f / 1.5f, quad_scale_delta); | |
| 6235 break; | |
| 6236 case 4: | |
| 6237 if (quad_scale_delta != 1.f) | |
| 6238 break; | |
| 6239 // Drew at scale 1.5 when all the tiles completed. | |
| 6240 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); | |
| 6241 EXPECT_EQ(1.f, quad_scale_delta); | |
| 6242 break; | |
| 6243 case 5: | |
| 6244 // TODO(danakj): We get more draws before the NotifyReadyToDraw | |
| 6245 // because it is asynchronous from the previous draw and happens late. | |
| 6246 break; | |
| 6247 case 6: | |
| 6248 // NotifyReadyToDraw happened. If we were already inside a frame, we may | |
| 6249 // try to draw once more. | |
| 6250 break; | |
| 6251 case 7: | |
| 6252 NOTREACHED() << "No draws should happen once we have a complete frame."; | |
| 6253 break; | |
| 6254 } | |
| 6255 return draw_result; | |
| 6256 } | |
| 6257 | |
| 6258 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 6259 switch (step_) { | |
| 6260 case 1: | |
| 6261 // Delay tile production. | |
| 6262 playback_allowed_event_.Reset(); | |
| 6263 // Pinch zoom in to cause new tiles to be required. | |
| 6264 host_impl->PinchGestureBegin(); | |
| 6265 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100)); | |
| 6266 host_impl->PinchGestureEnd(); | |
| 6267 ++step_; | |
| 6268 break; | |
| 6269 case 2: | |
| 6270 ++step_; | |
| 6271 break; | |
| 6272 case 3: | |
| 6273 // We should continue to try draw while there are incomplete visible | |
| 6274 // tiles. | |
| 6275 if (++continuous_draws_ > 5) { | |
| 6276 // Allow the tiles to complete. | |
| 6277 playback_allowed_event_.Signal(); | |
| 6278 ++step_; | |
| 6279 } | |
| 6280 break; | |
| 6281 case 4: | |
| 6282 ++step_; | |
| 6283 break; | |
| 6284 case 5: | |
| 6285 // Waiting for NotifyReadyToDraw. | |
| 6286 break; | |
| 6287 case 6: | |
| 6288 // NotifyReadyToDraw happened. | |
| 6289 ++step_; | |
| 6290 break; | |
| 6291 } | |
| 6292 } | |
| 6293 | |
| 6294 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override { | |
| 6295 if (step_ == 5) { | |
| 6296 ++step_; | |
| 6297 // NotifyReadyToDraw has happened, we may draw once more, but should not | |
| 6298 // get any more draws after that. End the test after a timeout to watch | |
| 6299 // for any extraneous draws. | |
| 6300 // TODO(brianderson): We could remove this delay and instead wait until | |
| 6301 // the BeginFrameSource decides it doesn't need to send frames anymore, | |
| 6302 // or test that it already doesn't here. | |
| 6303 EndTestAfterDelayMs(16 * 4); | |
| 6304 } | |
| 6305 } | |
| 6306 | |
| 6307 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, | |
| 6308 const Tile* tile) override { | |
| 6309 // On step_ == 2, we are preventing texture uploads from completing, | |
| 6310 // so this verifies they are not completing before step_ == 3. | |
| 6311 // Flaky failures here indicate we're failing to prevent uploads from | |
| 6312 // completing. | |
| 6313 EXPECT_NE(2, step_); | |
| 6314 } | |
| 6315 | |
| 6316 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); } | |
| 6317 | |
| 6318 FakeContentLayerClient client_; | |
| 6319 int step_; | |
| 6320 int continuous_draws_; | |
| 6321 base::WaitableEvent playback_allowed_event_; | |
| 6322 }; | |
| 6323 | |
| 6324 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles); | |
| 6325 | |
| 6326 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest { | |
| 6327 public: | |
| 6328 LayerTreeHostTestOneActivatePerPrepareTiles() | |
| 6329 : notify_ready_to_activate_count_(0u), | |
| 6330 scheduled_prepare_tiles_count_(0) {} | |
| 6331 | |
| 6332 void SetupTree() override { | |
| 6333 client_.set_fill_with_nonsolid_color(true); | |
| 6334 scoped_refptr<FakePictureLayer> root_layer = | |
| 6335 FakePictureLayer::Create(&client_); | |
| 6336 root_layer->SetBounds(gfx::Size(1500, 1500)); | |
| 6337 root_layer->SetIsDrawable(true); | |
| 6338 | |
| 6339 layer_tree_host()->SetRootLayer(root_layer); | |
| 6340 LayerTreeHostTest::SetupTree(); | |
| 6341 } | |
| 6342 | |
| 6343 void BeginTest() override { | |
| 6344 layer_tree_host()->SetViewportSize(gfx::Size(16, 16)); | |
| 6345 PostSetNeedsCommitToMainThread(); | |
| 6346 } | |
| 6347 | |
| 6348 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, | |
| 6349 bool success) override { | |
| 6350 ASSERT_TRUE(success); | |
| 6351 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1); | |
| 6352 } | |
| 6353 | |
| 6354 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { | |
| 6355 ++notify_ready_to_activate_count_; | |
| 6356 EndTestAfterDelayMs(100); | |
| 6357 } | |
| 6358 | |
| 6359 void ScheduledActionPrepareTiles() override { | |
| 6360 ++scheduled_prepare_tiles_count_; | |
| 6361 } | |
| 6362 | |
| 6363 void AfterTest() override { | |
| 6364 // Expect at most a notification for each scheduled prepare tiles, plus one | |
| 6365 // for the initial commit (which doesn't go through scheduled actions). | |
| 6366 // The reason this is not an equality is because depending on timing, we | |
| 6367 // might get a prepare tiles but not yet get a notification that we're | |
| 6368 // ready to activate. The intent of a test is to ensure that we don't | |
| 6369 // get more than one notification per prepare tiles, so this is OK. | |
| 6370 EXPECT_LE(notify_ready_to_activate_count_, | |
| 6371 1u + scheduled_prepare_tiles_count_); | |
| 6372 } | |
| 6373 | |
| 6374 protected: | |
| 6375 FakeContentLayerClient client_; | |
| 6376 size_t notify_ready_to_activate_count_; | |
| 6377 size_t scheduled_prepare_tiles_count_; | |
| 6378 }; | |
| 6379 | |
| 6380 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles); | |
| 6381 | |
| 6382 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps | |
| 6383 : public LayerTreeHostTest { | |
| 6384 public: | |
| 6385 LayerTreeHostTestFrameTimingRequestsSaveTimestamps() | |
| 6386 : check_results_on_commit_(false) {} | |
| 6387 | |
| 6388 void SetupTree() override { | |
| 6389 scoped_refptr<FakePictureLayer> root_layer = | |
| 6390 FakePictureLayer::Create(&client_); | |
| 6391 root_layer->SetBounds(gfx::Size(200, 200)); | |
| 6392 root_layer->SetIsDrawable(true); | |
| 6393 | |
| 6394 scoped_refptr<FakePictureLayer> child_layer = | |
| 6395 FakePictureLayer::Create(&client_); | |
| 6396 child_layer->SetBounds(gfx::Size(1500, 1500)); | |
| 6397 child_layer->SetIsDrawable(true); | |
| 6398 | |
| 6399 std::vector<FrameTimingRequest> requests; | |
| 6400 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100))); | |
| 6401 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100))); | |
| 6402 child_layer->SetFrameTimingRequests(requests); | |
| 6403 | |
| 6404 root_layer->AddChild(child_layer); | |
| 6405 layer_tree_host()->SetRootLayer(root_layer); | |
| 6406 LayerTreeHostTest::SetupTree(); | |
| 6407 } | |
| 6408 | |
| 6409 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 6410 | |
| 6411 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
| 6412 if (!check_results_on_commit_) | |
| 6413 return; | |
| 6414 | |
| 6415 // Since in reality, the events will be read by LayerTreeHost during commit, | |
| 6416 // we check the requests here to ensure that they are correct at the next | |
| 6417 // commit time (as opposed to checking in DrawLayers for instance). | |
| 6418 // TODO(vmpstr): Change this to read things from the main thread when this | |
| 6419 // information is propagated to the main thread (not yet implemented). | |
| 6420 FrameTimingTracker* tracker = host_impl->frame_timing_tracker(); | |
| 6421 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set = | |
| 6422 tracker->GroupCountsByRectId(); | |
| 6423 EXPECT_EQ(1u, timing_set->size()); | |
| 6424 auto rect_1_it = timing_set->find(1); | |
| 6425 EXPECT_TRUE(rect_1_it != timing_set->end()); | |
| 6426 const auto& timing_events = rect_1_it->second; | |
| 6427 EXPECT_EQ(1u, timing_events.size()); | |
| 6428 EXPECT_EQ(host_impl->active_tree()->source_frame_number(), | |
| 6429 timing_events[0].frame_id); | |
| 6430 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks()); | |
| 6431 | |
| 6432 EndTest(); | |
| 6433 } | |
| 6434 | |
| 6435 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 6436 check_results_on_commit_ = true; | |
| 6437 PostSetNeedsCommitToMainThread(); | |
| 6438 } | |
| 6439 | |
| 6440 void AfterTest() override {} | |
| 6441 | |
| 6442 private: | |
| 6443 FakeContentLayerClient client_; | |
| 6444 bool check_results_on_commit_; | |
| 6445 }; | |
| 6446 | |
| 6447 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps); | |
| 6448 | |
| 6449 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest { | |
| 6450 public: | |
| 6451 LayerTreeHostTestActivationCausesPrepareTiles() | |
| 6452 : scheduled_prepare_tiles_count_(0) {} | |
| 6453 | |
| 6454 void SetupTree() override { | |
| 6455 client_.set_fill_with_nonsolid_color(true); | |
| 6456 scoped_refptr<FakePictureLayer> root_layer = | |
| 6457 FakePictureLayer::Create(&client_); | |
| 6458 root_layer->SetBounds(gfx::Size(150, 150)); | |
| 6459 root_layer->SetIsDrawable(true); | |
| 6460 | |
| 6461 layer_tree_host()->SetRootLayer(root_layer); | |
| 6462 LayerTreeHostTest::SetupTree(); | |
| 6463 } | |
| 6464 | |
| 6465 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 6466 | |
| 6467 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { | |
| 6468 // Ensure we've already activated. | |
| 6469 EXPECT_FALSE(impl->pending_tree()); | |
| 6470 | |
| 6471 // After activating, we either need to prepare tiles, or we've already | |
| 6472 // called a scheduled prepare tiles. This is done because activation might | |
| 6473 // cause us to have to memory available (old active tree is gone), so we | |
| 6474 // need to ensure we will get a PrepareTiles call. | |
| 6475 if (!impl->prepare_tiles_needed()) | |
| 6476 EXPECT_GE(scheduled_prepare_tiles_count_, 1); | |
| 6477 EndTest(); | |
| 6478 } | |
| 6479 | |
| 6480 void ScheduledActionPrepareTiles() override { | |
| 6481 ++scheduled_prepare_tiles_count_; | |
| 6482 } | |
| 6483 | |
| 6484 void AfterTest() override {} | |
| 6485 | |
| 6486 protected: | |
| 6487 FakeContentLayerClient client_; | |
| 6488 int scheduled_prepare_tiles_count_; | |
| 6489 }; | |
| 6490 | |
| 6491 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles); | |
| 6492 | |
| 6493 // This tests an assertion that DidCommit and WillCommit happen in the same | |
| 6494 // stack frame with no tasks that run between them. Various embedders of | |
| 6495 // cc depend on this logic. ui::Compositor holds a compositor lock between | |
| 6496 // these events and the inspector timeline wants begin/end CompositeLayers | |
| 6497 // to be properly nested with other begin/end events. | |
| 6498 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit | |
| 6499 : public LayerTreeHostTest { | |
| 6500 public: | |
| 6501 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {} | |
| 6502 | |
| 6503 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 6504 | |
| 6505 void WillCommit() override { | |
| 6506 MainThreadTaskRunner()->PostTask( | |
| 6507 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit:: | |
| 6508 EndTestShouldRunAfterDidCommit, | |
| 6509 base::Unretained(this))); | |
| 6510 } | |
| 6511 | |
| 6512 void EndTestShouldRunAfterDidCommit() { | |
| 6513 EXPECT_TRUE(did_commit_); | |
| 6514 EndTest(); | |
| 6515 } | |
| 6516 | |
| 6517 void DidCommit() override { | |
| 6518 EXPECT_FALSE(did_commit_); | |
| 6519 did_commit_ = true; | |
| 6520 } | |
| 6521 | |
| 6522 void AfterTest() override { EXPECT_TRUE(did_commit_); } | |
| 6523 | |
| 6524 private: | |
| 6525 bool did_commit_; | |
| 6526 }; | |
| 6527 | |
| 6528 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit); | |
| 6529 | |
| 6530 // Verify that if a LayerImpl holds onto a copy request for multiple | |
| 6531 // frames that it will continue to have a render surface through | |
| 6532 // multiple commits, even though the Layer itself has no reason | |
| 6533 // to have a render surface. | |
| 6534 class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest { | |
| 6535 protected: | |
| 6536 void SetupTree() override { | |
| 6537 scoped_refptr<Layer> root = Layer::Create(); | |
| 6538 root->CreateRenderSurface(); | |
| 6539 root->SetBounds(gfx::Size(10, 10)); | |
| 6540 child_ = Layer::Create(); | |
| 6541 child_->SetBounds(gfx::Size(20, 20)); | |
| 6542 root->AddChild(child_); | |
| 6543 | |
| 6544 layer_tree_host()->SetRootLayer(root); | |
| 6545 LayerTreeHostTest::SetupTree(); | |
| 6546 } | |
| 6547 | |
| 6548 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} | |
| 6549 | |
| 6550 void BeginTest() override { | |
| 6551 child_->RequestCopyOfOutput( | |
| 6552 CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback))); | |
| 6553 EXPECT_TRUE(child_->HasCopyRequest()); | |
| 6554 PostSetNeedsCommitToMainThread(); | |
| 6555 } | |
| 6556 | |
| 6557 void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); } | |
| 6558 | |
| 6559 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 6560 LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id()); | |
| 6561 | |
| 6562 switch (host_impl->sync_tree()->source_frame_number()) { | |
| 6563 case 0: | |
| 6564 EXPECT_TRUE(child_impl->HasCopyRequest()); | |
| 6565 EXPECT_TRUE(child_impl->render_surface()); | |
| 6566 break; | |
| 6567 case 1: | |
| 6568 if (host_impl->proxy()->CommitToActiveTree()) { | |
| 6569 EXPECT_TRUE(child_impl->HasCopyRequest()); | |
| 6570 EXPECT_TRUE(child_impl->render_surface()); | |
| 6571 } else { | |
| 6572 EXPECT_FALSE(child_impl->HasCopyRequest()); | |
| 6573 EXPECT_FALSE(child_impl->render_surface()); | |
| 6574 } | |
| 6575 break; | |
| 6576 default: | |
| 6577 NOTREACHED(); | |
| 6578 break; | |
| 6579 } | |
| 6580 } | |
| 6581 | |
| 6582 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 6583 LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id()); | |
| 6584 EXPECT_TRUE(child_impl->HasCopyRequest()); | |
| 6585 EXPECT_TRUE(child_impl->render_surface()); | |
| 6586 | |
| 6587 switch (host_impl->active_tree()->source_frame_number()) { | |
| 6588 case 0: | |
| 6589 // Lose output surface to prevent drawing and cause another commit. | |
| 6590 host_impl->DidLoseOutputSurface(); | |
| 6591 break; | |
| 6592 case 1: | |
| 6593 EndTest(); | |
| 6594 break; | |
| 6595 default: | |
| 6596 NOTREACHED(); | |
| 6597 break; | |
| 6598 } | |
| 6599 } | |
| 6600 | |
| 6601 void AfterTest() override {} | |
| 6602 | |
| 6603 private: | |
| 6604 scoped_refptr<Layer> child_; | |
| 6605 }; | |
| 6606 | |
| 6607 SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests); | |
| 6608 | |
| 6609 } // namespace cc | |
| OLD | NEW |