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/base/swap_promise.h" 13 #include "cc/debug/frame_rate_counter.h" 14 #include "cc/layers/content_layer.h" 15 #include "cc/layers/content_layer_client.h" 16 #include "cc/layers/io_surface_layer.h" 17 #include "cc/layers/layer_impl.h" 18 #include "cc/layers/painted_scrollbar_layer.h" 19 #include "cc/layers/picture_layer.h" 20 #include "cc/layers/solid_color_layer.h" 21 #include "cc/layers/video_layer.h" 22 #include "cc/output/begin_frame_args.h" 23 #include "cc/output/compositor_frame_ack.h" 24 #include "cc/output/copy_output_request.h" 25 #include "cc/output/copy_output_result.h" 26 #include "cc/output/output_surface.h" 27 #include "cc/quads/draw_quad.h" 28 #include "cc/quads/io_surface_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_proxy.h" 41 #include "cc/test/fake_scoped_ui_resource.h" 42 #include "cc/test/fake_video_frame_provider.h" 43 #include "cc/test/geometry_test_utils.h" 44 #include "cc/test/layer_tree_test.h" 45 #include "cc/test/test_shared_bitmap_manager.h" 46 #include "cc/test/test_web_graphics_context_3d.h" 47 #include "cc/trees/layer_tree_host_impl.h" 48 #include "cc/trees/layer_tree_impl.h" 49 #include "cc/trees/single_thread_proxy.h" 50 #include "cc/trees/thread_proxy.h" 51 #include "gpu/GLES2/gl2extchromium.h" 52 #include "skia/ext/refptr.h" 53 #include "testing/gmock/include/gmock/gmock.h" 54 #include "third_party/khronos/GLES2/gl2.h" 55 #include "third_party/khronos/GLES2/gl2ext.h" 56 #include "third_party/skia/include/core/SkPicture.h" 57 #include "ui/gfx/frame_time.h" 58 #include "ui/gfx/point_conversions.h" 59 #include "ui/gfx/size_conversions.h" 60 #include "ui/gfx/vector2d_conversions.h" 61 62 using testing::_; 63 using testing::AnyNumber; 64 using testing::AtLeast; 65 using testing::Mock; 66 67 namespace cc { 68 namespace { 69 70 class LayerTreeHostTest : public LayerTreeTest {}; 71 72 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1 73 // draw with frame 0. 74 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest { 75 public: 76 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {} 77 78 virtual void BeginTest() OVERRIDE { 79 PostSetNeedsCommitToMainThread(); 80 PostSetNeedsCommitToMainThread(); 81 } 82 83 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 84 num_draws_++; 85 if (!impl->active_tree()->source_frame_number()) 86 EndTest(); 87 } 88 89 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 90 num_commits_++; 91 } 92 93 virtual void AfterTest() OVERRIDE { 94 EXPECT_GE(1, num_commits_); 95 EXPECT_GE(1, num_draws_); 96 } 97 98 private: 99 int num_commits_; 100 int num_draws_; 101 }; 102 103 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1); 104 105 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that 106 // first committed frame draws should lead to another commit. 107 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest { 108 public: 109 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {} 110 111 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 112 113 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 114 ++num_draws_; 115 } 116 117 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 118 ++num_commits_; 119 switch (num_commits_) { 120 case 1: 121 PostSetNeedsCommitToMainThread(); 122 break; 123 case 2: 124 EndTest(); 125 break; 126 default: 127 NOTREACHED(); 128 } 129 } 130 131 virtual void AfterTest() OVERRIDE { 132 EXPECT_EQ(2, num_commits_); 133 EXPECT_LE(1, num_draws_); 134 } 135 136 private: 137 int num_commits_; 138 int num_draws_; 139 }; 140 141 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2); 142 143 // Verify that we pass property values in PushPropertiesTo. 144 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { 145 protected: 146 virtual void SetupTree() OVERRIDE { 147 scoped_refptr<Layer> root = Layer::Create(); 148 root->SetBounds(gfx::Size(10, 10)); 149 layer_tree_host()->SetRootLayer(root); 150 LayerTreeHostTest::SetupTree(); 151 } 152 153 enum Properties { 154 STARTUP, 155 BOUNDS, 156 HIDE_LAYER_AND_SUBTREE, 157 DRAWS_CONTENT, 158 DONE, 159 }; 160 161 virtual void BeginTest() OVERRIDE { 162 index_ = STARTUP; 163 PostSetNeedsCommitToMainThread(); 164 } 165 166 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 167 VerifyAfterValues(impl->active_tree()->root_layer()); 168 } 169 170 virtual void DidCommitAndDrawFrame() OVERRIDE { 171 SetBeforeValues(layer_tree_host()->root_layer()); 172 VerifyBeforeValues(layer_tree_host()->root_layer()); 173 174 ++index_; 175 if (index_ == DONE) { 176 EndTest(); 177 return; 178 } 179 180 SetAfterValues(layer_tree_host()->root_layer()); 181 } 182 183 virtual void AfterTest() OVERRIDE {} 184 185 void VerifyBeforeValues(Layer* layer) { 186 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString()); 187 EXPECT_FALSE(layer->hide_layer_and_subtree()); 188 EXPECT_FALSE(layer->DrawsContent()); 189 } 190 191 void SetBeforeValues(Layer* layer) { 192 layer->SetBounds(gfx::Size(10, 10)); 193 layer->SetHideLayerAndSubtree(false); 194 layer->SetIsDrawable(false); 195 } 196 197 void VerifyAfterValues(LayerImpl* layer) { 198 switch (static_cast<Properties>(index_)) { 199 case STARTUP: 200 case DONE: 201 break; 202 case BOUNDS: 203 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString()); 204 break; 205 case HIDE_LAYER_AND_SUBTREE: 206 EXPECT_TRUE(layer->hide_layer_and_subtree()); 207 break; 208 case DRAWS_CONTENT: 209 EXPECT_TRUE(layer->DrawsContent()); 210 break; 211 } 212 } 213 214 void SetAfterValues(Layer* layer) { 215 switch (static_cast<Properties>(index_)) { 216 case STARTUP: 217 case DONE: 218 break; 219 case BOUNDS: 220 layer->SetBounds(gfx::Size(20, 20)); 221 break; 222 case HIDE_LAYER_AND_SUBTREE: 223 layer->SetHideLayerAndSubtree(true); 224 break; 225 case DRAWS_CONTENT: 226 layer->SetIsDrawable(true); 227 break; 228 } 229 } 230 231 int index_; 232 }; 233 234 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo); 235 236 // 1 setNeedsRedraw after the first commit has completed should lead to 1 237 // additional draw. 238 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest { 239 public: 240 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {} 241 242 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 243 244 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 245 EXPECT_EQ(0, impl->active_tree()->source_frame_number()); 246 if (!num_draws_) { 247 // Redraw again to verify that the second redraw doesn't commit. 248 PostSetNeedsRedrawToMainThread(); 249 } else { 250 EndTest(); 251 } 252 num_draws_++; 253 } 254 255 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 256 EXPECT_EQ(0, num_draws_); 257 num_commits_++; 258 } 259 260 virtual void AfterTest() OVERRIDE { 261 EXPECT_GE(2, num_draws_); 262 EXPECT_EQ(1, num_commits_); 263 } 264 265 private: 266 int num_commits_; 267 int num_draws_; 268 }; 269 270 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw); 271 272 // After setNeedsRedrawRect(invalid_rect) the final damage_rect 273 // must contain invalid_rect. 274 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { 275 public: 276 LayerTreeHostTestSetNeedsRedrawRect() 277 : num_draws_(0), 278 bounds_(50, 50), 279 invalid_rect_(10, 10, 20, 20), 280 root_layer_(ContentLayer::Create(&client_)) {} 281 282 virtual void BeginTest() OVERRIDE { 283 root_layer_->SetIsDrawable(true); 284 root_layer_->SetBounds(bounds_); 285 layer_tree_host()->SetRootLayer(root_layer_); 286 layer_tree_host()->SetViewportSize(bounds_); 287 PostSetNeedsCommitToMainThread(); 288 } 289 290 virtual DrawResult PrepareToDrawOnThread( 291 LayerTreeHostImpl* host_impl, 292 LayerTreeHostImpl::FrameData* frame_data, 293 DrawResult draw_result) OVERRIDE { 294 EXPECT_EQ(DRAW_SUCCESS, draw_result); 295 296 gfx::RectF root_damage_rect; 297 if (!frame_data->render_passes.empty()) 298 root_damage_rect = frame_data->render_passes.back()->damage_rect; 299 300 if (!num_draws_) { 301 // If this is the first frame, expect full frame damage. 302 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_)); 303 } else { 304 // Check that invalid_rect_ is indeed repainted. 305 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_)); 306 } 307 308 return draw_result; 309 } 310 311 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 312 if (!num_draws_) { 313 PostSetNeedsRedrawRectToMainThread(invalid_rect_); 314 } else { 315 EndTest(); 316 } 317 num_draws_++; 318 } 319 320 virtual void AfterTest() OVERRIDE { EXPECT_EQ(2, num_draws_); } 321 322 private: 323 int num_draws_; 324 const gfx::Size bounds_; 325 const gfx::Rect invalid_rect_; 326 FakeContentLayerClient client_; 327 scoped_refptr<ContentLayer> root_layer_; 328 }; 329 330 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect); 331 332 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { 333 public: 334 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 335 settings->layer_transforms_should_scale_layer_contents = true; 336 } 337 338 virtual void SetupTree() OVERRIDE { 339 root_layer_ = Layer::Create(); 340 root_layer_->SetBounds(gfx::Size(10, 20)); 341 342 scaled_layer_ = FakeContentLayer::Create(&client_); 343 scaled_layer_->SetBounds(gfx::Size(1, 1)); 344 root_layer_->AddChild(scaled_layer_); 345 346 layer_tree_host()->SetRootLayer(root_layer_); 347 LayerTreeHostTest::SetupTree(); 348 } 349 350 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 351 352 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 353 if (host_impl->active_tree()->source_frame_number() == 1) 354 EndTest(); 355 } 356 357 virtual void DidCommit() OVERRIDE { 358 switch (layer_tree_host()->source_frame_number()) { 359 case 1: 360 // Changing the device scale factor causes a commit. It also changes 361 // the content bounds of |scaled_layer_|, which should not generate 362 // a second commit as a result. 363 layer_tree_host()->SetDeviceScaleFactor(4.f); 364 break; 365 default: 366 // No extra commits. 367 EXPECT_EQ(2, layer_tree_host()->source_frame_number()); 368 } 369 } 370 371 virtual void AfterTest() OVERRIDE { 372 EXPECT_EQ(gfx::Size(4, 4).ToString(), 373 scaled_layer_->content_bounds().ToString()); 374 } 375 376 private: 377 FakeContentLayerClient client_; 378 scoped_refptr<Layer> root_layer_; 379 scoped_refptr<FakeContentLayer> scaled_layer_; 380 }; 381 382 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate); 383 384 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate 385 : public LayerTreeHostTest { 386 public: 387 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 388 settings->layer_transforms_should_scale_layer_contents = true; 389 } 390 391 virtual void SetupTree() OVERRIDE { 392 root_layer_ = Layer::Create(); 393 root_layer_->SetBounds(gfx::Size(10, 20)); 394 395 bool paint_scrollbar = true; 396 bool has_thumb = false; 397 scrollbar_ = FakePaintedScrollbarLayer::Create( 398 paint_scrollbar, has_thumb, root_layer_->id()); 399 scrollbar_->SetPosition(gfx::Point(0, 10)); 400 scrollbar_->SetBounds(gfx::Size(10, 10)); 401 402 root_layer_->AddChild(scrollbar_); 403 404 layer_tree_host()->SetRootLayer(root_layer_); 405 LayerTreeHostTest::SetupTree(); 406 } 407 408 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 409 410 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 411 if (host_impl->active_tree()->source_frame_number() == 1) 412 EndTest(); 413 } 414 415 virtual void DidCommit() OVERRIDE { 416 switch (layer_tree_host()->source_frame_number()) { 417 case 1: 418 // Changing the device scale factor causes a commit. It also changes 419 // the content bounds of |scrollbar_|, which should not generate 420 // a second commit as a result. 421 layer_tree_host()->SetDeviceScaleFactor(4.f); 422 break; 423 default: 424 // No extra commits. 425 EXPECT_EQ(2, layer_tree_host()->source_frame_number()); 426 } 427 } 428 429 virtual void AfterTest() OVERRIDE { 430 EXPECT_EQ(gfx::Size(40, 40).ToString(), 431 scrollbar_->content_bounds().ToString()); 432 } 433 434 private: 435 FakeContentLayerClient client_; 436 scoped_refptr<Layer> root_layer_; 437 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; 438 }; 439 440 SINGLE_AND_MULTI_THREAD_TEST_F( 441 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate); 442 443 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { 444 public: 445 LayerTreeHostTestSetNextCommitForcesRedraw() 446 : num_draws_(0), 447 bounds_(50, 50), 448 invalid_rect_(10, 10, 20, 20), 449 root_layer_(ContentLayer::Create(&client_)) {} 450 451 virtual void BeginTest() OVERRIDE { 452 root_layer_->SetIsDrawable(true); 453 root_layer_->SetBounds(bounds_); 454 layer_tree_host()->SetRootLayer(root_layer_); 455 layer_tree_host()->SetViewportSize(bounds_); 456 PostSetNeedsCommitToMainThread(); 457 } 458 459 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 460 if (num_draws_ == 3 && host_impl->settings().impl_side_painting) 461 host_impl->SetNeedsRedrawRect(invalid_rect_); 462 } 463 464 virtual DrawResult PrepareToDrawOnThread( 465 LayerTreeHostImpl* host_impl, 466 LayerTreeHostImpl::FrameData* frame_data, 467 DrawResult draw_result) OVERRIDE { 468 EXPECT_EQ(DRAW_SUCCESS, draw_result); 469 470 gfx::RectF root_damage_rect; 471 if (!frame_data->render_passes.empty()) 472 root_damage_rect = frame_data->render_passes.back()->damage_rect; 473 474 switch (num_draws_) { 475 case 0: 476 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect); 477 break; 478 case 1: 479 case 2: 480 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect); 481 break; 482 case 3: 483 EXPECT_RECT_EQ(invalid_rect_, root_damage_rect); 484 break; 485 case 4: 486 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect); 487 break; 488 default: 489 NOTREACHED(); 490 } 491 492 return draw_result; 493 } 494 495 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 496 switch (num_draws_) { 497 case 0: 498 case 1: 499 // Cycle through a couple of empty commits to ensure we're observing the 500 // right behavior 501 PostSetNeedsCommitToMainThread(); 502 break; 503 case 2: 504 // Should force full frame damage on the next commit 505 PostSetNextCommitForcesRedrawToMainThread(); 506 PostSetNeedsCommitToMainThread(); 507 if (host_impl->settings().impl_side_painting) 508 host_impl->BlockNotifyReadyToActivateForTesting(true); 509 else 510 num_draws_++; 511 break; 512 case 3: 513 host_impl->BlockNotifyReadyToActivateForTesting(false); 514 break; 515 default: 516 EndTest(); 517 break; 518 } 519 num_draws_++; 520 } 521 522 virtual void AfterTest() OVERRIDE { EXPECT_EQ(5, num_draws_); } 523 524 private: 525 int num_draws_; 526 const gfx::Size bounds_; 527 const gfx::Rect invalid_rect_; 528 FakeContentLayerClient client_; 529 scoped_refptr<ContentLayer> root_layer_; 530 }; 531 532 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw); 533 534 // Tests that if a layer is not drawn because of some reason in the parent then 535 // its damage is preserved until the next time it is drawn. 536 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { 537 public: 538 LayerTreeHostTestUndrawnLayersDamageLater() 539 : root_layer_(ContentLayer::Create(&client_)) {} 540 541 virtual void SetupTree() OVERRIDE { 542 root_layer_->SetIsDrawable(true); 543 root_layer_->SetBounds(gfx::Size(50, 50)); 544 layer_tree_host()->SetRootLayer(root_layer_); 545 546 // The initially transparent layer has a larger child layer, which is 547 // not initially drawn because of the this (parent) layer. 548 parent_layer_ = FakeContentLayer::Create(&client_); 549 parent_layer_->SetBounds(gfx::Size(15, 15)); 550 parent_layer_->SetOpacity(0.0f); 551 root_layer_->AddChild(parent_layer_); 552 553 child_layer_ = FakeContentLayer::Create(&client_); 554 child_layer_->SetBounds(gfx::Size(25, 25)); 555 parent_layer_->AddChild(child_layer_); 556 557 LayerTreeHostTest::SetupTree(); 558 } 559 560 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 561 562 virtual DrawResult PrepareToDrawOnThread( 563 LayerTreeHostImpl* host_impl, 564 LayerTreeHostImpl::FrameData* frame_data, 565 DrawResult draw_result) OVERRIDE { 566 EXPECT_EQ(DRAW_SUCCESS, draw_result); 567 568 gfx::RectF root_damage_rect; 569 if (!frame_data->render_passes.empty()) 570 root_damage_rect = frame_data->render_passes.back()->damage_rect; 571 572 // The first time, the whole view needs be drawn. 573 // Afterwards, just the opacity of surface_layer1 is changed a few times, 574 // and each damage should be the bounding box of it and its child. If this 575 // was working improperly, the damage might not include its childs bounding 576 // box. 577 switch (host_impl->active_tree()->source_frame_number()) { 578 case 0: 579 EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect); 580 break; 581 case 1: 582 case 2: 583 case 3: 584 EXPECT_RECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect); 585 break; 586 default: 587 NOTREACHED(); 588 } 589 590 return draw_result; 591 } 592 593 virtual void DidCommitAndDrawFrame() OVERRIDE { 594 switch (layer_tree_host()->source_frame_number()) { 595 case 1: 596 // Test not owning the surface. 597 parent_layer_->SetOpacity(1.0f); 598 break; 599 case 2: 600 parent_layer_->SetOpacity(0.0f); 601 break; 602 case 3: 603 // Test owning the surface. 604 parent_layer_->SetOpacity(0.5f); 605 parent_layer_->SetForceRenderSurface(true); 606 break; 607 case 4: 608 EndTest(); 609 break; 610 default: 611 NOTREACHED(); 612 } 613 } 614 615 virtual void AfterTest() OVERRIDE {} 616 617 private: 618 FakeContentLayerClient client_; 619 scoped_refptr<ContentLayer> root_layer_; 620 scoped_refptr<FakeContentLayer> parent_layer_; 621 scoped_refptr<FakeContentLayer> child_layer_; 622 }; 623 624 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater); 625 626 // Tests that if a layer is not drawn because of some reason in the parent, 627 // causing its content bounds to not be computed, then when it is later drawn, 628 // its content bounds get pushed. 629 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater 630 : public LayerTreeHostTest { 631 public: 632 LayerTreeHostTestUndrawnLayersPushContentBoundsLater() 633 : root_layer_(Layer::Create()) {} 634 635 virtual void SetupTree() OVERRIDE { 636 root_layer_->SetIsDrawable(true); 637 root_layer_->SetBounds(gfx::Size(20, 20)); 638 layer_tree_host()->SetRootLayer(root_layer_); 639 640 parent_layer_ = Layer::Create(); 641 parent_layer_->SetBounds(gfx::Size(20, 20)); 642 parent_layer_->SetOpacity(0.0f); 643 root_layer_->AddChild(parent_layer_); 644 645 child_layer_ = Layer::Create(); 646 child_layer_->SetBounds(gfx::Size(15, 15)); 647 parent_layer_->AddChild(child_layer_); 648 649 LayerTreeHostTest::SetupTree(); 650 } 651 652 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 653 654 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 655 LayerImpl* root = host_impl->active_tree()->root_layer(); 656 LayerImpl* parent = root->children()[0]; 657 LayerImpl* child = parent->children()[0]; 658 659 switch (host_impl->active_tree()->source_frame_number()) { 660 case 0: 661 EXPECT_EQ(0.f, parent->opacity()); 662 EXPECT_EQ(gfx::SizeF(), child->content_bounds()); 663 break; 664 case 1: 665 EXPECT_EQ(1.f, parent->opacity()); 666 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds()); 667 EndTest(); 668 break; 669 default: 670 NOTREACHED(); 671 } 672 } 673 674 virtual void DidCommit() OVERRIDE { 675 switch (layer_tree_host()->source_frame_number()) { 676 case 1: 677 parent_layer_->SetOpacity(1.0f); 678 break; 679 case 2: 680 break; 681 default: 682 NOTREACHED(); 683 } 684 } 685 686 virtual void AfterTest() OVERRIDE {} 687 688 private: 689 scoped_refptr<Layer> root_layer_; 690 scoped_refptr<Layer> parent_layer_; 691 scoped_refptr<Layer> child_layer_; 692 }; 693 694 SINGLE_AND_MULTI_THREAD_TEST_F( 695 LayerTreeHostTestUndrawnLayersPushContentBoundsLater); 696 697 class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest { 698 public: 699 LayerTreeHostTestAbortFrameWhenInvisible() {} 700 701 virtual void BeginTest() OVERRIDE { 702 // Request a commit (from the main thread), Which will trigger the commit 703 // flow from the impl side. 704 layer_tree_host()->SetNeedsCommit(); 705 // Then mark ourselves as not visible before processing any more messages 706 // on the main thread. 707 layer_tree_host()->SetVisible(false); 708 // If we make it without kicking a frame, we pass! 709 EndTestAfterDelay(1); 710 } 711 712 virtual void Layout() OVERRIDE { 713 ASSERT_FALSE(true); 714 EndTest(); 715 } 716 717 virtual void AfterTest() OVERRIDE {} 718 }; 719 720 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible); 721 722 // This test verifies that properties on the layer tree host are commited 723 // to the impl side. 724 class LayerTreeHostTestCommit : public LayerTreeHostTest { 725 public: 726 LayerTreeHostTestCommit() {} 727 728 virtual void BeginTest() OVERRIDE { 729 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); 730 layer_tree_host()->set_background_color(SK_ColorGRAY); 731 732 PostSetNeedsCommitToMainThread(); 733 } 734 735 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 736 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize()); 737 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color()); 738 739 EndTest(); 740 } 741 742 virtual void AfterTest() OVERRIDE {} 743 }; 744 745 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit); 746 747 // This test verifies that LayerTreeHostImpl's current frame time gets 748 // updated in consecutive frames when it doesn't draw due to tree 749 // activation failure. 750 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails 751 : public LayerTreeHostTest { 752 public: 753 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails() 754 : frame_count_with_pending_tree_(0) {} 755 756 virtual void BeginTest() OVERRIDE { 757 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); 758 layer_tree_host()->set_background_color(SK_ColorGRAY); 759 760 PostSetNeedsCommitToMainThread(); 761 } 762 763 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { 764 EXPECT_EQ(frame_count_with_pending_tree_, 0); 765 impl->BlockNotifyReadyToActivateForTesting(true); 766 } 767 768 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl, 769 const BeginFrameArgs& args) OVERRIDE { 770 if (impl->pending_tree()) 771 frame_count_with_pending_tree_++; 772 773 if (frame_count_with_pending_tree_ == 1) { 774 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0); 775 first_frame_time_ = impl->CurrentFrameTimeTicks(); 776 } else if (frame_count_with_pending_tree_ == 2) { 777 impl->BlockNotifyReadyToActivateForTesting(false); 778 } 779 } 780 781 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 782 if (frame_count_with_pending_tree_ > 1) { 783 EXPECT_NE(first_frame_time_.ToInternalValue(), 0); 784 EXPECT_NE(first_frame_time_.ToInternalValue(), 785 impl->CurrentFrameTimeTicks().ToInternalValue()); 786 EndTest(); 787 return; 788 } 789 790 EXPECT_FALSE(impl->settings().impl_side_painting); 791 EndTest(); 792 } 793 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 794 if (impl->settings().impl_side_painting) 795 EXPECT_NE(frame_count_with_pending_tree_, 1); 796 } 797 798 virtual void AfterTest() OVERRIDE {} 799 800 private: 801 int frame_count_with_pending_tree_; 802 base::TimeTicks first_frame_time_; 803 }; 804 805 SINGLE_AND_MULTI_THREAD_TEST_F( 806 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails); 807 808 // This test verifies that LayerTreeHostImpl's current frame time gets 809 // updated in consecutive frames when it draws in each frame. 810 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { 811 public: 812 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {} 813 814 virtual void BeginTest() OVERRIDE { 815 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); 816 layer_tree_host()->set_background_color(SK_ColorGRAY); 817 818 PostSetNeedsCommitToMainThread(); 819 } 820 821 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 822 frame_++; 823 if (frame_ == 1) { 824 first_frame_time_ = impl->CurrentFrameTimeTicks(); 825 impl->SetNeedsRedraw(); 826 827 // Since we might use a low-resolution clock on Windows, we need to 828 // make sure that the clock has incremented past first_frame_time_. 829 while (first_frame_time_ == gfx::FrameTime::Now()) { 830 } 831 832 return; 833 } 834 835 EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks()); 836 EndTest(); 837 } 838 839 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 840 // Ensure there isn't a commit between the two draws, to ensure that a 841 // commit isn't required for updating the current frame time. We can 842 // only check for this in the multi-threaded case, since in the single- 843 // threaded case there will always be a commit between consecutive draws. 844 if (HasImplThread()) 845 EXPECT_EQ(0, frame_); 846 } 847 848 virtual void AfterTest() OVERRIDE {} 849 850 private: 851 int frame_; 852 base::TimeTicks first_frame_time_; 853 }; 854 855 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw); 856 857 // Verifies that StartPageScaleAnimation events propagate correctly 858 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor. 859 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { 860 public: 861 LayerTreeHostTestStartPageScaleAnimation() {} 862 863 virtual void SetupTree() OVERRIDE { 864 LayerTreeHostTest::SetupTree(); 865 866 if (layer_tree_host()->settings().impl_side_painting) { 867 scoped_refptr<FakePictureLayer> layer = 868 FakePictureLayer::Create(&client_); 869 layer->set_always_update_resources(true); 870 scroll_layer_ = layer; 871 } else { 872 scroll_layer_ = FakeContentLayer::Create(&client_); 873 } 874 875 Layer* root_layer = layer_tree_host()->root_layer(); 876 scroll_layer_->SetScrollClipLayerId(root_layer->id()); 877 scroll_layer_->SetIsContainerForFixedPositionLayers(true); 878 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(), 879 2 * root_layer->bounds().height())); 880 scroll_layer_->SetScrollOffset(gfx::Vector2d()); 881 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 882 // This test requires the page_scale and inner viewport layers to be 883 // identified. 884 layer_tree_host()->RegisterViewportLayers( 885 root_layer, scroll_layer_.get(), NULL); 886 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f); 887 } 888 889 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 890 891 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, 892 float scale) OVERRIDE { 893 gfx::Vector2d offset = scroll_layer_->scroll_offset(); 894 scroll_layer_->SetScrollOffset(offset + scroll_delta); 895 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f); 896 } 897 898 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 899 // We get one commit before the first draw, and the animation doesn't happen 900 // until the second draw. 901 switch (impl->active_tree()->source_frame_number()) { 902 case 0: 903 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor()); 904 // We'll start an animation when we get back to the main thread. 905 break; 906 case 1: 907 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor()); 908 break; 909 case 2: 910 EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor()); 911 EndTest(); 912 break; 913 default: 914 NOTREACHED(); 915 } 916 } 917 918 virtual void DidCommitAndDrawFrame() OVERRIDE { 919 switch (layer_tree_host()->source_frame_number()) { 920 case 1: 921 layer_tree_host()->StartPageScaleAnimation( 922 gfx::Vector2d(), false, 1.25f, base::TimeDelta()); 923 break; 924 } 925 } 926 927 virtual void AfterTest() OVERRIDE {} 928 929 FakeContentLayerClient client_; 930 scoped_refptr<Layer> scroll_layer_; 931 }; 932 933 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation); 934 935 class LayerTreeHostTestSetVisible : public LayerTreeHostTest { 936 public: 937 LayerTreeHostTestSetVisible() : num_draws_(0) {} 938 939 virtual void BeginTest() OVERRIDE { 940 PostSetNeedsCommitToMainThread(); 941 PostSetVisibleToMainThread(false); 942 // This is suppressed while we're invisible. 943 PostSetNeedsRedrawToMainThread(); 944 // Triggers the redraw. 945 PostSetVisibleToMainThread(true); 946 } 947 948 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 949 EXPECT_TRUE(impl->visible()); 950 ++num_draws_; 951 EndTest(); 952 } 953 954 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); } 955 956 private: 957 int num_draws_; 958 }; 959 960 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible); 961 962 class TestOpacityChangeLayerDelegate : public ContentLayerClient { 963 public: 964 TestOpacityChangeLayerDelegate() : test_layer_(0) {} 965 966 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; } 967 968 virtual void PaintContents( 969 SkCanvas* canvas, 970 const gfx::Rect& clip, 971 gfx::RectF* opaque, 972 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE { 973 // Set layer opacity to 0. 974 if (test_layer_) 975 test_layer_->SetOpacity(0.f); 976 } 977 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} 978 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } 979 980 private: 981 Layer* test_layer_; 982 }; 983 984 class ContentLayerWithUpdateTracking : public ContentLayer { 985 public: 986 static scoped_refptr<ContentLayerWithUpdateTracking> Create( 987 ContentLayerClient* client) { 988 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client)); 989 } 990 991 int PaintContentsCount() { return paint_contents_count_; } 992 void ResetPaintContentsCount() { paint_contents_count_ = 0; } 993 994 virtual bool Update(ResourceUpdateQueue* queue, 995 const OcclusionTracker<Layer>* occlusion) OVERRIDE { 996 bool updated = ContentLayer::Update(queue, occlusion); 997 paint_contents_count_++; 998 return updated; 999 } 1000 1001 private: 1002 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client) 1003 : ContentLayer(client), paint_contents_count_(0) { 1004 SetBounds(gfx::Size(10, 10)); 1005 SetIsDrawable(true); 1006 } 1007 virtual ~ContentLayerWithUpdateTracking() {} 1008 1009 int paint_contents_count_; 1010 }; 1011 1012 // Layer opacity change during paint should not prevent compositor resources 1013 // from being updated during commit. 1014 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest { 1015 public: 1016 LayerTreeHostTestOpacityChange() 1017 : test_opacity_change_delegate_(), 1018 update_check_layer_(ContentLayerWithUpdateTracking::Create( 1019 &test_opacity_change_delegate_)) { 1020 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get()); 1021 } 1022 1023 virtual void BeginTest() OVERRIDE { 1024 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); 1025 layer_tree_host()->root_layer()->AddChild(update_check_layer_); 1026 1027 PostSetNeedsCommitToMainThread(); 1028 } 1029 1030 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1031 EndTest(); 1032 } 1033 1034 virtual void AfterTest() OVERRIDE { 1035 // Update() should have been called once. 1036 EXPECT_EQ(1, update_check_layer_->PaintContentsCount()); 1037 } 1038 1039 private: 1040 TestOpacityChangeLayerDelegate test_opacity_change_delegate_; 1041 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_; 1042 }; 1043 1044 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange); 1045 1046 class NoScaleContentLayer : public ContentLayer { 1047 public: 1048 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) { 1049 return make_scoped_refptr(new NoScaleContentLayer(client)); 1050 } 1051 1052 virtual void CalculateContentsScale(float ideal_contents_scale, 1053 float device_scale_factor, 1054 float page_scale_factor, 1055 float maximum_animation_contents_scale, 1056 bool animating_transform_to_screen, 1057 float* contents_scale_x, 1058 float* contents_scale_y, 1059 gfx::Size* contentBounds) OVERRIDE { 1060 // Skip over the ContentLayer's method to the base Layer class. 1061 Layer::CalculateContentsScale(ideal_contents_scale, 1062 device_scale_factor, 1063 page_scale_factor, 1064 maximum_animation_contents_scale, 1065 animating_transform_to_screen, 1066 contents_scale_x, 1067 contents_scale_y, 1068 contentBounds); 1069 } 1070 1071 private: 1072 explicit NoScaleContentLayer(ContentLayerClient* client) 1073 : ContentLayer(client) {} 1074 virtual ~NoScaleContentLayer() {} 1075 }; 1076 1077 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers 1078 : public LayerTreeHostTest { 1079 public: 1080 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() 1081 : root_layer_(NoScaleContentLayer::Create(&client_)), 1082 child_layer_(ContentLayer::Create(&client_)) {} 1083 1084 virtual void BeginTest() OVERRIDE { 1085 layer_tree_host()->SetViewportSize(gfx::Size(60, 60)); 1086 layer_tree_host()->SetDeviceScaleFactor(1.5); 1087 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size()); 1088 1089 root_layer_->AddChild(child_layer_); 1090 1091 root_layer_->SetIsDrawable(true); 1092 root_layer_->SetBounds(gfx::Size(30, 30)); 1093 1094 child_layer_->SetIsDrawable(true); 1095 child_layer_->SetPosition(gfx::Point(2, 2)); 1096 child_layer_->SetBounds(gfx::Size(10, 10)); 1097 1098 layer_tree_host()->SetRootLayer(root_layer_); 1099 1100 PostSetNeedsCommitToMainThread(); 1101 } 1102 1103 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1104 // Should only do one commit. 1105 EXPECT_EQ(0, impl->active_tree()->source_frame_number()); 1106 // Device scale factor should come over to impl. 1107 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f); 1108 1109 // Both layers are on impl. 1110 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size()); 1111 1112 // Device viewport is scaled. 1113 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize()); 1114 1115 LayerImpl* root = impl->active_tree()->root_layer(); 1116 LayerImpl* child = impl->active_tree()->root_layer()->children()[0]; 1117 1118 // Positions remain in layout pixels. 1119 EXPECT_EQ(gfx::Point(0, 0), root->position()); 1120 EXPECT_EQ(gfx::Point(2, 2), child->position()); 1121 1122 // Compute all the layer transforms for the frame. 1123 LayerTreeHostImpl::FrameData frame_data; 1124 impl->PrepareToDraw(&frame_data); 1125 impl->DidDrawAllLayers(frame_data); 1126 1127 const LayerImplList& render_surface_layer_list = 1128 *frame_data.render_surface_layer_list; 1129 1130 // Both layers should be drawing into the root render surface. 1131 ASSERT_EQ(1u, render_surface_layer_list.size()); 1132 ASSERT_EQ(root->render_surface(), 1133 render_surface_layer_list[0]->render_surface()); 1134 ASSERT_EQ(2u, root->render_surface()->layer_list().size()); 1135 1136 // The root render surface is the size of the viewport. 1137 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60), 1138 root->render_surface()->content_rect()); 1139 1140 // The content bounds of the child should be scaled. 1141 gfx::Size child_bounds_scaled = 1142 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5)); 1143 EXPECT_EQ(child_bounds_scaled, child->content_bounds()); 1144 1145 gfx::Transform scale_transform; 1146 scale_transform.Scale(impl->device_scale_factor(), 1147 impl->device_scale_factor()); 1148 1149 // The root layer is scaled by 2x. 1150 gfx::Transform root_screen_space_transform = scale_transform; 1151 gfx::Transform root_draw_transform = scale_transform; 1152 1153 EXPECT_EQ(root_draw_transform, root->draw_transform()); 1154 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform()); 1155 1156 // The child is at position 2,2, which is transformed to 3,3 after the scale 1157 gfx::Transform child_screen_space_transform; 1158 child_screen_space_transform.Translate(3.f, 3.f); 1159 gfx::Transform child_draw_transform = child_screen_space_transform; 1160 1161 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform, 1162 child->draw_transform()); 1163 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform, 1164 child->screen_space_transform()); 1165 1166 EndTest(); 1167 } 1168 1169 virtual void AfterTest() OVERRIDE {} 1170 1171 private: 1172 FakeContentLayerClient client_; 1173 scoped_refptr<NoScaleContentLayer> root_layer_; 1174 scoped_refptr<ContentLayer> child_layer_; 1175 }; 1176 1177 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); 1178 1179 // Verify atomicity of commits and reuse of textures. 1180 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { 1181 public: 1182 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 1183 settings->texture_id_allocation_chunk_size = 1; 1184 // Make sure partial texture updates are turned off. 1185 settings->max_partial_texture_updates = 0; 1186 // Linear fade animator prevents scrollbars from drawing immediately. 1187 settings->scrollbar_animator = LayerTreeSettings::NoAnimator; 1188 } 1189 1190 virtual void SetupTree() OVERRIDE { 1191 layer_ = FakeContentLayer::Create(&client_); 1192 layer_->SetBounds(gfx::Size(10, 20)); 1193 1194 bool paint_scrollbar = true; 1195 bool has_thumb = false; 1196 scrollbar_ = FakePaintedScrollbarLayer::Create( 1197 paint_scrollbar, has_thumb, layer_->id()); 1198 scrollbar_->SetPosition(gfx::Point(0, 10)); 1199 scrollbar_->SetBounds(gfx::Size(10, 10)); 1200 1201 layer_->AddChild(scrollbar_); 1202 1203 layer_tree_host()->SetRootLayer(layer_); 1204 LayerTreeHostTest::SetupTree(); 1205 } 1206 1207 virtual void BeginTest() OVERRIDE { 1208 drew_frame_ = -1; 1209 PostSetNeedsCommitToMainThread(); 1210 } 1211 1212 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1213 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates); 1214 1215 TestWebGraphicsContext3D* context = TestContext(); 1216 1217 switch (impl->active_tree()->source_frame_number()) { 1218 case 0: 1219 // Number of textures should be one for each layer 1220 ASSERT_EQ(2u, context->NumTextures()); 1221 // Number of textures used for commit should be one for each layer. 1222 EXPECT_EQ(2u, context->NumUsedTextures()); 1223 // Verify that used texture is correct. 1224 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); 1225 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); 1226 1227 context->ResetUsedTextures(); 1228 break; 1229 case 1: 1230 // Number of textures should be one for scrollbar layer since it was 1231 // requested and deleted on the impl-thread, and double for the content 1232 // layer since its first texture is used by impl thread and cannot by 1233 // used for update. 1234 ASSERT_EQ(3u, context->NumTextures()); 1235 // Number of textures used for commit should be one for each layer. 1236 EXPECT_EQ(2u, context->NumUsedTextures()); 1237 // First textures should not have been used. 1238 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); 1239 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); 1240 // New textures should have been used. 1241 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); 1242 context->ResetUsedTextures(); 1243 break; 1244 case 2: 1245 EndTest(); 1246 break; 1247 default: 1248 NOTREACHED(); 1249 break; 1250 } 1251 } 1252 1253 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1254 TestWebGraphicsContext3D* context = TestContext(); 1255 1256 if (drew_frame_ == impl->active_tree()->source_frame_number()) { 1257 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_; 1258 return; 1259 } 1260 drew_frame_ = impl->active_tree()->source_frame_number(); 1261 1262 // We draw/ship one texture each frame for each layer. 1263 EXPECT_EQ(2u, context->NumUsedTextures()); 1264 context->ResetUsedTextures(); 1265 1266 if (!TestEnded()) 1267 PostSetNeedsCommitToMainThread(); 1268 } 1269 1270 virtual void Layout() OVERRIDE { 1271 layer_->SetNeedsDisplay(); 1272 scrollbar_->SetNeedsDisplay(); 1273 } 1274 1275 virtual void AfterTest() OVERRIDE {} 1276 1277 protected: 1278 FakeContentLayerClient client_; 1279 scoped_refptr<FakeContentLayer> layer_; 1280 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; 1281 int drew_frame_; 1282 }; 1283 1284 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( 1285 LayerTreeHostTestDirectRendererAtomicCommit); 1286 1287 class LayerTreeHostTestDelegatingRendererAtomicCommit 1288 : public LayerTreeHostTestDirectRendererAtomicCommit { 1289 public: 1290 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1291 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates); 1292 1293 TestWebGraphicsContext3D* context = TestContext(); 1294 1295 switch (impl->active_tree()->source_frame_number()) { 1296 case 0: 1297 // Number of textures should be one for each layer 1298 ASSERT_EQ(2u, context->NumTextures()); 1299 // Number of textures used for commit should be one for each layer. 1300 EXPECT_EQ(2u, context->NumUsedTextures()); 1301 // Verify that used texture is correct. 1302 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); 1303 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); 1304 context->ResetUsedTextures(); 1305 break; 1306 case 1: 1307 // Number of textures should be doubled as the first context layer 1308 // texture is being used by the impl-thread and cannot be used for 1309 // update. The scrollbar behavior is different direct renderer because 1310 // UI resource deletion with delegating renderer occurs after tree 1311 // activation. 1312 ASSERT_EQ(4u, context->NumTextures()); 1313 // Number of textures used for commit should still be 1314 // one for each layer. 1315 EXPECT_EQ(2u, context->NumUsedTextures()); 1316 // First textures should not have been used. 1317 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); 1318 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); 1319 // New textures should have been used. 1320 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); 1321 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); 1322 context->ResetUsedTextures(); 1323 break; 1324 case 2: 1325 EndTest(); 1326 break; 1327 default: 1328 NOTREACHED(); 1329 break; 1330 } 1331 } 1332 }; 1333 1334 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F( 1335 LayerTreeHostTestDelegatingRendererAtomicCommit); 1336 1337 static void SetLayerPropertiesForTesting(Layer* layer, 1338 Layer* parent, 1339 const gfx::Transform& transform, 1340 const gfx::Point3F& transform_origin, 1341 const gfx::PointF& position, 1342 const gfx::Size& bounds, 1343 bool opaque) { 1344 layer->RemoveAllChildren(); 1345 if (parent) 1346 parent->AddChild(layer); 1347 layer->SetTransform(transform); 1348 layer->SetTransformOrigin(transform_origin); 1349 layer->SetPosition(position); 1350 layer->SetBounds(bounds); 1351 layer->SetContentsOpaque(opaque); 1352 } 1353 1354 class LayerTreeHostTestAtomicCommitWithPartialUpdate 1355 : public LayerTreeHostTest { 1356 public: 1357 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 1358 settings->texture_id_allocation_chunk_size = 1; 1359 // Allow one partial texture update. 1360 settings->max_partial_texture_updates = 1; 1361 // No partial updates when impl side painting is enabled. 1362 settings->impl_side_painting = false; 1363 } 1364 1365 virtual void SetupTree() OVERRIDE { 1366 parent_ = FakeContentLayer::Create(&client_); 1367 parent_->SetBounds(gfx::Size(10, 20)); 1368 1369 child_ = FakeContentLayer::Create(&client_); 1370 child_->SetPosition(gfx::Point(0, 10)); 1371 child_->SetBounds(gfx::Size(3, 10)); 1372 1373 parent_->AddChild(child_); 1374 1375 layer_tree_host()->SetRootLayer(parent_); 1376 LayerTreeHostTest::SetupTree(); 1377 } 1378 1379 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 1380 1381 virtual void DidCommitAndDrawFrame() OVERRIDE { 1382 switch (layer_tree_host()->source_frame_number()) { 1383 case 1: 1384 parent_->SetNeedsDisplay(); 1385 child_->SetNeedsDisplay(); 1386 break; 1387 case 2: 1388 // Damage part of layers. 1389 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f)); 1390 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f)); 1391 break; 1392 case 3: 1393 child_->SetNeedsDisplay(); 1394 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); 1395 break; 1396 case 4: 1397 layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); 1398 break; 1399 case 5: 1400 EndTest(); 1401 break; 1402 default: 1403 NOTREACHED() << layer_tree_host()->source_frame_number(); 1404 break; 1405 } 1406 } 1407 1408 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1409 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates); 1410 1411 TestWebGraphicsContext3D* context = TestContext(); 1412 1413 switch (impl->active_tree()->source_frame_number()) { 1414 case 0: 1415 // Number of textures should be one for each layer. 1416 ASSERT_EQ(2u, context->NumTextures()); 1417 // Number of textures used for commit should be one for each layer. 1418 EXPECT_EQ(2u, context->NumUsedTextures()); 1419 // Verify that used textures are correct. 1420 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); 1421 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); 1422 context->ResetUsedTextures(); 1423 break; 1424 case 1: 1425 if (HasImplThread()) { 1426 // Number of textures should be two for each content layer. 1427 ASSERT_EQ(4u, context->NumTextures()); 1428 } else { 1429 // In single thread we can always do partial updates, so the limit has 1430 // no effect. 1431 ASSERT_EQ(2u, context->NumTextures()); 1432 } 1433 // Number of textures used for commit should be one for each content 1434 // layer. 1435 EXPECT_EQ(2u, context->NumUsedTextures()); 1436 1437 if (HasImplThread()) { 1438 // First content textures should not have been used. 1439 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); 1440 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); 1441 // New textures should have been used. 1442 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); 1443 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); 1444 } else { 1445 // In single thread we can always do partial updates, so the limit has 1446 // no effect. 1447 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); 1448 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); 1449 } 1450 1451 context->ResetUsedTextures(); 1452 break; 1453 case 2: 1454 if (HasImplThread()) { 1455 // Number of textures should be two for each content layer. 1456 ASSERT_EQ(4u, context->NumTextures()); 1457 } else { 1458 // In single thread we can always do partial updates, so the limit has 1459 // no effect. 1460 ASSERT_EQ(2u, context->NumTextures()); 1461 } 1462 // Number of textures used for commit should be one for each content 1463 // layer. 1464 EXPECT_EQ(2u, context->NumUsedTextures()); 1465 1466 if (HasImplThread()) { 1467 // One content layer does a partial update also. 1468 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); 1469 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3))); 1470 } else { 1471 // In single thread we can always do partial updates, so the limit has 1472 // no effect. 1473 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); 1474 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); 1475 } 1476 1477 context->ResetUsedTextures(); 1478 break; 1479 case 3: 1480 // No textures should be used for commit. 1481 EXPECT_EQ(0u, context->NumUsedTextures()); 1482 1483 context->ResetUsedTextures(); 1484 break; 1485 case 4: 1486 // Number of textures used for commit should be one, for the 1487 // content layer. 1488 EXPECT_EQ(1u, context->NumUsedTextures()); 1489 1490 context->ResetUsedTextures(); 1491 break; 1492 default: 1493 NOTREACHED(); 1494 break; 1495 } 1496 } 1497 1498 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1499 EXPECT_LT(impl->active_tree()->source_frame_number(), 5); 1500 1501 TestWebGraphicsContext3D* context = TestContext(); 1502 1503 // Number of textures used for drawing should one per layer except for 1504 // frame 3 where the viewport only contains one layer. 1505 if (impl->active_tree()->source_frame_number() == 3) { 1506 EXPECT_EQ(1u, context->NumUsedTextures()); 1507 } else { 1508 EXPECT_EQ(2u, context->NumUsedTextures()) 1509 << "For frame " << impl->active_tree()->source_frame_number(); 1510 } 1511 1512 context->ResetUsedTextures(); 1513 } 1514 1515 virtual void AfterTest() OVERRIDE {} 1516 1517 private: 1518 FakeContentLayerClient client_; 1519 scoped_refptr<FakeContentLayer> parent_; 1520 scoped_refptr<FakeContentLayer> child_; 1521 }; 1522 1523 // Partial updates are not possible with a delegating renderer. 1524 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( 1525 LayerTreeHostTestAtomicCommitWithPartialUpdate); 1526 1527 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit 1528 : public LayerTreeHostTest { 1529 protected: 1530 virtual void SetupTree() OVERRIDE { 1531 root_layer_ = FakeContentLayer::Create(&client_); 1532 root_layer_->SetBounds(gfx::Size(100, 100)); 1533 1534 surface_layer1_ = FakeContentLayer::Create(&client_); 1535 surface_layer1_->SetBounds(gfx::Size(100, 100)); 1536 surface_layer1_->SetForceRenderSurface(true); 1537 surface_layer1_->SetOpacity(0.5f); 1538 root_layer_->AddChild(surface_layer1_); 1539 1540 surface_layer2_ = FakeContentLayer::Create(&client_); 1541 surface_layer2_->SetBounds(gfx::Size(100, 100)); 1542 surface_layer2_->SetForceRenderSurface(true); 1543 surface_layer2_->SetOpacity(0.5f); 1544 surface_layer1_->AddChild(surface_layer2_); 1545 1546 replica_layer1_ = FakeContentLayer::Create(&client_); 1547 surface_layer1_->SetReplicaLayer(replica_layer1_.get()); 1548 1549 replica_layer2_ = FakeContentLayer::Create(&client_); 1550 surface_layer2_->SetReplicaLayer(replica_layer2_.get()); 1551 1552 layer_tree_host()->SetRootLayer(root_layer_); 1553 LayerTreeHostTest::SetupTree(); 1554 } 1555 1556 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 1557 1558 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 1559 Renderer* renderer = host_impl->renderer(); 1560 RenderPass::Id surface1_render_pass_id = host_impl->active_tree() 1561 ->root_layer() 1562 ->children()[0] 1563 ->render_surface() 1564 ->RenderPassId(); 1565 RenderPass::Id surface2_render_pass_id = host_impl->active_tree() 1566 ->root_layer() 1567 ->children()[0] 1568 ->children()[0] 1569 ->render_surface() 1570 ->RenderPassId(); 1571 1572 switch (host_impl->active_tree()->source_frame_number()) { 1573 case 0: 1574 EXPECT_TRUE( 1575 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id)); 1576 EXPECT_TRUE( 1577 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id)); 1578 1579 // Reduce the memory limit to only fit the root layer and one render 1580 // surface. This prevents any contents drawing into surfaces 1581 // from being allocated. 1582 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2)); 1583 break; 1584 case 1: 1585 EXPECT_FALSE( 1586 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id)); 1587 EXPECT_FALSE( 1588 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id)); 1589 1590 EndTest(); 1591 break; 1592 } 1593 } 1594 1595 virtual void DidCommitAndDrawFrame() OVERRIDE { 1596 if (layer_tree_host()->source_frame_number() < 2) 1597 root_layer_->SetNeedsDisplay(); 1598 } 1599 1600 virtual void AfterTest() OVERRIDE { 1601 EXPECT_LE(2u, root_layer_->update_count()); 1602 EXPECT_LE(2u, surface_layer1_->update_count()); 1603 EXPECT_LE(2u, surface_layer2_->update_count()); 1604 } 1605 1606 FakeContentLayerClient client_; 1607 scoped_refptr<FakeContentLayer> root_layer_; 1608 scoped_refptr<FakeContentLayer> surface_layer1_; 1609 scoped_refptr<FakeContentLayer> replica_layer1_; 1610 scoped_refptr<FakeContentLayer> surface_layer2_; 1611 scoped_refptr<FakeContentLayer> replica_layer2_; 1612 }; 1613 1614 // Surfaces don't exist with a delegated renderer. 1615 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( 1616 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit); 1617 1618 class EvictionTestLayer : public Layer { 1619 public: 1620 static scoped_refptr<EvictionTestLayer> Create() { 1621 return make_scoped_refptr(new EvictionTestLayer()); 1622 } 1623 1624 virtual bool Update(ResourceUpdateQueue*, 1625 const OcclusionTracker<Layer>*) OVERRIDE; 1626 virtual bool DrawsContent() const OVERRIDE { return true; } 1627 1628 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) 1629 OVERRIDE; 1630 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE; 1631 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE; 1632 1633 bool HaveBackingTexture() const { 1634 return texture_.get() ? texture_->have_backing_texture() : false; 1635 } 1636 1637 private: 1638 EvictionTestLayer() : Layer() {} 1639 virtual ~EvictionTestLayer() {} 1640 1641 void CreateTextureIfNeeded() { 1642 if (texture_) 1643 return; 1644 texture_ = PrioritizedResource::Create( 1645 layer_tree_host()->contents_texture_manager()); 1646 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888); 1647 bitmap_.allocN32Pixels(10, 10); 1648 } 1649 1650 scoped_ptr<PrioritizedResource> texture_; 1651 SkBitmap bitmap_; 1652 }; 1653 1654 class EvictionTestLayerImpl : public LayerImpl { 1655 public: 1656 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl, 1657 int id) { 1658 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id)); 1659 } 1660 virtual ~EvictionTestLayerImpl() {} 1661 1662 virtual void AppendQuads(QuadSink* quad_sink, 1663 AppendQuadsData* append_quads_data) OVERRIDE { 1664 ASSERT_TRUE(has_texture_); 1665 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources()); 1666 } 1667 1668 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; } 1669 1670 private: 1671 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id) 1672 : LayerImpl(tree_impl, id), has_texture_(false) {} 1673 1674 bool has_texture_; 1675 }; 1676 1677 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) { 1678 CreateTextureIfNeeded(); 1679 if (!texture_) 1680 return; 1681 texture_->set_request_priority(PriorityCalculator::UIPriority(true)); 1682 } 1683 1684 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue, 1685 const OcclusionTracker<Layer>* occlusion) { 1686 CreateTextureIfNeeded(); 1687 if (!texture_) 1688 return false; 1689 1690 gfx::Rect full_rect(0, 0, 10, 10); 1691 ResourceUpdate upload = ResourceUpdate::Create( 1692 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d()); 1693 queue->AppendFullUpload(upload); 1694 return true; 1695 } 1696 1697 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl( 1698 LayerTreeImpl* tree_impl) { 1699 return EvictionTestLayerImpl::Create(tree_impl, layer_id_) 1700 .PassAs<LayerImpl>(); 1701 } 1702 1703 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) { 1704 Layer::PushPropertiesTo(layer_impl); 1705 1706 EvictionTestLayerImpl* test_layer_impl = 1707 static_cast<EvictionTestLayerImpl*>(layer_impl); 1708 test_layer_impl->SetHasTexture(texture_->have_backing_texture()); 1709 } 1710 1711 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { 1712 public: 1713 LayerTreeHostTestEvictTextures() 1714 : layer_(EvictionTestLayer::Create()), 1715 impl_for_evict_textures_(0), 1716 num_commits_(0) {} 1717 1718 virtual void BeginTest() OVERRIDE { 1719 layer_tree_host()->SetRootLayer(layer_); 1720 layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); 1721 1722 gfx::Transform identity_matrix; 1723 SetLayerPropertiesForTesting(layer_.get(), 1724 0, 1725 identity_matrix, 1726 gfx::Point3F(0.f, 0.f, 0.f), 1727 gfx::PointF(0.f, 0.f), 1728 gfx::Size(10, 20), 1729 true); 1730 1731 PostSetNeedsCommitToMainThread(); 1732 } 1733 1734 void PostEvictTextures() { 1735 ImplThreadTaskRunner()->PostTask( 1736 FROM_HERE, 1737 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread, 1738 base::Unretained(this))); 1739 } 1740 1741 void EvictTexturesOnImplThread() { 1742 DCHECK(impl_for_evict_textures_); 1743 impl_for_evict_textures_->EvictTexturesForTesting(); 1744 } 1745 1746 // Commit 1: Just commit and draw normally, then post an eviction at the end 1747 // that will trigger a commit. 1748 // Commit 2: Triggered by the eviction, let it go through and then set 1749 // needsCommit. 1750 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction 1751 // task, which will be handled before the commit. Don't set needsCommit, it 1752 // should have been posted. A frame should not be drawn (note, 1753 // didCommitAndDrawFrame may be called anyway). 1754 // Commit 4: Triggered by the eviction, let it go through and then set 1755 // needsCommit. 1756 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in 1757 // Layout(), a frame should not be drawn but a commit will be posted. 1758 // Commit 6: Triggered by the eviction, post an eviction task in 1759 // Layout(), which will be a noop, letting the commit (which recreates the 1760 // textures) go through and draw a frame, then end the test. 1761 // 1762 // Commits 1+2 test the eviction recovery path where eviction happens outside 1763 // of the beginFrame/commit pair. 1764 // Commits 3+4 test the eviction recovery path where eviction happens inside 1765 // the beginFrame/commit pair. 1766 // Commits 5+6 test the path where an eviction happens during the eviction 1767 // recovery path. 1768 virtual void DidCommit() OVERRIDE { 1769 switch (num_commits_) { 1770 case 1: 1771 EXPECT_TRUE(layer_->HaveBackingTexture()); 1772 PostEvictTextures(); 1773 break; 1774 case 2: 1775 EXPECT_TRUE(layer_->HaveBackingTexture()); 1776 layer_tree_host()->SetNeedsCommit(); 1777 break; 1778 case 3: 1779 break; 1780 case 4: 1781 EXPECT_TRUE(layer_->HaveBackingTexture()); 1782 layer_tree_host()->SetNeedsCommit(); 1783 break; 1784 case 5: 1785 break; 1786 case 6: 1787 EXPECT_TRUE(layer_->HaveBackingTexture()); 1788 EndTest(); 1789 break; 1790 default: 1791 NOTREACHED(); 1792 break; 1793 } 1794 } 1795 1796 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1797 impl_for_evict_textures_ = impl; 1798 } 1799 1800 virtual void Layout() OVERRIDE { 1801 ++num_commits_; 1802 switch (num_commits_) { 1803 case 1: 1804 case 2: 1805 break; 1806 case 3: 1807 PostEvictTextures(); 1808 break; 1809 case 4: 1810 // We couldn't check in didCommitAndDrawFrame on commit 3, 1811 // so check here. 1812 EXPECT_FALSE(layer_->HaveBackingTexture()); 1813 break; 1814 case 5: 1815 PostEvictTextures(); 1816 break; 1817 case 6: 1818 // We couldn't check in didCommitAndDrawFrame on commit 5, 1819 // so check here. 1820 EXPECT_FALSE(layer_->HaveBackingTexture()); 1821 PostEvictTextures(); 1822 break; 1823 default: 1824 NOTREACHED(); 1825 break; 1826 } 1827 } 1828 1829 virtual void AfterTest() OVERRIDE {} 1830 1831 private: 1832 FakeContentLayerClient client_; 1833 scoped_refptr<EvictionTestLayer> layer_; 1834 LayerTreeHostImpl* impl_for_evict_textures_; 1835 int num_commits_; 1836 }; 1837 1838 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures); 1839 1840 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest { 1841 public: 1842 LayerTreeHostTestContinuousCommit() 1843 : num_commit_complete_(0), num_draw_layers_(0) {} 1844 1845 virtual void BeginTest() OVERRIDE { 1846 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); 1847 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); 1848 1849 PostSetNeedsCommitToMainThread(); 1850 } 1851 1852 virtual void DidCommit() OVERRIDE { 1853 if (num_draw_layers_ == 2) 1854 return; 1855 layer_tree_host()->SetNeedsCommit(); 1856 } 1857 1858 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1859 if (num_draw_layers_ == 1) 1860 num_commit_complete_++; 1861 } 1862 1863 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1864 num_draw_layers_++; 1865 if (num_draw_layers_ == 2) 1866 EndTest(); 1867 } 1868 1869 virtual void AfterTest() OVERRIDE { 1870 // Check that we didn't commit twice between first and second draw. 1871 EXPECT_EQ(1, num_commit_complete_); 1872 } 1873 1874 private: 1875 int num_commit_complete_; 1876 int num_draw_layers_; 1877 }; 1878 1879 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit); 1880 1881 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { 1882 public: 1883 LayerTreeHostTestContinuousInvalidate() 1884 : num_commit_complete_(0), num_draw_layers_(0) {} 1885 1886 virtual void BeginTest() OVERRIDE { 1887 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); 1888 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); 1889 1890 content_layer_ = ContentLayer::Create(&client_); 1891 content_layer_->SetBounds(gfx::Size(10, 10)); 1892 content_layer_->SetPosition(gfx::PointF(0.f, 0.f)); 1893 content_layer_->SetIsDrawable(true); 1894 layer_tree_host()->root_layer()->AddChild(content_layer_); 1895 1896 PostSetNeedsCommitToMainThread(); 1897 } 1898 1899 virtual void DidCommitAndDrawFrame() OVERRIDE { 1900 if (num_draw_layers_ == 2) 1901 return; 1902 content_layer_->SetNeedsDisplay(); 1903 } 1904 1905 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1906 if (num_draw_layers_ == 1) 1907 num_commit_complete_++; 1908 } 1909 1910 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 1911 num_draw_layers_++; 1912 if (num_draw_layers_ == 2) 1913 EndTest(); 1914 } 1915 1916 virtual void AfterTest() OVERRIDE { 1917 // Check that we didn't commit twice between first and second draw. 1918 EXPECT_EQ(1, num_commit_complete_); 1919 } 1920 1921 private: 1922 FakeContentLayerClient client_; 1923 scoped_refptr<Layer> content_layer_; 1924 int num_commit_complete_; 1925 int num_draw_layers_; 1926 }; 1927 1928 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestContinuousInvalidate); 1929 1930 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { 1931 public: 1932 LayerTreeHostTestDeferCommits() 1933 : num_commits_deferred_(0), num_complete_commits_(0) {} 1934 1935 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 1936 1937 virtual void DidDeferCommit() OVERRIDE { 1938 num_commits_deferred_++; 1939 layer_tree_host()->SetDeferCommits(false); 1940 } 1941 1942 virtual void DidCommit() OVERRIDE { 1943 num_complete_commits_++; 1944 switch (num_complete_commits_) { 1945 case 1: 1946 EXPECT_EQ(0, num_commits_deferred_); 1947 layer_tree_host()->SetDeferCommits(true); 1948 PostSetNeedsCommitToMainThread(); 1949 break; 1950 case 2: 1951 EndTest(); 1952 break; 1953 default: 1954 NOTREACHED(); 1955 break; 1956 } 1957 } 1958 1959 virtual void AfterTest() OVERRIDE { 1960 EXPECT_EQ(1, num_commits_deferred_); 1961 EXPECT_EQ(2, num_complete_commits_); 1962 } 1963 1964 private: 1965 int num_commits_deferred_; 1966 int num_complete_commits_; 1967 }; 1968 1969 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); 1970 1971 class LayerTreeHostWithProxy : public LayerTreeHost { 1972 public: 1973 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client, 1974 const LayerTreeSettings& settings, 1975 scoped_ptr<FakeProxy> proxy) 1976 : LayerTreeHost(client, NULL, settings) { 1977 proxy->SetLayerTreeHost(this); 1978 InitializeForTesting(proxy.PassAs<Proxy>()); 1979 } 1980 }; 1981 1982 TEST(LayerTreeHostTest, LimitPartialUpdates) { 1983 // When partial updates are not allowed, max updates should be 0. 1984 { 1985 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); 1986 1987 scoped_ptr<FakeProxy> proxy(new FakeProxy); 1988 proxy->GetRendererCapabilities().allow_partial_texture_updates = false; 1989 proxy->SetMaxPartialTextureUpdates(5); 1990 1991 LayerTreeSettings settings; 1992 settings.max_partial_texture_updates = 10; 1993 1994 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); 1995 host.OnCreateAndInitializeOutputSurfaceAttempted(true); 1996 1997 EXPECT_EQ(0u, host.MaxPartialTextureUpdates()); 1998 } 1999 2000 // When partial updates are allowed, 2001 // max updates should be limited by the proxy. 2002 { 2003 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); 2004 2005 scoped_ptr<FakeProxy> proxy(new FakeProxy); 2006 proxy->GetRendererCapabilities().allow_partial_texture_updates = true; 2007 proxy->SetMaxPartialTextureUpdates(5); 2008 2009 LayerTreeSettings settings; 2010 settings.max_partial_texture_updates = 10; 2011 2012 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); 2013 host.OnCreateAndInitializeOutputSurfaceAttempted(true); 2014 2015 EXPECT_EQ(5u, host.MaxPartialTextureUpdates()); 2016 } 2017 2018 // When partial updates are allowed, 2019 // max updates should also be limited by the settings. 2020 { 2021 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); 2022 2023 scoped_ptr<FakeProxy> proxy(new FakeProxy); 2024 proxy->GetRendererCapabilities().allow_partial_texture_updates = true; 2025 proxy->SetMaxPartialTextureUpdates(20); 2026 2027 LayerTreeSettings settings; 2028 settings.max_partial_texture_updates = 10; 2029 2030 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); 2031 host.OnCreateAndInitializeOutputSurfaceAttempted(true); 2032 2033 EXPECT_EQ(10u, host.MaxPartialTextureUpdates()); 2034 } 2035 } 2036 2037 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) { 2038 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); 2039 2040 LayerTreeSettings settings; 2041 settings.max_partial_texture_updates = 4; 2042 2043 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 2044 new TestSharedBitmapManager()); 2045 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( 2046 &client, &client, shared_bitmap_manager.get(), settings); 2047 host->Composite(base::TimeTicks::Now()); 2048 2049 EXPECT_EQ(4u, host->settings().max_partial_texture_updates); 2050 } 2051 2052 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) { 2053 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE); 2054 2055 LayerTreeSettings settings; 2056 settings.max_partial_texture_updates = 4; 2057 2058 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 2059 new TestSharedBitmapManager()); 2060 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( 2061 &client, &client, shared_bitmap_manager.get(), settings); 2062 host->Composite(base::TimeTicks::Now()); 2063 2064 EXPECT_EQ(4u, host->settings().max_partial_texture_updates); 2065 } 2066 2067 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) { 2068 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D); 2069 2070 LayerTreeSettings settings; 2071 settings.max_partial_texture_updates = 4; 2072 2073 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 2074 new TestSharedBitmapManager()); 2075 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( 2076 &client, &client, shared_bitmap_manager.get(), settings); 2077 host->Composite(base::TimeTicks::Now()); 2078 2079 EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); 2080 } 2081 2082 TEST(LayerTreeHostTest, 2083 PartialUpdatesWithDelegatingRendererAndSoftwareContent) { 2084 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE); 2085 2086 LayerTreeSettings settings; 2087 settings.max_partial_texture_updates = 4; 2088 2089 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 2090 new TestSharedBitmapManager()); 2091 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( 2092 &client, &client, shared_bitmap_manager.get(), settings); 2093 host->Composite(base::TimeTicks::Now()); 2094 2095 EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); 2096 } 2097 2098 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted 2099 : public LayerTreeHostTest { 2100 public: 2101 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted() 2102 : root_layer_(FakeContentLayer::Create(&client_)), 2103 child_layer1_(FakeContentLayer::Create(&client_)), 2104 child_layer2_(FakeContentLayer::Create(&client_)), 2105 num_commits_(0) {} 2106 2107 virtual void BeginTest() OVERRIDE { 2108 layer_tree_host()->SetViewportSize(gfx::Size(100, 100)); 2109 root_layer_->SetBounds(gfx::Size(100, 100)); 2110 child_layer1_->SetBounds(gfx::Size(100, 100)); 2111 child_layer2_->SetBounds(gfx::Size(100, 100)); 2112 root_layer_->AddChild(child_layer1_); 2113 root_layer_->AddChild(child_layer2_); 2114 layer_tree_host()->SetRootLayer(root_layer_); 2115 PostSetNeedsCommitToMainThread(); 2116 } 2117 2118 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, 2119 bool visible) OVERRIDE { 2120 if (visible) { 2121 // One backing should remain unevicted. 2122 EXPECT_EQ( 2123 100u * 100u * 4u * 1u, 2124 layer_tree_host()->contents_texture_manager()->MemoryUseBytes()); 2125 } else { 2126 EXPECT_EQ( 2127 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes()); 2128 } 2129 2130 // Make sure that contents textures are marked as having been 2131 // purged. 2132 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged()); 2133 // End the test in this state. 2134 EndTest(); 2135 } 2136 2137 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 2138 ++num_commits_; 2139 switch (num_commits_) { 2140 case 1: 2141 // All three backings should have memory. 2142 EXPECT_EQ( 2143 100u * 100u * 4u * 3u, 2144 layer_tree_host()->contents_texture_manager()->MemoryUseBytes()); 2145 // Set a new policy that will kick out 1 of the 3 resources. 2146 // Because a resource was evicted, a commit will be kicked off. 2147 host_impl->SetMemoryPolicy( 2148 ManagedMemoryPolicy(100 * 100 * 4 * 2, 2149 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 2150 1000)); 2151 break; 2152 case 2: 2153 // Only two backings should have memory. 2154 EXPECT_EQ( 2155 100u * 100u * 4u * 2u, 2156 layer_tree_host()->contents_texture_manager()->MemoryUseBytes()); 2157 // Become backgrounded, which will cause 1 more resource to be 2158 // evicted. 2159 PostSetVisibleToMainThread(false); 2160 break; 2161 default: 2162 // No further commits should happen because this is not visible 2163 // anymore. 2164 NOTREACHED(); 2165 break; 2166 } 2167 } 2168 2169 virtual void AfterTest() OVERRIDE {} 2170 2171 private: 2172 FakeContentLayerClient client_; 2173 scoped_refptr<FakeContentLayer> root_layer_; 2174 scoped_refptr<FakeContentLayer> child_layer1_; 2175 scoped_refptr<FakeContentLayer> child_layer2_; 2176 int num_commits_; 2177 }; 2178 2179 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F( 2180 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted); 2181 2182 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest { 2183 public: 2184 class NotificationClient : public ContentLayerClient { 2185 public: 2186 NotificationClient() 2187 : layer_(0), paint_count_(0), lcd_notification_count_(0) {} 2188 2189 void set_layer(Layer* layer) { layer_ = layer; } 2190 int paint_count() const { return paint_count_; } 2191 int lcd_notification_count() const { return lcd_notification_count_; } 2192 2193 virtual void PaintContents( 2194 SkCanvas* canvas, 2195 const gfx::Rect& clip, 2196 gfx::RectF* opaque, 2197 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE { 2198 ++paint_count_; 2199 } 2200 virtual void DidChangeLayerCanUseLCDText() OVERRIDE { 2201 ++lcd_notification_count_; 2202 layer_->SetNeedsDisplay(); 2203 } 2204 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } 2205 2206 private: 2207 Layer* layer_; 2208 int paint_count_; 2209 int lcd_notification_count_; 2210 }; 2211 2212 virtual void SetupTree() OVERRIDE { 2213 scoped_refptr<Layer> root_layer; 2214 if (layer_tree_host()->settings().impl_side_painting) 2215 root_layer = PictureLayer::Create(&client_); 2216 else 2217 root_layer = ContentLayer::Create(&client_); 2218 root_layer->SetIsDrawable(true); 2219 root_layer->SetBounds(gfx::Size(1, 1)); 2220 2221 layer_tree_host()->SetRootLayer(root_layer); 2222 client_.set_layer(root_layer.get()); 2223 2224 // The expecations are based on the assumption that the default 2225 // LCD settings are: 2226 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text); 2227 EXPECT_FALSE(root_layer->can_use_lcd_text()); 2228 2229 LayerTreeHostTest::SetupTree(); 2230 } 2231 2232 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 2233 virtual void AfterTest() OVERRIDE {} 2234 2235 virtual void DidCommit() OVERRIDE { 2236 switch (layer_tree_host()->source_frame_number()) { 2237 case 1: 2238 // The first update consists of one LCD notification and one paint. 2239 EXPECT_EQ(1, client_.lcd_notification_count()); 2240 EXPECT_EQ(1, client_.paint_count()); 2241 // LCD text must have been enabled on the layer. 2242 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text()); 2243 PostSetNeedsCommitToMainThread(); 2244 break; 2245 case 2: 2246 // Since nothing changed on layer, there should be no notification 2247 // or paint on the second update. 2248 EXPECT_EQ(1, client_.lcd_notification_count()); 2249 EXPECT_EQ(1, client_.paint_count()); 2250 // LCD text must not have changed. 2251 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text()); 2252 // Change layer opacity that should trigger lcd notification. 2253 layer_tree_host()->root_layer()->SetOpacity(.5f); 2254 // No need to request a commit - setting opacity will do it. 2255 break; 2256 default: 2257 // Verify that there is no extra commit due to layer invalidation. 2258 EXPECT_EQ(3, layer_tree_host()->source_frame_number()); 2259 // LCD notification count should have incremented due to 2260 // change in layer opacity. 2261 EXPECT_EQ(2, client_.lcd_notification_count()); 2262 // Paint count should be incremented due to invalidation. 2263 EXPECT_EQ(2, client_.paint_count()); 2264 // LCD text must have been disabled on the layer due to opacity. 2265 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text()); 2266 EndTest(); 2267 break; 2268 } 2269 } 2270 2271 private: 2272 NotificationClient client_; 2273 }; 2274 2275 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDNotification); 2276 2277 // Verify that the BeginFrame notification is used to initiate rendering. 2278 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest { 2279 public: 2280 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 2281 settings->begin_frame_scheduling_enabled = true; 2282 } 2283 2284 virtual void BeginTest() OVERRIDE { 2285 // This will trigger a SetNeedsBeginFrame which will trigger a 2286 // BeginFrame. 2287 PostSetNeedsCommitToMainThread(); 2288 } 2289 2290 virtual DrawResult PrepareToDrawOnThread( 2291 LayerTreeHostImpl* host_impl, 2292 LayerTreeHostImpl::FrameData* frame, 2293 DrawResult draw_result) OVERRIDE { 2294 EndTest(); 2295 return DRAW_SUCCESS; 2296 } 2297 2298 virtual void AfterTest() OVERRIDE {} 2299 2300 private: 2301 base::TimeTicks frame_time_; 2302 }; 2303 2304 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification); 2305 2306 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled 2307 : public LayerTreeHostTest { 2308 public: 2309 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 2310 settings->begin_frame_scheduling_enabled = true; 2311 settings->using_synchronous_renderer_compositor = true; 2312 } 2313 2314 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 2315 2316 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 2317 // The BeginFrame notification is turned off now but will get enabled 2318 // once we return. End test while it's enabled. 2319 ImplThreadTaskRunner()->PostTask( 2320 FROM_HERE, 2321 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest, 2322 base::Unretained(this))); 2323 } 2324 2325 virtual void AfterTest() OVERRIDE {} 2326 }; 2327 2328 MULTI_THREAD_TEST_F( 2329 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled); 2330 2331 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { 2332 protected: 2333 LayerTreeHostTestAbortedCommitDoesntStall() 2334 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {} 2335 2336 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 2337 settings->begin_frame_scheduling_enabled = true; 2338 } 2339 2340 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 2341 2342 virtual void DidCommit() OVERRIDE { 2343 commit_count_++; 2344 if (commit_count_ == 4) { 2345 // After two aborted commits, request a real commit now to make sure a 2346 // real commit following an aborted commit will still complete and 2347 // end the test even when the Impl thread is idle. 2348 layer_tree_host()->SetNeedsCommit(); 2349 } 2350 } 2351 2352 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, 2353 bool did_handle) OVERRIDE { 2354 commit_abort_count_++; 2355 // Initiate another abortable commit. 2356 host_impl->SetNeedsCommit(); 2357 } 2358 2359 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 2360 commit_complete_count_++; 2361 if (commit_complete_count_ == 1) { 2362 // Initiate an abortable commit after the first commit. 2363 host_impl->SetNeedsCommit(); 2364 } else { 2365 EndTest(); 2366 } 2367 } 2368 2369 virtual void AfterTest() OVERRIDE { 2370 EXPECT_EQ(commit_count_, 5); 2371 EXPECT_EQ(commit_abort_count_, 3); 2372 EXPECT_EQ(commit_complete_count_, 2); 2373 } 2374 2375 int commit_count_; 2376 int commit_abort_count_; 2377 int commit_complete_count_; 2378 }; 2379 2380 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor 2381 : public LayerTreeHostTestAbortedCommitDoesntStall { 2382 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 2383 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); 2384 settings->using_synchronous_renderer_compositor = true; 2385 } 2386 }; 2387 2388 MULTI_THREAD_TEST_F( 2389 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor); 2390 2391 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync 2392 : public LayerTreeHostTestAbortedCommitDoesntStall { 2393 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 2394 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); 2395 settings->throttle_frame_production = false; 2396 } 2397 }; 2398 2399 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync); 2400 2401 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation 2402 : public LayerTreeHostTest { 2403 protected: 2404 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 2405 settings->impl_side_painting = true; 2406 } 2407 2408 virtual void SetupTree() OVERRIDE { 2409 LayerTreeHostTest::SetupTree(); 2410 2411 scoped_refptr<Layer> layer = PictureLayer::Create(&client_); 2412 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); 2413 layer->SetBounds(gfx::Size(10, 10)); 2414 layer_tree_host()->root_layer()->AddChild(layer); 2415 } 2416 2417 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 2418 2419 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 2420 EndTest(); 2421 } 2422 2423 virtual void AfterTest() OVERRIDE {} 2424 2425 FakeContentLayerClient client_; 2426 }; 2427 2428 MULTI_THREAD_TEST_F( 2429 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation); 2430 2431 class LayerTreeHostTestChangeLayerPropertiesInPaintContents 2432 : public LayerTreeHostTest { 2433 public: 2434 class SetBoundsClient : public ContentLayerClient { 2435 public: 2436 SetBoundsClient() : layer_(0) {} 2437 2438 void set_layer(Layer* layer) { layer_ = layer; } 2439 2440 virtual void PaintContents( 2441 SkCanvas* canvas, 2442 const gfx::Rect& clip, 2443 gfx::RectF* opaque, 2444 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE { 2445 layer_->SetBounds(gfx::Size(2, 2)); 2446 } 2447 2448 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} 2449 2450 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } 2451 2452 private: 2453 Layer* layer_; 2454 }; 2455 2456 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {} 2457 2458 virtual void SetupTree() OVERRIDE { 2459 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_); 2460 root_layer->SetIsDrawable(true); 2461 root_layer->SetBounds(gfx::Size(1, 1)); 2462 2463 layer_tree_host()->SetRootLayer(root_layer); 2464 client_.set_layer(root_layer.get()); 2465 2466 LayerTreeHostTest::SetupTree(); 2467 } 2468 2469 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 2470 virtual void AfterTest() OVERRIDE {} 2471 2472 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 2473 num_commits_++; 2474 if (num_commits_ == 1) { 2475 LayerImpl* root_layer = host_impl->active_tree()->root_layer(); 2476 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds()); 2477 } else { 2478 LayerImpl* root_layer = host_impl->active_tree()->root_layer(); 2479 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds()); 2480 EndTest(); 2481 } 2482 } 2483 2484 private: 2485 SetBoundsClient client_; 2486 int num_commits_; 2487 }; 2488 2489 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents); 2490 2491 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { 2492 public: 2493 MockIOSurfaceWebGraphicsContext3D() { 2494 test_capabilities_.gpu.iosurface = true; 2495 test_capabilities_.gpu.texture_rectangle = true; 2496 } 2497 2498 virtual GLuint createTexture() OVERRIDE { 2499 return 1; 2500 } 2501 MOCK_METHOD1(activeTexture, void(GLenum texture)); 2502 MOCK_METHOD2(bindTexture, void(GLenum target, 2503 GLuint texture_id)); 2504 MOCK_METHOD3(texParameteri, void(GLenum target, 2505 GLenum pname, 2506 GLint param)); 2507 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target, 2508 GLint width, 2509 GLint height, 2510 GLuint ioSurfaceId, 2511 GLuint plane)); 2512 MOCK_METHOD4(drawElements, void(GLenum mode, 2513 GLsizei count, 2514 GLenum type, 2515 GLintptr offset)); 2516 MOCK_METHOD1(deleteTexture, void(GLenum texture)); 2517 MOCK_METHOD2(produceTextureCHROMIUM, 2518 void(GLenum target, const GLbyte* mailbox)); 2519 }; 2520 2521 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { 2522 protected: 2523 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) 2524 OVERRIDE { 2525 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned( 2526 new MockIOSurfaceWebGraphicsContext3D); 2527 mock_context_ = mock_context_owned.get(); 2528 2529 if (delegating_renderer()) { 2530 return FakeOutputSurface::CreateDelegating3d( 2531 mock_context_owned.PassAs<TestWebGraphicsContext3D>()); 2532 } else { 2533 return FakeOutputSurface::Create3d( 2534 mock_context_owned.PassAs<TestWebGraphicsContext3D>()); 2535 } 2536 } 2537 2538 virtual void SetupTree() OVERRIDE { 2539 LayerTreeHostTest::SetupTree(); 2540 2541 layer_tree_host()->root_layer()->SetIsDrawable(false); 2542 2543 io_surface_id_ = 9; 2544 io_surface_size_ = gfx::Size(6, 7); 2545 2546 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create(); 2547 io_surface_layer->SetBounds(gfx::Size(10, 10)); 2548 io_surface_layer->SetIsDrawable(true); 2549 io_surface_layer->SetContentsOpaque(true); 2550 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); 2551 layer_tree_host()->root_layer()->AddChild(io_surface_layer); 2552 } 2553 2554 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 2555 2556 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 2557 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources()); 2558 // In WillDraw, the IOSurfaceLayer sets up the io surface texture. 2559 2560 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0); 2561 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1)) 2562 .Times(AtLeast(1)); 2563 EXPECT_CALL(*mock_context_, 2564 texParameteri( 2565 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)) 2566 .Times(1); 2567 EXPECT_CALL(*mock_context_, 2568 texParameteri( 2569 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR)) 2570 .Times(1); 2571 EXPECT_CALL(*mock_context_, 2572 texParameteri(GL_TEXTURE_RECTANGLE_ARB, 2573 GL_TEXTURE_POOL_CHROMIUM, 2574 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1); 2575 EXPECT_CALL(*mock_context_, 2576 texParameteri(GL_TEXTURE_RECTANGLE_ARB, 2577 GL_TEXTURE_WRAP_S, 2578 GL_CLAMP_TO_EDGE)).Times(1); 2579 EXPECT_CALL(*mock_context_, 2580 texParameteri(GL_TEXTURE_RECTANGLE_ARB, 2581 GL_TEXTURE_WRAP_T, 2582 GL_CLAMP_TO_EDGE)).Times(1); 2583 2584 EXPECT_CALL(*mock_context_, 2585 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, 2586 io_surface_size_.width(), 2587 io_surface_size_.height(), 2588 io_surface_id_, 2589 0)).Times(1); 2590 2591 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber()); 2592 } 2593 2594 virtual DrawResult PrepareToDrawOnThread( 2595 LayerTreeHostImpl* host_impl, 2596 LayerTreeHostImpl::FrameData* frame, 2597 DrawResult draw_result) OVERRIDE { 2598 Mock::VerifyAndClearExpectations(&mock_context_); 2599 ResourceProvider* resource_provider = host_impl->resource_provider(); 2600 EXPECT_EQ(1u, resource_provider->num_resources()); 2601 CHECK_EQ(1u, frame->render_passes.size()); 2602 CHECK_LE(1u, frame->render_passes[0]->quad_list.size()); 2603 const DrawQuad* quad = frame->render_passes[0]->quad_list[0]; 2604 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material); 2605 const IOSurfaceDrawQuad* io_surface_draw_quad = 2606 IOSurfaceDrawQuad::MaterialCast(quad); 2607 EXPECT_SIZE_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size); 2608 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id); 2609 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), 2610 resource_provider->TargetForTesting( 2611 io_surface_draw_quad->io_surface_resource_id)); 2612 2613 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1)) 2614 .Times(1); 2615 if (delegating_renderer()) { 2616 // The io surface layer's resource should be sent to the parent. 2617 EXPECT_CALL(*mock_context_, 2618 produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1); 2619 } else { 2620 // The io surface layer's texture is drawn. 2621 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1)); 2622 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _)) 2623 .Times(AtLeast(1)); 2624 } 2625 2626 return draw_result; 2627 } 2628 2629 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 2630 Mock::VerifyAndClearExpectations(&mock_context_); 2631 2632 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1)); 2633 EndTest(); 2634 } 2635 2636 virtual void AfterTest() OVERRIDE {} 2637 2638 int io_surface_id_; 2639 MockIOSurfaceWebGraphicsContext3D* mock_context_; 2640 gfx::Size io_surface_size_; 2641 }; 2642 2643 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing); 2644 2645 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { 2646 public: 2647 virtual void BeginTest() OVERRIDE { 2648 frame_ = 0; 2649 PostSetNeedsCommitToMainThread(); 2650 } 2651 2652 // Round 1: commit + draw 2653 // Round 2: commit only (no draw/swap) 2654 // Round 3: draw only (no commit) 2655 2656 virtual void DidCommit() OVERRIDE { 2657 int commit = layer_tree_host()->source_frame_number(); 2658 switch (commit) { 2659 case 2: 2660 // Round 2 done. 2661 EXPECT_EQ(1, frame_); 2662 layer_tree_host()->SetNeedsRedraw(); 2663 break; 2664 } 2665 } 2666 2667 virtual void DidCompleteSwapBuffers() OVERRIDE { 2668 int commit = layer_tree_host()->source_frame_number(); 2669 ++frame_; 2670 switch (frame_) { 2671 case 1: 2672 // Round 1 done. 2673 EXPECT_EQ(1, commit); 2674 layer_tree_host()->SetNeedsCommit(); 2675 break; 2676 case 2: 2677 // Round 3 done. 2678 EXPECT_EQ(2, commit); 2679 EndTest(); 2680 break; 2681 } 2682 } 2683 2684 virtual void AfterTest() OVERRIDE {} 2685 2686 protected: 2687 int frame_; 2688 }; 2689 2690 // Flaky on all platforms: http://crbug.com/327498 2691 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) { 2692 RunTest(true, true, true); 2693 } 2694 2695 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) { 2696 RunTest(true, false, true); 2697 } 2698 2699 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { 2700 public: 2701 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 2702 // PictureLayer can only be used with impl side painting enabled. 2703 settings->impl_side_painting = true; 2704 } 2705 2706 virtual void SetupTree() OVERRIDE { 2707 layer_ = FakePictureLayer::Create(&client_); 2708 // Force commits to not be aborted so new frames get drawn, otherwise 2709 // the renderer gets deferred initialized but nothing new needs drawing. 2710 layer_->set_always_update_resources(true); 2711 layer_tree_host()->SetRootLayer(layer_); 2712 LayerTreeHostTest::SetupTree(); 2713 } 2714 2715 virtual void BeginTest() OVERRIDE { 2716 did_initialize_gl_ = false; 2717 did_release_gl_ = false; 2718 last_source_frame_number_drawn_ = -1; // Never drawn. 2719 PostSetNeedsCommitToMainThread(); 2720 } 2721 2722 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) 2723 OVERRIDE { 2724 scoped_ptr<TestWebGraphicsContext3D> context3d( 2725 TestWebGraphicsContext3D::Create()); 2726 2727 return FakeOutputSurface::CreateDeferredGL( 2728 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice), 2729 delegating_renderer()); 2730 } 2731 2732 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 2733 ASSERT_TRUE(host_impl->RootLayer()); 2734 FakePictureLayerImpl* layer_impl = 2735 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer()); 2736 2737 // The same frame can be draw multiple times if new visible tiles are 2738 // rasterized. But we want to make sure we only post DeferredInitialize 2739 // and ReleaseGL once, so early out if the same frame is drawn again. 2740 if (last_source_frame_number_drawn_ == 2741 host_impl->active_tree()->source_frame_number()) 2742 return; 2743 2744 last_source_frame_number_drawn_ = 2745 host_impl->active_tree()->source_frame_number(); 2746 2747 if (!did_initialize_gl_) { 2748 EXPECT_LE(1u, layer_impl->append_quads_count()); 2749 ImplThreadTaskRunner()->PostTask( 2750 FROM_HERE, 2751 base::Bind( 2752 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw, 2753 base::Unretained(this), 2754 base::Unretained(host_impl))); 2755 } else if (did_initialize_gl_ && !did_release_gl_) { 2756 EXPECT_LE(2u, layer_impl->append_quads_count()); 2757 ImplThreadTaskRunner()->PostTask( 2758 FROM_HERE, 2759 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw, 2760 base::Unretained(this), 2761 base::Unretained(host_impl))); 2762 } else if (did_initialize_gl_ && did_release_gl_) { 2763 EXPECT_LE(3u, layer_impl->append_quads_count()); 2764 EndTest(); 2765 } 2766 } 2767 2768 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) { 2769 EXPECT_FALSE(did_initialize_gl_); 2770 // SetAndInitializeContext3D calls SetNeedsCommit. 2771 FakeOutputSurface* fake_output_surface = 2772 static_cast<FakeOutputSurface*>(host_impl->output_surface()); 2773 scoped_refptr<TestContextProvider> context_provider = 2774 TestContextProvider::Create(); // Not bound to thread. 2775 EXPECT_TRUE( 2776 fake_output_surface->InitializeAndSetContext3d(context_provider)); 2777 did_initialize_gl_ = true; 2778 } 2779 2780 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) { 2781 EXPECT_TRUE(did_initialize_gl_); 2782 EXPECT_FALSE(did_release_gl_); 2783 // ReleaseGL calls SetNeedsCommit. 2784 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL(); 2785 did_release_gl_ = true; 2786 } 2787 2788 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, 2789 bool result) OVERRIDE { 2790 ASSERT_TRUE(result); 2791 DelegatedFrameData* delegated_frame_data = 2792 output_surface()->last_sent_frame().delegated_frame_data.get(); 2793 if (!delegated_frame_data) 2794 return; 2795 2796 // Return all resources immediately. 2797 TransferableResourceArray resources_to_return = 2798 output_surface()->resources_held_by_parent(); 2799 2800 CompositorFrameAck ack; 2801 for (size_t i = 0; i < resources_to_return.size(); ++i) 2802 output_surface()->ReturnResource(resources_to_return[i].id, &ack); 2803 host_impl->ReclaimResources(&ack); 2804 } 2805 2806 virtual void AfterTest() OVERRIDE { 2807 EXPECT_TRUE(did_initialize_gl_); 2808 EXPECT_TRUE(did_release_gl_); 2809 } 2810 2811 private: 2812 FakeContentLayerClient client_; 2813 scoped_refptr<FakePictureLayer> layer_; 2814 bool did_initialize_gl_; 2815 bool did_release_gl_; 2816 int last_source_frame_number_drawn_; 2817 }; 2818 2819 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize); 2820 2821 // Test for UI Resource management. 2822 class LayerTreeHostTestUIResource : public LayerTreeHostTest { 2823 public: 2824 LayerTreeHostTestUIResource() : num_ui_resources_(0) {} 2825 2826 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 2827 settings->texture_id_allocation_chunk_size = 1; 2828 } 2829 2830 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 2831 2832 virtual void DidCommit() OVERRIDE { 2833 int frame = layer_tree_host()->source_frame_number(); 2834 switch (frame) { 2835 case 1: 2836 CreateResource(); 2837 CreateResource(); 2838 PostSetNeedsCommitToMainThread(); 2839 break; 2840 case 2: 2841 // Usually ScopedUIResource are deleted from the manager in their 2842 // destructor. Here we just want to test that a direct call to 2843 // DeleteUIResource works. 2844 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id()); 2845 PostSetNeedsCommitToMainThread(); 2846 break; 2847 case 3: 2848 // DeleteUIResource can be called with an invalid id. 2849 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id()); 2850 PostSetNeedsCommitToMainThread(); 2851 break; 2852 case 4: 2853 CreateResource(); 2854 CreateResource(); 2855 PostSetNeedsCommitToMainThread(); 2856 break; 2857 case 5: 2858 ClearResources(); 2859 EndTest(); 2860 break; 2861 } 2862 } 2863 2864 void PerformTest(LayerTreeHostImpl* impl) { 2865 TestWebGraphicsContext3D* context = TestContext(); 2866 2867 int frame = impl->active_tree()->source_frame_number(); 2868 switch (frame) { 2869 case 0: 2870 ASSERT_EQ(0u, context->NumTextures()); 2871 break; 2872 case 1: 2873 // Created two textures. 2874 ASSERT_EQ(2u, context->NumTextures()); 2875 break; 2876 case 2: 2877 // One texture left after one deletion. 2878 ASSERT_EQ(1u, context->NumTextures()); 2879 break; 2880 case 3: 2881 // Resource manager state should not change when delete is called on an 2882 // invalid id. 2883 ASSERT_EQ(1u, context->NumTextures()); 2884 break; 2885 case 4: 2886 // Creation after deletion: two more creates should total up to 2887 // three textures. 2888 ASSERT_EQ(3u, context->NumTextures()); 2889 break; 2890 } 2891 } 2892 2893 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 2894 if (!layer_tree_host()->settings().impl_side_painting) 2895 PerformTest(impl); 2896 } 2897 2898 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 2899 if (layer_tree_host()->settings().impl_side_painting) 2900 PerformTest(impl); 2901 } 2902 2903 virtual void AfterTest() OVERRIDE {} 2904 2905 private: 2906 // Must clear all resources before exiting. 2907 void ClearResources() { 2908 for (int i = 0; i < num_ui_resources_; i++) 2909 ui_resources_[i].reset(); 2910 } 2911 2912 void CreateResource() { 2913 ui_resources_[num_ui_resources_++] = 2914 FakeScopedUIResource::Create(layer_tree_host()); 2915 } 2916 2917 scoped_ptr<FakeScopedUIResource> ui_resources_[5]; 2918 int num_ui_resources_; 2919 }; 2920 2921 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource); 2922 2923 class PushPropertiesCountingLayerImpl : public LayerImpl { 2924 public: 2925 static scoped_ptr<PushPropertiesCountingLayerImpl> Create( 2926 LayerTreeImpl* tree_impl, int id) { 2927 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id)); 2928 } 2929 2930 virtual ~PushPropertiesCountingLayerImpl() {} 2931 2932 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE { 2933 LayerImpl::PushPropertiesTo(layer); 2934 push_properties_count_++; 2935 // Push state to the active tree because we can only access it from there. 2936 static_cast<PushPropertiesCountingLayerImpl*>( 2937 layer)->push_properties_count_ = push_properties_count_; 2938 } 2939 2940 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) 2941 OVERRIDE { 2942 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()). 2943 PassAs<LayerImpl>(); 2944 } 2945 2946 size_t push_properties_count() const { return push_properties_count_; } 2947 void reset_push_properties_count() { push_properties_count_ = 0; } 2948 2949 private: 2950 size_t push_properties_count_; 2951 2952 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id) 2953 : LayerImpl(tree_impl, id), 2954 push_properties_count_(0) { 2955 SetBounds(gfx::Size(1, 1)); 2956 } 2957 }; 2958 2959 class PushPropertiesCountingLayer : public Layer { 2960 public: 2961 static scoped_refptr<PushPropertiesCountingLayer> Create() { 2962 return new PushPropertiesCountingLayer(); 2963 } 2964 2965 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE { 2966 Layer::PushPropertiesTo(layer); 2967 push_properties_count_++; 2968 if (persist_needs_push_properties_) 2969 needs_push_properties_ = true; 2970 } 2971 2972 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) 2973 OVERRIDE { 2974 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()). 2975 PassAs<LayerImpl>(); 2976 } 2977 2978 size_t push_properties_count() const { return push_properties_count_; } 2979 void reset_push_properties_count() { push_properties_count_ = 0; } 2980 2981 void set_persist_needs_push_properties(bool persist) { 2982 persist_needs_push_properties_ = persist; 2983 } 2984 2985 private: 2986 PushPropertiesCountingLayer() 2987 : push_properties_count_(0), persist_needs_push_properties_(false) { 2988 SetBounds(gfx::Size(1, 1)); 2989 SetIsDrawable(true); 2990 } 2991 virtual ~PushPropertiesCountingLayer() {} 2992 2993 size_t push_properties_count_; 2994 bool persist_needs_push_properties_; 2995 }; 2996 2997 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { 2998 protected: 2999 virtual void BeginTest() OVERRIDE { 3000 num_commits_ = 0; 3001 expected_push_properties_root_ = 0; 3002 expected_push_properties_child_ = 0; 3003 expected_push_properties_grandchild_ = 0; 3004 expected_push_properties_child2_ = 0; 3005 expected_push_properties_other_root_ = 0; 3006 expected_push_properties_leaf_layer_ = 0; 3007 PostSetNeedsCommitToMainThread(); 3008 } 3009 3010 virtual void SetupTree() OVERRIDE { 3011 root_ = PushPropertiesCountingLayer::Create(); 3012 child_ = PushPropertiesCountingLayer::Create(); 3013 child2_ = PushPropertiesCountingLayer::Create(); 3014 grandchild_ = PushPropertiesCountingLayer::Create(); 3015 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create(); 3016 leaf_always_pushing_layer_->set_persist_needs_push_properties(true); 3017 3018 root_->AddChild(child_); 3019 root_->AddChild(child2_); 3020 child_->AddChild(grandchild_); 3021 child2_->AddChild(leaf_always_pushing_layer_); 3022 3023 other_root_ = PushPropertiesCountingLayer::Create(); 3024 3025 // Don't set the root layer here. 3026 LayerTreeHostTest::SetupTree(); 3027 } 3028 3029 virtual void DidCommitAndDrawFrame() OVERRIDE { 3030 ++num_commits_; 3031 3032 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count()); 3033 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count()); 3034 EXPECT_EQ(expected_push_properties_grandchild_, 3035 grandchild_->push_properties_count()); 3036 EXPECT_EQ(expected_push_properties_child2_, 3037 child2_->push_properties_count()); 3038 EXPECT_EQ(expected_push_properties_other_root_, 3039 other_root_->push_properties_count()); 3040 EXPECT_EQ(expected_push_properties_leaf_layer_, 3041 leaf_always_pushing_layer_->push_properties_count()); 3042 3043 // The scrollbar layer always needs to be pushed. 3044 if (root_->layer_tree_host()) { 3045 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3046 EXPECT_FALSE(root_->needs_push_properties()); 3047 } 3048 if (child2_->layer_tree_host()) { 3049 EXPECT_TRUE(child2_->descendant_needs_push_properties()); 3050 EXPECT_FALSE(child2_->needs_push_properties()); 3051 } 3052 if (leaf_always_pushing_layer_->layer_tree_host()) { 3053 EXPECT_FALSE( 3054 leaf_always_pushing_layer_->descendant_needs_push_properties()); 3055 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties()); 3056 } 3057 3058 // child_ and grandchild_ don't persist their need to push properties. 3059 if (child_->layer_tree_host()) { 3060 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3061 EXPECT_FALSE(child_->needs_push_properties()); 3062 } 3063 if (grandchild_->layer_tree_host()) { 3064 EXPECT_FALSE(grandchild_->descendant_needs_push_properties()); 3065 EXPECT_FALSE(grandchild_->needs_push_properties()); 3066 } 3067 3068 if (other_root_->layer_tree_host()) { 3069 EXPECT_FALSE(other_root_->descendant_needs_push_properties()); 3070 EXPECT_FALSE(other_root_->needs_push_properties()); 3071 } 3072 3073 switch (num_commits_) { 3074 case 1: 3075 layer_tree_host()->SetRootLayer(root_); 3076 // Layers added to the tree get committed. 3077 ++expected_push_properties_root_; 3078 ++expected_push_properties_child_; 3079 ++expected_push_properties_grandchild_; 3080 ++expected_push_properties_child2_; 3081 break; 3082 case 2: 3083 layer_tree_host()->SetNeedsCommit(); 3084 // No layers need commit. 3085 break; 3086 case 3: 3087 layer_tree_host()->SetRootLayer(other_root_); 3088 // Layers added to the tree get committed. 3089 ++expected_push_properties_other_root_; 3090 break; 3091 case 4: 3092 layer_tree_host()->SetRootLayer(root_); 3093 // Layers added to the tree get committed. 3094 ++expected_push_properties_root_; 3095 ++expected_push_properties_child_; 3096 ++expected_push_properties_grandchild_; 3097 ++expected_push_properties_child2_; 3098 break; 3099 case 5: 3100 layer_tree_host()->SetNeedsCommit(); 3101 // No layers need commit. 3102 break; 3103 case 6: 3104 child_->RemoveFromParent(); 3105 // No layers need commit. 3106 break; 3107 case 7: 3108 root_->AddChild(child_); 3109 // Layers added to the tree get committed. 3110 ++expected_push_properties_child_; 3111 ++expected_push_properties_grandchild_; 3112 break; 3113 case 8: 3114 grandchild_->RemoveFromParent(); 3115 // No layers need commit. 3116 break; 3117 case 9: 3118 child_->AddChild(grandchild_); 3119 // Layers added to the tree get committed. 3120 ++expected_push_properties_grandchild_; 3121 break; 3122 case 10: 3123 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); 3124 // No layers need commit. 3125 break; 3126 case 11: 3127 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f); 3128 // No layers need commit. 3129 break; 3130 case 12: 3131 child_->SetPosition(gfx::Point(1, 1)); 3132 // The modified layer needs commit 3133 ++expected_push_properties_child_; 3134 break; 3135 case 13: 3136 child2_->SetPosition(gfx::Point(1, 1)); 3137 // The modified layer needs commit 3138 ++expected_push_properties_child2_; 3139 break; 3140 case 14: 3141 child_->RemoveFromParent(); 3142 root_->AddChild(child_); 3143 // Layers added to the tree get committed. 3144 ++expected_push_properties_child_; 3145 ++expected_push_properties_grandchild_; 3146 break; 3147 case 15: 3148 grandchild_->SetPosition(gfx::Point(1, 1)); 3149 // The modified layer needs commit 3150 ++expected_push_properties_grandchild_; 3151 break; 3152 case 16: 3153 // SetNeedsDisplay does not always set needs commit (so call it 3154 // explicitly), but is a property change. 3155 child_->SetNeedsDisplay(); 3156 ++expected_push_properties_child_; 3157 layer_tree_host()->SetNeedsCommit(); 3158 break; 3159 case 17: 3160 EndTest(); 3161 break; 3162 } 3163 3164 // The leaf layer always pushes. 3165 if (leaf_always_pushing_layer_->layer_tree_host()) 3166 ++expected_push_properties_leaf_layer_; 3167 } 3168 3169 virtual void AfterTest() OVERRIDE {} 3170 3171 int num_commits_; 3172 FakeContentLayerClient client_; 3173 scoped_refptr<PushPropertiesCountingLayer> root_; 3174 scoped_refptr<PushPropertiesCountingLayer> child_; 3175 scoped_refptr<PushPropertiesCountingLayer> child2_; 3176 scoped_refptr<PushPropertiesCountingLayer> grandchild_; 3177 scoped_refptr<PushPropertiesCountingLayer> other_root_; 3178 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_; 3179 size_t expected_push_properties_root_; 3180 size_t expected_push_properties_child_; 3181 size_t expected_push_properties_child2_; 3182 size_t expected_push_properties_grandchild_; 3183 size_t expected_push_properties_other_root_; 3184 size_t expected_push_properties_leaf_layer_; 3185 }; 3186 3187 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties); 3188 3189 class LayerTreeHostTestImplLayersPushProperties 3190 : public LayerTreeHostTestLayersPushProperties { 3191 protected: 3192 virtual void BeginTest() OVERRIDE { 3193 expected_push_properties_root_impl_ = 0; 3194 expected_push_properties_child_impl_ = 0; 3195 expected_push_properties_grandchild_impl_ = 0; 3196 expected_push_properties_child2_impl_ = 0; 3197 expected_push_properties_grandchild2_impl_ = 0; 3198 LayerTreeHostTestLayersPushProperties::BeginTest(); 3199 } 3200 3201 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 3202 // These commits are in response to the changes made in 3203 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame() 3204 switch (num_commits_) { 3205 case 0: 3206 // Tree hasn't been setup yet don't bother to check anything. 3207 return; 3208 case 1: 3209 // Root gets set up, Everyone is initialized. 3210 ++expected_push_properties_root_impl_; 3211 ++expected_push_properties_child_impl_; 3212 ++expected_push_properties_grandchild_impl_; 3213 ++expected_push_properties_child2_impl_; 3214 ++expected_push_properties_grandchild2_impl_; 3215 break; 3216 case 2: 3217 // Tree doesn't change but the one leaf that always pushes is pushed. 3218 ++expected_push_properties_grandchild2_impl_; 3219 break; 3220 case 3: 3221 // Root is swapped here. 3222 // Clear the expected push properties the tree will be rebuilt. 3223 expected_push_properties_root_impl_ = 0; 3224 expected_push_properties_child_impl_ = 0; 3225 expected_push_properties_grandchild_impl_ = 0; 3226 expected_push_properties_child2_impl_ = 0; 3227 expected_push_properties_grandchild2_impl_ = 0; 3228 3229 // Make sure the new root is pushed. 3230 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>( 3231 host_impl->RootLayer())->push_properties_count()); 3232 return; 3233 case 4: 3234 // Root is swapped back all of the layers in the tree get pushed. 3235 ++expected_push_properties_root_impl_; 3236 ++expected_push_properties_child_impl_; 3237 ++expected_push_properties_grandchild_impl_; 3238 ++expected_push_properties_child2_impl_; 3239 ++expected_push_properties_grandchild2_impl_; 3240 break; 3241 case 5: 3242 // Tree doesn't change but the one leaf that always pushes is pushed. 3243 ++expected_push_properties_grandchild2_impl_; 3244 break; 3245 case 6: 3246 // First child is removed. Structure of the tree changes here so swap 3247 // some of the values. child_impl becomes child2_impl. 3248 expected_push_properties_child_impl_ = 3249 expected_push_properties_child2_impl_; 3250 expected_push_properties_child2_impl_ = 0; 3251 // grandchild_impl becomes grandchild2_impl. 3252 expected_push_properties_grandchild_impl_ = 3253 expected_push_properties_grandchild2_impl_; 3254 expected_push_properties_grandchild2_impl_ = 0; 3255 3256 // grandchild_impl is now the leaf that always pushes. It is pushed. 3257 ++expected_push_properties_grandchild_impl_; 3258 break; 3259 case 7: 3260 // The leaf that always pushes is pushed. 3261 ++expected_push_properties_grandchild_impl_; 3262 3263 // Child is added back. New layers are initialized. 3264 ++expected_push_properties_grandchild2_impl_; 3265 ++expected_push_properties_child2_impl_; 3266 break; 3267 case 8: 3268 // Leaf is removed. 3269 expected_push_properties_grandchild2_impl_ = 0; 3270 3271 // Always pushing. 3272 ++expected_push_properties_grandchild_impl_; 3273 break; 3274 case 9: 3275 // Leaf is added back 3276 ++expected_push_properties_grandchild2_impl_; 3277 3278 // The leaf that always pushes is pushed. 3279 ++expected_push_properties_grandchild_impl_; 3280 break; 3281 case 10: 3282 // The leaf that always pushes is pushed. 3283 ++expected_push_properties_grandchild_impl_; 3284 break; 3285 case 11: 3286 // The leaf that always pushes is pushed. 3287 ++expected_push_properties_grandchild_impl_; 3288 break; 3289 case 12: 3290 // The leaf that always pushes is pushed. 3291 ++expected_push_properties_grandchild_impl_; 3292 3293 // This child position was changed. 3294 ++expected_push_properties_child2_impl_; 3295 break; 3296 case 13: 3297 // The position of this child was changed. 3298 ++expected_push_properties_child_impl_; 3299 3300 // The leaf that always pushes is pushed. 3301 ++expected_push_properties_grandchild_impl_; 3302 break; 3303 case 14: 3304 // Second child is removed from tree. Don't discard counts because 3305 // they are added back before commit. 3306 3307 // The leaf that always pushes is pushed. 3308 ++expected_push_properties_grandchild_impl_; 3309 3310 // Second child added back. 3311 ++expected_push_properties_child2_impl_; 3312 ++expected_push_properties_grandchild2_impl_; 3313 3314 break; 3315 case 15: 3316 // The position of this child was changed. 3317 ++expected_push_properties_grandchild2_impl_; 3318 3319 // The leaf that always pushes is pushed. 3320 ++expected_push_properties_grandchild_impl_; 3321 break; 3322 case 16: 3323 // Second child is invalidated with SetNeedsDisplay 3324 ++expected_push_properties_child2_impl_; 3325 3326 // The leaf that always pushed is pushed. 3327 ++expected_push_properties_grandchild_impl_; 3328 break; 3329 } 3330 3331 PushPropertiesCountingLayerImpl* root_impl_ = NULL; 3332 PushPropertiesCountingLayerImpl* child_impl_ = NULL; 3333 PushPropertiesCountingLayerImpl* child2_impl_ = NULL; 3334 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL; 3335 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL; 3336 3337 // Pull the layers that we need from the tree assuming the same structure 3338 // as LayerTreeHostTestLayersPushProperties 3339 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( 3340 host_impl->RootLayer()); 3341 3342 if (root_impl_ && root_impl_->children().size() > 0) { 3343 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( 3344 root_impl_->children()[0]); 3345 3346 if (child_impl_ && child_impl_->children().size() > 0) 3347 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( 3348 child_impl_->children()[0]); 3349 } 3350 3351 if (root_impl_ && root_impl_->children().size() > 1) { 3352 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( 3353 root_impl_->children()[1]); 3354 3355 if (child2_impl_ && child2_impl_->children().size() > 0) 3356 leaf_always_pushing_layer_impl_ = 3357 static_cast<PushPropertiesCountingLayerImpl*>( 3358 child2_impl_->children()[0]); 3359 } 3360 3361 if (root_impl_) 3362 EXPECT_EQ(expected_push_properties_root_impl_, 3363 root_impl_->push_properties_count()); 3364 if (child_impl_) 3365 EXPECT_EQ(expected_push_properties_child_impl_, 3366 child_impl_->push_properties_count()); 3367 if (grandchild_impl_) 3368 EXPECT_EQ(expected_push_properties_grandchild_impl_, 3369 grandchild_impl_->push_properties_count()); 3370 if (child2_impl_) 3371 EXPECT_EQ(expected_push_properties_child2_impl_, 3372 child2_impl_->push_properties_count()); 3373 if (leaf_always_pushing_layer_impl_) 3374 EXPECT_EQ(expected_push_properties_grandchild2_impl_, 3375 leaf_always_pushing_layer_impl_->push_properties_count()); 3376 } 3377 3378 size_t expected_push_properties_root_impl_; 3379 size_t expected_push_properties_child_impl_; 3380 size_t expected_push_properties_child2_impl_; 3381 size_t expected_push_properties_grandchild_impl_; 3382 size_t expected_push_properties_grandchild2_impl_; 3383 }; 3384 3385 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) { 3386 RunTestWithImplSidePainting(); 3387 } 3388 3389 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed 3390 : public LayerTreeHostTest { 3391 protected: 3392 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 3393 3394 virtual void SetupTree() OVERRIDE { 3395 root_ = Layer::Create(); 3396 root_->SetBounds(gfx::Size(1, 1)); 3397 3398 bool paint_scrollbar = true; 3399 bool has_thumb = false; 3400 scrollbar_layer_ = FakePaintedScrollbarLayer::Create( 3401 paint_scrollbar, has_thumb, root_->id()); 3402 3403 root_->AddChild(scrollbar_layer_); 3404 3405 layer_tree_host()->SetRootLayer(root_); 3406 LayerTreeHostTest::SetupTree(); 3407 } 3408 3409 virtual void DidCommitAndDrawFrame() OVERRIDE { 3410 switch (layer_tree_host()->source_frame_number()) { 3411 case 0: 3412 break; 3413 case 1: { 3414 // During update, the ignore_set_needs_commit_ bit is set to true to 3415 // avoid causing a second commit to be scheduled. If a property change 3416 // is made during this, however, it needs to be pushed in the upcoming 3417 // commit. 3418 scoped_ptr<base::AutoReset<bool> > ignore = 3419 scrollbar_layer_->IgnoreSetNeedsCommit(); 3420 3421 scrollbar_layer_->SetBounds(gfx::Size(30, 30)); 3422 3423 EXPECT_TRUE(scrollbar_layer_->needs_push_properties()); 3424 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3425 layer_tree_host()->SetNeedsCommit(); 3426 3427 scrollbar_layer_->reset_push_properties_count(); 3428 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count()); 3429 break; 3430 } 3431 case 2: 3432 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count()); 3433 EndTest(); 3434 break; 3435 } 3436 } 3437 3438 virtual void AfterTest() OVERRIDE {} 3439 3440 scoped_refptr<Layer> root_; 3441 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_; 3442 }; 3443 3444 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed); 3445 3446 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren 3447 : public LayerTreeHostTest { 3448 protected: 3449 virtual void BeginTest() OVERRIDE { 3450 expected_push_properties_root_ = 0; 3451 expected_push_properties_child_ = 0; 3452 expected_push_properties_grandchild1_ = 0; 3453 expected_push_properties_grandchild2_ = 0; 3454 expected_push_properties_grandchild3_ = 0; 3455 PostSetNeedsCommitToMainThread(); 3456 } 3457 3458 virtual void SetupTree() OVERRIDE { 3459 root_ = PushPropertiesCountingLayer::Create(); 3460 child_ = PushPropertiesCountingLayer::Create(); 3461 grandchild1_ = PushPropertiesCountingLayer::Create(); 3462 grandchild2_ = PushPropertiesCountingLayer::Create(); 3463 grandchild3_ = PushPropertiesCountingLayer::Create(); 3464 3465 root_->AddChild(child_); 3466 child_->AddChild(grandchild1_); 3467 child_->AddChild(grandchild2_); 3468 child_->AddChild(grandchild3_); 3469 3470 // Don't set the root layer here. 3471 LayerTreeHostTest::SetupTree(); 3472 } 3473 3474 virtual void AfterTest() OVERRIDE {} 3475 3476 FakeContentLayerClient client_; 3477 scoped_refptr<PushPropertiesCountingLayer> root_; 3478 scoped_refptr<PushPropertiesCountingLayer> child_; 3479 scoped_refptr<PushPropertiesCountingLayer> grandchild1_; 3480 scoped_refptr<PushPropertiesCountingLayer> grandchild2_; 3481 scoped_refptr<PushPropertiesCountingLayer> grandchild3_; 3482 size_t expected_push_properties_root_; 3483 size_t expected_push_properties_child_; 3484 size_t expected_push_properties_grandchild1_; 3485 size_t expected_push_properties_grandchild2_; 3486 size_t expected_push_properties_grandchild3_; 3487 }; 3488 3489 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush 3490 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { 3491 protected: 3492 virtual void DidCommitAndDrawFrame() OVERRIDE { 3493 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; 3494 switch (last_source_frame_number) { 3495 case 0: 3496 EXPECT_FALSE(root_->needs_push_properties()); 3497 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3498 EXPECT_FALSE(child_->needs_push_properties()); 3499 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3500 EXPECT_FALSE(grandchild1_->needs_push_properties()); 3501 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3502 EXPECT_FALSE(grandchild2_->needs_push_properties()); 3503 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3504 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3505 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3506 3507 layer_tree_host()->SetRootLayer(root_); 3508 3509 EXPECT_TRUE(root_->needs_push_properties()); 3510 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3511 EXPECT_TRUE(child_->needs_push_properties()); 3512 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3513 EXPECT_TRUE(grandchild1_->needs_push_properties()); 3514 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3515 EXPECT_TRUE(grandchild2_->needs_push_properties()); 3516 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3517 EXPECT_TRUE(grandchild3_->needs_push_properties()); 3518 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3519 break; 3520 case 1: 3521 EndTest(); 3522 break; 3523 } 3524 } 3525 }; 3526 3527 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush); 3528 3529 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion 3530 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { 3531 protected: 3532 virtual void DidCommitAndDrawFrame() OVERRIDE { 3533 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; 3534 switch (last_source_frame_number) { 3535 case 0: 3536 layer_tree_host()->SetRootLayer(root_); 3537 break; 3538 case 1: 3539 EXPECT_FALSE(root_->needs_push_properties()); 3540 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3541 EXPECT_FALSE(child_->needs_push_properties()); 3542 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3543 EXPECT_FALSE(grandchild1_->needs_push_properties()); 3544 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3545 EXPECT_FALSE(grandchild2_->needs_push_properties()); 3546 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3547 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3548 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3549 3550 grandchild1_->RemoveFromParent(); 3551 grandchild1_->SetPosition(gfx::Point(1, 1)); 3552 3553 EXPECT_FALSE(root_->needs_push_properties()); 3554 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3555 EXPECT_FALSE(child_->needs_push_properties()); 3556 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3557 EXPECT_FALSE(grandchild2_->needs_push_properties()); 3558 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3559 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3560 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3561 3562 child_->AddChild(grandchild1_); 3563 3564 EXPECT_FALSE(root_->needs_push_properties()); 3565 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3566 EXPECT_FALSE(child_->needs_push_properties()); 3567 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3568 EXPECT_TRUE(grandchild1_->needs_push_properties()); 3569 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3570 EXPECT_FALSE(grandchild2_->needs_push_properties()); 3571 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3572 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3573 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3574 3575 grandchild2_->SetPosition(gfx::Point(1, 1)); 3576 3577 EXPECT_FALSE(root_->needs_push_properties()); 3578 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3579 EXPECT_FALSE(child_->needs_push_properties()); 3580 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3581 EXPECT_TRUE(grandchild1_->needs_push_properties()); 3582 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3583 EXPECT_TRUE(grandchild2_->needs_push_properties()); 3584 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3585 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3586 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3587 3588 // grandchild2_ will still need a push properties. 3589 grandchild1_->RemoveFromParent(); 3590 3591 EXPECT_FALSE(root_->needs_push_properties()); 3592 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3593 EXPECT_FALSE(child_->needs_push_properties()); 3594 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3595 3596 // grandchild3_ does not need a push properties, so recursing should 3597 // no longer be needed. 3598 grandchild2_->RemoveFromParent(); 3599 3600 EXPECT_FALSE(root_->needs_push_properties()); 3601 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3602 EXPECT_FALSE(child_->needs_push_properties()); 3603 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3604 EndTest(); 3605 break; 3606 } 3607 } 3608 }; 3609 3610 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion); 3611 3612 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence 3613 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { 3614 protected: 3615 virtual void DidCommitAndDrawFrame() OVERRIDE { 3616 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; 3617 switch (last_source_frame_number) { 3618 case 0: 3619 layer_tree_host()->SetRootLayer(root_); 3620 grandchild1_->set_persist_needs_push_properties(true); 3621 grandchild2_->set_persist_needs_push_properties(true); 3622 break; 3623 case 1: 3624 EXPECT_FALSE(root_->needs_push_properties()); 3625 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3626 EXPECT_FALSE(child_->needs_push_properties()); 3627 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3628 EXPECT_TRUE(grandchild1_->needs_push_properties()); 3629 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3630 EXPECT_TRUE(grandchild2_->needs_push_properties()); 3631 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3632 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3633 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3634 3635 // grandchild2_ will still need a push properties. 3636 grandchild1_->RemoveFromParent(); 3637 3638 EXPECT_FALSE(root_->needs_push_properties()); 3639 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3640 EXPECT_FALSE(child_->needs_push_properties()); 3641 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3642 3643 // grandchild3_ does not need a push properties, so recursing should 3644 // no longer be needed. 3645 grandchild2_->RemoveFromParent(); 3646 3647 EXPECT_FALSE(root_->needs_push_properties()); 3648 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3649 EXPECT_FALSE(child_->needs_push_properties()); 3650 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3651 EndTest(); 3652 break; 3653 } 3654 } 3655 }; 3656 3657 MULTI_THREAD_TEST_F( 3658 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence); 3659 3660 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree 3661 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { 3662 protected: 3663 virtual void DidCommitAndDrawFrame() OVERRIDE { 3664 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; 3665 switch (last_source_frame_number) { 3666 case 0: 3667 layer_tree_host()->SetRootLayer(root_); 3668 break; 3669 case 1: 3670 EXPECT_FALSE(root_->needs_push_properties()); 3671 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3672 EXPECT_FALSE(child_->needs_push_properties()); 3673 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3674 EXPECT_FALSE(grandchild1_->needs_push_properties()); 3675 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3676 EXPECT_FALSE(grandchild2_->needs_push_properties()); 3677 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3678 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3679 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3680 3681 // Change grandchildren while their parent is not in the tree. 3682 child_->RemoveFromParent(); 3683 grandchild1_->SetPosition(gfx::Point(1, 1)); 3684 grandchild2_->SetPosition(gfx::Point(1, 1)); 3685 root_->AddChild(child_); 3686 3687 EXPECT_FALSE(root_->needs_push_properties()); 3688 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3689 EXPECT_TRUE(child_->needs_push_properties()); 3690 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3691 EXPECT_TRUE(grandchild1_->needs_push_properties()); 3692 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3693 EXPECT_TRUE(grandchild2_->needs_push_properties()); 3694 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3695 EXPECT_TRUE(grandchild3_->needs_push_properties()); 3696 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3697 3698 grandchild1_->RemoveFromParent(); 3699 3700 EXPECT_FALSE(root_->needs_push_properties()); 3701 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3702 EXPECT_TRUE(child_->needs_push_properties()); 3703 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3704 3705 grandchild2_->RemoveFromParent(); 3706 3707 EXPECT_FALSE(root_->needs_push_properties()); 3708 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3709 EXPECT_TRUE(child_->needs_push_properties()); 3710 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3711 3712 grandchild3_->RemoveFromParent(); 3713 3714 EXPECT_FALSE(root_->needs_push_properties()); 3715 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3716 EXPECT_TRUE(child_->needs_push_properties()); 3717 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3718 3719 EndTest(); 3720 break; 3721 } 3722 } 3723 }; 3724 3725 MULTI_THREAD_TEST_F( 3726 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree); 3727 3728 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild 3729 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { 3730 protected: 3731 virtual void DidCommitAndDrawFrame() OVERRIDE { 3732 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; 3733 switch (last_source_frame_number) { 3734 case 0: 3735 layer_tree_host()->SetRootLayer(root_); 3736 break; 3737 case 1: 3738 EXPECT_FALSE(root_->needs_push_properties()); 3739 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3740 EXPECT_FALSE(child_->needs_push_properties()); 3741 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3742 EXPECT_FALSE(grandchild1_->needs_push_properties()); 3743 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3744 EXPECT_FALSE(grandchild2_->needs_push_properties()); 3745 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3746 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3747 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3748 3749 child_->SetPosition(gfx::Point(1, 1)); 3750 grandchild1_->SetPosition(gfx::Point(1, 1)); 3751 grandchild2_->SetPosition(gfx::Point(1, 1)); 3752 3753 EXPECT_FALSE(root_->needs_push_properties()); 3754 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3755 EXPECT_TRUE(child_->needs_push_properties()); 3756 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3757 EXPECT_TRUE(grandchild1_->needs_push_properties()); 3758 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3759 EXPECT_TRUE(grandchild2_->needs_push_properties()); 3760 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3761 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3762 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3763 3764 grandchild1_->RemoveFromParent(); 3765 3766 EXPECT_FALSE(root_->needs_push_properties()); 3767 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3768 EXPECT_TRUE(child_->needs_push_properties()); 3769 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3770 3771 grandchild2_->RemoveFromParent(); 3772 3773 EXPECT_FALSE(root_->needs_push_properties()); 3774 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3775 EXPECT_TRUE(child_->needs_push_properties()); 3776 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3777 3778 child_->RemoveFromParent(); 3779 3780 EXPECT_FALSE(root_->needs_push_properties()); 3781 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3782 3783 EndTest(); 3784 break; 3785 } 3786 } 3787 }; 3788 3789 MULTI_THREAD_TEST_F( 3790 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild); 3791 3792 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent 3793 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { 3794 protected: 3795 virtual void DidCommitAndDrawFrame() OVERRIDE { 3796 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; 3797 switch (last_source_frame_number) { 3798 case 0: 3799 layer_tree_host()->SetRootLayer(root_); 3800 break; 3801 case 1: 3802 EXPECT_FALSE(root_->needs_push_properties()); 3803 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3804 EXPECT_FALSE(child_->needs_push_properties()); 3805 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3806 EXPECT_FALSE(grandchild1_->needs_push_properties()); 3807 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3808 EXPECT_FALSE(grandchild2_->needs_push_properties()); 3809 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3810 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3811 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3812 3813 grandchild1_->SetPosition(gfx::Point(1, 1)); 3814 grandchild2_->SetPosition(gfx::Point(1, 1)); 3815 child_->SetPosition(gfx::Point(1, 1)); 3816 3817 EXPECT_FALSE(root_->needs_push_properties()); 3818 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3819 EXPECT_TRUE(child_->needs_push_properties()); 3820 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3821 EXPECT_TRUE(grandchild1_->needs_push_properties()); 3822 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); 3823 EXPECT_TRUE(grandchild2_->needs_push_properties()); 3824 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); 3825 EXPECT_FALSE(grandchild3_->needs_push_properties()); 3826 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); 3827 3828 grandchild1_->RemoveFromParent(); 3829 3830 EXPECT_FALSE(root_->needs_push_properties()); 3831 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3832 EXPECT_TRUE(child_->needs_push_properties()); 3833 EXPECT_TRUE(child_->descendant_needs_push_properties()); 3834 3835 grandchild2_->RemoveFromParent(); 3836 3837 EXPECT_FALSE(root_->needs_push_properties()); 3838 EXPECT_TRUE(root_->descendant_needs_push_properties()); 3839 EXPECT_TRUE(child_->needs_push_properties()); 3840 EXPECT_FALSE(child_->descendant_needs_push_properties()); 3841 3842 child_->RemoveFromParent(); 3843 3844 EXPECT_FALSE(root_->needs_push_properties()); 3845 EXPECT_FALSE(root_->descendant_needs_push_properties()); 3846 3847 EndTest(); 3848 break; 3849 } 3850 } 3851 }; 3852 3853 MULTI_THREAD_TEST_F( 3854 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent); 3855 3856 // This test verifies that the tree activation callback is invoked correctly. 3857 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest { 3858 public: 3859 LayerTreeHostTestTreeActivationCallback() 3860 : num_commits_(0), callback_count_(0) {} 3861 3862 virtual void BeginTest() OVERRIDE { 3863 EXPECT_TRUE(HasImplThread()); 3864 PostSetNeedsCommitToMainThread(); 3865 } 3866 3867 virtual DrawResult PrepareToDrawOnThread( 3868 LayerTreeHostImpl* host_impl, 3869 LayerTreeHostImpl::FrameData* frame_data, 3870 DrawResult draw_result) OVERRIDE { 3871 ++num_commits_; 3872 switch (num_commits_) { 3873 case 1: 3874 EXPECT_EQ(0, callback_count_); 3875 callback_count_ = 0; 3876 SetCallback(true); 3877 PostSetNeedsCommitToMainThread(); 3878 break; 3879 case 2: 3880 EXPECT_EQ(1, callback_count_); 3881 callback_count_ = 0; 3882 SetCallback(false); 3883 PostSetNeedsCommitToMainThread(); 3884 break; 3885 case 3: 3886 EXPECT_EQ(0, callback_count_); 3887 callback_count_ = 0; 3888 EndTest(); 3889 break; 3890 default: 3891 ADD_FAILURE() << num_commits_; 3892 EndTest(); 3893 break; 3894 } 3895 return LayerTreeHostTest::PrepareToDrawOnThread( 3896 host_impl, frame_data, draw_result); 3897 } 3898 3899 virtual void AfterTest() OVERRIDE { EXPECT_EQ(3, num_commits_); } 3900 3901 void SetCallback(bool enable) { 3902 output_surface()->SetTreeActivationCallback( 3903 enable 3904 ? base::Bind( 3905 &LayerTreeHostTestTreeActivationCallback::ActivationCallback, 3906 base::Unretained(this)) 3907 : base::Closure()); 3908 } 3909 3910 void ActivationCallback() { ++callback_count_; } 3911 3912 int num_commits_; 3913 int callback_count_; 3914 }; 3915 3916 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) { 3917 RunTest(true, false, true); 3918 } 3919 3920 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) { 3921 RunTest(true, true, true); 3922 } 3923 3924 class LayerInvalidateCausesDraw : public LayerTreeHostTest { 3925 public: 3926 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {} 3927 3928 virtual void BeginTest() OVERRIDE { 3929 ASSERT_TRUE(!!invalidate_layer_) 3930 << "Derived tests must set this in SetupTree"; 3931 3932 // One initial commit. 3933 PostSetNeedsCommitToMainThread(); 3934 } 3935 3936 virtual void DidCommitAndDrawFrame() OVERRIDE { 3937 // After commit, invalidate the layer. This should cause a commit. 3938 if (layer_tree_host()->source_frame_number() == 1) 3939 invalidate_layer_->SetNeedsDisplay(); 3940 } 3941 3942 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 3943 num_draws_++; 3944 if (impl->active_tree()->source_frame_number() == 1) 3945 EndTest(); 3946 } 3947 3948 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 3949 num_commits_++; 3950 } 3951 3952 virtual void AfterTest() OVERRIDE { 3953 EXPECT_GE(2, num_commits_); 3954 EXPECT_GE(2, num_draws_); 3955 } 3956 3957 protected: 3958 scoped_refptr<Layer> invalidate_layer_; 3959 3960 private: 3961 int num_commits_; 3962 int num_draws_; 3963 }; 3964 3965 // VideoLayer must support being invalidated and then passing that along 3966 // to the compositor thread, even though no resources are updated in 3967 // response to that invalidation. 3968 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw { 3969 public: 3970 virtual void SetupTree() OVERRIDE { 3971 LayerTreeHostTest::SetupTree(); 3972 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_); 3973 video_layer->SetBounds(gfx::Size(10, 10)); 3974 video_layer->SetIsDrawable(true); 3975 layer_tree_host()->root_layer()->AddChild(video_layer); 3976 3977 invalidate_layer_ = video_layer; 3978 } 3979 3980 private: 3981 FakeVideoFrameProvider provider_; 3982 }; 3983 3984 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate); 3985 3986 // IOSurfaceLayer must support being invalidated and then passing that along 3987 // to the compositor thread, even though no resources are updated in 3988 // response to that invalidation. 3989 class LayerTreeHostTestIOSurfaceLayerInvalidate 3990 : public LayerInvalidateCausesDraw { 3991 public: 3992 virtual void SetupTree() OVERRIDE { 3993 LayerTreeHostTest::SetupTree(); 3994 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create(); 3995 layer->SetBounds(gfx::Size(10, 10)); 3996 uint32_t fake_io_surface_id = 7; 3997 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds()); 3998 layer->SetIsDrawable(true); 3999 layer_tree_host()->root_layer()->AddChild(layer); 4000 4001 invalidate_layer_ = layer; 4002 } 4003 }; 4004 4005 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335 4006 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( 4007 LayerTreeHostTestIOSurfaceLayerInvalidate); 4008 4009 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { 4010 protected: 4011 virtual void SetupTree() OVERRIDE { 4012 root_layer_ = Layer::Create(); 4013 root_layer_->SetPosition(gfx::Point()); 4014 root_layer_->SetBounds(gfx::Size(10, 10)); 4015 4016 parent_layer_ = SolidColorLayer::Create(); 4017 parent_layer_->SetPosition(gfx::Point()); 4018 parent_layer_->SetBounds(gfx::Size(10, 10)); 4019 parent_layer_->SetIsDrawable(true); 4020 root_layer_->AddChild(parent_layer_); 4021 4022 child_layer_ = SolidColorLayer::Create(); 4023 child_layer_->SetPosition(gfx::Point()); 4024 child_layer_->SetBounds(gfx::Size(10, 10)); 4025 child_layer_->SetIsDrawable(true); 4026 parent_layer_->AddChild(child_layer_); 4027 4028 layer_tree_host()->SetRootLayer(root_layer_); 4029 LayerTreeHostTest::SetupTree(); 4030 } 4031 4032 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 4033 4034 virtual void DidCommitAndDrawFrame() OVERRIDE { 4035 switch (layer_tree_host()->source_frame_number()) { 4036 case 1: 4037 // The layer type used does not need to push properties every frame. 4038 EXPECT_FALSE(child_layer_->needs_push_properties()); 4039 4040 // Change the bounds of the child layer, but make it skipped 4041 // by CalculateDrawProperties. 4042 parent_layer_->SetOpacity(0.f); 4043 child_layer_->SetBounds(gfx::Size(5, 5)); 4044 break; 4045 case 2: 4046 // The bounds of the child layer were pushed to the impl side. 4047 EXPECT_FALSE(child_layer_->needs_push_properties()); 4048 4049 EndTest(); 4050 break; 4051 } 4052 } 4053 4054 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 4055 LayerImpl* root = impl->active_tree()->root_layer(); 4056 LayerImpl* parent = root->children()[0]; 4057 LayerImpl* child = parent->children()[0]; 4058 4059 switch (impl->active_tree()->source_frame_number()) { 4060 case 1: 4061 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString()); 4062 break; 4063 } 4064 } 4065 4066 virtual void AfterTest() OVERRIDE {} 4067 4068 scoped_refptr<Layer> root_layer_; 4069 scoped_refptr<SolidColorLayer> parent_layer_; 4070 scoped_refptr<SolidColorLayer> child_layer_; 4071 }; 4072 4073 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer); 4074 4075 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { 4076 protected: 4077 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 4078 settings->impl_side_painting = true; 4079 } 4080 4081 virtual void SetupTree() OVERRIDE { 4082 root_layer_ = FakePictureLayer::Create(&client_); 4083 root_layer_->SetBounds(gfx::Size(10, 10)); 4084 4085 layer_tree_host()->SetRootLayer(root_layer_); 4086 LayerTreeHostTest::SetupTree(); 4087 } 4088 4089 virtual void BeginTest() OVERRIDE { 4090 // The viewport is empty, but we still need to update layers on the main 4091 // thread. 4092 layer_tree_host()->SetViewportSize(gfx::Size(0, 0)); 4093 PostSetNeedsCommitToMainThread(); 4094 } 4095 4096 virtual void DidCommit() OVERRIDE { 4097 // The layer should be updated even though the viewport is empty, so we 4098 // are capable of drawing it on the impl tree. 4099 EXPECT_GT(root_layer_->update_count(), 0u); 4100 EndTest(); 4101 } 4102 4103 virtual void AfterTest() OVERRIDE {} 4104 4105 FakeContentLayerClient client_; 4106 scoped_refptr<FakePictureLayer> root_layer_; 4107 }; 4108 4109 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); 4110 4111 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest { 4112 public: 4113 LayerTreeHostTestAbortEvictedTextures() 4114 : num_will_begin_main_frames_(0), num_impl_commits_(0) {} 4115 4116 protected: 4117 virtual void SetupTree() OVERRIDE { 4118 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create(); 4119 root_layer->SetBounds(gfx::Size(200, 200)); 4120 root_layer->SetIsDrawable(true); 4121 4122 layer_tree_host()->SetRootLayer(root_layer); 4123 LayerTreeHostTest::SetupTree(); 4124 } 4125 4126 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 4127 4128 virtual void WillBeginMainFrame() OVERRIDE { 4129 num_will_begin_main_frames_++; 4130 switch (num_will_begin_main_frames_) { 4131 case 2: 4132 // Send a redraw to the compositor thread. This will (wrongly) be 4133 // ignored unless aborting resets the texture state. 4134 layer_tree_host()->SetNeedsRedraw(); 4135 break; 4136 } 4137 } 4138 4139 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { 4140 num_impl_commits_++; 4141 } 4142 4143 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 4144 switch (impl->SourceAnimationFrameNumber()) { 4145 case 1: 4146 // Prevent draws until commit. 4147 impl->active_tree()->SetContentsTexturesPurged(); 4148 EXPECT_FALSE(impl->CanDraw()); 4149 // Trigger an abortable commit. 4150 impl->SetNeedsCommit(); 4151 break; 4152 case 2: 4153 EndTest(); 4154 break; 4155 } 4156 } 4157 4158 virtual void AfterTest() OVERRIDE { 4159 // Ensure that the commit was truly aborted. 4160 EXPECT_EQ(2, num_will_begin_main_frames_); 4161 EXPECT_EQ(1, num_impl_commits_); 4162 } 4163 4164 private: 4165 int num_will_begin_main_frames_; 4166 int num_impl_commits_; 4167 }; 4168 4169 // Commits can only be aborted when using the thread proxy. 4170 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures); 4171 4172 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest { 4173 protected: 4174 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 4175 settings->impl_side_painting = true; 4176 } 4177 4178 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) 4179 OVERRIDE { 4180 scoped_refptr<TestContextProvider> context_provider = 4181 TestContextProvider::Create(); 4182 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024); 4183 if (delegating_renderer()) 4184 return FakeOutputSurface::CreateDelegating3d(context_provider); 4185 else 4186 return FakeOutputSurface::Create3d(context_provider); 4187 } 4188 4189 virtual void SetupTree() OVERRIDE { 4190 scoped_refptr<FakePictureLayer> root_layer = 4191 FakePictureLayer::Create(&client_); 4192 root_layer->SetBounds(gfx::Size(6000, 6000)); 4193 root_layer->SetIsDrawable(true); 4194 4195 layer_tree_host()->SetRootLayer(root_layer); 4196 LayerTreeHostTest::SetupTree(); 4197 } 4198 4199 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 4200 4201 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { 4202 TestWebGraphicsContext3D* context = TestContext(); 4203 4204 // Expect that the transfer buffer memory used is equal to the 4205 // MaxTransferBufferUsageBytes value set in CreateOutputSurface. 4206 EXPECT_EQ(1024 * 1024u, context->max_used_transfer_buffer_usage_bytes()); 4207 EndTest(); 4208 } 4209 4210 virtual void AfterTest() OVERRIDE {} 4211 4212 private: 4213 FakeContentLayerClient client_; 4214 }; 4215 4216 // Impl-side painting is a multi-threaded compositor feature. 4217 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes); 4218 4219 // Test ensuring that memory limits are sent to the prioritized resource 4220 // manager. 4221 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest { 4222 public: 4223 LayerTreeHostTestMemoryLimits() : num_commits_(0) {} 4224 4225 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 4226 4227 virtual void WillCommit() OVERRIDE { 4228 // Some commits are aborted, so increment number of attempted commits here. 4229 num_commits_++; 4230 } 4231 4232 virtual void DidCommit() OVERRIDE { 4233 switch (num_commits_) { 4234 case 1: 4235 // Verify default values. 4236 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(), 4237 layer_tree_host() 4238 ->contents_texture_manager() 4239 ->MaxMemoryLimitBytes()); 4240 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(), 4241 layer_tree_host() 4242 ->contents_texture_manager() 4243 ->ExternalPriorityCutoff()); 4244 PostSetNeedsCommitToMainThread(); 4245 break; 4246 case 2: 4247 // The values should remain the same until the commit after the policy 4248 // is changed. 4249 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(), 4250 layer_tree_host() 4251 ->contents_texture_manager() 4252 ->MaxMemoryLimitBytes()); 4253 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(), 4254 layer_tree_host() 4255 ->contents_texture_manager() 4256 ->ExternalPriorityCutoff()); 4257 break; 4258 case 3: 4259 // Verify values were correctly passed. 4260 EXPECT_EQ(16u * 1024u * 1024u, 4261 layer_tree_host() 4262 ->contents_texture_manager() 4263 ->MaxMemoryLimitBytes()); 4264 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(), 4265 layer_tree_host() 4266 ->contents_texture_manager() 4267 ->ExternalPriorityCutoff()); 4268 EndTest(); 4269 break; 4270 case 4: 4271 // Make sure no extra commits happen. 4272 NOTREACHED(); 4273 break; 4274 } 4275 } 4276 4277 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 4278 switch (num_commits_) { 4279 case 1: 4280 break; 4281 case 2: 4282 // This will trigger a commit because the priority cutoff has changed. 4283 impl->SetMemoryPolicy(ManagedMemoryPolicy( 4284 16u * 1024u * 1024u, 4285 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, 4286 1000)); 4287 break; 4288 case 3: 4289 // This will not trigger a commit because the priority cutoff has not 4290 // changed, and there is already enough memory for all allocations. 4291 impl->SetMemoryPolicy(ManagedMemoryPolicy( 4292 32u * 1024u * 1024u, 4293 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, 4294 1000)); 4295 break; 4296 case 4: 4297 NOTREACHED(); 4298 break; 4299 } 4300 } 4301 4302 virtual void AfterTest() OVERRIDE {} 4303 4304 private: 4305 int num_commits_; 4306 }; 4307 4308 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits); 4309 4310 } // namespace 4311 4312 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface 4313 : public LayerTreeHostTest { 4314 protected: 4315 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface() 4316 : first_output_surface_memory_limit_(4321234), 4317 second_output_surface_memory_limit_(1234321) {} 4318 4319 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) 4320 OVERRIDE { 4321 if (!first_context_provider_) { 4322 first_context_provider_ = TestContextProvider::Create(); 4323 } else { 4324 EXPECT_FALSE(second_context_provider_); 4325 second_context_provider_ = TestContextProvider::Create(); 4326 } 4327 4328 scoped_refptr<TestContextProvider> provider(second_context_provider_ 4329 ? second_context_provider_ 4330 : first_context_provider_); 4331 scoped_ptr<FakeOutputSurface> output_surface; 4332 if (delegating_renderer()) 4333 output_surface = FakeOutputSurface::CreateDelegating3d(provider); 4334 else 4335 output_surface = FakeOutputSurface::Create3d(provider); 4336 output_surface->SetMemoryPolicyToSetAtBind( 4337 make_scoped_ptr(new ManagedMemoryPolicy( 4338 second_context_provider_ ? second_output_surface_memory_limit_ 4339 : first_output_surface_memory_limit_, 4340 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, 4341 ManagedMemoryPolicy::kDefaultNumResourcesLimit))); 4342 return output_surface.Pass(); 4343 } 4344 4345 virtual void SetupTree() OVERRIDE { 4346 root_ = FakeContentLayer::Create(&client_); 4347 root_->SetBounds(gfx::Size(20, 20)); 4348 layer_tree_host()->SetRootLayer(root_); 4349 LayerTreeHostTest::SetupTree(); 4350 } 4351 4352 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 4353 4354 virtual void DidCommitAndDrawFrame() OVERRIDE { 4355 // Lost context sometimes takes two frames to recreate. The third frame 4356 // is sometimes aborted, so wait until the fourth frame to verify that 4357 // the memory has been set, and the fifth frame to end the test. 4358 if (layer_tree_host()->source_frame_number() < 5) { 4359 layer_tree_host()->SetNeedsCommit(); 4360 } else if (layer_tree_host()->source_frame_number() == 5) { 4361 EndTest(); 4362 } 4363 } 4364 4365 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl, 4366 bool result) OVERRIDE { 4367 switch (impl->active_tree()->source_frame_number()) { 4368 case 1: 4369 EXPECT_EQ(first_output_surface_memory_limit_, 4370 impl->memory_allocation_limit_bytes()); 4371 // Lose the output surface. 4372 first_context_provider_->TestContext3d()->loseContextCHROMIUM( 4373 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); 4374 break; 4375 case 4: 4376 EXPECT_EQ(second_output_surface_memory_limit_, 4377 impl->memory_allocation_limit_bytes()); 4378 break; 4379 } 4380 } 4381 4382 virtual void AfterTest() OVERRIDE {} 4383 4384 scoped_refptr<TestContextProvider> first_context_provider_; 4385 scoped_refptr<TestContextProvider> second_context_provider_; 4386 size_t first_output_surface_memory_limit_; 4387 size_t second_output_surface_memory_limit_; 4388 FakeContentLayerClient client_; 4389 scoped_refptr<FakeContentLayer> root_; 4390 }; 4391 4392 // No output to copy for delegated renderers. 4393 SINGLE_AND_MULTI_THREAD_TEST_F( 4394 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface); 4395 4396 struct TestSwapPromiseResult { 4397 TestSwapPromiseResult() 4398 : did_swap_called(false), 4399 did_not_swap_called(false), 4400 dtor_called(false), 4401 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {} 4402 4403 bool did_swap_called; 4404 bool did_not_swap_called; 4405 bool dtor_called; 4406 SwapPromise::DidNotSwapReason reason; 4407 base::Lock lock; 4408 }; 4409 4410 class TestSwapPromise : public SwapPromise { 4411 public: 4412 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {} 4413 4414 virtual ~TestSwapPromise() { 4415 base::AutoLock lock(result_->lock); 4416 result_->dtor_called = true; 4417 } 4418 4419 virtual void DidSwap(CompositorFrameMetadata* metadata) OVERRIDE { 4420 base::AutoLock lock(result_->lock); 4421 EXPECT_FALSE(result_->did_swap_called); 4422 EXPECT_FALSE(result_->did_not_swap_called); 4423 result_->did_swap_called = true; 4424 } 4425 4426 virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE { 4427 base::AutoLock lock(result_->lock); 4428 EXPECT_FALSE(result_->did_swap_called); 4429 EXPECT_FALSE(result_->did_not_swap_called); 4430 result_->did_not_swap_called = true; 4431 result_->reason = reason; 4432 } 4433 4434 private: 4435 // Not owned. 4436 TestSwapPromiseResult* result_; 4437 }; 4438 4439 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { 4440 protected: 4441 LayerTreeHostTestBreakSwapPromise() 4442 : commit_count_(0), commit_complete_count_(0) {} 4443 4444 virtual void WillBeginMainFrame() OVERRIDE { 4445 ASSERT_LE(commit_count_, 2); 4446 scoped_ptr<SwapPromise> swap_promise( 4447 new TestSwapPromise(&swap_promise_result_[commit_count_])); 4448 layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); 4449 } 4450 4451 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 4452 4453 virtual void DidCommit() OVERRIDE { 4454 commit_count_++; 4455 if (commit_count_ == 2) { 4456 // This commit will finish. 4457 layer_tree_host()->SetNeedsCommit(); 4458 } 4459 } 4460 4461 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 4462 commit_complete_count_++; 4463 if (commit_complete_count_ == 1) { 4464 // This commit will be aborted because no actual update. 4465 PostSetNeedsUpdateLayersToMainThread(); 4466 } else { 4467 EndTest(); 4468 } 4469 } 4470 4471 virtual void AfterTest() OVERRIDE { 4472 // 3 commits are scheduled. 2 completes. 1 is aborted. 4473 EXPECT_EQ(commit_count_, 3); 4474 EXPECT_EQ(commit_complete_count_, 2); 4475 4476 { 4477 // The first commit completes and causes swap buffer which finishes 4478 // the promise. 4479 base::AutoLock lock(swap_promise_result_[0].lock); 4480 EXPECT_TRUE(swap_promise_result_[0].did_swap_called); 4481 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called); 4482 EXPECT_TRUE(swap_promise_result_[0].dtor_called); 4483 } 4484 4485 { 4486 // The second commit aborts. 4487 base::AutoLock lock(swap_promise_result_[1].lock); 4488 EXPECT_FALSE(swap_promise_result_[1].did_swap_called); 4489 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); 4490 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_[1].reason); 4491 EXPECT_TRUE(swap_promise_result_[1].dtor_called); 4492 } 4493 4494 { 4495 // The last commit completes but it does not cause swap buffer because 4496 // there is no damage in the frame data. 4497 base::AutoLock lock(swap_promise_result_[2].lock); 4498 EXPECT_FALSE(swap_promise_result_[2].did_swap_called); 4499 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called); 4500 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason); 4501 EXPECT_TRUE(swap_promise_result_[2].dtor_called); 4502 } 4503 } 4504 4505 int commit_count_; 4506 int commit_complete_count_; 4507 TestSwapPromiseResult swap_promise_result_[3]; 4508 }; 4509 4510 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); 4511 4512 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { 4513 public: 4514 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, 4515 LayerTreeHostImpl* layer_tree_host_impl, 4516 int* set_needs_commit_count, 4517 int* set_needs_redraw_count) 4518 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl), 4519 set_needs_commit_count_(set_needs_commit_count), 4520 set_needs_redraw_count_(set_needs_redraw_count) {} 4521 4522 virtual ~SimpleSwapPromiseMonitor() {} 4523 4524 virtual void OnSetNeedsCommitOnMain() OVERRIDE { 4525 (*set_needs_commit_count_)++; 4526 } 4527 4528 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE { 4529 (*set_needs_redraw_count_)++; 4530 } 4531 4532 private: 4533 int* set_needs_commit_count_; 4534 int* set_needs_redraw_count_; 4535 }; 4536 4537 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { 4538 public: 4539 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 4540 4541 virtual void WillBeginMainFrame() OVERRIDE { 4542 int set_needs_commit_count = 0; 4543 int set_needs_redraw_count = 0; 4544 4545 { 4546 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 4547 new SimpleSwapPromiseMonitor(layer_tree_host(), 4548 NULL, 4549 &set_needs_commit_count, 4550 &set_needs_redraw_count)); 4551 layer_tree_host()->SetNeedsCommit(); 4552 EXPECT_EQ(1, set_needs_commit_count); 4553 EXPECT_EQ(0, set_needs_redraw_count); 4554 } 4555 4556 // Now the monitor is destroyed, SetNeedsCommit() is no longer being 4557 // monitored. 4558 layer_tree_host()->SetNeedsCommit(); 4559 EXPECT_EQ(1, set_needs_commit_count); 4560 EXPECT_EQ(0, set_needs_redraw_count); 4561 4562 { 4563 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 4564 new SimpleSwapPromiseMonitor(layer_tree_host(), 4565 NULL, 4566 &set_needs_commit_count, 4567 &set_needs_redraw_count)); 4568 layer_tree_host()->SetNeedsUpdateLayers(); 4569 EXPECT_EQ(2, set_needs_commit_count); 4570 EXPECT_EQ(0, set_needs_redraw_count); 4571 } 4572 4573 { 4574 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 4575 new SimpleSwapPromiseMonitor(layer_tree_host(), 4576 NULL, 4577 &set_needs_commit_count, 4578 &set_needs_redraw_count)); 4579 layer_tree_host()->SetNeedsAnimate(); 4580 EXPECT_EQ(3, set_needs_commit_count); 4581 EXPECT_EQ(0, set_needs_redraw_count); 4582 } 4583 4584 EndTest(); 4585 } 4586 4587 virtual void AfterTest() OVERRIDE {} 4588 }; 4589 4590 MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); 4591 4592 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources 4593 : public LayerTreeHostTest { 4594 protected: 4595 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 4596 settings->impl_side_painting = true; 4597 } 4598 4599 virtual void SetupTree() OVERRIDE { 4600 LayerTreeHostTest::SetupTree(); 4601 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); 4602 } 4603 4604 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 4605 4606 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 4607 host_impl->EvictAllUIResources(); 4608 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY 4609 // mode. Active tree should require high-res to draw after entering this 4610 // mode to ensure that high-res tiles are also required for a pending tree 4611 // to be activated. 4612 EXPECT_TRUE(host_impl->active_tree()->RequiresHighResToDraw()); 4613 } 4614 4615 virtual void DidCommit() OVERRIDE { 4616 int frame = layer_tree_host()->source_frame_number(); 4617 switch (frame) { 4618 case 1: 4619 PostSetNeedsCommitToMainThread(); 4620 break; 4621 case 2: 4622 ui_resource_.reset(); 4623 EndTest(); 4624 break; 4625 } 4626 } 4627 4628 virtual void AfterTest() OVERRIDE {} 4629 4630 FakeContentLayerClient client_; 4631 scoped_ptr<FakeScopedUIResource> ui_resource_; 4632 }; 4633 4634 // This test is flaky, see http://crbug.com/386199 4635 //MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources); 4636 4637 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { 4638 protected: 4639 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 4640 settings->impl_side_painting = true; 4641 4642 EXPECT_FALSE(settings->gpu_rasterization_enabled); 4643 EXPECT_FALSE(settings->gpu_rasterization_forced); 4644 } 4645 4646 virtual void SetupTree() OVERRIDE { 4647 LayerTreeHostTest::SetupTree(); 4648 4649 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); 4650 layer->SetBounds(gfx::Size(10, 10)); 4651 layer->SetIsDrawable(true); 4652 layer_tree_host()->root_layer()->AddChild(layer); 4653 } 4654 4655 virtual void BeginTest() OVERRIDE { 4656 Layer* root = layer_tree_host()->root_layer(); 4657 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); 4658 PicturePile* pile = layer->GetPicturePileForTesting(); 4659 4660 // Verify default values. 4661 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); 4662 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); 4663 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); 4664 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); 4665 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); 4666 4667 // Setting gpu rasterization trigger does not enable gpu rasterization. 4668 layer_tree_host()->SetHasGpuRasterizationTrigger(true); 4669 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); 4670 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); 4671 4672 PostSetNeedsCommitToMainThread(); 4673 } 4674 4675 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 4676 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); 4677 EXPECT_FALSE(host_impl->use_gpu_rasterization()); 4678 } 4679 4680 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 4681 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); 4682 EXPECT_FALSE(host_impl->use_gpu_rasterization()); 4683 EndTest(); 4684 } 4685 4686 virtual void AfterTest() OVERRIDE {} 4687 4688 FakeContentLayerClient layer_client_; 4689 }; 4690 4691 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault); 4692 4693 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { 4694 protected: 4695 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 4696 settings->impl_side_painting = true; 4697 4698 EXPECT_FALSE(settings->gpu_rasterization_enabled); 4699 settings->gpu_rasterization_enabled = true; 4700 } 4701 4702 virtual void SetupTree() OVERRIDE { 4703 LayerTreeHostTest::SetupTree(); 4704 4705 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); 4706 layer->SetBounds(gfx::Size(10, 10)); 4707 layer->SetIsDrawable(true); 4708 layer_tree_host()->root_layer()->AddChild(layer); 4709 } 4710 4711 virtual void BeginTest() OVERRIDE { 4712 Layer* root = layer_tree_host()->root_layer(); 4713 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); 4714 PicturePile* pile = layer->GetPicturePileForTesting(); 4715 4716 // Verify default values. 4717 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); 4718 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); 4719 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); 4720 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); 4721 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); 4722 4723 // Gpu rasterization trigger is relevant. 4724 layer_tree_host()->SetHasGpuRasterizationTrigger(true); 4725 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); 4726 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); 4727 4728 // Content-based veto is relevant as well. 4729 pile->SetUnsuitableForGpuRasterizationForTesting(); 4730 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization()); 4731 EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); 4732 // Veto will take effect when layers are updated. 4733 // The results will be verified after commit is completed below. 4734 // Since we are manually marking picture pile as unsuitable, 4735 // make sure that the layer gets a chance to update. 4736 layer->SetNeedsDisplay(); 4737 PostSetNeedsCommitToMainThread(); 4738 } 4739 4740 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 4741 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); 4742 EXPECT_FALSE(host_impl->use_gpu_rasterization()); 4743 } 4744 4745 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 4746 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); 4747 EXPECT_FALSE(host_impl->use_gpu_rasterization()); 4748 EndTest(); 4749 } 4750 4751 virtual void AfterTest() OVERRIDE {} 4752 4753 FakeContentLayerClient layer_client_; 4754 }; 4755 4756 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); 4757 4758 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { 4759 protected: 4760 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 4761 settings->impl_side_painting = true; 4762 4763 EXPECT_FALSE(settings->gpu_rasterization_forced); 4764 settings->gpu_rasterization_forced = true; 4765 } 4766 4767 virtual void SetupTree() OVERRIDE { 4768 LayerTreeHostTest::SetupTree(); 4769 4770 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); 4771 layer->SetBounds(gfx::Size(10, 10)); 4772 layer->SetIsDrawable(true); 4773 layer_tree_host()->root_layer()->AddChild(layer); 4774 } 4775 4776 virtual void BeginTest() OVERRIDE { 4777 Layer* root = layer_tree_host()->root_layer(); 4778 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); 4779 PicturePile* pile = layer->GetPicturePileForTesting(); 4780 4781 // Verify default values. 4782 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); 4783 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); 4784 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); 4785 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); 4786 4787 // With gpu rasterization forced, gpu rasterization trigger is irrelevant. 4788 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); 4789 layer_tree_host()->SetHasGpuRasterizationTrigger(true); 4790 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); 4791 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); 4792 4793 // Content-based veto is irrelevant as well. 4794 pile->SetUnsuitableForGpuRasterizationForTesting(); 4795 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization()); 4796 EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); 4797 // Veto will take effect when layers are updated. 4798 // The results will be verified after commit is completed below. 4799 // Since we are manually marking picture pile as unsuitable, 4800 // make sure that the layer gets a chance to update. 4801 layer->SetNeedsDisplay(); 4802 PostSetNeedsCommitToMainThread(); 4803 } 4804 4805 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 4806 EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization()); 4807 EXPECT_TRUE(host_impl->use_gpu_rasterization()); 4808 } 4809 4810 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 4811 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); 4812 EXPECT_TRUE(host_impl->use_gpu_rasterization()); 4813 EndTest(); 4814 } 4815 4816 virtual void AfterTest() OVERRIDE {} 4817 4818 FakeContentLayerClient layer_client_; 4819 }; 4820 4821 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced); 4822 4823 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest { 4824 public: 4825 LayerTreeHostTestContinuousPainting() 4826 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {} 4827 4828 protected: 4829 enum { kExpectedNumCommits = 10 }; 4830 4831 virtual void SetupTree() OVERRIDE { 4832 scoped_refptr<Layer> root_layer = Layer::Create(); 4833 root_layer->SetBounds(bounds_); 4834 4835 if (layer_tree_host()->settings().impl_side_painting) { 4836 picture_layer_ = FakePictureLayer::Create(&client_); 4837 child_layer_ = picture_layer_.get(); 4838 } else { 4839 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_); 4840 child_layer_ = content_layer_.get(); 4841 } 4842 child_layer_->SetBounds(bounds_); 4843 child_layer_->SetIsDrawable(true); 4844 root_layer->AddChild(child_layer_); 4845 4846 layer_tree_host()->SetRootLayer(root_layer); 4847 layer_tree_host()->SetViewportSize(bounds_); 4848 LayerTreeHostTest::SetupTree(); 4849 } 4850 4851 virtual void BeginTest() OVERRIDE { 4852 // Wait 50x longer than expected. 4853 double milliseconds_per_frame = 4854 1000 / layer_tree_host()->settings().refresh_rate; 4855 EndTestAfterDelay(50 * kExpectedNumCommits * milliseconds_per_frame); 4856 MainThreadTaskRunner()->PostTask( 4857 FROM_HERE, 4858 base::Bind( 4859 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting, 4860 base::Unretained(this))); 4861 } 4862 4863 virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE { 4864 child_layer_->SetNeedsDisplay(); 4865 } 4866 4867 virtual void AfterTest() OVERRIDE { 4868 EXPECT_LE(kExpectedNumCommits, num_commits_); 4869 EXPECT_LE(kExpectedNumCommits, num_draws_); 4870 int update_count = content_layer_ ? content_layer_->PaintContentsCount() 4871 : picture_layer_->update_count(); 4872 EXPECT_LE(kExpectedNumCommits, update_count); 4873 } 4874 4875 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 4876 if (++num_draws_ == kExpectedNumCommits) 4877 EndTest(); 4878 } 4879 4880 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 4881 ++num_commits_; 4882 } 4883 4884 private: 4885 void EnableContinuousPainting() { 4886 LayerTreeDebugState debug_state = layer_tree_host()->debug_state(); 4887 debug_state.continuous_painting = true; 4888 layer_tree_host()->SetDebugState(debug_state); 4889 } 4890 4891 int num_commits_; 4892 int num_draws_; 4893 const gfx::Size bounds_; 4894 FakeContentLayerClient client_; 4895 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_; 4896 scoped_refptr<FakePictureLayer> picture_layer_; 4897 Layer* child_layer_; 4898 }; 4899 4900 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting); 4901 4902 } // namespace cc 4903