Home | History | Annotate | Download | only in test
      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