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