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/layers/content_layer.h"
9 #include "cc/layers/delegated_frame_provider.h"
10 #include "cc/layers/delegated_frame_resource_collection.h"
11 #include "cc/layers/heads_up_display_layer.h"
12 #include "cc/layers/io_surface_layer.h"
13 #include "cc/layers/layer_impl.h"
14 #include "cc/layers/painted_scrollbar_layer.h"
15 #include "cc/layers/picture_layer.h"
16 #include "cc/layers/texture_layer.h"
17 #include "cc/layers/texture_layer_impl.h"
18 #include "cc/layers/video_layer.h"
19 #include "cc/layers/video_layer_impl.h"
20 #include "cc/output/filter_operations.h"
21 #include "cc/test/fake_content_layer.h"
22 #include "cc/test/fake_content_layer_client.h"
23 #include "cc/test/fake_content_layer_impl.h"
24 #include "cc/test/fake_delegated_renderer_layer.h"
25 #include "cc/test/fake_delegated_renderer_layer_impl.h"
26 #include "cc/test/fake_layer_tree_host_client.h"
27 #include "cc/test/fake_output_surface.h"
28 #include "cc/test/fake_output_surface_client.h"
29 #include "cc/test/fake_painted_scrollbar_layer.h"
30 #include "cc/test/fake_scoped_ui_resource.h"
31 #include "cc/test/fake_scrollbar.h"
32 #include "cc/test/fake_video_frame_provider.h"
33 #include "cc/test/layer_tree_test.h"
34 #include "cc/test/render_pass_test_common.h"
35 #include "cc/test/test_context_provider.h"
36 #include "cc/test/test_web_graphics_context_3d.h"
37 #include "cc/trees/layer_tree_host_impl.h"
38 #include "cc/trees/layer_tree_impl.h"
39 #include "cc/trees/single_thread_proxy.h"
40 #include "gpu/GLES2/gl2extchromium.h"
41 #include "media/base/media.h"
43 using media::VideoFrame
;
48 // These tests deal with losing the 3d graphics context.
49 class LayerTreeHostContextTest
: public LayerTreeTest
{
51 LayerTreeHostContextTest()
54 times_to_fail_create_(0),
55 times_to_lose_during_commit_(0),
56 times_to_lose_during_draw_(0),
57 times_to_fail_recreate_(0),
58 times_to_fail_create_offscreen_(0),
59 times_to_fail_recreate_offscreen_(0),
60 times_to_expect_create_failed_(0),
61 times_create_failed_(0),
62 times_offscreen_created_(0),
63 committed_at_least_once_(false),
64 context_should_support_io_surface_(false),
65 fallback_context_works_(false) {
66 media::InitializeMediaLibraryForTesting();
70 context3d_
->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
71 GL_INNOCENT_CONTEXT_RESET_ARB
);
75 virtual scoped_ptr
<TestWebGraphicsContext3D
> CreateContext3d() {
76 return TestWebGraphicsContext3D::Create();
79 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(bool fallback
)
81 if (times_to_fail_create_
) {
82 --times_to_fail_create_
;
84 return scoped_ptr
<OutputSurface
>();
87 scoped_ptr
<TestWebGraphicsContext3D
> context3d
= CreateContext3d();
88 context3d_
= context3d
.get();
90 if (context_should_support_io_surface_
) {
91 context3d_
->set_have_extension_io_surface(true);
92 context3d_
->set_have_extension_egl_image(true);
95 if (delegating_renderer()) {
96 return FakeOutputSurface::CreateDelegating3d(context3d
.Pass())
97 .PassAs
<OutputSurface
>();
99 return FakeOutputSurface::Create3d(context3d
.Pass())
100 .PassAs
<OutputSurface
>();
103 scoped_ptr
<TestWebGraphicsContext3D
> CreateOffscreenContext3d() {
105 return scoped_ptr
<TestWebGraphicsContext3D
>();
107 ++times_offscreen_created_
;
109 if (times_to_fail_create_offscreen_
) {
110 --times_to_fail_create_offscreen_
;
111 ExpectCreateToFail();
112 return scoped_ptr
<TestWebGraphicsContext3D
>();
115 scoped_ptr
<TestWebGraphicsContext3D
> offscreen_context3d
=
116 TestWebGraphicsContext3D::Create().Pass();
117 DCHECK(offscreen_context3d
);
118 context3d_
->add_share_group_context(offscreen_context3d
.get());
120 return offscreen_context3d
.Pass();
123 virtual scoped_refptr
<ContextProvider
> OffscreenContextProvider() OVERRIDE
{
124 if (!offscreen_contexts_
.get() ||
125 offscreen_contexts_
->DestroyedOnMainThread()) {
126 offscreen_contexts_
=
127 TestContextProvider::Create(CreateOffscreenContext3d());
129 return offscreen_contexts_
;
132 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
133 LayerTreeHostImpl::FrameData
* frame
,
134 bool result
) OVERRIDE
{
136 if (!times_to_lose_during_draw_
)
139 --times_to_lose_during_draw_
;
142 times_to_fail_create_
= times_to_fail_recreate_
;
143 times_to_fail_recreate_
= 0;
144 times_to_fail_create_offscreen_
= times_to_fail_recreate_offscreen_
;
145 times_to_fail_recreate_offscreen_
= 0;
150 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
151 committed_at_least_once_
= true;
153 if (!times_to_lose_during_commit_
)
155 --times_to_lose_during_commit_
;
158 times_to_fail_create_
= times_to_fail_recreate_
;
159 times_to_fail_recreate_
= 0;
160 times_to_fail_create_offscreen_
= times_to_fail_recreate_offscreen_
;
161 times_to_fail_recreate_offscreen_
= 0;
164 virtual void DidFailToInitializeOutputSurface() OVERRIDE
{
165 ++times_create_failed_
;
168 virtual void TearDown() OVERRIDE
{
169 LayerTreeTest::TearDown();
170 EXPECT_EQ(times_to_expect_create_failed_
, times_create_failed_
);
173 void ExpectCreateToFail() {
174 ++times_to_expect_create_failed_
;
178 TestWebGraphicsContext3D
* context3d_
;
179 int times_to_fail_create_
;
180 int times_to_lose_during_commit_
;
181 int times_to_lose_during_draw_
;
182 int times_to_fail_recreate_
;
183 int times_to_fail_create_offscreen_
;
184 int times_to_fail_recreate_offscreen_
;
185 int times_to_expect_create_failed_
;
186 int times_create_failed_
;
187 int times_offscreen_created_
;
188 bool committed_at_least_once_
;
189 bool context_should_support_io_surface_
;
190 bool fallback_context_works_
;
192 scoped_refptr
<TestContextProvider
> offscreen_contexts_
;
195 class LayerTreeHostContextTestLostContextSucceeds
196 : public LayerTreeHostContextTest
{
198 LayerTreeHostContextTestLostContextSucceeds()
199 : LayerTreeHostContextTest(),
202 num_losses_last_test_case_(-1),
203 recovered_context_(true),
204 first_initialized_(false) {}
206 virtual void BeginTest() OVERRIDE
{
207 PostSetNeedsCommitToMainThread();
210 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
211 EXPECT_TRUE(succeeded
);
213 if (first_initialized_
)
216 first_initialized_
= true;
218 recovered_context_
= true;
221 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(9u, test_case_
); }
223 virtual void DidCommitAndDrawFrame() OVERRIDE
{
224 // If the last frame had a context loss, then we'll commit again to
226 if (!recovered_context_
)
228 if (times_to_lose_during_commit_
)
230 if (times_to_lose_during_draw_
)
233 recovered_context_
= false;
235 InvalidateAndSetNeedsCommit();
240 virtual void InvalidateAndSetNeedsCommit() {
241 // Cause damage so we try to draw.
242 layer_tree_host()->root_layer()->SetNeedsDisplay();
243 layer_tree_host()->SetNeedsCommit();
246 bool NextTestCase() {
247 static const TestCase kTests
[] = {
248 // Losing the context and failing to recreate it (or losing it again
249 // immediately) a small number of times should succeed.
250 { 1, // times_to_lose_during_commit
251 0, // times_to_lose_during_draw
252 0, // times_to_fail_recreate
253 0, // times_to_fail_recreate_offscreen
254 false, // fallback_context_works
256 { 0, // times_to_lose_during_commit
257 1, // times_to_lose_during_draw
258 0, // times_to_fail_recreate
259 0, // times_to_fail_recreate_offscreen
260 false, // fallback_context_works
262 { 1, // times_to_lose_during_commit
263 0, // times_to_lose_during_draw
264 3, // times_to_fail_recreate
265 0, // times_to_fail_recreate_offscreen
266 false, // fallback_context_works
268 { 0, // times_to_lose_during_commit
269 1, // times_to_lose_during_draw
270 3, // times_to_fail_recreate
271 0, // times_to_fail_recreate_offscreen
272 false, // fallback_context_works
274 { 1, // times_to_lose_during_commit
275 0, // times_to_lose_during_draw
276 0, // times_to_fail_recreate
277 3, // times_to_fail_recreate_offscreen
278 false, // fallback_context_works
280 { 0, // times_to_lose_during_commit
281 1, // times_to_lose_during_draw
282 0, // times_to_fail_recreate
283 3, // times_to_fail_recreate_offscreen
284 false, // fallback_context_works
286 // Losing the context and recreating it any number of times should
288 { 10, // times_to_lose_during_commit
289 0, // times_to_lose_during_draw
290 0, // times_to_fail_recreate
291 0, // times_to_fail_recreate_offscreen
292 false, // fallback_context_works
294 { 0, // times_to_lose_during_commit
295 10, // times_to_lose_during_draw
296 0, // times_to_fail_recreate
297 0, // times_to_fail_recreate_offscreen
298 false, // fallback_context_works
300 // Losing the context, failing to reinitialize it, and making a fallback
301 // context should work.
302 { 0, // times_to_lose_during_commit
303 1, // times_to_lose_during_draw
304 0, // times_to_fail_recreate
305 0, // times_to_fail_recreate_offscreen
306 true, // fallback_context_works
310 if (test_case_
>= arraysize(kTests
))
312 // Make sure that we lost our context at least once in the last test run so
313 // the test did something.
314 EXPECT_GT(num_losses_
, num_losses_last_test_case_
);
315 num_losses_last_test_case_
= num_losses_
;
317 times_to_lose_during_commit_
=
318 kTests
[test_case_
].times_to_lose_during_commit
;
319 times_to_lose_during_draw_
=
320 kTests
[test_case_
].times_to_lose_during_draw
;
321 times_to_fail_recreate_
= kTests
[test_case_
].times_to_fail_recreate
;
322 times_to_fail_recreate_offscreen_
=
323 kTests
[test_case_
].times_to_fail_recreate_offscreen
;
324 fallback_context_works_
= kTests
[test_case_
].fallback_context_works
;
330 int times_to_lose_during_commit
;
331 int times_to_lose_during_draw
;
332 int times_to_fail_recreate
;
333 int times_to_fail_recreate_offscreen
;
334 bool fallback_context_works
;
340 int num_losses_last_test_case_
;
341 bool recovered_context_
;
342 bool first_initialized_
;
345 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds
);
347 class LayerTreeHostClientNotReadyDoesNotCreateOutputSurface
348 : public LayerTreeHostContextTest
{
350 LayerTreeHostClientNotReadyDoesNotCreateOutputSurface()
351 : LayerTreeHostContextTest() {}
353 virtual void WillBeginTest() OVERRIDE
{
354 // Override and do not signal SetLayerTreeHostClientReady.
357 virtual void BeginTest() OVERRIDE
{
358 PostSetNeedsCommitToMainThread();
362 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(bool fallback
)
365 return scoped_ptr
<OutputSurface
>();
368 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
372 virtual void AfterTest() OVERRIDE
{
376 MULTI_THREAD_TEST_F(LayerTreeHostClientNotReadyDoesNotCreateOutputSurface
);
378 class LayerTreeHostContextTestLostContextSucceedsWithContent
379 : public LayerTreeHostContextTestLostContextSucceeds
{
381 LayerTreeHostContextTestLostContextSucceedsWithContent()
382 : LayerTreeHostContextTestLostContextSucceeds() {}
384 virtual void SetupTree() OVERRIDE
{
385 root_
= Layer::Create();
386 root_
->SetBounds(gfx::Size(10, 10));
387 root_
->SetAnchorPoint(gfx::PointF());
388 root_
->SetIsDrawable(true);
390 content_
= FakeContentLayer::Create(&client_
);
391 content_
->SetBounds(gfx::Size(10, 10));
392 content_
->SetAnchorPoint(gfx::PointF());
393 content_
->SetIsDrawable(true);
395 content_
->SetForceRenderSurface(true);
396 // Filters require us to create an offscreen context.
397 FilterOperations filters
;
398 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
399 content_
->SetFilters(filters
);
400 content_
->SetBackgroundFilters(filters
);
403 root_
->AddChild(content_
);
405 layer_tree_host()->SetRootLayer(root_
);
406 LayerTreeHostContextTest::SetupTree();
409 virtual void InvalidateAndSetNeedsCommit() OVERRIDE
{
410 // Invalidate the render surface so we don't try to use a cached copy of the
411 // surface. We want to make sure to test the drawing paths for drawing to
413 content_
->SetNeedsDisplay();
414 LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit();
417 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
418 FakeContentLayerImpl
* content_impl
= static_cast<FakeContentLayerImpl
*>(
419 host_impl
->active_tree()->root_layer()->children()[0]);
420 // Even though the context was lost, we should have a resource. The
421 // TestWebGraphicsContext3D ensures that this resource is created with
422 // the active context.
423 EXPECT_TRUE(content_impl
->HaveResourceForTileAt(0, 0));
425 ContextProvider
* contexts
= host_impl
->offscreen_context_provider();
427 ASSERT_TRUE(contexts
);
428 EXPECT_TRUE(contexts
->ContextGL());
429 // TODO(danakj): Make a fake GrContext.
430 // EXPECT_TRUE(contexts->GrContext());
432 EXPECT_FALSE(contexts
);
436 virtual void AfterTest() OVERRIDE
{
437 LayerTreeHostContextTestLostContextSucceeds::AfterTest();
439 // 1 create to start with +
440 // 4 from test cases that lose the offscreen context directly +
441 // 2 from test cases that create a fallback +
442 // All the test cases that recreate both contexts only once
443 // per time it is lost.
444 EXPECT_EQ(4 + 1 + 2 + num_losses_
, times_offscreen_created_
);
446 EXPECT_EQ(0, times_offscreen_created_
);
452 FakeContentLayerClient client_
;
453 scoped_refptr
<Layer
> root_
;
454 scoped_refptr
<ContentLayer
> content_
;
457 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
458 NoSurface_SingleThread_DirectRenderer
) {
459 use_surface_
= false;
460 RunTest(false, false, false);
463 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
464 NoSurface_SingleThread_DelegatingRenderer
) {
465 use_surface_
= false;
466 RunTest(false, true, false);
469 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
470 NoSurface_MultiThread_DirectRenderer_MainThreadPaint
) {
471 use_surface_
= false;
472 RunTest(true, false, false);
475 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
476 NoSurface_MultiThread_DelegatingRenderer_MainThreadPaint
) {
477 use_surface_
= false;
478 RunTest(true, true, false);
481 // Surfaces don't exist with a delegating renderer.
482 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
483 WithSurface_SingleThread_DirectRenderer
) {
485 RunTest(false, false, false);
488 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
489 WithSurface_MultiThread_DirectRenderer_MainThreadPaint
) {
491 RunTest(true, false, false);
494 class LayerTreeHostContextTestCreateOutputSurfaceFails
495 : public LayerTreeHostContextTest
{
497 // Run a test that initially fails OutputSurface creation |times_to_fail|
498 // times. If |expect_fallback_attempt| is |true|, an attempt to create a
499 // fallback/software OutputSurface is expected to occur.
500 LayerTreeHostContextTestCreateOutputSurfaceFails(int times_to_fail
,
501 bool expect_fallback_attempt
,
502 bool expect_to_give_up
)
503 : times_to_fail_(times_to_fail
),
504 expect_fallback_attempt_(expect_fallback_attempt
),
505 expect_to_give_up_(expect_to_give_up
),
506 did_attempt_fallback_(false),
507 times_initialized_(0) {}
509 virtual void BeginTest() OVERRIDE
{
510 times_to_fail_create_
= times_to_fail_
;
511 PostSetNeedsCommitToMainThread();
514 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(bool fallback
)
516 scoped_ptr
<OutputSurface
> surface
=
517 LayerTreeHostContextTest::CreateOutputSurface(fallback
);
520 EXPECT_EQ(times_to_fail_
, times_create_failed_
);
522 did_attempt_fallback_
= fallback
;
523 return surface
.Pass();
526 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
528 times_initialized_
++;
533 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
537 virtual void AfterTest() OVERRIDE
{
538 EXPECT_EQ(times_to_fail_
, times_create_failed_
);
539 EXPECT_EQ(expect_to_give_up_
, times_initialized_
== 0);
540 EXPECT_EQ(expect_fallback_attempt_
, did_attempt_fallback_
);
545 bool expect_fallback_attempt_
;
546 bool expect_to_give_up_
;
547 bool did_attempt_fallback_
;
548 int times_initialized_
;
551 class LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
552 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
554 LayerTreeHostContextTestCreateOutputSurfaceFailsOnce()
555 : LayerTreeHostContextTestCreateOutputSurfaceFails(1, false, false) {}
558 SINGLE_AND_MULTI_THREAD_TEST_F(
559 LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
);
561 // After 4 failures we expect an attempt to create a fallback/software
563 class LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback
564 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
566 LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback()
567 : LayerTreeHostContextTestCreateOutputSurfaceFails(4, true, false) {}
570 SINGLE_AND_MULTI_THREAD_TEST_F(
571 LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback
);
573 // If we fail that often, we should be giving up cleanly.
574 class LayerTreeHostContextTestCreateOutputSurfaceIsHopeless
575 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
577 LayerTreeHostContextTestCreateOutputSurfaceIsHopeless()
578 : LayerTreeHostContextTestCreateOutputSurfaceFails(5, true, true) {}
581 SINGLE_AND_MULTI_THREAD_TEST_F(
582 LayerTreeHostContextTestCreateOutputSurfaceIsHopeless
);
585 class LayerTreeHostContextTestOffscreenContextFails
586 : public LayerTreeHostContextTest
{
588 virtual void SetupTree() OVERRIDE
{
589 root_
= Layer::Create();
590 root_
->SetBounds(gfx::Size(10, 10));
591 root_
->SetAnchorPoint(gfx::PointF());
592 root_
->SetIsDrawable(true);
594 content_
= FakeContentLayer::Create(&client_
);
595 content_
->SetBounds(gfx::Size(10, 10));
596 content_
->SetAnchorPoint(gfx::PointF());
597 content_
->SetIsDrawable(true);
598 content_
->SetForceRenderSurface(true);
599 // Filters require us to create an offscreen context.
600 FilterOperations filters
;
601 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
602 content_
->SetFilters(filters
);
603 content_
->SetBackgroundFilters(filters
);
605 root_
->AddChild(content_
);
607 layer_tree_host()->SetRootLayer(root_
);
608 LayerTreeHostContextTest::SetupTree();
611 virtual void BeginTest() OVERRIDE
{
612 times_to_fail_create_offscreen_
= 1;
613 PostSetNeedsCommitToMainThread();
616 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
617 ContextProvider
* contexts
= host_impl
->offscreen_context_provider();
618 EXPECT_FALSE(contexts
);
620 // This did not lead to create failure.
621 times_to_expect_create_failed_
= 0;
625 virtual void AfterTest() OVERRIDE
{}
628 FakeContentLayerClient client_
;
629 scoped_refptr
<Layer
> root_
;
630 scoped_refptr
<ContentLayer
> content_
;
633 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestOffscreenContextFails
);
635 class LayerTreeHostContextTestLostContextFails
636 : public LayerTreeHostContextTest
{
638 LayerTreeHostContextTestLostContextFails()
639 : LayerTreeHostContextTest(),
641 first_initialized_(false) {
642 times_to_lose_during_commit_
= 1;
645 virtual void BeginTest() OVERRIDE
{
646 PostSetNeedsCommitToMainThread();
649 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
650 if (first_initialized_
) {
651 EXPECT_FALSE(succeeded
);
654 first_initialized_
= true;
658 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
659 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
662 if (num_commits_
== 1) {
663 // When the context is ok, we should have these things.
664 EXPECT_TRUE(host_impl
->output_surface());
665 EXPECT_TRUE(host_impl
->renderer());
666 EXPECT_TRUE(host_impl
->resource_provider());
670 // When context recreation fails we shouldn't be left with any of them.
671 EXPECT_FALSE(host_impl
->output_surface());
672 EXPECT_FALSE(host_impl
->renderer());
673 EXPECT_FALSE(host_impl
->resource_provider());
676 virtual void AfterTest() OVERRIDE
{}
680 bool first_initialized_
;
683 class LayerTreeHostContextTestLostContextAndEvictTextures
684 : public LayerTreeHostContextTest
{
686 LayerTreeHostContextTestLostContextAndEvictTextures()
687 : LayerTreeHostContextTest(),
688 layer_(FakeContentLayer::Create(&client_
)),
692 virtual void SetupTree() OVERRIDE
{
693 layer_
->SetBounds(gfx::Size(10, 20));
694 layer_tree_host()->SetRootLayer(layer_
);
695 LayerTreeHostContextTest::SetupTree();
698 virtual void BeginTest() OVERRIDE
{
699 PostSetNeedsCommitToMainThread();
702 void PostEvictTextures() {
703 if (HasImplThread()) {
704 ImplThreadTaskRunner()->PostTask(
707 &LayerTreeHostContextTestLostContextAndEvictTextures::
708 EvictTexturesOnImplThread
,
709 base::Unretained(this)));
711 DebugScopedSetImplThread
impl(proxy());
712 EvictTexturesOnImplThread();
716 void EvictTexturesOnImplThread() {
717 impl_host_
->EvictTexturesForTesting();
718 if (lose_after_evict_
)
722 virtual void DidCommitAndDrawFrame() OVERRIDE
{
723 if (num_commits_
> 1)
725 EXPECT_TRUE(layer_
->HaveBackingAt(0, 0));
729 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
730 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
731 if (num_commits_
> 1)
734 if (!lose_after_evict_
)
739 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
740 EXPECT_TRUE(succeeded
);
744 virtual void AfterTest() OVERRIDE
{}
747 bool lose_after_evict_
;
748 FakeContentLayerClient client_
;
749 scoped_refptr
<FakeContentLayer
> layer_
;
750 LayerTreeHostImpl
* impl_host_
;
754 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
755 LoseAfterEvict_SingleThread_DirectRenderer
) {
756 lose_after_evict_
= true;
757 RunTest(false, false, false);
760 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
761 LoseAfterEvict_SingleThread_DelegatingRenderer
) {
762 lose_after_evict_
= true;
763 RunTest(false, true, false);
766 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
767 LoseAfterEvict_MultiThread_DirectRenderer_MainThreadPaint
) {
768 lose_after_evict_
= true;
769 RunTest(true, false, false);
772 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
773 LoseAfterEvict_MultiThread_DelegatingRenderer_MainThreadPaint
) {
774 lose_after_evict_
= true;
775 RunTest(true, true, false);
778 // Flaky on all platforms, http://crbug.com/310979
779 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
780 DISABLED_LoseAfterEvict_MultiThread_DelegatingRenderer_ImplSidePaint
) {
781 lose_after_evict_
= true;
782 RunTest(true, true, true);
785 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
786 LoseBeforeEvict_SingleThread_DirectRenderer
) {
787 lose_after_evict_
= false;
788 RunTest(false, false, false);
791 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
792 LoseBeforeEvict_SingleThread_DelegatingRenderer
) {
793 lose_after_evict_
= false;
794 RunTest(false, true, false);
797 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
798 LoseBeforeEvict_MultiThread_DirectRenderer_MainThreadPaint
) {
799 lose_after_evict_
= false;
800 RunTest(true, false, false);
803 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
804 LoseBeforeEvict_MultiThread_DirectRenderer_ImplSidePaint
) {
805 lose_after_evict_
= false;
806 RunTest(true, false, true);
809 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
810 LoseBeforeEvict_MultiThread_DelegatingRenderer_MainThreadPaint
) {
811 lose_after_evict_
= false;
812 RunTest(true, true, false);
815 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
816 LoseBeforeEvict_MultiThread_DelegatingRenderer_ImplSidePaint
) {
817 lose_after_evict_
= false;
818 RunTest(true, true, true);
821 class LayerTreeHostContextTestLostContextWhileUpdatingResources
822 : public LayerTreeHostContextTest
{
824 LayerTreeHostContextTestLostContextWhileUpdatingResources()
825 : parent_(FakeContentLayer::Create(&client_
)),
827 times_to_lose_on_end_query_(3) {}
829 virtual scoped_ptr
<TestWebGraphicsContext3D
> CreateContext3d() OVERRIDE
{
830 scoped_ptr
<TestWebGraphicsContext3D
> context
=
831 LayerTreeHostContextTest::CreateContext3d();
832 if (times_to_lose_on_end_query_
) {
833 --times_to_lose_on_end_query_
;
834 context
->set_times_end_query_succeeds(5);
836 return context
.Pass();
839 virtual void SetupTree() OVERRIDE
{
840 parent_
->SetBounds(gfx::Size(num_children_
, 1));
842 for (int i
= 0; i
< num_children_
; i
++) {
843 scoped_refptr
<FakeContentLayer
> child
=
844 FakeContentLayer::Create(&client_
);
845 child
->SetPosition(gfx::PointF(i
, 0.f
));
846 child
->SetBounds(gfx::Size(1, 1));
847 parent_
->AddChild(child
);
850 layer_tree_host()->SetRootLayer(parent_
);
851 LayerTreeHostContextTest::SetupTree();
854 virtual void BeginTest() OVERRIDE
{
855 PostSetNeedsCommitToMainThread();
858 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
859 EXPECT_EQ(0, times_to_lose_on_end_query_
);
863 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
864 EXPECT_TRUE(succeeded
);
867 virtual void AfterTest() OVERRIDE
{
868 EXPECT_EQ(0, times_to_lose_on_end_query_
);
872 FakeContentLayerClient client_
;
873 scoped_refptr
<FakeContentLayer
> parent_
;
875 int times_to_lose_on_end_query_
;
878 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
879 LayerTreeHostContextTestLostContextWhileUpdatingResources
);
881 class LayerTreeHostContextTestLayersNotified
882 : public LayerTreeHostContextTest
{
884 LayerTreeHostContextTestLayersNotified()
885 : LayerTreeHostContextTest(),
888 virtual void SetupTree() OVERRIDE
{
889 root_
= FakeContentLayer::Create(&client_
);
890 child_
= FakeContentLayer::Create(&client_
);
891 grandchild_
= FakeContentLayer::Create(&client_
);
893 root_
->AddChild(child_
);
894 child_
->AddChild(grandchild_
);
896 layer_tree_host()->SetRootLayer(root_
);
897 LayerTreeHostContextTest::SetupTree();
900 virtual void BeginTest() OVERRIDE
{
901 PostSetNeedsCommitToMainThread();
904 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
905 LayerTreeHostContextTest::DidActivateTreeOnThread(host_impl
);
907 FakeContentLayerImpl
* root
= static_cast<FakeContentLayerImpl
*>(
908 host_impl
->active_tree()->root_layer());
909 FakeContentLayerImpl
* child
= static_cast<FakeContentLayerImpl
*>(
910 root
->children()[0]);
911 FakeContentLayerImpl
* grandchild
= static_cast<FakeContentLayerImpl
*>(
912 child
->children()[0]);
915 switch (num_commits_
) {
917 EXPECT_EQ(0u, root
->lost_output_surface_count());
918 EXPECT_EQ(0u, child
->lost_output_surface_count());
919 EXPECT_EQ(0u, grandchild
->lost_output_surface_count());
920 // Lose the context and struggle to recreate it.
922 times_to_fail_create_
= 1;
925 EXPECT_GE(1u, root
->lost_output_surface_count());
926 EXPECT_GE(1u, child
->lost_output_surface_count());
927 EXPECT_GE(1u, grandchild
->lost_output_surface_count());
935 virtual void AfterTest() OVERRIDE
{}
940 FakeContentLayerClient client_
;
941 scoped_refptr
<FakeContentLayer
> root_
;
942 scoped_refptr
<FakeContentLayer
> child_
;
943 scoped_refptr
<FakeContentLayer
> grandchild_
;
946 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLayersNotified
);
948 class LayerTreeHostContextTestDontUseLostResources
949 : public LayerTreeHostContextTest
{
951 LayerTreeHostContextTestDontUseLostResources()
952 : lost_context_(false) {
953 context_should_support_io_surface_
= true;
955 child_output_surface_
= FakeOutputSurface::Create3d();
956 child_output_surface_
->BindToClient(&output_surface_client_
);
957 child_resource_provider_
=
958 ResourceProvider::Create(child_output_surface_
.get(),
965 static void EmptyReleaseCallback(unsigned sync_point
, bool lost
) {}
967 virtual void SetupTree() OVERRIDE
{
968 gpu::gles2::GLES2Interface
* gl
=
969 child_output_surface_
->context_provider()->ContextGL();
971 scoped_ptr
<DelegatedFrameData
> frame_data(new DelegatedFrameData
);
973 scoped_ptr
<TestRenderPass
> pass_for_quad
= TestRenderPass::Create();
974 pass_for_quad
->SetNew(
975 // AppendOneOfEveryQuadType() makes a RenderPass quad with this id.
976 RenderPass::Id(2, 1),
977 gfx::Rect(0, 0, 10, 10),
978 gfx::Rect(0, 0, 10, 10),
981 scoped_ptr
<TestRenderPass
> pass
= TestRenderPass::Create();
982 pass
->SetNew(RenderPass::Id(1, 1),
983 gfx::Rect(0, 0, 10, 10),
984 gfx::Rect(0, 0, 10, 10),
986 pass
->AppendOneOfEveryQuadType(child_resource_provider_
.get(),
987 RenderPass::Id(2, 1));
989 frame_data
->render_pass_list
.push_back(pass_for_quad
.PassAs
<RenderPass
>());
990 frame_data
->render_pass_list
.push_back(pass
.PassAs
<RenderPass
>());
992 delegated_resource_collection_
= new DelegatedFrameResourceCollection
;
993 delegated_frame_provider_
= new DelegatedFrameProvider(
994 delegated_resource_collection_
.get(), frame_data
.Pass());
996 ResourceProvider::ResourceId resource
=
997 child_resource_provider_
->CreateResource(
1000 ResourceProvider::TextureUsageAny
,
1002 ResourceProvider::ScopedWriteLockGL
lock(child_resource_provider_
.get(),
1005 gpu::Mailbox mailbox
;
1006 gl
->GenMailboxCHROMIUM(mailbox
.name
);
1007 GLuint sync_point
= gl
->InsertSyncPointCHROMIUM();
1009 scoped_refptr
<Layer
> root
= Layer::Create();
1010 root
->SetBounds(gfx::Size(10, 10));
1011 root
->SetAnchorPoint(gfx::PointF());
1012 root
->SetIsDrawable(true);
1014 scoped_refptr
<FakeDelegatedRendererLayer
> delegated
=
1015 FakeDelegatedRendererLayer::Create(delegated_frame_provider_
.get());
1016 delegated
->SetBounds(gfx::Size(10, 10));
1017 delegated
->SetAnchorPoint(gfx::PointF());
1018 delegated
->SetIsDrawable(true);
1019 root
->AddChild(delegated
);
1021 scoped_refptr
<ContentLayer
> content
= ContentLayer::Create(&client_
);
1022 content
->SetBounds(gfx::Size(10, 10));
1023 content
->SetAnchorPoint(gfx::PointF());
1024 content
->SetIsDrawable(true);
1025 root
->AddChild(content
);
1027 scoped_refptr
<TextureLayer
> texture
= TextureLayer::CreateForMailbox(NULL
);
1028 texture
->SetBounds(gfx::Size(10, 10));
1029 texture
->SetAnchorPoint(gfx::PointF());
1030 texture
->SetIsDrawable(true);
1031 texture
->SetTextureMailbox(
1032 TextureMailbox(mailbox
, sync_point
),
1033 SingleReleaseCallback::Create(base::Bind(
1034 &LayerTreeHostContextTestDontUseLostResources::
1035 EmptyReleaseCallback
)));
1036 root
->AddChild(texture
);
1038 scoped_refptr
<ContentLayer
> mask
= ContentLayer::Create(&client_
);
1039 mask
->SetBounds(gfx::Size(10, 10));
1040 mask
->SetAnchorPoint(gfx::PointF());
1042 scoped_refptr
<ContentLayer
> content_with_mask
=
1043 ContentLayer::Create(&client_
);
1044 content_with_mask
->SetBounds(gfx::Size(10, 10));
1045 content_with_mask
->SetAnchorPoint(gfx::PointF());
1046 content_with_mask
->SetIsDrawable(true);
1047 content_with_mask
->SetMaskLayer(mask
.get());
1048 root
->AddChild(content_with_mask
);
1050 scoped_refptr
<VideoLayer
> video_color
=
1051 VideoLayer::Create(&color_frame_provider_
);
1052 video_color
->SetBounds(gfx::Size(10, 10));
1053 video_color
->SetAnchorPoint(gfx::PointF());
1054 video_color
->SetIsDrawable(true);
1055 root
->AddChild(video_color
);
1057 scoped_refptr
<VideoLayer
> video_hw
=
1058 VideoLayer::Create(&hw_frame_provider_
);
1059 video_hw
->SetBounds(gfx::Size(10, 10));
1060 video_hw
->SetAnchorPoint(gfx::PointF());
1061 video_hw
->SetIsDrawable(true);
1062 root
->AddChild(video_hw
);
1064 scoped_refptr
<VideoLayer
> video_scaled_hw
=
1065 VideoLayer::Create(&scaled_hw_frame_provider_
);
1066 video_scaled_hw
->SetBounds(gfx::Size(10, 10));
1067 video_scaled_hw
->SetAnchorPoint(gfx::PointF());
1068 video_scaled_hw
->SetIsDrawable(true);
1069 root
->AddChild(video_scaled_hw
);
1071 color_video_frame_
= VideoFrame::CreateColorFrame(
1072 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
1073 hw_video_frame_
= VideoFrame::WrapNativeTexture(
1074 make_scoped_ptr(new VideoFrame::MailboxHolder(
1077 VideoFrame::MailboxHolder::TextureNoLongerNeededCallback())),
1080 gfx::Rect(0, 0, 4, 4),
1083 VideoFrame::ReadPixelsCB(),
1085 scaled_hw_video_frame_
= VideoFrame::WrapNativeTexture(
1086 make_scoped_ptr(new VideoFrame::MailboxHolder(
1089 VideoFrame::MailboxHolder::TextureNoLongerNeededCallback())),
1092 gfx::Rect(0, 0, 3, 2),
1095 VideoFrame::ReadPixelsCB(),
1098 color_frame_provider_
.set_frame(color_video_frame_
);
1099 hw_frame_provider_
.set_frame(hw_video_frame_
);
1100 scaled_hw_frame_provider_
.set_frame(scaled_hw_video_frame_
);
1102 if (!delegating_renderer()) {
1103 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
1104 scoped_refptr
<IOSurfaceLayer
> io_surface
= IOSurfaceLayer::Create();
1105 io_surface
->SetBounds(gfx::Size(10, 10));
1106 io_surface
->SetAnchorPoint(gfx::PointF());
1107 io_surface
->SetIsDrawable(true);
1108 io_surface
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
1109 root
->AddChild(io_surface
);
1113 LayerTreeDebugState debug_state
;
1114 debug_state
.show_property_changed_rects
= true;
1115 layer_tree_host()->SetDebugState(debug_state
);
1117 scoped_refptr
<PaintedScrollbarLayer
> scrollbar
=
1118 PaintedScrollbarLayer::Create(
1119 scoped_ptr
<Scrollbar
>(new FakeScrollbar
).Pass(), content
->id());
1120 scrollbar
->SetBounds(gfx::Size(10, 10));
1121 scrollbar
->SetAnchorPoint(gfx::PointF());
1122 scrollbar
->SetIsDrawable(true);
1123 root
->AddChild(scrollbar
);
1125 layer_tree_host()->SetRootLayer(root
);
1126 LayerTreeHostContextTest::SetupTree();
1129 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1131 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1132 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
1134 if (host_impl
->active_tree()->source_frame_number() == 3) {
1135 // On the third commit we're recovering from context loss. Hardware
1136 // video frames should not be reused by the VideoFrameProvider, but
1137 // software frames can be.
1138 hw_frame_provider_
.set_frame(NULL
);
1139 scaled_hw_frame_provider_
.set_frame(NULL
);
1143 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1144 LayerTreeHostImpl::FrameData
* frame
,
1145 bool result
) OVERRIDE
{
1146 if (host_impl
->active_tree()->source_frame_number() == 2) {
1147 // Lose the context during draw on the second commit. This will cause
1148 // a third commit to recover.
1149 context3d_
->set_times_bind_texture_succeeds(0);
1154 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(
1155 bool fallback
) OVERRIDE
{
1156 // This will get called twice:
1157 // First when we create the initial output surface...
1158 if (layer_tree_host()->source_frame_number() > 0) {
1159 // ... and then again after we forced the context to be lost on the third
1160 // frame. Verify this assumption here.
1161 lost_context_
= true;
1162 EXPECT_EQ(layer_tree_host()->source_frame_number(), 3);
1164 return LayerTreeHostContextTest::CreateOutputSurface(fallback
);
1167 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1168 ASSERT_TRUE(layer_tree_host()->hud_layer());
1169 // End the test once we know the 3nd frame drew.
1170 if (layer_tree_host()->source_frame_number() < 4) {
1171 layer_tree_host()->root_layer()->SetNeedsDisplay();
1172 layer_tree_host()->SetNeedsCommit();
1178 virtual void AfterTest() OVERRIDE
{
1179 EXPECT_TRUE(lost_context_
);
1183 FakeContentLayerClient client_
;
1186 FakeOutputSurfaceClient output_surface_client_
;
1187 scoped_ptr
<FakeOutputSurface
> child_output_surface_
;
1188 scoped_ptr
<ResourceProvider
> child_resource_provider_
;
1190 scoped_refptr
<DelegatedFrameResourceCollection
>
1191 delegated_resource_collection_
;
1192 scoped_refptr
<DelegatedFrameProvider
> delegated_frame_provider_
;
1194 scoped_refptr
<VideoFrame
> color_video_frame_
;
1195 scoped_refptr
<VideoFrame
> hw_video_frame_
;
1196 scoped_refptr
<VideoFrame
> scaled_hw_video_frame_
;
1198 FakeVideoFrameProvider color_frame_provider_
;
1199 FakeVideoFrameProvider hw_frame_provider_
;
1200 FakeVideoFrameProvider scaled_hw_frame_provider_
;
1203 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources
);
1205 class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
1206 : public LayerTreeHostContextTest
{
1208 virtual void BeginTest() OVERRIDE
{
1209 // This must be called immediately after creating LTH, before the first
1210 // OutputSurface is initialized.
1211 ASSERT_TRUE(layer_tree_host()->output_surface_lost());
1213 times_output_surface_created_
= 0;
1215 // Post the SetNeedsCommit before the readback to make sure it is run
1216 // on the main thread before the readback's replacement commit when
1217 // we have a threaded compositor.
1218 PostSetNeedsCommitToMainThread();
1221 bool result
= layer_tree_host()->CompositeAndReadback(
1222 &pixels
, gfx::Rect(1, 1));
1223 EXPECT_EQ(!delegating_renderer(), result
);
1224 EXPECT_EQ(1, times_output_surface_created_
);
1227 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1228 EXPECT_TRUE(succeeded
);
1229 ++times_output_surface_created_
;
1232 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1236 virtual void AfterTest() OVERRIDE
{
1237 // Should not try to create output surface again after successfully
1238 // created by CompositeAndReadback.
1239 EXPECT_EQ(1, times_output_surface_created_
);
1242 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1243 LayerTreeHostImpl::FrameData
* frame_data
,
1244 bool result
) OVERRIDE
{
1245 EXPECT_GE(host_impl
->active_tree()->source_frame_number(), 0);
1246 EXPECT_LE(host_impl
->active_tree()->source_frame_number(), 1);
1250 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1251 // We should only draw for the readback and the replacement commit.
1252 // The replacement commit will also be the first commit after output
1253 // surface initialization.
1254 EXPECT_GE(host_impl
->active_tree()->source_frame_number(), 0);
1255 EXPECT_LE(host_impl
->active_tree()->source_frame_number(), 1);
1258 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1259 bool result
) OVERRIDE
{
1260 // We should only swap for the replacement commit.
1261 EXPECT_EQ(host_impl
->active_tree()->source_frame_number(), 1);
1266 int times_output_surface_created_
;
1269 SINGLE_AND_MULTI_THREAD_TEST_F(
1270 LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
);
1272 // This test verifies that losing an output surface during a
1273 // simultaneous readback and forced redraw works and does not deadlock.
1274 class LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw
1275 : public LayerTreeHostContextTest
{
1277 static const int kFirstOutputSurfaceInitSourceFrameNumber
= 0;
1278 static const int kReadbackSourceFrameNumber
= 1;
1279 static const int kReadbackReplacementSourceFrameNumber
= 2;
1280 static const int kSecondOutputSurfaceInitSourceFrameNumber
= 3;
1282 LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw()
1283 : did_react_to_first_commit_(false) {}
1285 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1286 // This enables forced draws after a single prepare to draw failure.
1287 settings
->timeout_and_draw_when_animation_checkerboards
= true;
1288 settings
->maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
1291 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1293 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1294 LayerTreeHostImpl::FrameData
* frame_data
,
1295 bool result
) OVERRIDE
{
1296 int sfn
= host_impl
->active_tree()->source_frame_number();
1297 EXPECT_TRUE(sfn
== kFirstOutputSurfaceInitSourceFrameNumber
||
1298 sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1299 sfn
== kReadbackSourceFrameNumber
)
1302 // Before we react to the failed draw by initiating the forced draw
1303 // sequence, start a readback on the main thread and then lose the context
1304 // to start output surface initialization all at the same time.
1305 if (sfn
== kFirstOutputSurfaceInitSourceFrameNumber
&&
1306 !did_react_to_first_commit_
) {
1307 did_react_to_first_commit_
= true;
1308 PostReadbackToMainThread();
1315 virtual void InitializedRendererOnThread(LayerTreeHostImpl
* host_impl
,
1316 bool success
) OVERRIDE
{
1317 // -1 is for the first output surface initialization.
1318 int sfn
= host_impl
->active_tree()->source_frame_number();
1319 EXPECT_TRUE(sfn
== -1 || sfn
== kReadbackReplacementSourceFrameNumber
)
1323 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1324 // We should only draw the first commit after output surface initialization
1325 // and attempt to draw the readback commit (which will fail).
1326 // All others should abort because the output surface is lost.
1327 int sfn
= host_impl
->active_tree()->source_frame_number();
1328 EXPECT_TRUE(sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1329 sfn
== kReadbackSourceFrameNumber
)
1333 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1334 bool result
) OVERRIDE
{
1335 // We should only swap the first commit after the second output surface
1337 int sfn
= host_impl
->active_tree()->source_frame_number();
1338 EXPECT_TRUE(sfn
== kSecondOutputSurfaceInitSourceFrameNumber
) << sfn
;
1342 virtual void AfterTest() OVERRIDE
{}
1344 int did_react_to_first_commit_
;
1347 MULTI_THREAD_TEST_F(
1348 LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw
);
1350 // This test verifies that losing an output surface right before a
1351 // simultaneous readback and forced redraw works and does not deadlock.
1352 class LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit
1353 : public LayerTreeHostContextTest
{
1355 static const int kFirstOutputSurfaceInitSourceFrameNumber
= 0;
1356 static const int kReadbackSourceFrameNumber
= 1;
1357 static const int kForcedDrawCommitSourceFrameNumber
= 2;
1358 static const int kSecondOutputSurfaceInitSourceFrameNumber
= 2;
1360 LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit()
1361 : did_lose_context_(false) {}
1363 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1364 // This enables forced draws after a single prepare to draw failure.
1365 settings
->timeout_and_draw_when_animation_checkerboards
= true;
1366 settings
->maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
1369 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1371 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1372 LayerTreeHostImpl::FrameData
* frame_data
,
1373 bool result
) OVERRIDE
{
1374 int sfn
= host_impl
->active_tree()->source_frame_number();
1375 EXPECT_TRUE(sfn
== kFirstOutputSurfaceInitSourceFrameNumber
||
1376 sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1377 sfn
== kReadbackSourceFrameNumber
)
1380 // Before we react to the failed draw by initiating the forced draw
1381 // sequence, start a readback on the main thread and then lose the context
1382 // to start output surface initialization all at the same time.
1383 if (sfn
== kFirstOutputSurfaceInitSourceFrameNumber
&& !did_lose_context_
) {
1384 did_lose_context_
= true;
1388 // Returning false will result in a forced draw.
1392 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1393 EXPECT_TRUE(succeeded
);
1394 if (layer_tree_host()->source_frame_number() > 0) {
1395 // Perform a readback right after the second output surface
1398 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
1402 virtual void InitializedRendererOnThread(LayerTreeHostImpl
* host_impl
,
1403 bool success
) OVERRIDE
{
1404 // -1 is for the first output surface initialization.
1405 int sfn
= host_impl
->active_tree()->source_frame_number();
1406 EXPECT_TRUE(sfn
== -1 || sfn
== kFirstOutputSurfaceInitSourceFrameNumber
)
1410 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1411 // We should only draw the first commit after output surface initialization
1412 // and attempt to draw the readback commit (which will fail).
1413 // All others should abort because the output surface is lost.
1414 int sfn
= host_impl
->active_tree()->source_frame_number();
1415 EXPECT_TRUE(sfn
== kForcedDrawCommitSourceFrameNumber
||
1416 sfn
== kReadbackSourceFrameNumber
)
1420 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1421 bool result
) OVERRIDE
{
1422 // We should only swap the first commit after the second output surface
1424 int sfn
= host_impl
->active_tree()->source_frame_number();
1425 EXPECT_TRUE(sfn
== kForcedDrawCommitSourceFrameNumber
) << sfn
;
1429 virtual void AfterTest() OVERRIDE
{}
1431 int did_lose_context_
;
1434 MULTI_THREAD_TEST_F(
1435 LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit
);
1437 class ImplSidePaintingLayerTreeHostContextTest
1438 : public LayerTreeHostContextTest
{
1440 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1441 settings
->impl_side_painting
= true;
1445 class LayerTreeHostContextTestImplSidePainting
1446 : public ImplSidePaintingLayerTreeHostContextTest
{
1448 virtual void SetupTree() OVERRIDE
{
1449 scoped_refptr
<Layer
> root
= Layer::Create();
1450 root
->SetBounds(gfx::Size(10, 10));
1451 root
->SetAnchorPoint(gfx::PointF());
1452 root
->SetIsDrawable(true);
1454 scoped_refptr
<PictureLayer
> picture
= PictureLayer::Create(&client_
);
1455 picture
->SetBounds(gfx::Size(10, 10));
1456 picture
->SetAnchorPoint(gfx::PointF());
1457 picture
->SetIsDrawable(true);
1458 root
->AddChild(picture
);
1460 layer_tree_host()->SetRootLayer(root
);
1461 LayerTreeHostContextTest::SetupTree();
1464 virtual void BeginTest() OVERRIDE
{
1465 times_to_lose_during_commit_
= 1;
1466 PostSetNeedsCommitToMainThread();
1469 virtual void AfterTest() OVERRIDE
{}
1471 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1472 EXPECT_TRUE(succeeded
);
1477 FakeContentLayerClient client_
;
1480 MULTI_THREAD_TEST_F(LayerTreeHostContextTestImplSidePainting
);
1482 class ScrollbarLayerLostContext
: public LayerTreeHostContextTest
{
1484 ScrollbarLayerLostContext() : commits_(0) {}
1486 virtual void BeginTest() OVERRIDE
{
1487 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
1488 scrollbar_layer_
= FakePaintedScrollbarLayer::Create(
1489 false, true, scroll_layer
->id());
1490 scrollbar_layer_
->SetBounds(gfx::Size(10, 100));
1491 layer_tree_host()->root_layer()->AddChild(scrollbar_layer_
);
1492 layer_tree_host()->root_layer()->AddChild(scroll_layer
);
1493 PostSetNeedsCommitToMainThread();
1496 virtual void AfterTest() OVERRIDE
{}
1498 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1499 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1504 // First (regular) update, we should upload 2 resources (thumb, and
1506 EXPECT_EQ(1, scrollbar_layer_
->update_count());
1510 // Second update, after the lost context, we should still upload 2
1511 // resources even if the contents haven't changed.
1512 EXPECT_EQ(2, scrollbar_layer_
->update_count());
1516 // Single thread proxy issues extra commits after context lost.
1517 // http://crbug.com/287250
1518 if (HasImplThread())
1528 scoped_refptr
<FakePaintedScrollbarLayer
> scrollbar_layer_
;
1531 SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext
);
1533 class UIResourceLostTest
: public LayerTreeHostContextTest
{
1535 UIResourceLostTest() : time_step_(0) {}
1536 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1537 settings
->texture_id_allocation_chunk_size
= 1;
1539 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1540 virtual void AfterTest() OVERRIDE
{}
1542 // This is called on the main thread after each commit and
1543 // DidActivateTreeOnThread, with the value of time_step_ at the time
1544 // of the call to DidActivateTreeOnThread. Similar tests will do
1545 // work on the main thread in DidCommit but that is unsuitable because
1546 // the main thread work for these tests must happen after
1547 // DidActivateTreeOnThread, which happens after DidCommit with impl-side
1549 virtual void StepCompleteOnMainThread(int time_step
) = 0;
1551 // Called after DidActivateTreeOnThread. If this is done during the commit,
1552 // the call to StepCompleteOnMainThread will not occur until after
1553 // the commit completes, because the main thread is blocked.
1554 void PostStepCompleteToMainThread() {
1555 proxy()->MainThreadTaskRunner()->PostTask(
1558 &UIResourceLostTest::StepCompleteOnMainThreadInternal
,
1559 base::Unretained(this),
1563 void PostLoseContextToImplThread() {
1564 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1565 base::SingleThreadTaskRunner
* task_runner
=
1566 HasImplThread() ? ImplThreadTaskRunner()
1567 : base::MessageLoopProxy::current();
1568 task_runner
->PostTask(
1571 &LayerTreeHostContextTest::LoseContext
,
1572 base::Unretained(this)));
1577 scoped_ptr
<FakeScopedUIResource
> ui_resource_
;
1580 void StepCompleteOnMainThreadInternal(int step
) {
1581 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1582 StepCompleteOnMainThread(step
);
1586 class UIResourceLostTestSimple
: public UIResourceLostTest
{
1588 // This is called when the commit is complete and the new layer tree has been
1590 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) = 0;
1592 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1593 if (!layer_tree_host()->settings().impl_side_painting
) {
1594 StepCompleteOnImplThread(impl
);
1595 PostStepCompleteToMainThread();
1600 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1601 if (layer_tree_host()->settings().impl_side_painting
) {
1602 StepCompleteOnImplThread(impl
);
1603 PostStepCompleteToMainThread();
1609 // Losing context after an UI resource has been created.
1610 class UIResourceLostAfterCommit
: public UIResourceLostTestSimple
{
1612 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1613 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1616 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1617 // Expects a valid UIResourceId.
1618 EXPECT_NE(0, ui_resource_
->id());
1619 PostSetNeedsCommitToMainThread();
1622 // Release resource before ending the test.
1623 ui_resource_
.reset();
1627 // Single thread proxy issues extra commits after context lost.
1628 // http://crbug.com/287250
1629 if (HasImplThread())
1637 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1638 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1639 switch (time_step_
) {
1641 // The resource should have been created on LTHI after the commit.
1642 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1643 PostSetNeedsCommitToMainThread();
1649 // The resources should have been recreated. The bitmap callback should
1650 // have been called once with the resource_lost flag set to true.
1651 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1652 // Resource Id on the impl-side have been recreated as well. Note
1653 // that the same UIResourceId persists after the context lost.
1654 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1655 PostSetNeedsCommitToMainThread();
1661 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostAfterCommit
);
1663 // Losing context before UI resource requests can be commited. Three sequences
1664 // of creation/deletion are considered:
1665 // 1. Create one resource -> Context Lost => Expect the resource to have been
1667 // 2. Delete an exisiting resource (test_id0_) -> create a second resource
1668 // (test_id1_) -> Context Lost => Expect the test_id0_ to be removed and
1669 // test_id1_ to have been created.
1670 // 3. Create one resource -> Delete that same resource -> Context Lost => Expect
1671 // the resource to not exist in the manager.
1672 class UIResourceLostBeforeCommit
: public UIResourceLostTestSimple
{
1674 UIResourceLostBeforeCommit()
1678 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1681 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1682 // Lose the context on the impl thread before the commit.
1683 PostLoseContextToImplThread();
1687 // Currently one resource has been created.
1688 test_id0_
= ui_resource_
->id();
1689 // Delete this resource.
1690 ui_resource_
.reset();
1691 // Create another resource.
1692 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1693 test_id1_
= ui_resource_
->id();
1694 // Sanity check that two resource creations return different ids.
1695 EXPECT_NE(test_id0_
, test_id1_
);
1696 // Lose the context on the impl thread before the commit.
1697 PostLoseContextToImplThread();
1700 // Clear the manager of resources.
1701 ui_resource_
.reset();
1702 PostSetNeedsCommitToMainThread();
1706 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1707 test_id0_
= ui_resource_
->id();
1708 // Sanity check the UIResourceId should not be 0.
1709 EXPECT_NE(0, test_id0_
);
1710 // Usually ScopedUIResource are deleted from the manager in their
1711 // destructor (so usually ui_resource_.reset()). But here we need
1712 // ui_resource_ for the next step, so call DeleteUIResource directly.
1713 layer_tree_host()->DeleteUIResource(test_id0_
);
1714 // Delete the resouce and then lose the context.
1715 PostLoseContextToImplThread();
1718 // Release resource before ending the test.
1719 ui_resource_
.reset();
1723 // Single thread proxy issues extra commits after context lost.
1724 // http://crbug.com/287250
1725 if (HasImplThread())
1733 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1734 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1735 switch (time_step_
) {
1737 // Sequence 1 (continued):
1738 // The first context lost happens before the resources were created,
1739 // and because it resulted in no resources being destroyed, it does not
1740 // trigger resource re-creation.
1741 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1742 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1743 // Resource Id on the impl-side has been created.
1744 PostSetNeedsCommitToMainThread();
1747 // Sequence 2 (continued):
1748 // The previous resource should have been deleted.
1749 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id0_
));
1750 if (HasImplThread()) {
1751 // The second resource should have been created.
1752 EXPECT_NE(0u, impl
->ResourceIdForUIResource(test_id1_
));
1754 // The extra commit that happens at context lost in the single thread
1755 // proxy changes the timing so that the resource has been destroyed.
1756 // http://crbug.com/287250
1757 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id1_
));
1759 // The second resource called the resource callback once and since the
1760 // context is lost, a "resource lost" callback was also issued.
1761 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1762 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1765 // Sequence 3 (continued):
1766 // Expect the resource callback to have been called once.
1767 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1768 // No "resource lost" callbacks.
1769 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1770 // The UI resource id should not be valid
1771 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id0_
));
1777 UIResourceId test_id0_
;
1778 UIResourceId test_id1_
;
1781 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit
);
1783 // Losing UI resource before the pending trees is activated but after the
1784 // commit. Impl-side-painting only.
1785 class UIResourceLostBeforeActivateTree
: public UIResourceLostTest
{
1786 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1787 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1790 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1791 PostSetNeedsCommitToMainThread();
1794 test_id_
= ui_resource_
->id();
1795 ui_resource_
.reset();
1796 PostSetNeedsCommitToMainThread();
1799 // Release resource before ending the test.
1800 ui_resource_
.reset();
1804 // Make sure no extra commits happened.
1809 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1810 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1811 switch (time_step_
) {
1813 PostSetNeedsCommitToMainThread();
1816 PostSetNeedsCommitToMainThread();
1821 virtual void WillActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1822 switch (time_step_
) {
1824 // The resource creation callback has been called.
1825 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1826 // The resource is not yet lost (sanity check).
1827 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1828 // The resource should not have been created yet on the impl-side.
1829 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1838 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1839 LayerTreeHostContextTest::DidActivateTreeOnThread(impl
);
1840 switch (time_step_
) {
1842 // The pending requests on the impl-side should have been processed.
1843 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1846 // The "lost resource" callback should have been called once.
1847 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1850 // The resource is deleted and should not be in the manager. Use
1851 // test_id_ since ui_resource_ has been deleted.
1852 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id_
));
1856 PostStepCompleteToMainThread();
1861 UIResourceId test_id_
;
1864 TEST_F(UIResourceLostBeforeActivateTree
,
1865 RunMultiThread_DirectRenderer_ImplSidePaint
) {
1866 RunTest(true, false, true);
1869 TEST_F(UIResourceLostBeforeActivateTree
,
1870 RunMultiThread_DelegatingRenderer_ImplSidePaint
) {
1871 RunTest(true, true, true);
1874 // Resources evicted explicitly and by visibility changes.
1875 class UIResourceLostEviction
: public UIResourceLostTestSimple
{
1877 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1878 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1881 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1882 EXPECT_NE(0, ui_resource_
->id());
1883 PostSetNeedsCommitToMainThread();
1886 // Make the tree not visible.
1887 PostSetVisibleToMainThread(false);
1890 // Release resource before ending the test.
1891 ui_resource_
.reset();
1899 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl
* impl
,
1900 bool visible
) OVERRIDE
{
1901 TestWebGraphicsContext3D
* context
= static_cast<TestContextProvider
*>(
1902 impl
->output_surface()->context_provider().get())->TestContext3d();
1904 // All resources should have been evicted.
1905 ASSERT_EQ(0u, context
->NumTextures());
1906 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1907 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1908 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1909 // Drawing is disabled both because of the evicted resources and
1910 // because the renderer is not visible.
1911 EXPECT_FALSE(impl
->CanDraw());
1912 // Make the renderer visible again.
1913 PostSetVisibleToMainThread(true);
1917 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1918 TestWebGraphicsContext3D
* context
= static_cast<TestContextProvider
*>(
1919 impl
->output_surface()->context_provider().get())->TestContext3d();
1920 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1921 switch (time_step_
) {
1923 // The resource should have been created on LTHI after the commit.
1924 ASSERT_EQ(1u, context
->NumTextures());
1925 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1926 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1927 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1928 EXPECT_TRUE(impl
->CanDraw());
1929 // Evict all UI resources. This will trigger a commit.
1930 impl
->EvictAllUIResources();
1931 ASSERT_EQ(0u, context
->NumTextures());
1932 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1933 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1934 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1935 EXPECT_FALSE(impl
->CanDraw());
1938 // The resource should have been recreated.
1939 ASSERT_EQ(1u, context
->NumTextures());
1940 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1941 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1942 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1943 EXPECT_TRUE(impl
->CanDraw());
1946 // The resource should have been recreated after visibility was
1948 ASSERT_EQ(1u, context
->NumTextures());
1949 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1950 EXPECT_EQ(3, ui_resource_
->resource_create_count
);
1951 EXPECT_EQ(2, ui_resource_
->lost_resource_count
);
1952 EXPECT_TRUE(impl
->CanDraw());
1958 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostEviction
);
1960 class LayerTreeHostContextTestSurfaceCreateCallback
1961 : public LayerTreeHostContextTest
{
1963 LayerTreeHostContextTestSurfaceCreateCallback()
1964 : LayerTreeHostContextTest(),
1965 layer_(FakeContentLayer::Create(&client_
)),
1968 virtual void SetupTree() OVERRIDE
{
1969 layer_
->SetBounds(gfx::Size(10, 20));
1970 layer_tree_host()->SetRootLayer(layer_
);
1971 LayerTreeHostContextTest::SetupTree();
1974 virtual void BeginTest() OVERRIDE
{
1975 PostSetNeedsCommitToMainThread();
1978 virtual void DidCommit() OVERRIDE
{
1979 switch (num_commits_
) {
1981 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1982 layer_tree_host()->SetNeedsCommit();
1985 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1986 layer_tree_host()->SetNeedsCommit();
1989 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1992 EXPECT_EQ(2u, layer_
->output_surface_created_count());
1993 layer_tree_host()->SetNeedsCommit();
1999 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
2000 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
2001 switch (num_commits_
) {
2015 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
2016 EXPECT_TRUE(succeeded
);
2019 virtual void AfterTest() OVERRIDE
{}
2022 FakeContentLayerClient client_
;
2023 scoped_refptr
<FakeContentLayer
> layer_
;
2027 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestSurfaceCreateCallback
);