• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TestHooks()33 TestHooks::TestHooks() {}
34 
~TestHooks()35 TestHooks::~TestHooks() {}
36 
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,bool result)37 bool TestHooks::PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
38                                       LayerTreeHostImpl::FrameData* frame_data,
39                                       bool result) {
40   return true;
41 }
42 
LowFrequencyAnimationInterval() const43 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:
Create(TestHooks * test_hooks,const LayerTreeSettings & settings,LayerTreeHostImplClient * host_impl_client,Proxy * proxy,RenderingStatsInstrumentation * stats_instrumentation)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:
LayerTreeHostImplForTesting(TestHooks * test_hooks,const LayerTreeSettings & settings,LayerTreeHostImplClient * host_impl_client,Proxy * proxy,RenderingStatsInstrumentation * stats_instrumentation)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 
BeginImplFrame(const BeginFrameArgs & args)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 
BeginMainFrameAborted(bool did_handle)87   virtual void BeginMainFrameAborted(bool did_handle) OVERRIDE {
88     LayerTreeHostImpl::BeginMainFrameAborted(did_handle);
89     test_hooks_->BeginMainFrameAbortedOnThread(this, did_handle);
90   }
91 
BeginCommit()92   virtual void BeginCommit() OVERRIDE {
93     LayerTreeHostImpl::BeginCommit();
94     test_hooks_->BeginCommitOnThread(this);
95   }
96 
CommitComplete()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 
PrepareToDraw(FrameData * frame,gfx::Rect damage_rect)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 
DrawLayers(FrameData * frame,base::TimeTicks frame_begin_time)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 
SwapBuffers(const LayerTreeHostImpl::FrameData & frame)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 
OnSwapBuffersComplete()126   virtual void OnSwapBuffersComplete() OVERRIDE {
127     LayerTreeHostImpl::OnSwapBuffersComplete();
128     test_hooks_->SwapBuffersCompleteOnThread(this);
129   }
130 
ReclaimResources(const CompositorFrameAck * ack)131   virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE {
132     LayerTreeHostImpl::ReclaimResources(ack);
133   }
134 
UpdateVisibleTiles()135   virtual void UpdateVisibleTiles() OVERRIDE {
136     LayerTreeHostImpl::UpdateVisibleTiles();
137     test_hooks_->UpdateVisibleTilesOnThread(this);
138   }
139 
NotifyReadyToActivate()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 
BlockNotifyReadyToActivateForTesting(bool block)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 
ActivatePendingTree()155   virtual void ActivatePendingTree() OVERRIDE {
156     test_hooks_->WillActivateTreeOnThread(this);
157     LayerTreeHostImpl::ActivatePendingTree();
158     DCHECK(!pending_tree());
159     test_hooks_->DidActivateTreeOnThread(this);
160   }
161 
InitializeRenderer(scoped_ptr<OutputSurface> output_surface)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 
SetVisible(bool visible)169   virtual void SetVisible(bool visible) OVERRIDE {
170     LayerTreeHostImpl::SetVisible(visible);
171     test_hooks_->DidSetVisibleOnImplTree(this, visible);
172   }
173 
AnimateLayers(base::TimeTicks monotonic_time,base::Time wall_clock_time)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 
UpdateAnimationState(bool start_ready_animations)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 
LowFrequencyAnimationInterval() const195   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:
Create(TestHooks * test_hooks)209   static scoped_ptr<LayerTreeHostClientForTesting> Create(
210       TestHooks* test_hooks) {
211     return make_scoped_ptr(new LayerTreeHostClientForTesting(test_hooks));
212   }
~LayerTreeHostClientForTesting()213   virtual ~LayerTreeHostClientForTesting() {}
214 
WillBeginMainFrame(int frame_id)215   virtual void WillBeginMainFrame(int frame_id) OVERRIDE {
216     test_hooks_->WillBeginMainFrame();
217   }
218 
DidBeginMainFrame()219   virtual void DidBeginMainFrame() OVERRIDE {
220     test_hooks_->DidBeginMainFrame();
221   }
222 
Animate(double monotonic_time)223   virtual void Animate(double monotonic_time) OVERRIDE {
224     test_hooks_->Animate(base::TimeTicks::FromInternalValue(
225         monotonic_time * base::Time::kMicrosecondsPerSecond));
226   }
227 
Layout()228   virtual void Layout() OVERRIDE {
229     test_hooks_->Layout();
230   }
231 
ApplyScrollAndScale(gfx::Vector2d scroll_delta,float scale)232   virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
233                                    float scale) OVERRIDE {
234     test_hooks_->ApplyScrollAndScale(scroll_delta, scale);
235   }
236 
CreateOutputSurface(bool fallback)237   virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
238       OVERRIDE {
239     return test_hooks_->CreateOutputSurface(fallback);
240   }
241 
DidInitializeOutputSurface(bool succeeded)242   virtual void DidInitializeOutputSurface(bool succeeded) OVERRIDE {
243     test_hooks_->DidInitializeOutputSurface(succeeded);
244   }
245 
DidFailToInitializeOutputSurface()246   virtual void DidFailToInitializeOutputSurface() OVERRIDE {
247     test_hooks_->DidFailToInitializeOutputSurface();
248   }
249 
WillCommit()250   virtual void WillCommit() OVERRIDE { test_hooks_->WillCommit(); }
251 
DidCommit()252   virtual void DidCommit() OVERRIDE {
253     test_hooks_->DidCommit();
254   }
255 
DidCommitAndDrawFrame()256   virtual void DidCommitAndDrawFrame() OVERRIDE {
257     test_hooks_->DidCommitAndDrawFrame();
258   }
259 
DidCompleteSwapBuffers()260   virtual void DidCompleteSwapBuffers() OVERRIDE {
261     test_hooks_->DidCompleteSwapBuffers();
262   }
263 
ScheduleComposite()264   virtual void ScheduleComposite() OVERRIDE {
265     test_hooks_->ScheduleComposite();
266   }
267 
ScheduleAnimation()268   virtual void ScheduleAnimation() OVERRIDE {
269     test_hooks_->ScheduleAnimation();
270   }
271 
DidPostSwapBuffers()272   virtual void DidPostSwapBuffers() OVERRIDE {}
DidAbortSwapBuffers()273   virtual void DidAbortSwapBuffers() OVERRIDE {}
274 
OffscreenContextProvider()275   virtual scoped_refptr<ContextProvider> OffscreenContextProvider() OVERRIDE {
276     return test_hooks_->OffscreenContextProvider();
277   }
278 
279  private:
LayerTreeHostClientForTesting(TestHooks * test_hooks)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:
Create(TestHooks * test_hooks,LayerTreeHostClientForTesting * client,const LayerTreeSettings & settings,scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)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 
CreateLayerTreeHostImpl(LayerTreeHostImplClient * host_impl_client)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 
SetNeedsCommit()315   virtual void SetNeedsCommit() OVERRIDE {
316     if (!test_started_)
317       return;
318     LayerTreeHost::SetNeedsCommit();
319   }
320 
set_test_started(bool started)321   void set_test_started(bool started) { test_started_ = started; }
322 
DidDeferCommit()323   virtual void DidDeferCommit() OVERRIDE {
324     test_hooks_->DidDeferCommit();
325   }
326 
327  private:
LayerTreeHostForTesting(TestHooks * test_hooks,LayerTreeHostClient * client,const LayerTreeSettings & settings)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 
LayerTreeTest()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 
~LayerTreeTest()359 LayerTreeTest::~LayerTreeTest() {}
360 
EndTest()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 
EndTestAfterDelay(int delay_milliseconds)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 
PostAddAnimationToMainThread(Layer * layer_to_receive_animation)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 
PostAddInstantAnimationToMainThread(Layer * layer_to_receive_animation)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 
PostAddLongAnimationToMainThread(Layer * layer_to_receive_animation)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 
PostSetNeedsCommitToMainThread()412 void LayerTreeTest::PostSetNeedsCommitToMainThread() {
413   main_task_runner_->PostTask(FROM_HERE,
414                               base::Bind(&LayerTreeTest::DispatchSetNeedsCommit,
415                                          main_thread_weak_ptr_));
416 }
417 
PostSetNeedsUpdateLayersToMainThread()418 void LayerTreeTest::PostSetNeedsUpdateLayersToMainThread() {
419   main_task_runner_->PostTask(
420       FROM_HERE,
421       base::Bind(&LayerTreeTest::DispatchSetNeedsUpdateLayers,
422                  main_thread_weak_ptr_));
423 }
424 
PostReadbackToMainThread()425 void LayerTreeTest::PostReadbackToMainThread() {
426   main_task_runner_->PostTask(
427       FROM_HERE,
428       base::Bind(&LayerTreeTest::DispatchReadback, main_thread_weak_ptr_));
429 }
430 
PostAcquireLayerTextures()431 void LayerTreeTest::PostAcquireLayerTextures() {
432   main_task_runner_->PostTask(
433       FROM_HERE,
434       base::Bind(&LayerTreeTest::DispatchAcquireLayerTextures,
435                  main_thread_weak_ptr_));
436 }
437 
PostSetNeedsRedrawToMainThread()438 void LayerTreeTest::PostSetNeedsRedrawToMainThread() {
439   main_task_runner_->PostTask(FROM_HERE,
440                               base::Bind(&LayerTreeTest::DispatchSetNeedsRedraw,
441                                          main_thread_weak_ptr_));
442 }
443 
PostSetNeedsRedrawRectToMainThread(gfx::Rect damage_rect)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 
PostSetVisibleToMainThread(bool visible)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 
PostSetNextCommitForcesRedrawToMainThread()459 void LayerTreeTest::PostSetNextCommitForcesRedrawToMainThread() {
460   main_task_runner_->PostTask(
461       FROM_HERE,
462       base::Bind(&LayerTreeTest::DispatchSetNextCommitForcesRedraw,
463                  main_thread_weak_ptr_));
464 }
465 
DoBeginTest()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 
SetupTree()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 
Timeout()509 void LayerTreeTest::Timeout() {
510   timed_out_ = true;
511   EndTest();
512 }
513 
ScheduleComposite()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 
RealEndTest()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 
DispatchAddAnimation(Layer * layer_to_receive_animation,double animation_duration)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 
DispatchSetNeedsCommit()547 void LayerTreeTest::DispatchSetNeedsCommit() {
548   DCHECK(!proxy() || proxy()->IsMainThread());
549 
550   if (layer_tree_host_)
551     layer_tree_host_->SetNeedsCommit();
552 }
553 
DispatchSetNeedsUpdateLayers()554 void LayerTreeTest::DispatchSetNeedsUpdateLayers() {
555   DCHECK(!proxy() || proxy()->IsMainThread());
556 
557   if (layer_tree_host_)
558     layer_tree_host_->SetNeedsUpdateLayers();
559 }
560 
DispatchReadback()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 
DispatchAcquireLayerTextures()570 void LayerTreeTest::DispatchAcquireLayerTextures() {
571   DCHECK(!proxy() || proxy()->IsMainThread());
572 
573   if (layer_tree_host_)
574     layer_tree_host_->AcquireLayerTextures();
575 }
576 
DispatchSetNeedsRedraw()577 void LayerTreeTest::DispatchSetNeedsRedraw() {
578   DCHECK(!proxy() || proxy()->IsMainThread());
579 
580   if (layer_tree_host_)
581     layer_tree_host_->SetNeedsRedraw();
582 }
583 
DispatchSetNeedsRedrawRect(gfx::Rect damage_rect)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 
DispatchSetVisible(bool visible)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 
DispatchSetNextCommitForcesRedraw()605 void LayerTreeTest::DispatchSetNextCommitForcesRedraw() {
606   DCHECK(!proxy() || proxy()->IsMainThread());
607 
608   if (layer_tree_host_)
609     layer_tree_host_->SetNextCommitForcesRedraw();
610 }
611 
DispatchComposite()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 
RunTest(bool threaded,bool delegating_renderer,bool impl_side_painting)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 
RunTestWithImplSidePainting()680 void LayerTreeTest::RunTestWithImplSidePainting() {
681   RunTest(true, false, true);
682 }
683 
CreateOutputSurface(bool fallback)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 
OffscreenContextProvider()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