1 // Copyright 2012 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/trees/layer_tree_host.h"
7 #include "base/basictypes.h"
8 #include "cc/base/thread_impl.h"
9 #include "cc/layers/content_layer.h"
10 #include "cc/layers/heads_up_display_layer.h"
11 #include "cc/layers/io_surface_layer.h"
12 #include "cc/layers/layer_impl.h"
13 #include "cc/layers/picture_layer.h"
14 #include "cc/layers/scrollbar_layer.h"
15 #include "cc/layers/texture_layer.h"
16 #include "cc/layers/video_layer.h"
17 #include "cc/layers/video_layer_impl.h"
18 #include "cc/test/fake_content_layer.h"
19 #include "cc/test/fake_content_layer_client.h"
20 #include "cc/test/fake_content_layer_impl.h"
21 #include "cc/test/fake_context_provider.h"
22 #include "cc/test/fake_delegated_renderer_layer.h"
23 #include "cc/test/fake_delegated_renderer_layer_impl.h"
24 #include "cc/test/fake_layer_tree_host_client.h"
25 #include "cc/test/fake_output_surface.h"
26 #include "cc/test/fake_scrollbar_layer.h"
27 #include "cc/test/fake_scrollbar_theme_painter.h"
28 #include "cc/test/fake_video_frame_provider.h"
29 #include "cc/test/fake_web_scrollbar.h"
30 #include "cc/test/fake_web_scrollbar_theme_geometry.h"
31 #include "cc/test/layer_tree_test.h"
32 #include "cc/test/render_pass_test_common.h"
33 #include "cc/test/test_web_graphics_context_3d.h"
34 #include "cc/trees/layer_tree_host_impl.h"
35 #include "cc/trees/layer_tree_impl.h"
36 #include "cc/trees/single_thread_proxy.h"
37 #include "gpu/GLES2/gl2extchromium.h"
38 #include "media/base/media.h"
39 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h"
41 using media::VideoFrame
;
42 using WebKit::WebGraphicsContext3D
;
47 // These tests deal with losing the 3d graphics context.
48 class LayerTreeHostContextTest
: public LayerTreeTest
{
50 LayerTreeHostContextTest()
53 times_to_fail_create_(0),
54 times_to_fail_initialize_(0),
55 times_to_lose_on_create_(0),
56 times_to_lose_during_commit_(0),
57 times_to_lose_during_draw_(0),
58 times_to_fail_recreate_(0),
59 times_to_fail_reinitialize_(0),
60 times_to_lose_on_recreate_(0),
61 times_to_fail_create_offscreen_(0),
62 times_to_fail_recreate_offscreen_(0),
63 times_to_expect_create_failed_(0),
64 times_create_failed_(0),
65 times_offscreen_created_(0),
66 committed_at_least_once_(false),
67 context_should_support_io_surface_(false) {
68 media::InitializeMediaLibraryForTesting();
72 context3d_
->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
73 GL_INNOCENT_CONTEXT_RESET_ARB
);
77 virtual scoped_ptr
<TestWebGraphicsContext3D
> CreateContext3d() {
78 return TestWebGraphicsContext3D::Create();
81 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
82 if (times_to_fail_create_
) {
83 --times_to_fail_create_
;
85 return scoped_ptr
<OutputSurface
>();
88 scoped_ptr
<TestWebGraphicsContext3D
> context3d
= CreateContext3d();
89 context3d_
= context3d
.get();
91 if (context_should_support_io_surface_
) {
92 context3d_
->set_have_extension_io_surface(true);
93 context3d_
->set_have_extension_egl_image(true);
96 if (times_to_fail_initialize_
) {
97 --times_to_fail_initialize_
;
98 // Make the context get lost during reinitialization.
99 // The number of times MakeCurrent succeeds is not important, and
100 // can be changed if needed to make this pass with future changes.
101 context3d_
->set_times_make_current_succeeds(2);
102 ExpectCreateToFail();
103 } else if (times_to_lose_on_create_
) {
104 --times_to_lose_on_create_
;
106 ExpectCreateToFail();
109 return FakeOutputSurface::Create3d(
110 context3d
.PassAs
<WebGraphicsContext3D
>()).PassAs
<OutputSurface
>();
113 scoped_ptr
<TestWebGraphicsContext3D
> CreateOffscreenContext3d() {
115 return scoped_ptr
<TestWebGraphicsContext3D
>();
117 ++times_offscreen_created_
;
119 if (times_to_fail_create_offscreen_
) {
120 --times_to_fail_create_offscreen_
;
121 ExpectCreateToFail();
122 return scoped_ptr
<TestWebGraphicsContext3D
>();
125 scoped_ptr
<TestWebGraphicsContext3D
> offscreen_context3d
=
126 TestWebGraphicsContext3D::Create().Pass();
127 DCHECK(offscreen_context3d
);
128 context3d_
->add_share_group_context(offscreen_context3d
.get());
130 return offscreen_context3d
.Pass();
133 virtual scoped_refptr
<cc::ContextProvider
>
134 OffscreenContextProviderForMainThread() OVERRIDE
{
135 DCHECK(!ImplThread());
137 if (!offscreen_contexts_main_thread_
||
138 offscreen_contexts_main_thread_
->DestroyedOnMainThread()) {
139 offscreen_contexts_main_thread_
= FakeContextProvider::Create(
140 base::Bind(&LayerTreeHostContextTest::CreateOffscreenContext3d
,
141 base::Unretained(this)));
142 if (offscreen_contexts_main_thread_
&&
143 !offscreen_contexts_main_thread_
->BindToCurrentThread())
144 offscreen_contexts_main_thread_
= NULL
;
146 return offscreen_contexts_main_thread_
;
149 virtual scoped_refptr
<cc::ContextProvider
>
150 OffscreenContextProviderForCompositorThread() OVERRIDE
{
151 DCHECK(ImplThread());
153 if (!offscreen_contexts_compositor_thread_
||
154 offscreen_contexts_compositor_thread_
->DestroyedOnMainThread()) {
155 offscreen_contexts_compositor_thread_
= FakeContextProvider::Create(
156 base::Bind(&LayerTreeHostContextTest::CreateOffscreenContext3d
,
157 base::Unretained(this)));
159 return offscreen_contexts_compositor_thread_
;
162 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
163 LayerTreeHostImpl::FrameData
* frame
,
164 bool result
) OVERRIDE
{
166 if (!times_to_lose_during_draw_
)
169 --times_to_lose_during_draw_
;
170 context3d_
->set_times_make_current_succeeds(0);
172 times_to_fail_create_
= times_to_fail_recreate_
;
173 times_to_fail_recreate_
= 0;
174 times_to_fail_initialize_
= times_to_fail_reinitialize_
;
175 times_to_fail_reinitialize_
= 0;
176 times_to_lose_on_create_
= times_to_lose_on_recreate_
;
177 times_to_lose_on_recreate_
= 0;
178 times_to_fail_create_offscreen_
= times_to_fail_recreate_offscreen_
;
179 times_to_fail_recreate_offscreen_
= 0;
184 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
185 committed_at_least_once_
= true;
187 if (!times_to_lose_during_commit_
)
189 --times_to_lose_during_commit_
;
192 times_to_fail_create_
= times_to_fail_recreate_
;
193 times_to_fail_recreate_
= 0;
194 times_to_fail_initialize_
= times_to_fail_reinitialize_
;
195 times_to_fail_reinitialize_
= 0;
196 times_to_lose_on_create_
= times_to_lose_on_recreate_
;
197 times_to_lose_on_recreate_
= 0;
198 times_to_fail_create_offscreen_
= times_to_fail_recreate_offscreen_
;
199 times_to_fail_recreate_offscreen_
= 0;
202 virtual void DidFailToInitializeOutputSurface() OVERRIDE
{
203 ++times_create_failed_
;
206 virtual void TearDown() OVERRIDE
{
207 LayerTreeTest::TearDown();
208 EXPECT_EQ(times_to_expect_create_failed_
, times_create_failed_
);
211 void ExpectCreateToFail() {
212 ++times_to_expect_create_failed_
;
216 TestWebGraphicsContext3D
* context3d_
;
217 int times_to_fail_create_
;
218 int times_to_fail_initialize_
;
219 int times_to_lose_on_create_
;
220 int times_to_lose_during_commit_
;
221 int times_to_lose_during_draw_
;
222 int times_to_fail_recreate_
;
223 int times_to_fail_reinitialize_
;
224 int times_to_lose_on_recreate_
;
225 int times_to_fail_create_offscreen_
;
226 int times_to_fail_recreate_offscreen_
;
227 int times_to_expect_create_failed_
;
228 int times_create_failed_
;
229 int times_offscreen_created_
;
230 bool committed_at_least_once_
;
231 bool context_should_support_io_surface_
;
233 scoped_refptr
<FakeContextProvider
> offscreen_contexts_main_thread_
;
234 scoped_refptr
<FakeContextProvider
> offscreen_contexts_compositor_thread_
;
237 class LayerTreeHostContextTestLostContextSucceeds
238 : public LayerTreeHostContextTest
{
240 LayerTreeHostContextTestLostContextSucceeds()
241 : LayerTreeHostContextTest(),
244 recovered_context_(true),
245 first_initialized_(false) {}
247 virtual void BeginTest() OVERRIDE
{
248 PostSetNeedsCommitToMainThread();
251 virtual void DidRecreateOutputSurface(bool succeeded
) OVERRIDE
{
252 EXPECT_TRUE(succeeded
);
254 if (first_initialized_
)
257 first_initialized_
= true;
259 recovered_context_
= true;
262 virtual void AfterTest() OVERRIDE
{
263 EXPECT_EQ(10u, test_case_
);
264 EXPECT_EQ(8 + 10 + 10, num_losses_
);
267 virtual void DidCommitAndDrawFrame() OVERRIDE
{
268 // If the last frame had a context loss, then we'll commit again to
270 if (!recovered_context_
)
272 if (times_to_lose_during_commit_
)
274 if (times_to_lose_during_draw_
)
277 recovered_context_
= false;
279 InvalidateAndSetNeedsCommit();
284 virtual void InvalidateAndSetNeedsCommit() {
285 // Cause damage so we try to draw.
286 layer_tree_host()->root_layer()->SetNeedsDisplay();
289 bool NextTestCase() {
290 static const TestCase kTests
[] = {
291 // Losing the context and failing to recreate it (or losing it again
292 // immediately) a small number of times should succeed.
293 { 1, // times_to_lose_during_commit
294 0, // times_to_lose_during_draw
295 3, // times_to_fail_reinitialize
296 0, // times_to_fail_recreate
297 0, // times_to_lose_on_recreate
298 0, // times_to_fail_recreate_offscreen
300 { 0, // times_to_lose_during_commit
301 1, // times_to_lose_during_draw
302 3, // times_to_fail_reinitialize
303 0, // times_to_fail_recreate
304 0, // times_to_lose_on_recreate
305 0, // times_to_fail_recreate_offscreen
307 { 1, // times_to_lose_during_commit
308 0, // times_to_lose_during_draw
309 0, // times_to_fail_reinitialize
310 3, // times_to_fail_recreate
311 0, // times_to_lose_on_recreate
312 0, // times_to_fail_recreate_offscreen
314 { 0, // times_to_lose_during_commit
315 1, // times_to_lose_during_draw
316 0, // times_to_fail_reinitialize
317 3, // times_to_fail_recreate
318 0, // times_to_lose_on_recreate
319 0, // times_to_fail_recreate_offscreen
321 { 1, // times_to_lose_during_commit
322 0, // times_to_lose_during_draw
323 0, // times_to_fail_reinitialize
324 0, // times_to_fail_recreate
325 3, // times_to_lose_on_recreate
326 0, // times_to_fail_recreate_offscreen
328 { 0, // times_to_lose_during_commit
329 1, // times_to_lose_during_draw
330 0, // times_to_fail_reinitialize
331 0, // times_to_fail_recreate
332 3, // times_to_lose_on_recreate
333 0, // times_to_fail_recreate_offscreen
335 { 1, // times_to_lose_during_commit
336 0, // times_to_lose_during_draw
337 0, // times_to_fail_reinitialize
338 0, // times_to_fail_recreate
339 0, // times_to_lose_on_recreate
340 3, // times_to_fail_recreate_offscreen
342 { 0, // times_to_lose_during_commit
343 1, // times_to_lose_during_draw
344 0, // times_to_fail_reinitialize
345 0, // times_to_fail_recreate
346 0, // times_to_lose_on_recreate
347 3, // times_to_fail_recreate_offscreen
349 // Losing the context and recreating it any number of times should
351 { 10, // times_to_lose_during_commit
352 0, // times_to_lose_during_draw
353 0, // times_to_fail_reinitialize
354 0, // times_to_fail_recreate
355 0, // times_to_lose_on_recreate
356 0, // times_to_fail_recreate_offscreen
358 { 0, // times_to_lose_during_commit
359 10, // times_to_lose_during_draw
360 0, // times_to_fail_reinitialize
361 0, // times_to_fail_recreate
362 0, // times_to_lose_on_recreate
363 0, // times_to_fail_recreate_offscreen
367 if (test_case_
>= arraysize(kTests
))
370 times_to_lose_during_commit_
=
371 kTests
[test_case_
].times_to_lose_during_commit
;
372 times_to_lose_during_draw_
=
373 kTests
[test_case_
].times_to_lose_during_draw
;
374 times_to_fail_reinitialize_
= kTests
[test_case_
].times_to_fail_reinitialize
;
375 times_to_fail_recreate_
= kTests
[test_case_
].times_to_fail_recreate
;
376 times_to_lose_on_recreate_
= kTests
[test_case_
].times_to_lose_on_recreate
;
377 times_to_fail_recreate_offscreen_
=
378 kTests
[test_case_
].times_to_fail_recreate_offscreen
;
384 int times_to_lose_during_commit
;
385 int times_to_lose_during_draw
;
386 int times_to_fail_reinitialize
;
387 int times_to_fail_recreate
;
388 int times_to_lose_on_recreate
;
389 int times_to_fail_recreate_offscreen
;
395 bool recovered_context_
;
396 bool first_initialized_
;
399 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds
);
401 class LayerTreeHostContextTestLostContextSucceedsWithContent
402 : public LayerTreeHostContextTestLostContextSucceeds
{
404 LayerTreeHostContextTestLostContextSucceedsWithContent()
405 : LayerTreeHostContextTestLostContextSucceeds() {}
407 virtual void SetupTree() OVERRIDE
{
408 root_
= Layer::Create();
409 root_
->SetBounds(gfx::Size(10, 10));
410 root_
->SetAnchorPoint(gfx::PointF());
411 root_
->SetIsDrawable(true);
413 content_
= FakeContentLayer::Create(&client_
);
414 content_
->SetBounds(gfx::Size(10, 10));
415 content_
->SetAnchorPoint(gfx::PointF());
416 content_
->SetIsDrawable(true);
418 content_
->SetForceRenderSurface(true);
419 // Filters require us to create an offscreen context.
420 WebKit::WebFilterOperations filters
;
421 filters
.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5f
));
422 content_
->SetFilters(filters
);
423 content_
->SetBackgroundFilters(filters
);
426 root_
->AddChild(content_
);
428 layer_tree_host()->SetRootLayer(root_
);
429 LayerTreeHostContextTest::SetupTree();
432 virtual void InvalidateAndSetNeedsCommit() OVERRIDE
{
433 // Invalidate the render surface so we don't try to use a cached copy of the
434 // surface. We want to make sure to test the drawing paths for drawing to
436 content_
->SetNeedsDisplay();
437 LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit();
440 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
441 FakeContentLayerImpl
* content_impl
= static_cast<FakeContentLayerImpl
*>(
442 host_impl
->active_tree()->root_layer()->children()[0]);
443 // Even though the context was lost, we should have a resource. The
444 // TestWebGraphicsContext3D ensures that this resource is created with
445 // the active context.
446 EXPECT_TRUE(content_impl
->HaveResourceForTileAt(0, 0));
448 cc::ContextProvider
* contexts
=
449 host_impl
->resource_provider()->offscreen_context_provider();
451 EXPECT_TRUE(contexts
->Context3d());
452 // TODO(danakj): Make a fake GrContext.
453 // EXPECT_TRUE(contexts->GrContext());
455 EXPECT_FALSE(contexts
);
459 virtual void AfterTest() OVERRIDE
{
460 LayerTreeHostContextTestLostContextSucceeds::AfterTest();
462 // 1 create to start with +
463 // 6 from test cases that fail on initializing the renderer (after the
464 // offscreen context is created) +
465 // 6 from test cases that lose the offscreen context directly +
466 // All the test cases that recreate both contexts only once
467 // per time it is lost.
468 EXPECT_EQ(6 + 6 + 1 + num_losses_
, times_offscreen_created_
);
470 EXPECT_EQ(0, times_offscreen_created_
);
476 FakeContentLayerClient client_
;
477 scoped_refptr
<Layer
> root_
;
478 scoped_refptr
<ContentLayer
> content_
;
481 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
482 NoSurface_SingleThread
) {
483 use_surface_
= false;
487 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
488 NoSurface_MultiThread
) {
489 use_surface_
= false;
493 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
494 WithSurface_SingleThread
) {
499 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
500 WithSurface_MultiThread
) {
505 class LayerTreeHostContextTestOffscreenContextFails
506 : public LayerTreeHostContextTest
{
508 virtual void SetupTree() OVERRIDE
{
509 root_
= Layer::Create();
510 root_
->SetBounds(gfx::Size(10, 10));
511 root_
->SetAnchorPoint(gfx::PointF());
512 root_
->SetIsDrawable(true);
514 content_
= FakeContentLayer::Create(&client_
);
515 content_
->SetBounds(gfx::Size(10, 10));
516 content_
->SetAnchorPoint(gfx::PointF());
517 content_
->SetIsDrawable(true);
518 content_
->SetForceRenderSurface(true);
519 // Filters require us to create an offscreen context.
520 WebKit::WebFilterOperations filters
;
521 filters
.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5f
));
522 content_
->SetFilters(filters
);
523 content_
->SetBackgroundFilters(filters
);
525 root_
->AddChild(content_
);
527 layer_tree_host()->SetRootLayer(root_
);
528 LayerTreeHostContextTest::SetupTree();
531 virtual void BeginTest() OVERRIDE
{
532 times_to_fail_create_offscreen_
= 1;
533 PostSetNeedsCommitToMainThread();
536 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
537 cc::ContextProvider
* contexts
=
538 host_impl
->resource_provider()->offscreen_context_provider();
539 EXPECT_FALSE(contexts
);
541 // This did not lead to create failure.
542 times_to_expect_create_failed_
= 0;
546 virtual void AfterTest() OVERRIDE
{}
549 FakeContentLayerClient client_
;
550 scoped_refptr
<Layer
> root_
;
551 scoped_refptr
<ContentLayer
> content_
;
554 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestOffscreenContextFails
);
556 class LayerTreeHostContextTestLostContextFails
557 : public LayerTreeHostContextTest
{
559 LayerTreeHostContextTestLostContextFails()
560 : LayerTreeHostContextTest(),
562 first_initialized_(false) {
563 times_to_lose_during_commit_
= 1;
566 virtual void BeginTest() OVERRIDE
{
567 PostSetNeedsCommitToMainThread();
570 virtual void DidRecreateOutputSurface(bool succeeded
) OVERRIDE
{
571 if (first_initialized_
) {
572 EXPECT_FALSE(succeeded
);
575 first_initialized_
= true;
579 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
580 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
583 if (num_commits_
== 1) {
584 // When the context is ok, we should have these things.
585 EXPECT_TRUE(host_impl
->output_surface());
586 EXPECT_TRUE(host_impl
->renderer());
587 EXPECT_TRUE(host_impl
->resource_provider());
591 // When context recreation fails we shouldn't be left with any of them.
592 EXPECT_FALSE(host_impl
->output_surface());
593 EXPECT_FALSE(host_impl
->renderer());
594 EXPECT_FALSE(host_impl
->resource_provider());
597 virtual void AfterTest() OVERRIDE
{}
601 bool first_initialized_
;
604 TEST_F(LayerTreeHostContextTestLostContextFails
,
605 FailReinitialize100_SingleThread
) {
606 times_to_fail_reinitialize_
= 100;
607 times_to_fail_recreate_
= 0;
608 times_to_lose_on_recreate_
= 0;
612 TEST_F(LayerTreeHostContextTestLostContextFails
,
613 FailReinitialize100_MultiThread
) {
614 times_to_fail_reinitialize_
= 100;
615 times_to_fail_recreate_
= 0;
616 times_to_lose_on_recreate_
= 0;
620 TEST_F(LayerTreeHostContextTestLostContextFails
,
621 FailRecreate100_SingleThread
) {
622 times_to_fail_reinitialize_
= 0;
623 times_to_fail_recreate_
= 100;
624 times_to_lose_on_recreate_
= 0;
628 TEST_F(LayerTreeHostContextTestLostContextFails
,
629 FailRecreate100_MultiThread
) {
630 times_to_fail_reinitialize_
= 0;
631 times_to_fail_recreate_
= 100;
632 times_to_lose_on_recreate_
= 0;
636 TEST_F(LayerTreeHostContextTestLostContextFails
,
637 LoseOnRecreate100_SingleThread
) {
638 times_to_fail_reinitialize_
= 0;
639 times_to_fail_recreate_
= 0;
640 times_to_lose_on_recreate_
= 100;
644 TEST_F(LayerTreeHostContextTestLostContextFails
,
645 LoseOnRecreate100_MultiThread
) {
646 times_to_fail_reinitialize_
= 0;
647 times_to_fail_recreate_
= 0;
648 times_to_lose_on_recreate_
= 100;
652 class LayerTreeHostContextTestFinishAllRenderingAfterLoss
653 : public LayerTreeHostContextTest
{
655 virtual void BeginTest() OVERRIDE
{
656 // Lose the context until the compositor gives up on it.
657 first_initialized_
= false;
658 times_to_lose_during_commit_
= 1;
659 times_to_fail_reinitialize_
= 10;
660 PostSetNeedsCommitToMainThread();
663 virtual void DidRecreateOutputSurface(bool succeeded
) OVERRIDE
{
664 if (first_initialized_
) {
665 EXPECT_FALSE(succeeded
);
666 layer_tree_host()->FinishAllRendering();
669 first_initialized_
= true;
673 virtual void AfterTest() OVERRIDE
{}
676 bool first_initialized_
;
679 SINGLE_AND_MULTI_THREAD_TEST_F(
680 LayerTreeHostContextTestFinishAllRenderingAfterLoss
);
682 class LayerTreeHostContextTestLostContextAndEvictTextures
683 : public LayerTreeHostContextTest
{
685 LayerTreeHostContextTestLostContextAndEvictTextures()
686 : LayerTreeHostContextTest(),
687 layer_(FakeContentLayer::Create(&client_
)),
691 virtual void SetupTree() OVERRIDE
{
692 layer_
->SetBounds(gfx::Size(10, 20));
693 layer_tree_host()->SetRootLayer(layer_
);
694 LayerTreeHostContextTest::SetupTree();
697 virtual void BeginTest() OVERRIDE
{
698 PostSetNeedsCommitToMainThread();
701 void PostEvictTextures() {
703 ImplThread()->PostTask(
705 &LayerTreeHostContextTestLostContextAndEvictTextures::
706 EvictTexturesOnImplThread
,
707 base::Unretained(this)));
709 DebugScopedSetImplThread
impl(proxy());
710 EvictTexturesOnImplThread();
714 void EvictTexturesOnImplThread() {
715 impl_host_
->EnforceManagedMemoryPolicy(ManagedMemoryPolicy(0));
716 if (lose_after_evict_
)
720 virtual void DidCommitAndDrawFrame() OVERRIDE
{
721 if (num_commits_
> 1)
723 EXPECT_TRUE(layer_
->HaveBackingAt(0, 0));
727 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
728 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
729 if (num_commits_
> 1)
732 if (!lose_after_evict_
)
737 virtual void DidRecreateOutputSurface(bool succeeded
) OVERRIDE
{
738 EXPECT_TRUE(succeeded
);
742 virtual void AfterTest() OVERRIDE
{}
745 bool lose_after_evict_
;
746 FakeContentLayerClient client_
;
747 scoped_refptr
<FakeContentLayer
> layer_
;
748 LayerTreeHostImpl
* impl_host_
;
752 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
753 LoseAfterEvict_SingleThread
) {
754 lose_after_evict_
= true;
758 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
759 LoseAfterEvict_MultiThread
) {
760 lose_after_evict_
= true;
764 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
765 LoseBeforeEvict_SingleThread
) {
766 lose_after_evict_
= false;
770 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
771 LoseBeforeEvict_MultiThread
) {
772 lose_after_evict_
= false;
776 class LayerTreeHostContextTestLostContextWhileUpdatingResources
777 : public LayerTreeHostContextTest
{
779 LayerTreeHostContextTestLostContextWhileUpdatingResources()
780 : parent_(FakeContentLayer::Create(&client_
)),
782 times_to_lose_on_end_query_(3) {}
784 virtual scoped_ptr
<TestWebGraphicsContext3D
> CreateContext3d() OVERRIDE
{
785 scoped_ptr
<TestWebGraphicsContext3D
> context
=
786 LayerTreeHostContextTest::CreateContext3d();
787 if (times_to_lose_on_end_query_
) {
788 --times_to_lose_on_end_query_
;
789 context
->set_times_end_query_succeeds(5);
791 return context
.Pass();
794 virtual void SetupTree() OVERRIDE
{
795 parent_
->SetBounds(gfx::Size(num_children_
, 1));
797 for (int i
= 0; i
< num_children_
; i
++) {
798 scoped_refptr
<FakeContentLayer
> child
=
799 FakeContentLayer::Create(&client_
);
800 child
->SetPosition(gfx::PointF(i
, 0.f
));
801 child
->SetBounds(gfx::Size(1, 1));
802 parent_
->AddChild(child
);
805 layer_tree_host()->SetRootLayer(parent_
);
806 LayerTreeHostContextTest::SetupTree();
809 virtual void BeginTest() OVERRIDE
{
810 PostSetNeedsCommitToMainThread();
813 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
814 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
818 virtual void DidRecreateOutputSurface(bool succeeded
) OVERRIDE
{
819 EXPECT_TRUE(succeeded
);
822 virtual void AfterTest() OVERRIDE
{
823 EXPECT_EQ(0, times_to_lose_on_end_query_
);
827 FakeContentLayerClient client_
;
828 scoped_refptr
<FakeContentLayer
> parent_
;
830 int times_to_lose_on_end_query_
;
833 SINGLE_AND_MULTI_THREAD_TEST_F(
834 LayerTreeHostContextTestLostContextWhileUpdatingResources
);
836 class LayerTreeHostContextTestLayersNotified
837 : public LayerTreeHostContextTest
{
839 LayerTreeHostContextTestLayersNotified()
840 : LayerTreeHostContextTest(),
843 virtual void SetupTree() OVERRIDE
{
844 root_
= FakeContentLayer::Create(&client_
);
845 child_
= FakeContentLayer::Create(&client_
);
846 grandchild_
= FakeContentLayer::Create(&client_
);
848 root_
->AddChild(child_
);
849 child_
->AddChild(grandchild_
);
851 layer_tree_host()->SetRootLayer(root_
);
852 LayerTreeHostContextTest::SetupTree();
855 virtual void BeginTest() OVERRIDE
{
856 PostSetNeedsCommitToMainThread();
859 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
860 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
862 FakeContentLayerImpl
* root
= static_cast<FakeContentLayerImpl
*>(
863 host_impl
->active_tree()->root_layer());
864 FakeContentLayerImpl
* child
= static_cast<FakeContentLayerImpl
*>(
865 root
->children()[0]);
866 FakeContentLayerImpl
* grandchild
= static_cast<FakeContentLayerImpl
*>(
867 child
->children()[0]);
870 switch (num_commits_
) {
872 EXPECT_EQ(0u, root
->lost_output_surface_count());
873 EXPECT_EQ(0u, child
->lost_output_surface_count());
874 EXPECT_EQ(0u, grandchild
->lost_output_surface_count());
875 // Lose the context and struggle to recreate it.
877 times_to_fail_create_
= 1;
880 EXPECT_EQ(1u, root
->lost_output_surface_count());
881 EXPECT_EQ(1u, child
->lost_output_surface_count());
882 EXPECT_EQ(1u, grandchild
->lost_output_surface_count());
883 // Lose the context and again during recreate.
885 times_to_lose_on_create_
= 1;
888 EXPECT_EQ(3u, root
->lost_output_surface_count());
889 EXPECT_EQ(3u, child
->lost_output_surface_count());
890 EXPECT_EQ(3u, grandchild
->lost_output_surface_count());
891 // Lose the context and again during reinitialization.
893 times_to_fail_initialize_
= 1;
896 EXPECT_EQ(5u, root
->lost_output_surface_count());
897 EXPECT_EQ(5u, child
->lost_output_surface_count());
898 EXPECT_EQ(5u, grandchild
->lost_output_surface_count());
906 virtual void AfterTest() OVERRIDE
{}
911 FakeContentLayerClient client_
;
912 scoped_refptr
<FakeContentLayer
> root_
;
913 scoped_refptr
<FakeContentLayer
> child_
;
914 scoped_refptr
<FakeContentLayer
> grandchild_
;
917 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLayersNotified
);
919 class LayerTreeHostContextTestDontUseLostResources
920 : public LayerTreeHostContextTest
{
922 virtual void SetupTree() OVERRIDE
{
923 scoped_refptr
<Layer
> root_
= Layer::Create();
924 root_
->SetBounds(gfx::Size(10, 10));
925 root_
->SetAnchorPoint(gfx::PointF());
926 root_
->SetIsDrawable(true);
928 scoped_refptr
<FakeDelegatedRendererLayer
> delegated_
=
929 FakeDelegatedRendererLayer::Create();
930 delegated_
->SetBounds(gfx::Size(10, 10));
931 delegated_
->SetAnchorPoint(gfx::PointF());
932 delegated_
->SetIsDrawable(true);
933 root_
->AddChild(delegated_
);
935 scoped_refptr
<ContentLayer
> content_
= ContentLayer::Create(&client_
);
936 content_
->SetBounds(gfx::Size(10, 10));
937 content_
->SetAnchorPoint(gfx::PointF());
938 content_
->SetIsDrawable(true);
939 root_
->AddChild(content_
);
941 scoped_refptr
<TextureLayer
> texture_
= TextureLayer::Create(NULL
);
942 texture_
->SetBounds(gfx::Size(10, 10));
943 texture_
->SetAnchorPoint(gfx::PointF());
944 texture_
->SetTextureId(TestWebGraphicsContext3D::kExternalTextureId
);
945 texture_
->SetIsDrawable(true);
946 root_
->AddChild(texture_
);
948 scoped_refptr
<ContentLayer
> mask_
= ContentLayer::Create(&client_
);
949 mask_
->SetBounds(gfx::Size(10, 10));
950 mask_
->SetAnchorPoint(gfx::PointF());
952 scoped_refptr
<ContentLayer
> content_with_mask_
=
953 ContentLayer::Create(&client_
);
954 content_with_mask_
->SetBounds(gfx::Size(10, 10));
955 content_with_mask_
->SetAnchorPoint(gfx::PointF());
956 content_with_mask_
->SetIsDrawable(true);
957 content_with_mask_
->SetMaskLayer(mask_
.get());
958 root_
->AddChild(content_with_mask_
);
960 scoped_refptr
<VideoLayer
> video_color_
= VideoLayer::Create(
961 &color_frame_provider_
);
962 video_color_
->SetBounds(gfx::Size(10, 10));
963 video_color_
->SetAnchorPoint(gfx::PointF());
964 video_color_
->SetIsDrawable(true);
965 root_
->AddChild(video_color_
);
967 scoped_refptr
<VideoLayer
> video_hw_
= VideoLayer::Create(
968 &hw_frame_provider_
);
969 video_hw_
->SetBounds(gfx::Size(10, 10));
970 video_hw_
->SetAnchorPoint(gfx::PointF());
971 video_hw_
->SetIsDrawable(true);
972 root_
->AddChild(video_hw_
);
974 scoped_refptr
<VideoLayer
> video_scaled_hw_
= VideoLayer::Create(
975 &scaled_hw_frame_provider_
);
976 video_scaled_hw_
->SetBounds(gfx::Size(10, 10));
977 video_scaled_hw_
->SetAnchorPoint(gfx::PointF());
978 video_scaled_hw_
->SetIsDrawable(true);
979 root_
->AddChild(video_scaled_hw_
);
981 scoped_refptr
<IOSurfaceLayer
> io_surface_
= IOSurfaceLayer::Create();
982 io_surface_
->SetBounds(gfx::Size(10, 10));
983 io_surface_
->SetAnchorPoint(gfx::PointF());
984 io_surface_
->SetIsDrawable(true);
985 io_surface_
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
986 root_
->AddChild(io_surface_
);
989 LayerTreeDebugState debug_state
;
990 debug_state
.show_property_changed_rects
= true;
991 layer_tree_host()->SetDebugState(debug_state
);
993 bool paint_scrollbar
= true;
994 bool has_thumb
= true;
995 scoped_refptr
<ScrollbarLayer
> scrollbar_
= ScrollbarLayer::Create(
996 FakeWebScrollbar::Create().PassAs
<WebKit::WebScrollbar
>(),
997 FakeScrollbarThemePainter::Create(paint_scrollbar
)
998 .PassAs
<ScrollbarThemePainter
>(),
999 FakeWebScrollbarThemeGeometry::Create(has_thumb
)
1000 .PassAs
<WebKit::WebScrollbarThemeGeometry
>(),
1002 scrollbar_
->SetBounds(gfx::Size(10, 10));
1003 scrollbar_
->SetAnchorPoint(gfx::PointF());
1004 scrollbar_
->SetIsDrawable(true);
1005 root_
->AddChild(scrollbar_
);
1007 layer_tree_host()->SetRootLayer(root_
);
1008 LayerTreeHostContextTest::SetupTree();
1011 virtual void BeginTest() OVERRIDE
{
1012 context_should_support_io_surface_
= true;
1013 PostSetNeedsCommitToMainThread();
1016 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1017 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
1019 ResourceProvider
* resource_provider
= host_impl
->resource_provider();
1021 if (host_impl
->active_tree()->source_frame_number() == 0) {
1022 // Set up impl resources on the first commit.
1024 scoped_ptr
<TestRenderPass
> pass_for_quad
= TestRenderPass::Create();
1025 pass_for_quad
->SetNew(
1026 // AppendOneOfEveryQuadType() makes a RenderPass quad with this id.
1027 RenderPass::Id(1, 1),
1028 gfx::Rect(0, 0, 10, 10),
1029 gfx::Rect(0, 0, 10, 10),
1032 scoped_ptr
<TestRenderPass
> pass
= TestRenderPass::Create();
1034 RenderPass::Id(2, 1),
1035 gfx::Rect(0, 0, 10, 10),
1036 gfx::Rect(0, 0, 10, 10),
1038 pass
->AppendOneOfEveryQuadType(resource_provider
, RenderPass::Id(2, 1));
1040 ScopedPtrVector
<RenderPass
> pass_list
;
1041 pass_list
.push_back(pass_for_quad
.PassAs
<RenderPass
>());
1042 pass_list
.push_back(pass
.PassAs
<RenderPass
>());
1044 // First child is the delegated layer.
1045 FakeDelegatedRendererLayerImpl
* delegated_impl
=
1046 static_cast<FakeDelegatedRendererLayerImpl
*>(
1047 host_impl
->active_tree()->root_layer()->children()[0]);
1048 delegated_impl
->SetFrameDataForRenderPasses(&pass_list
);
1049 EXPECT_TRUE(pass_list
.empty());
1051 color_video_frame_
= VideoFrame::CreateColorFrame(
1052 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
1053 hw_video_frame_
= VideoFrame::WrapNativeTexture(
1054 resource_provider
->GraphicsContext3D()->createTexture(),
1056 gfx::Size(4, 4), gfx::Rect(0, 0, 4, 4), gfx::Size(4, 4),
1058 VideoFrame::ReadPixelsCB(),
1060 scaled_hw_video_frame_
= VideoFrame::WrapNativeTexture(
1061 resource_provider
->GraphicsContext3D()->createTexture(),
1063 gfx::Size(4, 4), gfx::Rect(0, 0, 3, 2), gfx::Size(4, 4),
1065 VideoFrame::ReadPixelsCB(),
1068 color_frame_provider_
.set_frame(color_video_frame_
);
1069 hw_frame_provider_
.set_frame(hw_video_frame_
);
1070 scaled_hw_frame_provider_
.set_frame(scaled_hw_video_frame_
);
1074 if (host_impl
->active_tree()->source_frame_number() == 3) {
1075 // On the third commit we're recovering from context loss. Hardware
1076 // video frames should not be reused by the VideoFrameProvider, but
1077 // software frames can be.
1078 hw_frame_provider_
.set_frame(NULL
);
1079 scaled_hw_frame_provider_
.set_frame(NULL
);
1083 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1084 LayerTreeHostImpl::FrameData
* frame
,
1085 bool result
) OVERRIDE
{
1086 if (host_impl
->active_tree()->source_frame_number() == 2) {
1087 // Lose the context during draw on the second commit. This will cause
1088 // a third commit to recover.
1090 context3d_
->set_times_bind_texture_succeeds(4);
1095 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1096 ASSERT_TRUE(layer_tree_host()->hud_layer());
1097 // End the test once we know the 3nd frame drew.
1098 if (layer_tree_host()->commit_number() == 4)
1101 layer_tree_host()->SetNeedsCommit();
1104 virtual void AfterTest() OVERRIDE
{}
1107 FakeContentLayerClient client_
;
1109 scoped_refptr
<Layer
> root_
;
1110 scoped_refptr
<DelegatedRendererLayer
> delegated_
;
1111 scoped_refptr
<ContentLayer
> content_
;
1112 scoped_refptr
<TextureLayer
> texture_
;
1113 scoped_refptr
<ContentLayer
> mask_
;
1114 scoped_refptr
<ContentLayer
> content_with_mask_
;
1115 scoped_refptr
<VideoLayer
> video_color_
;
1116 scoped_refptr
<VideoLayer
> video_hw_
;
1117 scoped_refptr
<VideoLayer
> video_scaled_hw_
;
1118 scoped_refptr
<IOSurfaceLayer
> io_surface_
;
1119 scoped_refptr
<ScrollbarLayer
> scrollbar_
;
1121 scoped_refptr
<VideoFrame
> color_video_frame_
;
1122 scoped_refptr
<VideoFrame
> hw_video_frame_
;
1123 scoped_refptr
<VideoFrame
> scaled_hw_video_frame_
;
1125 FakeVideoFrameProvider color_frame_provider_
;
1126 FakeVideoFrameProvider hw_frame_provider_
;
1127 FakeVideoFrameProvider scaled_hw_frame_provider_
;
1130 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources
);
1132 class LayerTreeHostContextTestLosesFirstOutputSurface
1133 : public LayerTreeHostContextTest
{
1135 LayerTreeHostContextTestLosesFirstOutputSurface() {
1136 // Always fail. This needs to be set before LayerTreeHost is created.
1137 times_to_lose_on_create_
= 1000;
1140 virtual void BeginTest() OVERRIDE
{
1141 PostSetNeedsCommitToMainThread();
1144 virtual void AfterTest() OVERRIDE
{}
1146 virtual void DidRecreateOutputSurface(bool succeeded
) OVERRIDE
{
1147 EXPECT_FALSE(succeeded
);
1149 // If we make it this far without crashing, we pass!
1153 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1158 SINGLE_AND_MULTI_THREAD_TEST_F(
1159 LayerTreeHostContextTestLosesFirstOutputSurface
);
1161 class LayerTreeHostContextTestRetriesFirstInitializationAndSucceeds
1162 : public LayerTreeHostContextTest
{
1164 virtual void AfterTest() OVERRIDE
{}
1166 virtual void BeginTest() OVERRIDE
{
1167 times_to_fail_initialize_
= 2;
1168 PostSetNeedsCommitToMainThread();
1171 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1176 SINGLE_AND_MULTI_THREAD_TEST_F(
1177 LayerTreeHostContextTestRetriesFirstInitializationAndSucceeds
);
1179 class LayerTreeHostContextTestRetryWorksWithForcedInit
1180 : public LayerTreeHostContextTestRetriesFirstInitializationAndSucceeds
{
1182 virtual void DidFailToInitializeOutputSurface() OVERRIDE
{
1183 LayerTreeHostContextTestRetriesFirstInitializationAndSucceeds
1184 ::DidFailToInitializeOutputSurface();
1186 if (times_create_failed_
== 1) {
1187 // CompositeAndReadback force recreates the output surface, which should
1190 EXPECT_FALSE(layer_tree_host()->CompositeAndReadback(
1191 &pixels
, gfx::Rect(1, 1)));
1196 SINGLE_AND_MULTI_THREAD_TEST_F(
1197 LayerTreeHostContextTestRetryWorksWithForcedInit
);
1199 class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
1200 : public LayerTreeHostContextTest
{
1202 virtual void BeginTest() OVERRIDE
{
1203 // This must be called immediately after creating LTH, before the first
1204 // OutputSurface is initialized.
1205 ASSERT_TRUE(layer_tree_host()->output_surface_lost());
1207 times_output_surface_created_
= 0;
1210 EXPECT_TRUE(layer_tree_host()->CompositeAndReadback(
1211 &pixels
, gfx::Rect(1, 1)));
1212 EXPECT_EQ(1, times_output_surface_created_
);
1214 PostSetNeedsCommitToMainThread();
1217 virtual void DidRecreateOutputSurface(bool succeeded
) OVERRIDE
{
1218 EXPECT_TRUE(succeeded
);
1219 ++times_output_surface_created_
;
1222 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1226 virtual void AfterTest() OVERRIDE
{
1227 // Should not try to create output surface again after successfully
1228 // created by CompositeAndReadback.
1229 EXPECT_EQ(1, times_output_surface_created_
);
1233 int times_output_surface_created_
;
1236 SINGLE_AND_MULTI_THREAD_TEST_F(
1237 LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
);
1239 class ImplSidePaintingLayerTreeHostContextTest
1240 : public LayerTreeHostContextTest
{
1242 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1243 settings
->impl_side_painting
= true;
1247 class LayerTreeHostContextTestImplSidePainting
1248 : public ImplSidePaintingLayerTreeHostContextTest
{
1250 virtual void SetupTree() OVERRIDE
{
1251 scoped_refptr
<Layer
> root
= Layer::Create();
1252 root
->SetBounds(gfx::Size(10, 10));
1253 root
->SetAnchorPoint(gfx::PointF());
1254 root
->SetIsDrawable(true);
1256 scoped_refptr
<PictureLayer
> picture
= PictureLayer::Create(&client_
);
1257 picture
->SetBounds(gfx::Size(10, 10));
1258 picture
->SetAnchorPoint(gfx::PointF());
1259 picture
->SetIsDrawable(true);
1260 root
->AddChild(picture
);
1262 layer_tree_host()->SetRootLayer(root
);
1263 LayerTreeHostContextTest::SetupTree();
1266 virtual void BeginTest() OVERRIDE
{
1267 times_to_lose_during_commit_
= 1;
1268 PostSetNeedsCommitToMainThread();
1271 virtual void AfterTest() OVERRIDE
{}
1273 virtual void DidRecreateOutputSurface(bool succeeded
) OVERRIDE
{
1274 EXPECT_TRUE(succeeded
);
1279 FakeContentLayerClient client_
;
1282 MULTI_THREAD_TEST_F(LayerTreeHostContextTestImplSidePainting
);
1284 class ScrollbarLayerLostContext
: public LayerTreeHostContextTest
{
1286 ScrollbarLayerLostContext() : commits_(0) {}
1288 virtual void BeginTest() OVERRIDE
{
1289 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
1290 scrollbar_layer_
= FakeScrollbarLayer::Create(
1291 false, true, scroll_layer
->id());
1292 scrollbar_layer_
->SetBounds(gfx::Size(10, 100));
1293 layer_tree_host()->root_layer()->AddChild(scrollbar_layer_
);
1294 layer_tree_host()->root_layer()->AddChild(scroll_layer
);
1295 PostSetNeedsCommitToMainThread();
1298 virtual void AfterTest() OVERRIDE
{}
1300 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1301 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1304 size_t upload_count
= scrollbar_layer_
->last_update_full_upload_size() +
1305 scrollbar_layer_
->last_update_partial_upload_size();
1308 // First (regular) update, we should upload 2 resources (thumb, and
1310 EXPECT_EQ(1, scrollbar_layer_
->update_count());
1311 EXPECT_EQ(2u, upload_count
);
1315 // Second update, after the lost context, we should still upload 2
1316 // resources even if the contents haven't changed.
1317 EXPECT_EQ(2, scrollbar_layer_
->update_count());
1318 EXPECT_EQ(2u, upload_count
);
1328 scoped_refptr
<FakeScrollbarLayer
> scrollbar_layer_
;
1331 SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext
);
1333 class LayerTreeHostContextTestFailsToCreateSurface
1334 : public LayerTreeHostContextTest
{
1336 LayerTreeHostContextTestFailsToCreateSurface()
1337 : LayerTreeHostContextTest(),
1339 times_to_lose_on_create_
= 10;
1342 virtual void BeginTest() OVERRIDE
{
1343 PostSetNeedsCommitToMainThread();
1346 virtual void AfterTest() OVERRIDE
{}
1348 virtual void DidRecreateOutputSurface(bool success
) OVERRIDE
{
1349 EXPECT_FALSE(success
);
1350 EXPECT_EQ(0, failure_count_
);
1351 times_to_lose_on_create_
= 0;
1353 // Normally, the embedder should stop trying to use the compositor at
1354 // this point, but let's force it back into action when we shouldn't.
1357 layer_tree_host()->CompositeAndReadback(pixels
, gfx::Rect(1, 1)));
1358 // If we've made it this far without crashing, we've succeeded.
1366 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestFailsToCreateSurface
);
1368 // Not reusing LayerTreeTest because it expects creating LTH to always succeed.
1369 class LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface
1370 : public testing::Test
,
1371 public FakeLayerTreeHostClient
{
1373 LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface()
1374 : FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D
) {}
1376 // FakeLayerTreeHostClient
1377 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
1378 return scoped_ptr
<OutputSurface
>();
1381 void RunTest(bool threaded
) {
1382 scoped_ptr
<base::Thread
> impl_thread
;
1383 scoped_ptr
<cc::Thread
> impl_ccthread(NULL
);
1385 impl_thread
.reset(new base::Thread("LayerTreeTest"));
1386 impl_ccthread
= cc::ThreadImpl::CreateForDifferentThread(
1387 impl_thread
->message_loop_proxy());
1388 ASSERT_TRUE(impl_ccthread
);
1391 LayerTreeSettings settings
;
1392 scoped_ptr
<LayerTreeHost
> layer_tree_host
=
1393 LayerTreeHost::Create(this, settings
, impl_ccthread
.Pass());
1394 EXPECT_FALSE(layer_tree_host
);
1398 SINGLE_AND_MULTI_THREAD_TEST_F(
1399 LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface
);