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