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