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