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