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