Making panels stacking order aware of launcher alignment
[chromium-blink-merge.git] / cc / test / layer_tree_test.cc
blobed97752eb2a5dfd5b3b829a3171df69d0a14a74f
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.
5 #include "cc/test/layer_tree_test.h"
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_context_provider.h"
19 #include "cc/test/fake_layer_tree_host_client.h"
20 #include "cc/test/fake_output_surface.h"
21 #include "cc/test/occlusion_tracker_test_common.h"
22 #include "cc/test/tiled_layer_test_common.h"
23 #include "cc/trees/layer_tree_host_impl.h"
24 #include "cc/trees/single_thread_proxy.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "ui/gfx/size_conversions.h"
28 namespace cc {
30 TestHooks::TestHooks() {}
32 TestHooks::~TestHooks() {}
34 bool TestHooks::PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
35 LayerTreeHostImpl::FrameData* frame_data,
36 bool result) {
37 return true;
40 bool TestHooks::CanActivatePendingTree(LayerTreeHostImpl* host_impl) {
41 return true;
44 bool TestHooks::CanActivatePendingTreeIfNeeded(LayerTreeHostImpl* host_impl) {
45 return true;
48 // Adapts LayerTreeHostImpl for test. Runs real code, then invokes test hooks.
49 class LayerTreeHostImplForTesting : public LayerTreeHostImpl {
50 public:
51 static scoped_ptr<LayerTreeHostImplForTesting> Create(
52 TestHooks* test_hooks,
53 const LayerTreeSettings& settings,
54 LayerTreeHostImplClient* host_impl_client,
55 Proxy* proxy,
56 RenderingStatsInstrumentation* stats_instrumentation) {
57 return make_scoped_ptr(
58 new LayerTreeHostImplForTesting(test_hooks,
59 settings,
60 host_impl_client,
61 proxy,
62 stats_instrumentation));
65 protected:
66 LayerTreeHostImplForTesting(
67 TestHooks* test_hooks,
68 const LayerTreeSettings& settings,
69 LayerTreeHostImplClient* host_impl_client,
70 Proxy* proxy,
71 RenderingStatsInstrumentation* stats_instrumentation)
72 : LayerTreeHostImpl(settings,
73 host_impl_client,
74 proxy,
75 stats_instrumentation),
76 test_hooks_(test_hooks) {}
78 virtual void BeginCommit() OVERRIDE {
79 LayerTreeHostImpl::BeginCommit();
80 test_hooks_->BeginCommitOnThread(this);
83 virtual void CommitComplete() OVERRIDE {
84 LayerTreeHostImpl::CommitComplete();
85 test_hooks_->CommitCompleteOnThread(this);
87 if (!settings().impl_side_painting) {
88 test_hooks_->WillActivateTreeOnThread(this);
89 test_hooks_->DidActivateTreeOnThread(this);
93 virtual bool PrepareToDraw(FrameData* frame, gfx::Rect damage_rect) OVERRIDE {
94 bool result = LayerTreeHostImpl::PrepareToDraw(frame, damage_rect);
95 if (!test_hooks_->PrepareToDrawOnThread(this, frame, result))
96 result = false;
97 return result;
100 virtual void DrawLayers(FrameData* frame,
101 base::TimeTicks frame_begin_time) OVERRIDE {
102 LayerTreeHostImpl::DrawLayers(frame, frame_begin_time);
103 test_hooks_->DrawLayersOnThread(this);
106 virtual bool SwapBuffers(const LayerTreeHostImpl::FrameData& frame) OVERRIDE {
107 bool result = LayerTreeHostImpl::SwapBuffers(frame);
108 test_hooks_->SwapBuffersOnThread(this, result);
109 return result;
112 virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {
113 LayerTreeHostImpl::OnSwapBuffersComplete(ack);
114 test_hooks_->SwapBuffersCompleteOnThread(this);
117 virtual void ActivatePendingTreeIfNeeded() OVERRIDE {
118 if (!pending_tree())
119 return;
121 if (!test_hooks_->CanActivatePendingTreeIfNeeded(this))
122 return;
124 LayerTreeHostImpl::ActivatePendingTreeIfNeeded();
127 virtual void ActivatePendingTree() OVERRIDE {
128 if (!test_hooks_->CanActivatePendingTree(this))
129 return;
131 test_hooks_->WillActivateTreeOnThread(this);
132 LayerTreeHostImpl::ActivatePendingTree();
133 DCHECK(!pending_tree());
134 test_hooks_->DidActivateTreeOnThread(this);
137 virtual bool InitializeRenderer(scoped_ptr<OutputSurface> output_surface)
138 OVERRIDE {
139 bool success = LayerTreeHostImpl::InitializeRenderer(output_surface.Pass());
140 test_hooks_->InitializedRendererOnThread(this, success);
141 return success;
144 virtual void SetVisible(bool visible) OVERRIDE {
145 LayerTreeHostImpl::SetVisible(visible);
146 test_hooks_->DidSetVisibleOnImplTree(this, visible);
149 virtual void AnimateLayers(base::TimeTicks monotonic_time,
150 base::Time wall_clock_time) OVERRIDE {
151 test_hooks_->WillAnimateLayers(this, monotonic_time);
152 LayerTreeHostImpl::AnimateLayers(monotonic_time, wall_clock_time);
153 test_hooks_->AnimateLayers(this, monotonic_time);
156 virtual void UpdateAnimationState(bool start_ready_animations) OVERRIDE {
157 LayerTreeHostImpl::UpdateAnimationState(start_ready_animations);
158 bool has_unfinished_animation = false;
159 AnimationRegistrar::AnimationControllerMap::const_iterator iter =
160 active_animation_controllers().begin();
161 for (; iter != active_animation_controllers().end(); ++iter) {
162 if (iter->second->HasActiveAnimation()) {
163 has_unfinished_animation = true;
164 break;
167 test_hooks_->UpdateAnimationState(this, has_unfinished_animation);
170 virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE {
171 return base::TimeDelta::FromMilliseconds(16);
174 private:
175 TestHooks* test_hooks_;
178 // Adapts LayerTreeHost for test. Injects LayerTreeHostImplForTesting.
179 class LayerTreeHostForTesting : public cc::LayerTreeHost {
180 public:
181 static scoped_ptr<LayerTreeHostForTesting> Create(
182 TestHooks* test_hooks,
183 cc::LayerTreeHostClient* host_client,
184 const cc::LayerTreeSettings& settings,
185 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
186 scoped_ptr<LayerTreeHostForTesting> layer_tree_host(
187 new LayerTreeHostForTesting(test_hooks, host_client, settings));
188 bool success = layer_tree_host->Initialize(impl_task_runner);
189 EXPECT_TRUE(success);
190 return layer_tree_host.Pass();
193 virtual scoped_ptr<cc::LayerTreeHostImpl> CreateLayerTreeHostImpl(
194 cc::LayerTreeHostImplClient* host_impl_client) OVERRIDE {
195 return LayerTreeHostImplForTesting::Create(
196 test_hooks_,
197 settings(),
198 host_impl_client,
199 proxy(),
200 rendering_stats_instrumentation()).PassAs<cc::LayerTreeHostImpl>();
203 virtual void SetNeedsCommit() OVERRIDE {
204 if (!test_started_)
205 return;
206 LayerTreeHost::SetNeedsCommit();
209 void set_test_started(bool started) { test_started_ = started; }
211 virtual void DidDeferCommit() OVERRIDE {
212 test_hooks_->DidDeferCommit();
215 private:
216 LayerTreeHostForTesting(TestHooks* test_hooks,
217 cc::LayerTreeHostClient* client,
218 const cc::LayerTreeSettings& settings)
219 : LayerTreeHost(client, settings),
220 test_hooks_(test_hooks),
221 test_started_(false) {}
223 TestHooks* test_hooks_;
224 bool test_started_;
227 // Implementation of LayerTreeHost callback interface.
228 class LayerTreeHostClientForTesting : public LayerTreeHostClient {
229 public:
230 static scoped_ptr<LayerTreeHostClientForTesting> Create(
231 TestHooks* test_hooks) {
232 return make_scoped_ptr(new LayerTreeHostClientForTesting(test_hooks));
234 virtual ~LayerTreeHostClientForTesting() {}
236 virtual void WillBeginFrame() OVERRIDE {}
238 virtual void DidBeginFrame() OVERRIDE {}
240 virtual void Animate(double monotonic_time) OVERRIDE {
241 test_hooks_->Animate(base::TimeTicks::FromInternalValue(
242 monotonic_time * base::Time::kMicrosecondsPerSecond));
245 virtual void Layout() OVERRIDE {
246 test_hooks_->Layout();
249 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
250 float scale) OVERRIDE {
251 test_hooks_->ApplyScrollAndScale(scroll_delta, scale);
254 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
255 return test_hooks_->CreateOutputSurface();
258 virtual void DidInitializeOutputSurface(bool succeeded) OVERRIDE {
259 test_hooks_->DidInitializeOutputSurface(succeeded);
262 virtual void DidFailToInitializeOutputSurface() OVERRIDE {
263 test_hooks_->DidFailToInitializeOutputSurface();
266 virtual void WillCommit() OVERRIDE {}
268 virtual void DidCommit() OVERRIDE {
269 test_hooks_->DidCommit();
272 virtual void DidCommitAndDrawFrame() OVERRIDE {
273 test_hooks_->DidCommitAndDrawFrame();
276 virtual void DidCompleteSwapBuffers() OVERRIDE {
277 test_hooks_->DidCompleteSwapBuffers();
280 virtual void ScheduleComposite() OVERRIDE {
281 test_hooks_->ScheduleComposite();
284 virtual scoped_refptr<cc::ContextProvider>
285 OffscreenContextProviderForMainThread() OVERRIDE {
286 return test_hooks_->OffscreenContextProviderForMainThread();
289 virtual scoped_refptr<cc::ContextProvider>
290 OffscreenContextProviderForCompositorThread() OVERRIDE {
291 return test_hooks_->OffscreenContextProviderForCompositorThread();
294 private:
295 explicit LayerTreeHostClientForTesting(TestHooks* test_hooks)
296 : test_hooks_(test_hooks) {}
298 TestHooks* test_hooks_;
301 LayerTreeTest::LayerTreeTest()
302 : beginning_(false),
303 end_when_begin_returns_(false),
304 timed_out_(false),
305 scheduled_(false),
306 schedule_when_set_visible_true_(false),
307 started_(false),
308 ended_(false),
309 delegating_renderer_(false),
310 timeout_seconds_(0),
311 weak_factory_(this) {
312 main_thread_weak_ptr_ = weak_factory_.GetWeakPtr();
314 // Tests should timeout quickly unless --cc-layer-tree-test-no-timeout was
315 // specified (for running in a debugger).
316 CommandLine* command_line = CommandLine::ForCurrentProcess();
317 if (!command_line->HasSwitch(switches::kCCLayerTreeTestNoTimeout))
318 timeout_seconds_ = 5;
321 LayerTreeTest::~LayerTreeTest() {}
323 void LayerTreeTest::EndTest() {
324 // For the case where we EndTest during BeginTest(), set a flag to indicate
325 // that the test should end the second BeginTest regains control.
326 ended_ = true;
328 if (beginning_) {
329 end_when_begin_returns_ = true;
330 } else if (proxy()) {
331 // Racy timeouts and explicit EndTest calls might have cleaned up
332 // the tree host. Should check proxy first.
333 proxy()->MainThreadTaskRunner()->PostTask(
334 FROM_HERE,
335 base::Bind(&LayerTreeTest::RealEndTest, main_thread_weak_ptr_));
339 void LayerTreeTest::EndTestAfterDelay(int delay_milliseconds) {
340 proxy()->MainThreadTaskRunner()->PostTask(
341 FROM_HERE,
342 base::Bind(&LayerTreeTest::EndTest, main_thread_weak_ptr_));
345 void LayerTreeTest::PostAddAnimationToMainThread(
346 Layer* layer_to_receive_animation) {
347 proxy()->MainThreadTaskRunner()->PostTask(
348 FROM_HERE,
349 base::Bind(&LayerTreeTest::DispatchAddAnimation,
350 main_thread_weak_ptr_,
351 base::Unretained(layer_to_receive_animation)));
354 void LayerTreeTest::PostAddInstantAnimationToMainThread(
355 Layer* layer_to_receive_animation) {
356 proxy()->MainThreadTaskRunner()->PostTask(
357 FROM_HERE,
358 base::Bind(&LayerTreeTest::DispatchAddInstantAnimation,
359 main_thread_weak_ptr_,
360 base::Unretained(layer_to_receive_animation)));
363 void LayerTreeTest::PostSetNeedsCommitToMainThread() {
364 proxy()->MainThreadTaskRunner()->PostTask(
365 FROM_HERE,
366 base::Bind(&LayerTreeTest::DispatchSetNeedsCommit,
367 main_thread_weak_ptr_));
370 void LayerTreeTest::PostAcquireLayerTextures() {
371 proxy()->MainThreadTaskRunner()->PostTask(
372 FROM_HERE,
373 base::Bind(&LayerTreeTest::DispatchAcquireLayerTextures,
374 main_thread_weak_ptr_));
377 void LayerTreeTest::PostSetNeedsRedrawToMainThread() {
378 proxy()->MainThreadTaskRunner()->PostTask(
379 FROM_HERE,
380 base::Bind(&LayerTreeTest::DispatchSetNeedsRedraw,
381 main_thread_weak_ptr_));
384 void LayerTreeTest::PostSetNeedsRedrawRectToMainThread(gfx::Rect damage_rect) {
385 proxy()->MainThreadTaskRunner()->PostTask(
386 FROM_HERE,
387 base::Bind(&LayerTreeTest::DispatchSetNeedsRedrawRect,
388 main_thread_weak_ptr_, damage_rect));
391 void LayerTreeTest::PostSetVisibleToMainThread(bool visible) {
392 proxy()->MainThreadTaskRunner()->PostTask(
393 FROM_HERE,
394 base::Bind(&LayerTreeTest::DispatchSetVisible,
395 main_thread_weak_ptr_,
396 visible));
399 void LayerTreeTest::DoBeginTest() {
400 client_ = LayerTreeHostClientForTesting::Create(this);
402 DCHECK(!impl_thread_ || impl_thread_->message_loop_proxy().get());
403 layer_tree_host_ = LayerTreeHostForTesting::Create(
404 this,
405 client_.get(),
406 settings_,
407 impl_thread_ ? impl_thread_->message_loop_proxy() : NULL);
408 ASSERT_TRUE(layer_tree_host_);
410 started_ = true;
411 beginning_ = true;
412 SetupTree();
413 layer_tree_host_->SetLayerTreeHostClientReady();
414 BeginTest();
415 beginning_ = false;
416 if (end_when_begin_returns_)
417 RealEndTest();
419 // Allow commits to happen once BeginTest() has had a chance to post tasks
420 // so that those tasks will happen before the first commit.
421 if (layer_tree_host_) {
422 static_cast<LayerTreeHostForTesting*>(layer_tree_host_.get())->
423 set_test_started(true);
427 void LayerTreeTest::SetupTree() {
428 if (!layer_tree_host_->root_layer()) {
429 scoped_refptr<Layer> root_layer = Layer::Create();
430 root_layer->SetAnchorPoint(gfx::PointF());
431 root_layer->SetBounds(gfx::Size(1, 1));
432 root_layer->SetIsDrawable(true);
433 layer_tree_host_->SetRootLayer(root_layer);
436 gfx::Size root_bounds = layer_tree_host_->root_layer()->bounds();
437 gfx::Size device_root_bounds = gfx::ToCeiledSize(
438 gfx::ScaleSize(root_bounds, layer_tree_host_->device_scale_factor()));
439 layer_tree_host_->SetViewportSize(device_root_bounds);
442 void LayerTreeTest::Timeout() {
443 timed_out_ = true;
444 EndTest();
447 void LayerTreeTest::ScheduleComposite() {
448 if (!started_ || scheduled_)
449 return;
450 scheduled_ = true;
451 proxy()->MainThreadTaskRunner()->PostTask(
452 FROM_HERE,
453 base::Bind(&LayerTreeTest::DispatchComposite, main_thread_weak_ptr_));
456 void LayerTreeTest::RealEndTest() {
457 if (layer_tree_host_ && proxy()->CommitPendingForTesting()) {
458 proxy()->MainThreadTaskRunner()->PostTask(
459 FROM_HERE,
460 base::Bind(&LayerTreeTest::RealEndTest, main_thread_weak_ptr_));
461 return;
464 base::MessageLoop::current()->Quit();
467 void LayerTreeTest::DispatchAddInstantAnimation(
468 Layer* layer_to_receive_animation) {
469 DCHECK(!proxy() || proxy()->IsMainThread());
471 if (layer_to_receive_animation) {
472 AddOpacityTransitionToLayer(layer_to_receive_animation,
475 0.5,
476 false);
480 void LayerTreeTest::DispatchAddAnimation(Layer* layer_to_receive_animation) {
481 DCHECK(!proxy() || proxy()->IsMainThread());
483 if (layer_to_receive_animation) {
484 AddOpacityTransitionToLayer(layer_to_receive_animation,
485 0.000001,
487 0.5,
488 true);
492 void LayerTreeTest::DispatchSetNeedsCommit() {
493 DCHECK(!proxy() || proxy()->IsMainThread());
495 if (layer_tree_host_)
496 layer_tree_host_->SetNeedsCommit();
499 void LayerTreeTest::DispatchAcquireLayerTextures() {
500 DCHECK(!proxy() || proxy()->IsMainThread());
502 if (layer_tree_host_)
503 layer_tree_host_->AcquireLayerTextures();
506 void LayerTreeTest::DispatchSetNeedsRedraw() {
507 DCHECK(!proxy() || proxy()->IsMainThread());
509 if (layer_tree_host_)
510 layer_tree_host_->SetNeedsRedraw();
513 void LayerTreeTest::DispatchSetNeedsRedrawRect(gfx::Rect damage_rect) {
514 DCHECK(!proxy() || proxy()->IsMainThread());
516 if (layer_tree_host_)
517 layer_tree_host_->SetNeedsRedrawRect(damage_rect);
520 void LayerTreeTest::DispatchSetVisible(bool visible) {
521 DCHECK(!proxy() || proxy()->IsMainThread());
523 if (!layer_tree_host_)
524 return;
526 layer_tree_host_->SetVisible(visible);
528 // If the LTH is being made visible and a previous ScheduleComposite() was
529 // deferred because the LTH was not visible, re-schedule the composite now.
530 if (layer_tree_host_->visible() && schedule_when_set_visible_true_)
531 ScheduleComposite();
534 void LayerTreeTest::DispatchComposite() {
535 scheduled_ = false;
537 if (!layer_tree_host_)
538 return;
540 // If the LTH is not visible, defer the composite until the LTH is made
541 // visible.
542 if (!layer_tree_host_->visible()) {
543 schedule_when_set_visible_true_ = true;
544 return;
547 schedule_when_set_visible_true_ = false;
548 base::TimeTicks now = base::TimeTicks::Now();
549 layer_tree_host_->Composite(now);
552 void LayerTreeTest::RunTest(bool threaded,
553 bool delegating_renderer,
554 bool impl_side_painting) {
555 if (threaded) {
556 impl_thread_.reset(new base::Thread("Compositor"));
557 ASSERT_TRUE(impl_thread_->Start());
560 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_ =
561 base::MessageLoopProxy::current();
563 delegating_renderer_ = delegating_renderer;
565 // Spend less time waiting for BeginFrame because the output is
566 // mocked out.
567 settings_.refresh_rate = 200.0;
568 if (impl_side_painting) {
569 DCHECK(threaded) <<
570 "Don't run single thread + impl side painting, it doesn't exist.";
571 settings_.impl_side_painting = true;
573 InitializeSettings(&settings_);
575 main_task_runner_->PostTask(
576 FROM_HERE,
577 base::Bind(&LayerTreeTest::DoBeginTest, base::Unretained(this)));
579 if (timeout_seconds_) {
580 timeout_.Reset(base::Bind(&LayerTreeTest::Timeout, base::Unretained(this)));
581 main_task_runner_->PostDelayedTask(
582 FROM_HERE,
583 timeout_.callback(),
584 base::TimeDelta::FromSeconds(timeout_seconds_));
587 base::MessageLoop::current()->Run();
588 if (layer_tree_host_ && layer_tree_host_->root_layer())
589 layer_tree_host_->root_layer()->SetLayerTreeHost(NULL);
590 layer_tree_host_.reset();
592 timeout_.Cancel();
594 ASSERT_FALSE(layer_tree_host_.get());
595 client_.reset();
596 if (timed_out_) {
597 FAIL() << "Test timed out";
598 return;
600 AfterTest();
603 scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface() {
604 scoped_ptr<FakeOutputSurface> output_surface;
605 if (delegating_renderer_)
606 output_surface = FakeOutputSurface::CreateDelegating3d();
607 else
608 output_surface = FakeOutputSurface::Create3d();
609 output_surface_ = output_surface.get();
610 return output_surface.PassAs<OutputSurface>();
613 scoped_refptr<cc::ContextProvider> LayerTreeTest::
614 OffscreenContextProviderForMainThread() {
615 if (!main_thread_contexts_.get() ||
616 main_thread_contexts_->DestroyedOnMainThread()) {
617 main_thread_contexts_ = FakeContextProvider::Create();
618 if (!main_thread_contexts_->BindToCurrentThread())
619 main_thread_contexts_ = NULL;
621 return main_thread_contexts_;
624 scoped_refptr<cc::ContextProvider> LayerTreeTest::
625 OffscreenContextProviderForCompositorThread() {
626 if (!compositor_thread_contexts_.get() ||
627 compositor_thread_contexts_->DestroyedOnMainThread())
628 compositor_thread_contexts_ = FakeContextProvider::Create();
629 return compositor_thread_contexts_;
632 } // namespace cc