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/test/layer_tree_test.h" 6 7 #include "base/command_line.h" 8 #include "cc/animation/animation.h" 9 #include "cc/animation/animation_registrar.h" 10 #include "cc/animation/layer_animation_controller.h" 11 #include "cc/animation/timing_function.h" 12 #include "cc/base/switches.h" 13 #include "cc/input/input_handler.h" 14 #include "cc/layers/content_layer.h" 15 #include "cc/layers/layer.h" 16 #include "cc/layers/layer_impl.h" 17 #include "cc/test/animation_test_common.h" 18 #include "cc/test/fake_layer_tree_host_client.h" 19 #include "cc/test/fake_output_surface.h" 20 #include "cc/test/test_context_provider.h" 21 #include "cc/test/test_shared_bitmap_manager.h" 22 #include "cc/test/tiled_layer_test_common.h" 23 #include "cc/trees/layer_tree_host_client.h" 24 #include "cc/trees/layer_tree_host_impl.h" 25 #include "cc/trees/layer_tree_host_single_thread_client.h" 26 #include "cc/trees/layer_tree_impl.h" 27 #include "cc/trees/single_thread_proxy.h" 28 #include "cc/trees/thread_proxy.h" 29 #include "testing/gmock/include/gmock/gmock.h" 30 #include "ui/gfx/frame_time.h" 31 #include "ui/gfx/size_conversions.h" 32 33 namespace cc { 34 35 TestHooks::TestHooks() {} 36 37 TestHooks::~TestHooks() {} 38 39 DrawResult TestHooks::PrepareToDrawOnThread( 40 LayerTreeHostImpl* host_impl, 41 LayerTreeHostImpl::FrameData* frame_data, 42 DrawResult draw_result) { 43 return draw_result; 44 } 45 46 base::TimeDelta TestHooks::LowFrequencyAnimationInterval() const { 47 return base::TimeDelta::FromMilliseconds(16); 48 } 49 50 // Adapts ThreadProxy for test. Injects test hooks for testing. 51 class ThreadProxyForTest : public ThreadProxy { 52 public: 53 static scoped_ptr<Proxy> Create( 54 TestHooks* test_hooks, 55 LayerTreeHost* host, 56 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { 57 return make_scoped_ptr( 58 new ThreadProxyForTest(test_hooks, 59 host, 60 impl_task_runner)).PassAs<Proxy>(); 61 } 62 63 virtual ~ThreadProxyForTest() {} 64 65 void test() { 66 test_hooks_->Layout(); 67 } 68 69 private: 70 TestHooks* test_hooks_; 71 72 virtual void ScheduledActionSendBeginMainFrame() OVERRIDE { 73 test_hooks_->ScheduledActionWillSendBeginMainFrame(); 74 ThreadProxy::ScheduledActionSendBeginMainFrame(); 75 test_hooks_->ScheduledActionSendBeginMainFrame(); 76 } 77 78 virtual DrawResult ScheduledActionDrawAndSwapIfPossible() OVERRIDE { 79 DrawResult result = ThreadProxy::ScheduledActionDrawAndSwapIfPossible(); 80 test_hooks_->ScheduledActionDrawAndSwapIfPossible(); 81 return result; 82 } 83 84 virtual void ScheduledActionAnimate() OVERRIDE { 85 ThreadProxy::ScheduledActionAnimate(); 86 test_hooks_->ScheduledActionAnimate(); 87 } 88 89 virtual void ScheduledActionCommit() OVERRIDE { 90 ThreadProxy::ScheduledActionCommit(); 91 test_hooks_->ScheduledActionCommit(); 92 } 93 94 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE { 95 ThreadProxy::ScheduledActionBeginOutputSurfaceCreation(); 96 test_hooks_->ScheduledActionBeginOutputSurfaceCreation(); 97 } 98 99 ThreadProxyForTest( 100 TestHooks* test_hooks, 101 LayerTreeHost* host, 102 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) 103 : ThreadProxy(host, impl_task_runner), 104 test_hooks_(test_hooks) { 105 } 106 }; 107 108 // Adapts LayerTreeHostImpl for test. Runs real code, then invokes test hooks. 109 class LayerTreeHostImplForTesting : public LayerTreeHostImpl { 110 public: 111 static scoped_ptr<LayerTreeHostImplForTesting> Create( 112 TestHooks* test_hooks, 113 const LayerTreeSettings& settings, 114 LayerTreeHostImplClient* host_impl_client, 115 Proxy* proxy, 116 SharedBitmapManager* manager, 117 RenderingStatsInstrumentation* stats_instrumentation) { 118 return make_scoped_ptr( 119 new LayerTreeHostImplForTesting(test_hooks, 120 settings, 121 host_impl_client, 122 proxy, 123 manager, 124 stats_instrumentation)); 125 } 126 127 protected: 128 LayerTreeHostImplForTesting( 129 TestHooks* test_hooks, 130 const LayerTreeSettings& settings, 131 LayerTreeHostImplClient* host_impl_client, 132 Proxy* proxy, 133 SharedBitmapManager* manager, 134 RenderingStatsInstrumentation* stats_instrumentation) 135 : LayerTreeHostImpl(settings, 136 host_impl_client, 137 proxy, 138 stats_instrumentation, 139 manager, 140 0), 141 test_hooks_(test_hooks), 142 block_notify_ready_to_activate_for_testing_(false), 143 notify_ready_to_activate_was_blocked_(false) {} 144 145 virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE { 146 LayerTreeHostImpl::WillBeginImplFrame(args); 147 test_hooks_->WillBeginImplFrameOnThread(this, args); 148 } 149 150 virtual void BeginMainFrameAborted(bool did_handle) OVERRIDE { 151 LayerTreeHostImpl::BeginMainFrameAborted(did_handle); 152 test_hooks_->BeginMainFrameAbortedOnThread(this, did_handle); 153 } 154 155 virtual void BeginCommit() OVERRIDE { 156 LayerTreeHostImpl::BeginCommit(); 157 test_hooks_->BeginCommitOnThread(this); 158 } 159 160 virtual void CommitComplete() OVERRIDE { 161 LayerTreeHostImpl::CommitComplete(); 162 test_hooks_->CommitCompleteOnThread(this); 163 164 if (!settings().impl_side_painting) { 165 test_hooks_->WillActivateTreeOnThread(this); 166 test_hooks_->DidActivateTreeOnThread(this); 167 } 168 } 169 170 virtual DrawResult PrepareToDraw(FrameData* frame) OVERRIDE { 171 DrawResult draw_result = LayerTreeHostImpl::PrepareToDraw(frame); 172 return test_hooks_->PrepareToDrawOnThread(this, frame, draw_result); 173 } 174 175 virtual void DrawLayers(FrameData* frame, 176 base::TimeTicks frame_begin_time) OVERRIDE { 177 LayerTreeHostImpl::DrawLayers(frame, frame_begin_time); 178 test_hooks_->DrawLayersOnThread(this); 179 } 180 181 virtual bool SwapBuffers(const LayerTreeHostImpl::FrameData& frame) OVERRIDE { 182 bool result = LayerTreeHostImpl::SwapBuffers(frame); 183 test_hooks_->SwapBuffersOnThread(this, result); 184 return result; 185 } 186 187 virtual void DidSwapBuffersComplete() OVERRIDE { 188 LayerTreeHostImpl::DidSwapBuffersComplete(); 189 test_hooks_->SwapBuffersCompleteOnThread(this); 190 } 191 192 virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE { 193 LayerTreeHostImpl::ReclaimResources(ack); 194 } 195 196 virtual void UpdateVisibleTiles() OVERRIDE { 197 LayerTreeHostImpl::UpdateVisibleTiles(); 198 test_hooks_->UpdateVisibleTilesOnThread(this); 199 } 200 201 virtual void NotifyReadyToActivate() OVERRIDE { 202 if (block_notify_ready_to_activate_for_testing_) 203 notify_ready_to_activate_was_blocked_ = true; 204 else 205 client_->NotifyReadyToActivate(); 206 } 207 208 virtual void BlockNotifyReadyToActivateForTesting(bool block) OVERRIDE { 209 block_notify_ready_to_activate_for_testing_ = block; 210 if (!block && notify_ready_to_activate_was_blocked_) { 211 NotifyReadyToActivate(); 212 notify_ready_to_activate_was_blocked_ = false; 213 } 214 } 215 216 virtual void ActivatePendingTree() OVERRIDE { 217 test_hooks_->WillActivateTreeOnThread(this); 218 LayerTreeHostImpl::ActivatePendingTree(); 219 DCHECK(!pending_tree()); 220 test_hooks_->DidActivateTreeOnThread(this); 221 } 222 223 virtual bool InitializeRenderer(scoped_ptr<OutputSurface> output_surface) 224 OVERRIDE { 225 bool success = LayerTreeHostImpl::InitializeRenderer(output_surface.Pass()); 226 test_hooks_->InitializedRendererOnThread(this, success); 227 return success; 228 } 229 230 virtual void SetVisible(bool visible) OVERRIDE { 231 LayerTreeHostImpl::SetVisible(visible); 232 test_hooks_->DidSetVisibleOnImplTree(this, visible); 233 } 234 235 virtual void AnimateLayers(base::TimeTicks monotonic_time) OVERRIDE { 236 test_hooks_->WillAnimateLayers(this, monotonic_time); 237 LayerTreeHostImpl::AnimateLayers(monotonic_time); 238 test_hooks_->AnimateLayers(this, monotonic_time); 239 } 240 241 virtual void UpdateAnimationState(bool start_ready_animations) OVERRIDE { 242 LayerTreeHostImpl::UpdateAnimationState(start_ready_animations); 243 bool has_unfinished_animation = false; 244 AnimationRegistrar::AnimationControllerMap::const_iterator iter = 245 active_animation_controllers().begin(); 246 for (; iter != active_animation_controllers().end(); ++iter) { 247 if (iter->second->HasActiveAnimation()) { 248 has_unfinished_animation = true; 249 break; 250 } 251 } 252 test_hooks_->UpdateAnimationState(this, has_unfinished_animation); 253 } 254 255 virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE { 256 return test_hooks_->LowFrequencyAnimationInterval(); 257 } 258 259 private: 260 TestHooks* test_hooks_; 261 bool block_notify_ready_to_activate_for_testing_; 262 bool notify_ready_to_activate_was_blocked_; 263 }; 264 265 // Implementation of LayerTreeHost callback interface. 266 class LayerTreeHostClientForTesting : public LayerTreeHostClient, 267 public LayerTreeHostSingleThreadClient { 268 public: 269 static scoped_ptr<LayerTreeHostClientForTesting> Create( 270 TestHooks* test_hooks) { 271 return make_scoped_ptr(new LayerTreeHostClientForTesting(test_hooks)); 272 } 273 virtual ~LayerTreeHostClientForTesting() {} 274 275 virtual void WillBeginMainFrame(int frame_id) OVERRIDE { 276 test_hooks_->WillBeginMainFrame(); 277 } 278 279 virtual void DidBeginMainFrame() OVERRIDE { 280 test_hooks_->DidBeginMainFrame(); 281 } 282 283 virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE { 284 test_hooks_->Animate(monotonic_time); 285 } 286 287 virtual void Layout() OVERRIDE { test_hooks_->Layout(); } 288 289 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, 290 float scale) OVERRIDE { 291 test_hooks_->ApplyScrollAndScale(scroll_delta, scale); 292 } 293 294 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) 295 OVERRIDE { 296 return test_hooks_->CreateOutputSurface(fallback); 297 } 298 299 virtual void DidInitializeOutputSurface() OVERRIDE { 300 test_hooks_->DidInitializeOutputSurface(); 301 } 302 303 virtual void DidFailToInitializeOutputSurface() OVERRIDE { 304 test_hooks_->DidFailToInitializeOutputSurface(); 305 } 306 307 virtual void WillCommit() OVERRIDE { test_hooks_->WillCommit(); } 308 309 virtual void DidCommit() OVERRIDE { test_hooks_->DidCommit(); } 310 311 virtual void DidCommitAndDrawFrame() OVERRIDE { 312 test_hooks_->DidCommitAndDrawFrame(); 313 } 314 315 virtual void DidCompleteSwapBuffers() OVERRIDE { 316 test_hooks_->DidCompleteSwapBuffers(); 317 } 318 319 virtual void ScheduleComposite() OVERRIDE { 320 test_hooks_->ScheduleComposite(); 321 } 322 323 virtual void ScheduleAnimation() OVERRIDE { 324 test_hooks_->ScheduleAnimation(); 325 } 326 327 virtual void DidPostSwapBuffers() OVERRIDE {} 328 virtual void DidAbortSwapBuffers() OVERRIDE {} 329 330 private: 331 explicit LayerTreeHostClientForTesting(TestHooks* test_hooks) 332 : test_hooks_(test_hooks) {} 333 334 TestHooks* test_hooks_; 335 }; 336 337 // Adapts LayerTreeHost for test. Injects LayerTreeHostImplForTesting. 338 class LayerTreeHostForTesting : public LayerTreeHost { 339 public: 340 static scoped_ptr<LayerTreeHostForTesting> Create( 341 TestHooks* test_hooks, 342 LayerTreeHostClientForTesting* client, 343 const LayerTreeSettings& settings, 344 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { 345 scoped_ptr<LayerTreeHostForTesting> layer_tree_host( 346 new LayerTreeHostForTesting(test_hooks, client, settings)); 347 if (impl_task_runner.get()) { 348 layer_tree_host->InitializeForTesting( 349 ThreadProxyForTest::Create(test_hooks, 350 layer_tree_host.get(), 351 impl_task_runner)); 352 } else { 353 layer_tree_host->InitializeForTesting( 354 SingleThreadProxy::Create(layer_tree_host.get(), client)); 355 } 356 return layer_tree_host.Pass(); 357 } 358 359 virtual scoped_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( 360 LayerTreeHostImplClient* host_impl_client) OVERRIDE { 361 return LayerTreeHostImplForTesting::Create( 362 test_hooks_, 363 settings(), 364 host_impl_client, 365 proxy(), 366 shared_bitmap_manager_.get(), 367 rendering_stats_instrumentation()).PassAs<LayerTreeHostImpl>(); 368 } 369 370 virtual void SetNeedsCommit() OVERRIDE { 371 if (!test_started_) 372 return; 373 LayerTreeHost::SetNeedsCommit(); 374 } 375 376 void set_test_started(bool started) { test_started_ = started; } 377 378 virtual void DidDeferCommit() OVERRIDE { test_hooks_->DidDeferCommit(); } 379 380 private: 381 LayerTreeHostForTesting(TestHooks* test_hooks, 382 LayerTreeHostClient* client, 383 const LayerTreeSettings& settings) 384 : LayerTreeHost(client, NULL, settings), 385 shared_bitmap_manager_(new TestSharedBitmapManager()), 386 test_hooks_(test_hooks), 387 test_started_(false) {} 388 389 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; 390 TestHooks* test_hooks_; 391 bool test_started_; 392 }; 393 394 LayerTreeTest::LayerTreeTest() 395 : beginning_(false), 396 end_when_begin_returns_(false), 397 timed_out_(false), 398 scheduled_(false), 399 schedule_when_set_visible_true_(false), 400 started_(false), 401 ended_(false), 402 delegating_renderer_(false), 403 timeout_seconds_(0), 404 weak_factory_(this) { 405 main_thread_weak_ptr_ = weak_factory_.GetWeakPtr(); 406 407 // Tests should timeout quickly unless --cc-layer-tree-test-no-timeout was 408 // specified (for running in a debugger). 409 CommandLine* command_line = CommandLine::ForCurrentProcess(); 410 if (!command_line->HasSwitch(switches::kCCLayerTreeTestNoTimeout)) 411 timeout_seconds_ = 5; 412 } 413 414 LayerTreeTest::~LayerTreeTest() {} 415 416 void LayerTreeTest::EndTest() { 417 if (ended_) 418 return; 419 ended_ = true; 420 421 // For the case where we EndTest during BeginTest(), set a flag to indicate 422 // that the test should end the second BeginTest regains control. 423 if (beginning_) { 424 end_when_begin_returns_ = true; 425 } else { 426 main_task_runner_->PostTask( 427 FROM_HERE, 428 base::Bind(&LayerTreeTest::RealEndTest, main_thread_weak_ptr_)); 429 } 430 } 431 432 void LayerTreeTest::EndTestAfterDelay(int delay_milliseconds) { 433 main_task_runner_->PostDelayedTask( 434 FROM_HERE, 435 base::Bind(&LayerTreeTest::EndTest, main_thread_weak_ptr_), 436 base::TimeDelta::FromMilliseconds(delay_milliseconds)); 437 } 438 439 void LayerTreeTest::PostAddAnimationToMainThread( 440 Layer* layer_to_receive_animation) { 441 main_task_runner_->PostTask( 442 FROM_HERE, 443 base::Bind(&LayerTreeTest::DispatchAddAnimation, 444 main_thread_weak_ptr_, 445 base::Unretained(layer_to_receive_animation), 446 0.000001)); 447 } 448 449 void LayerTreeTest::PostAddInstantAnimationToMainThread( 450 Layer* layer_to_receive_animation) { 451 main_task_runner_->PostTask( 452 FROM_HERE, 453 base::Bind(&LayerTreeTest::DispatchAddAnimation, 454 main_thread_weak_ptr_, 455 base::Unretained(layer_to_receive_animation), 456 0.0)); 457 } 458 459 void LayerTreeTest::PostAddLongAnimationToMainThread( 460 Layer* layer_to_receive_animation) { 461 main_task_runner_->PostTask( 462 FROM_HERE, 463 base::Bind(&LayerTreeTest::DispatchAddAnimation, 464 main_thread_weak_ptr_, 465 base::Unretained(layer_to_receive_animation), 466 1.0)); 467 } 468 469 void LayerTreeTest::PostSetNeedsCommitToMainThread() { 470 main_task_runner_->PostTask(FROM_HERE, 471 base::Bind(&LayerTreeTest::DispatchSetNeedsCommit, 472 main_thread_weak_ptr_)); 473 } 474 475 void LayerTreeTest::PostSetNeedsUpdateLayersToMainThread() { 476 main_task_runner_->PostTask( 477 FROM_HERE, 478 base::Bind(&LayerTreeTest::DispatchSetNeedsUpdateLayers, 479 main_thread_weak_ptr_)); 480 } 481 482 void LayerTreeTest::PostSetNeedsRedrawToMainThread() { 483 main_task_runner_->PostTask(FROM_HERE, 484 base::Bind(&LayerTreeTest::DispatchSetNeedsRedraw, 485 main_thread_weak_ptr_)); 486 } 487 488 void LayerTreeTest::PostSetNeedsRedrawRectToMainThread( 489 const gfx::Rect& damage_rect) { 490 main_task_runner_->PostTask( 491 FROM_HERE, 492 base::Bind(&LayerTreeTest::DispatchSetNeedsRedrawRect, 493 main_thread_weak_ptr_, 494 damage_rect)); 495 } 496 497 void LayerTreeTest::PostSetVisibleToMainThread(bool visible) { 498 main_task_runner_->PostTask( 499 FROM_HERE, 500 base::Bind( 501 &LayerTreeTest::DispatchSetVisible, main_thread_weak_ptr_, visible)); 502 } 503 504 void LayerTreeTest::PostSetNextCommitForcesRedrawToMainThread() { 505 main_task_runner_->PostTask( 506 FROM_HERE, 507 base::Bind(&LayerTreeTest::DispatchSetNextCommitForcesRedraw, 508 main_thread_weak_ptr_)); 509 } 510 511 void LayerTreeTest::WillBeginTest() { 512 layer_tree_host_->SetLayerTreeHostClientReady(); 513 } 514 515 void LayerTreeTest::DoBeginTest() { 516 client_ = LayerTreeHostClientForTesting::Create(this); 517 518 DCHECK(!impl_thread_ || impl_thread_->message_loop_proxy().get()); 519 layer_tree_host_ = LayerTreeHostForTesting::Create( 520 this, 521 client_.get(), 522 settings_, 523 impl_thread_ ? impl_thread_->message_loop_proxy() : NULL); 524 ASSERT_TRUE(layer_tree_host_); 525 526 started_ = true; 527 beginning_ = true; 528 SetupTree(); 529 WillBeginTest(); 530 BeginTest(); 531 beginning_ = false; 532 if (end_when_begin_returns_) 533 RealEndTest(); 534 535 // Allow commits to happen once BeginTest() has had a chance to post tasks 536 // so that those tasks will happen before the first commit. 537 if (layer_tree_host_) { 538 static_cast<LayerTreeHostForTesting*>(layer_tree_host_.get()) 539 ->set_test_started(true); 540 } 541 } 542 543 void LayerTreeTest::SetupTree() { 544 if (!layer_tree_host_->root_layer()) { 545 scoped_refptr<Layer> root_layer = Layer::Create(); 546 root_layer->SetBounds(gfx::Size(1, 1)); 547 root_layer->SetIsDrawable(true); 548 layer_tree_host_->SetRootLayer(root_layer); 549 } 550 551 gfx::Size root_bounds = layer_tree_host_->root_layer()->bounds(); 552 gfx::Size device_root_bounds = gfx::ToCeiledSize( 553 gfx::ScaleSize(root_bounds, layer_tree_host_->device_scale_factor())); 554 layer_tree_host_->SetViewportSize(device_root_bounds); 555 } 556 557 void LayerTreeTest::Timeout() { 558 timed_out_ = true; 559 EndTest(); 560 } 561 562 void LayerTreeTest::ScheduleComposite() { 563 if (!started_ || scheduled_) 564 return; 565 scheduled_ = true; 566 main_task_runner_->PostTask( 567 FROM_HERE, 568 base::Bind(&LayerTreeTest::DispatchComposite, main_thread_weak_ptr_)); 569 } 570 571 void LayerTreeTest::RealEndTest() { 572 if (layer_tree_host_ && proxy()->CommitPendingForTesting()) { 573 main_task_runner_->PostTask( 574 FROM_HERE, 575 base::Bind(&LayerTreeTest::RealEndTest, main_thread_weak_ptr_)); 576 return; 577 } 578 579 base::MessageLoop::current()->Quit(); 580 } 581 582 void LayerTreeTest::DispatchAddAnimation(Layer* layer_to_receive_animation, 583 double animation_duration) { 584 DCHECK(!proxy() || proxy()->IsMainThread()); 585 586 if (layer_to_receive_animation) { 587 AddOpacityTransitionToLayer( 588 layer_to_receive_animation, animation_duration, 0, 0.5, true); 589 } 590 } 591 592 void LayerTreeTest::DispatchSetNeedsCommit() { 593 DCHECK(!proxy() || proxy()->IsMainThread()); 594 595 if (layer_tree_host_) 596 layer_tree_host_->SetNeedsCommit(); 597 } 598 599 void LayerTreeTest::DispatchSetNeedsUpdateLayers() { 600 DCHECK(!proxy() || proxy()->IsMainThread()); 601 602 if (layer_tree_host_) 603 layer_tree_host_->SetNeedsUpdateLayers(); 604 } 605 606 void LayerTreeTest::DispatchSetNeedsRedraw() { 607 DCHECK(!proxy() || proxy()->IsMainThread()); 608 609 if (layer_tree_host_) 610 layer_tree_host_->SetNeedsRedraw(); 611 } 612 613 void LayerTreeTest::DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect) { 614 DCHECK(!proxy() || proxy()->IsMainThread()); 615 616 if (layer_tree_host_) 617 layer_tree_host_->SetNeedsRedrawRect(damage_rect); 618 } 619 620 void LayerTreeTest::DispatchSetVisible(bool visible) { 621 DCHECK(!proxy() || proxy()->IsMainThread()); 622 623 if (!layer_tree_host_) 624 return; 625 626 layer_tree_host_->SetVisible(visible); 627 628 // If the LTH is being made visible and a previous ScheduleComposite() was 629 // deferred because the LTH was not visible, re-schedule the composite now. 630 if (layer_tree_host_->visible() && schedule_when_set_visible_true_) 631 ScheduleComposite(); 632 } 633 634 void LayerTreeTest::DispatchSetNextCommitForcesRedraw() { 635 DCHECK(!proxy() || proxy()->IsMainThread()); 636 637 if (layer_tree_host_) 638 layer_tree_host_->SetNextCommitForcesRedraw(); 639 } 640 641 void LayerTreeTest::DispatchComposite() { 642 scheduled_ = false; 643 644 if (!layer_tree_host_) 645 return; 646 647 // If the LTH is not visible, defer the composite until the LTH is made 648 // visible. 649 if (!layer_tree_host_->visible()) { 650 schedule_when_set_visible_true_ = true; 651 return; 652 } 653 654 schedule_when_set_visible_true_ = false; 655 base::TimeTicks now = gfx::FrameTime::Now(); 656 layer_tree_host_->Composite(now); 657 } 658 659 void LayerTreeTest::RunTest(bool threaded, 660 bool delegating_renderer, 661 bool impl_side_painting) { 662 if (threaded) { 663 impl_thread_.reset(new base::Thread("Compositor")); 664 ASSERT_TRUE(impl_thread_->Start()); 665 } 666 667 main_task_runner_ = base::MessageLoopProxy::current(); 668 669 delegating_renderer_ = delegating_renderer; 670 671 // Spend less time waiting for BeginFrame because the output is 672 // mocked out. 673 settings_.refresh_rate = 200.0; 674 if (impl_side_painting) { 675 DCHECK(threaded) 676 << "Don't run single thread + impl side painting, it doesn't exist."; 677 settings_.impl_side_painting = true; 678 } 679 InitializeSettings(&settings_); 680 681 main_task_runner_->PostTask( 682 FROM_HERE, 683 base::Bind(&LayerTreeTest::DoBeginTest, base::Unretained(this))); 684 685 if (timeout_seconds_) { 686 timeout_.Reset(base::Bind(&LayerTreeTest::Timeout, base::Unretained(this))); 687 main_task_runner_->PostDelayedTask( 688 FROM_HERE, 689 timeout_.callback(), 690 base::TimeDelta::FromSeconds(timeout_seconds_)); 691 } 692 693 base::MessageLoop::current()->Run(); 694 DestroyLayerTreeHost(); 695 696 timeout_.Cancel(); 697 698 ASSERT_FALSE(layer_tree_host_.get()); 699 client_.reset(); 700 if (timed_out_) { 701 FAIL() << "Test timed out"; 702 return; 703 } 704 AfterTest(); 705 } 706 707 void LayerTreeTest::RunTestWithImplSidePainting() { 708 RunTest(true, false, true); 709 } 710 711 scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface(bool fallback) { 712 scoped_ptr<FakeOutputSurface> output_surface = 713 CreateFakeOutputSurface(fallback); 714 if (output_surface) { 715 DCHECK_EQ(delegating_renderer_, 716 output_surface->capabilities().delegated_rendering); 717 } 718 output_surface_ = output_surface.get(); 719 return output_surface.PassAs<OutputSurface>(); 720 } 721 722 scoped_ptr<FakeOutputSurface> LayerTreeTest::CreateFakeOutputSurface( 723 bool fallback) { 724 if (delegating_renderer_) 725 return FakeOutputSurface::CreateDelegating3d(); 726 else 727 return FakeOutputSurface::Create3d(); 728 } 729 730 TestWebGraphicsContext3D* LayerTreeTest::TestContext() { 731 return static_cast<TestContextProvider*>( 732 output_surface_->context_provider().get())->TestContext3d(); 733 } 734 735 int LayerTreeTest::LastCommittedSourceFrameNumber(LayerTreeHostImpl* impl) 736 const { 737 if (impl->pending_tree()) 738 return impl->pending_tree()->source_frame_number(); 739 if (impl->active_tree()) 740 return impl->active_tree()->source_frame_number(); 741 // Source frames start at 0, so this is invalid. 742 return -1; 743 } 744 745 void LayerTreeTest::DestroyLayerTreeHost() { 746 if (layer_tree_host_ && layer_tree_host_->root_layer()) 747 layer_tree_host_->root_layer()->SetLayerTreeHost(NULL); 748 layer_tree_host_.reset(); 749 } 750 751 } // namespace cc 752