• 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/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 
TestHooks()35 TestHooks::TestHooks() {}
36 
~TestHooks()37 TestHooks::~TestHooks() {}
38 
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)39 DrawResult TestHooks::PrepareToDrawOnThread(
40     LayerTreeHostImpl* host_impl,
41     LayerTreeHostImpl::FrameData* frame_data,
42     DrawResult draw_result) {
43   return draw_result;
44 }
45 
LowFrequencyAnimationInterval() const46 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:
Create(TestHooks * test_hooks,LayerTreeHost * host,scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)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 
~ThreadProxyForTest()64   virtual ~ThreadProxyForTest() {}
65 
test()66   void test() {
67     test_hooks_->Layout();
68   }
69 
70  private:
71   TestHooks* test_hooks_;
72 
ScheduledActionSendBeginMainFrame()73   virtual void ScheduledActionSendBeginMainFrame() OVERRIDE {
74     test_hooks_->ScheduledActionWillSendBeginMainFrame();
75     ThreadProxy::ScheduledActionSendBeginMainFrame();
76     test_hooks_->ScheduledActionSendBeginMainFrame();
77   }
78 
ScheduledActionDrawAndSwapIfPossible()79   virtual DrawResult ScheduledActionDrawAndSwapIfPossible() OVERRIDE {
80     DrawResult result = ThreadProxy::ScheduledActionDrawAndSwapIfPossible();
81     test_hooks_->ScheduledActionDrawAndSwapIfPossible();
82     return result;
83   }
84 
ScheduledActionAnimate()85   virtual void ScheduledActionAnimate() OVERRIDE {
86     ThreadProxy::ScheduledActionAnimate();
87     test_hooks_->ScheduledActionAnimate();
88   }
89 
ScheduledActionCommit()90   virtual void ScheduledActionCommit() OVERRIDE {
91     ThreadProxy::ScheduledActionCommit();
92     test_hooks_->ScheduledActionCommit();
93   }
94 
ScheduledActionBeginOutputSurfaceCreation()95   virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {
96     ThreadProxy::ScheduledActionBeginOutputSurfaceCreation();
97     test_hooks_->ScheduledActionBeginOutputSurfaceCreation();
98   }
99 
ThreadProxyForTest(TestHooks * test_hooks,LayerTreeHost * host,scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)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:
Create(TestHooks * test_hooks,const LayerTreeSettings & settings,LayerTreeHostImplClient * host_impl_client,Proxy * proxy,SharedBitmapManager * manager,RenderingStatsInstrumentation * stats_instrumentation)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:
LayerTreeHostImplForTesting(TestHooks * test_hooks,const LayerTreeSettings & settings,LayerTreeHostImplClient * host_impl_client,Proxy * proxy,SharedBitmapManager * manager,RenderingStatsInstrumentation * stats_instrumentation)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 
WillBeginImplFrame(const BeginFrameArgs & args)146   virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE {
147     LayerTreeHostImpl::WillBeginImplFrame(args);
148     test_hooks_->WillBeginImplFrameOnThread(this, args);
149   }
150 
BeginMainFrameAborted(bool did_handle)151   virtual void BeginMainFrameAborted(bool did_handle) OVERRIDE {
152     LayerTreeHostImpl::BeginMainFrameAborted(did_handle);
153     test_hooks_->BeginMainFrameAbortedOnThread(this, did_handle);
154   }
155 
BeginCommit()156   virtual void BeginCommit() OVERRIDE {
157     LayerTreeHostImpl::BeginCommit();
158     test_hooks_->BeginCommitOnThread(this);
159   }
160 
CommitComplete()161   virtual void CommitComplete() OVERRIDE {
162     LayerTreeHostImpl::CommitComplete();
163     test_hooks_->CommitCompleteOnThread(this);
164   }
165 
PrepareToDraw(FrameData * frame)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 
DrawLayers(FrameData * frame,base::TimeTicks frame_begin_time)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 
SwapBuffers(const LayerTreeHostImpl::FrameData & frame)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 
DidSwapBuffersComplete()183   virtual void DidSwapBuffersComplete() OVERRIDE {
184     LayerTreeHostImpl::DidSwapBuffersComplete();
185     test_hooks_->SwapBuffersCompleteOnThread(this);
186   }
187 
ReclaimResources(const CompositorFrameAck * ack)188   virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE {
189     LayerTreeHostImpl::ReclaimResources(ack);
190   }
191 
UpdateVisibleTiles()192   virtual void UpdateVisibleTiles() OVERRIDE {
193     LayerTreeHostImpl::UpdateVisibleTiles();
194     test_hooks_->UpdateVisibleTilesOnThread(this);
195   }
196 
NotifyReadyToActivate()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 
BlockNotifyReadyToActivateForTesting(bool block)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 
ActivateSyncTree()212   virtual void ActivateSyncTree() OVERRIDE {
213     test_hooks_->WillActivateTreeOnThread(this);
214     LayerTreeHostImpl::ActivateSyncTree();
215     DCHECK(!pending_tree());
216     test_hooks_->DidActivateTreeOnThread(this);
217   }
218 
InitializeRenderer(scoped_ptr<OutputSurface> output_surface)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 
SetVisible(bool visible)226   virtual void SetVisible(bool visible) OVERRIDE {
227     LayerTreeHostImpl::SetVisible(visible);
228     test_hooks_->DidSetVisibleOnImplTree(this, visible);
229   }
230 
AnimateLayers(base::TimeTicks monotonic_time)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 
UpdateAnimationState(bool start_ready_animations)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 
LowFrequencyAnimationInterval() const251   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:
Create(TestHooks * test_hooks)265   static scoped_ptr<LayerTreeHostClientForTesting> Create(
266       TestHooks* test_hooks) {
267     return make_scoped_ptr(new LayerTreeHostClientForTesting(test_hooks));
268   }
~LayerTreeHostClientForTesting()269   virtual ~LayerTreeHostClientForTesting() {}
270 
WillBeginMainFrame(int frame_id)271   virtual void WillBeginMainFrame(int frame_id) OVERRIDE {
272     test_hooks_->WillBeginMainFrame();
273   }
274 
DidBeginMainFrame()275   virtual void DidBeginMainFrame() OVERRIDE {
276     test_hooks_->DidBeginMainFrame();
277   }
278 
BeginMainFrame(const BeginFrameArgs & args)279   virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
280     test_hooks_->BeginMainFrame(args);
281   }
282 
Layout()283   virtual void Layout() OVERRIDE { test_hooks_->Layout(); }
284 
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float scale,float top_controls_delta)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 
RequestNewOutputSurface(bool fallback)293   virtual void RequestNewOutputSurface(bool fallback) OVERRIDE {
294     test_hooks_->RequestNewOutputSurface(fallback);
295   }
296 
DidInitializeOutputSurface()297   virtual void DidInitializeOutputSurface() OVERRIDE {
298     test_hooks_->DidInitializeOutputSurface();
299   }
300 
DidFailToInitializeOutputSurface()301   virtual void DidFailToInitializeOutputSurface() OVERRIDE {
302     test_hooks_->DidFailToInitializeOutputSurface();
303   }
304 
WillCommit()305   virtual void WillCommit() OVERRIDE { test_hooks_->WillCommit(); }
306 
DidCommit()307   virtual void DidCommit() OVERRIDE { test_hooks_->DidCommit(); }
308 
DidCommitAndDrawFrame()309   virtual void DidCommitAndDrawFrame() OVERRIDE {
310     test_hooks_->DidCommitAndDrawFrame();
311   }
312 
DidCompleteSwapBuffers()313   virtual void DidCompleteSwapBuffers() OVERRIDE {
314     test_hooks_->DidCompleteSwapBuffers();
315   }
316 
DidPostSwapBuffers()317   virtual void DidPostSwapBuffers() OVERRIDE {}
DidAbortSwapBuffers()318   virtual void DidAbortSwapBuffers() OVERRIDE {}
319 
320  private:
LayerTreeHostClientForTesting(TestHooks * test_hooks)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:
Create(TestHooks * test_hooks,LayerTreeHostClientForTesting * client,const LayerTreeSettings & settings,scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)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 
CreateLayerTreeHostImpl(LayerTreeHostImplClient * host_impl_client)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 
SetNeedsCommit()362   virtual void SetNeedsCommit() OVERRIDE {
363     if (!test_started_)
364       return;
365     LayerTreeHost::SetNeedsCommit();
366   }
367 
set_test_started(bool started)368   void set_test_started(bool started) { test_started_ = started; }
369 
DidDeferCommit()370   virtual void DidDeferCommit() OVERRIDE { test_hooks_->DidDeferCommit(); }
371 
372  private:
LayerTreeHostForTesting(TestHooks * test_hooks,LayerTreeHostClient * client,const LayerTreeSettings & settings)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 
LayerTreeTest()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 
~LayerTreeTest()405 LayerTreeTest::~LayerTreeTest() {}
406 
EndTest()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 
EndTestAfterDelay(int delay_milliseconds)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 
PostAddAnimationToMainThread(Layer * layer_to_receive_animation)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 
PostAddInstantAnimationToMainThread(Layer * layer_to_receive_animation)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 
PostAddLongAnimationToMainThread(Layer * layer_to_receive_animation)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 
PostSetNeedsCommitToMainThread()460 void LayerTreeTest::PostSetNeedsCommitToMainThread() {
461   main_task_runner_->PostTask(FROM_HERE,
462                               base::Bind(&LayerTreeTest::DispatchSetNeedsCommit,
463                                          main_thread_weak_ptr_));
464 }
465 
PostSetNeedsUpdateLayersToMainThread()466 void LayerTreeTest::PostSetNeedsUpdateLayersToMainThread() {
467   main_task_runner_->PostTask(
468       FROM_HERE,
469       base::Bind(&LayerTreeTest::DispatchSetNeedsUpdateLayers,
470                  main_thread_weak_ptr_));
471 }
472 
PostSetNeedsRedrawToMainThread()473 void LayerTreeTest::PostSetNeedsRedrawToMainThread() {
474   main_task_runner_->PostTask(FROM_HERE,
475                               base::Bind(&LayerTreeTest::DispatchSetNeedsRedraw,
476                                          main_thread_weak_ptr_));
477 }
478 
PostSetNeedsRedrawRectToMainThread(const gfx::Rect & damage_rect)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 
PostSetVisibleToMainThread(bool visible)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 
PostSetNextCommitForcesRedrawToMainThread()495 void LayerTreeTest::PostSetNextCommitForcesRedrawToMainThread() {
496   main_task_runner_->PostTask(
497       FROM_HERE,
498       base::Bind(&LayerTreeTest::DispatchSetNextCommitForcesRedraw,
499                  main_thread_weak_ptr_));
500 }
501 
WillBeginTest()502 void LayerTreeTest::WillBeginTest() {
503   layer_tree_host_->SetLayerTreeHostClientReady();
504 }
505 
DoBeginTest()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 
SetupTree()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 
Timeout()549 void LayerTreeTest::Timeout() {
550   timed_out_ = true;
551   EndTest();
552 }
553 
RealEndTest()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 
DispatchAddAnimation(Layer * layer_to_receive_animation,double animation_duration)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 
DispatchSetNeedsCommit()576 void LayerTreeTest::DispatchSetNeedsCommit() {
577   DCHECK(!proxy() || proxy()->IsMainThread());
578 
579   if (layer_tree_host_)
580     layer_tree_host_->SetNeedsCommit();
581 }
582 
DispatchSetNeedsUpdateLayers()583 void LayerTreeTest::DispatchSetNeedsUpdateLayers() {
584   DCHECK(!proxy() || proxy()->IsMainThread());
585 
586   if (layer_tree_host_)
587     layer_tree_host_->SetNeedsUpdateLayers();
588 }
589 
DispatchSetNeedsRedraw()590 void LayerTreeTest::DispatchSetNeedsRedraw() {
591   DCHECK(!proxy() || proxy()->IsMainThread());
592 
593   if (layer_tree_host_)
594     layer_tree_host_->SetNeedsRedraw();
595 }
596 
DispatchSetNeedsRedrawRect(const gfx::Rect & damage_rect)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 
DispatchSetVisible(bool visible)604 void LayerTreeTest::DispatchSetVisible(bool visible) {
605   DCHECK(!proxy() || proxy()->IsMainThread());
606   if (layer_tree_host_)
607     layer_tree_host_->SetVisible(visible);
608 }
609 
DispatchSetNextCommitForcesRedraw()610 void LayerTreeTest::DispatchSetNextCommitForcesRedraw() {
611   DCHECK(!proxy() || proxy()->IsMainThread());
612 
613   if (layer_tree_host_)
614     layer_tree_host_->SetNextCommitForcesRedraw();
615 }
616 
RunTest(bool threaded,bool delegating_renderer,bool impl_side_painting)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 
RunTestWithImplSidePainting()665 void LayerTreeTest::RunTestWithImplSidePainting() {
666   RunTest(true, false, true);
667 }
668 
RequestNewOutputSurface(bool fallback)669 void LayerTreeTest::RequestNewOutputSurface(bool fallback) {
670   layer_tree_host_->SetOutputSurface(CreateOutputSurface(fallback));
671 }
672 
CreateOutputSurface(bool fallback)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 
CreateFakeOutputSurface(bool fallback)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 
TestContext()692 TestWebGraphicsContext3D* LayerTreeTest::TestContext() {
693   return static_cast<TestContextProvider*>(output_surface_->context_provider())
694       ->TestContext3d();
695 }
696 
LastCommittedSourceFrameNumber(LayerTreeHostImpl * impl) const697 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 
DestroyLayerTreeHost()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