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