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
<FakeOutputSurface
> CreateFakeOutputSurfaceForTest(
80 bool fallback
) OVERRIDE
{
81 if (times_to_fail_create_
) {
82 --times_to_fail_create_
;
84 return scoped_ptr
<FakeOutputSurface
>();
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());
98 return FakeOutputSurface::Create3d(context3d
.Pass());
101 scoped_ptr
<TestWebGraphicsContext3D
> CreateOffscreenContext3d() {
103 return scoped_ptr
<TestWebGraphicsContext3D
>();
105 ++times_offscreen_created_
;
107 if (times_to_fail_create_offscreen_
) {
108 --times_to_fail_create_offscreen_
;
109 ExpectCreateToFail();
110 return scoped_ptr
<TestWebGraphicsContext3D
>();
113 scoped_ptr
<TestWebGraphicsContext3D
> offscreen_context3d
=
114 TestWebGraphicsContext3D::Create().Pass();
115 DCHECK(offscreen_context3d
);
116 context3d_
->add_share_group_context(offscreen_context3d
.get());
118 return offscreen_context3d
.Pass();
121 virtual scoped_refptr
<ContextProvider
> OffscreenContextProvider() OVERRIDE
{
122 if (!offscreen_contexts_
.get() ||
123 offscreen_contexts_
->DestroyedOnMainThread()) {
124 offscreen_contexts_
=
125 TestContextProvider::Create(CreateOffscreenContext3d());
127 return offscreen_contexts_
;
130 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
131 LayerTreeHostImpl::FrameData
* frame
,
132 bool result
) OVERRIDE
{
134 if (!times_to_lose_during_draw_
)
137 --times_to_lose_during_draw_
;
140 times_to_fail_create_
= times_to_fail_recreate_
;
141 times_to_fail_recreate_
= 0;
142 times_to_fail_create_offscreen_
= times_to_fail_recreate_offscreen_
;
143 times_to_fail_recreate_offscreen_
= 0;
148 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
149 committed_at_least_once_
= true;
151 if (!times_to_lose_during_commit_
)
153 --times_to_lose_during_commit_
;
156 times_to_fail_create_
= times_to_fail_recreate_
;
157 times_to_fail_recreate_
= 0;
158 times_to_fail_create_offscreen_
= times_to_fail_recreate_offscreen_
;
159 times_to_fail_recreate_offscreen_
= 0;
162 virtual void DidFailToInitializeOutputSurface() OVERRIDE
{
163 ++times_create_failed_
;
166 virtual void TearDown() OVERRIDE
{
167 LayerTreeTest::TearDown();
168 EXPECT_EQ(times_to_expect_create_failed_
, times_create_failed_
);
171 void ExpectCreateToFail() { ++times_to_expect_create_failed_
; }
174 TestWebGraphicsContext3D
* context3d_
;
175 int times_to_fail_create_
;
176 int times_to_lose_during_commit_
;
177 int times_to_lose_during_draw_
;
178 int times_to_fail_recreate_
;
179 int times_to_fail_create_offscreen_
;
180 int times_to_fail_recreate_offscreen_
;
181 int times_to_expect_create_failed_
;
182 int times_create_failed_
;
183 int times_offscreen_created_
;
184 bool committed_at_least_once_
;
185 bool context_should_support_io_surface_
;
186 bool fallback_context_works_
;
188 scoped_refptr
<TestContextProvider
> offscreen_contexts_
;
191 class LayerTreeHostContextTestLostContextSucceeds
192 : public LayerTreeHostContextTest
{
194 LayerTreeHostContextTestLostContextSucceeds()
195 : LayerTreeHostContextTest(),
198 num_losses_last_test_case_(-1),
199 recovered_context_(true),
200 first_initialized_(false) {}
202 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
204 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
205 EXPECT_TRUE(succeeded
);
207 if (first_initialized_
)
210 first_initialized_
= true;
212 recovered_context_
= true;
215 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(9u, test_case_
); }
217 virtual void DidCommitAndDrawFrame() OVERRIDE
{
218 // If the last frame had a context loss, then we'll commit again to
220 if (!recovered_context_
)
222 if (times_to_lose_during_commit_
)
224 if (times_to_lose_during_draw_
)
227 recovered_context_
= false;
229 InvalidateAndSetNeedsCommit();
234 virtual void InvalidateAndSetNeedsCommit() {
235 // Cause damage so we try to draw.
236 layer_tree_host()->root_layer()->SetNeedsDisplay();
237 layer_tree_host()->SetNeedsCommit();
240 bool NextTestCase() {
241 static const TestCase kTests
[] = {
242 // Losing the context and failing to recreate it (or losing it again
243 // immediately) a small number of times should succeed.
244 {1, // times_to_lose_during_commit
245 0, // times_to_lose_during_draw
246 0, // times_to_fail_recreate
247 0, // times_to_fail_recreate_offscreen
248 false, // fallback_context_works
250 {0, // times_to_lose_during_commit
251 1, // times_to_lose_during_draw
252 0, // times_to_fail_recreate
253 0, // times_to_fail_recreate_offscreen
254 false, // fallback_context_works
256 {1, // times_to_lose_during_commit
257 0, // times_to_lose_during_draw
258 3, // times_to_fail_recreate
259 0, // times_to_fail_recreate_offscreen
260 false, // fallback_context_works
262 {0, // times_to_lose_during_commit
263 1, // times_to_lose_during_draw
264 3, // times_to_fail_recreate
265 0, // times_to_fail_recreate_offscreen
266 false, // fallback_context_works
268 {1, // times_to_lose_during_commit
269 0, // times_to_lose_during_draw
270 0, // times_to_fail_recreate
271 3, // times_to_fail_recreate_offscreen
272 false, // fallback_context_works
274 {0, // times_to_lose_during_commit
275 1, // times_to_lose_during_draw
276 0, // times_to_fail_recreate
277 3, // times_to_fail_recreate_offscreen
278 false, // fallback_context_works
280 // Losing the context and recreating it any number of times should
282 {10, // times_to_lose_during_commit
283 0, // times_to_lose_during_draw
284 0, // times_to_fail_recreate
285 0, // times_to_fail_recreate_offscreen
286 false, // fallback_context_works
288 {0, // times_to_lose_during_commit
289 10, // times_to_lose_during_draw
290 0, // times_to_fail_recreate
291 0, // times_to_fail_recreate_offscreen
292 false, // fallback_context_works
294 // Losing the context, failing to reinitialize it, and making a fallback
295 // context should work.
296 {0, // times_to_lose_during_commit
297 1, // times_to_lose_during_draw
298 0, // times_to_fail_recreate
299 0, // times_to_fail_recreate_offscreen
300 true, // fallback_context_works
303 if (test_case_
>= arraysize(kTests
))
305 // Make sure that we lost our context at least once in the last test run so
306 // the test did something.
307 EXPECT_GT(num_losses_
, num_losses_last_test_case_
);
308 num_losses_last_test_case_
= num_losses_
;
310 times_to_lose_during_commit_
=
311 kTests
[test_case_
].times_to_lose_during_commit
;
312 times_to_lose_during_draw_
= kTests
[test_case_
].times_to_lose_during_draw
;
313 times_to_fail_recreate_
= kTests
[test_case_
].times_to_fail_recreate
;
314 times_to_fail_recreate_offscreen_
=
315 kTests
[test_case_
].times_to_fail_recreate_offscreen
;
316 fallback_context_works_
= kTests
[test_case_
].fallback_context_works
;
322 int times_to_lose_during_commit
;
323 int times_to_lose_during_draw
;
324 int times_to_fail_recreate
;
325 int times_to_fail_recreate_offscreen
;
326 bool fallback_context_works
;
332 int num_losses_last_test_case_
;
333 bool recovered_context_
;
334 bool first_initialized_
;
337 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds
);
339 class LayerTreeHostClientNotReadyDoesNotCreateOutputSurface
340 : public LayerTreeHostContextTest
{
342 LayerTreeHostClientNotReadyDoesNotCreateOutputSurface()
343 : LayerTreeHostContextTest() {}
345 virtual void WillBeginTest() OVERRIDE
{
346 // Override and do not signal SetLayerTreeHostClientReady.
349 virtual void BeginTest() OVERRIDE
{
350 PostSetNeedsCommitToMainThread();
354 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(bool fallback
)
357 return scoped_ptr
<OutputSurface
>();
360 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
364 virtual void AfterTest() OVERRIDE
{
368 MULTI_THREAD_TEST_F(LayerTreeHostClientNotReadyDoesNotCreateOutputSurface
);
370 class LayerTreeHostContextTestLostContextSucceedsWithContent
371 : public LayerTreeHostContextTestLostContextSucceeds
{
373 LayerTreeHostContextTestLostContextSucceedsWithContent()
374 : LayerTreeHostContextTestLostContextSucceeds() {}
376 virtual void SetupTree() OVERRIDE
{
377 root_
= Layer::Create();
378 root_
->SetBounds(gfx::Size(10, 10));
379 root_
->SetAnchorPoint(gfx::PointF());
380 root_
->SetIsDrawable(true);
382 content_
= FakeContentLayer::Create(&client_
);
383 content_
->SetBounds(gfx::Size(10, 10));
384 content_
->SetAnchorPoint(gfx::PointF());
385 content_
->SetIsDrawable(true);
387 content_
->SetForceRenderSurface(true);
388 // Filters require us to create an offscreen context.
389 FilterOperations filters
;
390 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
391 content_
->SetFilters(filters
);
392 content_
->SetBackgroundFilters(filters
);
395 root_
->AddChild(content_
);
397 layer_tree_host()->SetRootLayer(root_
);
398 LayerTreeHostContextTest::SetupTree();
401 virtual void InvalidateAndSetNeedsCommit() OVERRIDE
{
402 // Invalidate the render surface so we don't try to use a cached copy of the
403 // surface. We want to make sure to test the drawing paths for drawing to
405 content_
->SetNeedsDisplay();
406 LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit();
409 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
410 FakeContentLayerImpl
* content_impl
= static_cast<FakeContentLayerImpl
*>(
411 host_impl
->active_tree()->root_layer()->children()[0]);
412 // Even though the context was lost, we should have a resource. The
413 // TestWebGraphicsContext3D ensures that this resource is created with
414 // the active context.
415 EXPECT_TRUE(content_impl
->HaveResourceForTileAt(0, 0));
417 ContextProvider
* contexts
= host_impl
->offscreen_context_provider();
419 ASSERT_TRUE(contexts
);
420 EXPECT_TRUE(contexts
->ContextGL());
421 // TODO(danakj): Make a fake GrContext.
422 // EXPECT_TRUE(contexts->GrContext());
424 EXPECT_FALSE(contexts
);
428 virtual void AfterTest() OVERRIDE
{
429 LayerTreeHostContextTestLostContextSucceeds::AfterTest();
431 // 1 create to start with +
432 // 4 from test cases that lose the offscreen context directly +
433 // 2 from test cases that create a fallback +
434 // All the test cases that recreate both contexts only once
435 // per time it is lost.
436 EXPECT_EQ(4 + 1 + 2 + num_losses_
, times_offscreen_created_
);
438 EXPECT_EQ(0, times_offscreen_created_
);
444 FakeContentLayerClient client_
;
445 scoped_refptr
<Layer
> root_
;
446 scoped_refptr
<ContentLayer
> content_
;
449 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
450 NoSurface_SingleThread_DirectRenderer
) {
451 use_surface_
= false;
452 RunTest(false, false, false);
455 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
456 NoSurface_SingleThread_DelegatingRenderer
) {
457 use_surface_
= false;
458 RunTest(false, true, false);
461 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
462 NoSurface_MultiThread_DirectRenderer_MainThreadPaint
) {
463 use_surface_
= false;
464 RunTest(true, false, false);
467 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
468 NoSurface_MultiThread_DelegatingRenderer_MainThreadPaint
) {
469 use_surface_
= false;
470 RunTest(true, true, false);
473 // Surfaces don't exist with a delegating renderer.
474 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
475 WithSurface_SingleThread_DirectRenderer
) {
477 RunTest(false, false, false);
480 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
481 WithSurface_MultiThread_DirectRenderer_MainThreadPaint
) {
483 RunTest(true, false, false);
486 class LayerTreeHostContextTestCreateOutputSurfaceFails
487 : public LayerTreeHostContextTest
{
489 // Run a test that initially fails OutputSurface creation |times_to_fail|
490 // times. If |expect_fallback_attempt| is |true|, an attempt to create a
491 // fallback/software OutputSurface is expected to occur.
492 LayerTreeHostContextTestCreateOutputSurfaceFails(int times_to_fail
,
493 bool expect_fallback_attempt
,
494 bool expect_to_give_up
)
495 : times_to_fail_(times_to_fail
),
496 expect_fallback_attempt_(expect_fallback_attempt
),
497 expect_to_give_up_(expect_to_give_up
),
498 did_attempt_fallback_(false),
499 times_initialized_(0) {}
501 virtual void BeginTest() OVERRIDE
{
502 times_to_fail_create_
= times_to_fail_
;
503 PostSetNeedsCommitToMainThread();
506 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(bool fallback
)
508 scoped_ptr
<OutputSurface
> surface
=
509 LayerTreeHostContextTest::CreateOutputSurface(fallback
);
512 EXPECT_EQ(times_to_fail_
, times_create_failed_
);
514 did_attempt_fallback_
= fallback
;
515 return surface
.Pass();
518 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
520 times_initialized_
++;
525 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
529 virtual void AfterTest() OVERRIDE
{
530 EXPECT_EQ(times_to_fail_
, times_create_failed_
);
531 EXPECT_EQ(expect_to_give_up_
, times_initialized_
== 0);
532 EXPECT_EQ(expect_fallback_attempt_
, did_attempt_fallback_
);
537 bool expect_fallback_attempt_
;
538 bool expect_to_give_up_
;
539 bool did_attempt_fallback_
;
540 int times_initialized_
;
543 class LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
544 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
546 LayerTreeHostContextTestCreateOutputSurfaceFailsOnce()
547 : LayerTreeHostContextTestCreateOutputSurfaceFails(1, false, false) {}
550 SINGLE_AND_MULTI_THREAD_TEST_F(
551 LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
);
553 // After 4 failures we expect an attempt to create a fallback/software
555 class LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback
556 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
558 LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback()
559 : LayerTreeHostContextTestCreateOutputSurfaceFails(4, true, false) {}
562 SINGLE_AND_MULTI_THREAD_TEST_F(
563 LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback
);
565 // If we fail that often, we should be giving up cleanly.
566 class LayerTreeHostContextTestCreateOutputSurfaceIsHopeless
567 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
569 LayerTreeHostContextTestCreateOutputSurfaceIsHopeless()
570 : LayerTreeHostContextTestCreateOutputSurfaceFails(5, true, true) {}
573 SINGLE_AND_MULTI_THREAD_TEST_F(
574 LayerTreeHostContextTestCreateOutputSurfaceIsHopeless
);
577 class LayerTreeHostContextTestOffscreenContextFails
578 : public LayerTreeHostContextTest
{
580 virtual void SetupTree() OVERRIDE
{
581 root_
= Layer::Create();
582 root_
->SetBounds(gfx::Size(10, 10));
583 root_
->SetAnchorPoint(gfx::PointF());
584 root_
->SetIsDrawable(true);
586 content_
= FakeContentLayer::Create(&client_
);
587 content_
->SetBounds(gfx::Size(10, 10));
588 content_
->SetAnchorPoint(gfx::PointF());
589 content_
->SetIsDrawable(true);
590 content_
->SetForceRenderSurface(true);
591 // Filters require us to create an offscreen context.
592 FilterOperations filters
;
593 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
594 content_
->SetFilters(filters
);
595 content_
->SetBackgroundFilters(filters
);
597 root_
->AddChild(content_
);
599 layer_tree_host()->SetRootLayer(root_
);
600 LayerTreeHostContextTest::SetupTree();
603 virtual void BeginTest() OVERRIDE
{
604 times_to_fail_create_offscreen_
= 1;
605 PostSetNeedsCommitToMainThread();
608 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
609 ContextProvider
* contexts
= host_impl
->offscreen_context_provider();
610 EXPECT_FALSE(contexts
);
612 // This did not lead to create failure.
613 times_to_expect_create_failed_
= 0;
617 virtual void AfterTest() OVERRIDE
{}
620 FakeContentLayerClient client_
;
621 scoped_refptr
<Layer
> root_
;
622 scoped_refptr
<ContentLayer
> content_
;
625 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestOffscreenContextFails
);
627 class LayerTreeHostContextTestLostContextFails
628 : public LayerTreeHostContextTest
{
630 LayerTreeHostContextTestLostContextFails()
631 : LayerTreeHostContextTest(), num_commits_(0), first_initialized_(false) {
632 times_to_lose_during_commit_
= 1;
635 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
637 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
638 if (first_initialized_
) {
639 EXPECT_FALSE(succeeded
);
642 first_initialized_
= true;
646 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
647 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
650 if (num_commits_
== 1) {
651 // When the context is ok, we should have these things.
652 EXPECT_TRUE(host_impl
->output_surface());
653 EXPECT_TRUE(host_impl
->renderer());
654 EXPECT_TRUE(host_impl
->resource_provider());
658 // When context recreation fails we shouldn't be left with any of them.
659 EXPECT_FALSE(host_impl
->output_surface());
660 EXPECT_FALSE(host_impl
->renderer());
661 EXPECT_FALSE(host_impl
->resource_provider());
664 virtual void AfterTest() OVERRIDE
{}
668 bool first_initialized_
;
671 class LayerTreeHostContextTestLostContextAndEvictTextures
672 : public LayerTreeHostContextTest
{
674 LayerTreeHostContextTestLostContextAndEvictTextures()
675 : LayerTreeHostContextTest(),
676 layer_(FakeContentLayer::Create(&client_
)),
680 virtual void SetupTree() OVERRIDE
{
681 layer_
->SetBounds(gfx::Size(10, 20));
682 layer_tree_host()->SetRootLayer(layer_
);
683 LayerTreeHostContextTest::SetupTree();
686 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
688 void PostEvictTextures() {
689 if (HasImplThread()) {
690 ImplThreadTaskRunner()->PostTask(
692 base::Bind(&LayerTreeHostContextTestLostContextAndEvictTextures::
693 EvictTexturesOnImplThread
,
694 base::Unretained(this)));
696 DebugScopedSetImplThread
impl(proxy());
697 EvictTexturesOnImplThread();
701 void EvictTexturesOnImplThread() {
702 impl_host_
->EvictTexturesForTesting();
703 if (lose_after_evict_
)
707 virtual void DidCommitAndDrawFrame() OVERRIDE
{
708 if (num_commits_
> 1)
710 EXPECT_TRUE(layer_
->HaveBackingAt(0, 0));
714 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
715 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
716 if (num_commits_
> 1)
719 if (!lose_after_evict_
)
724 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
725 EXPECT_TRUE(succeeded
);
729 virtual void AfterTest() OVERRIDE
{}
732 bool lose_after_evict_
;
733 FakeContentLayerClient client_
;
734 scoped_refptr
<FakeContentLayer
> layer_
;
735 LayerTreeHostImpl
* impl_host_
;
739 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
740 LoseAfterEvict_SingleThread_DirectRenderer
) {
741 lose_after_evict_
= true;
742 RunTest(false, false, false);
745 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
746 LoseAfterEvict_SingleThread_DelegatingRenderer
) {
747 lose_after_evict_
= true;
748 RunTest(false, true, false);
751 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
752 LoseAfterEvict_MultiThread_DirectRenderer_MainThreadPaint
) {
753 lose_after_evict_
= true;
754 RunTest(true, false, false);
757 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
758 LoseAfterEvict_MultiThread_DelegatingRenderer_MainThreadPaint
) {
759 lose_after_evict_
= true;
760 RunTest(true, true, false);
763 // Flaky on all platforms, http://crbug.com/310979
764 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
765 DISABLED_LoseAfterEvict_MultiThread_DelegatingRenderer_ImplSidePaint
) {
766 lose_after_evict_
= true;
767 RunTest(true, true, true);
770 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
771 LoseBeforeEvict_SingleThread_DirectRenderer
) {
772 lose_after_evict_
= false;
773 RunTest(false, false, false);
776 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
777 LoseBeforeEvict_SingleThread_DelegatingRenderer
) {
778 lose_after_evict_
= false;
779 RunTest(false, true, false);
782 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
783 LoseBeforeEvict_MultiThread_DirectRenderer_MainThreadPaint
) {
784 lose_after_evict_
= false;
785 RunTest(true, false, false);
788 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
789 LoseBeforeEvict_MultiThread_DirectRenderer_ImplSidePaint
) {
790 lose_after_evict_
= false;
791 RunTest(true, false, true);
794 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
795 LoseBeforeEvict_MultiThread_DelegatingRenderer_MainThreadPaint
) {
796 lose_after_evict_
= false;
797 RunTest(true, true, false);
800 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
801 LoseBeforeEvict_MultiThread_DelegatingRenderer_ImplSidePaint
) {
802 lose_after_evict_
= false;
803 RunTest(true, true, true);
806 class LayerTreeHostContextTestLostContextWhileUpdatingResources
807 : public LayerTreeHostContextTest
{
809 LayerTreeHostContextTestLostContextWhileUpdatingResources()
810 : parent_(FakeContentLayer::Create(&client_
)),
812 times_to_lose_on_end_query_(3) {}
814 virtual scoped_ptr
<TestWebGraphicsContext3D
> CreateContext3d() OVERRIDE
{
815 scoped_ptr
<TestWebGraphicsContext3D
> context
=
816 LayerTreeHostContextTest::CreateContext3d();
817 if (times_to_lose_on_end_query_
) {
818 --times_to_lose_on_end_query_
;
819 context
->set_times_end_query_succeeds(5);
821 return context
.Pass();
824 virtual void SetupTree() OVERRIDE
{
825 parent_
->SetBounds(gfx::Size(num_children_
, 1));
827 for (int i
= 0; i
< num_children_
; i
++) {
828 scoped_refptr
<FakeContentLayer
> child
=
829 FakeContentLayer::Create(&client_
);
830 child
->SetPosition(gfx::PointF(i
, 0.f
));
831 child
->SetBounds(gfx::Size(1, 1));
832 parent_
->AddChild(child
);
835 layer_tree_host()->SetRootLayer(parent_
);
836 LayerTreeHostContextTest::SetupTree();
839 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
841 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
842 EXPECT_EQ(0, times_to_lose_on_end_query_
);
846 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
847 EXPECT_TRUE(succeeded
);
850 virtual void AfterTest() OVERRIDE
{
851 EXPECT_EQ(0, times_to_lose_on_end_query_
);
855 FakeContentLayerClient client_
;
856 scoped_refptr
<FakeContentLayer
> parent_
;
858 int times_to_lose_on_end_query_
;
861 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
862 LayerTreeHostContextTestLostContextWhileUpdatingResources
);
864 class LayerTreeHostContextTestLayersNotified
: public LayerTreeHostContextTest
{
866 LayerTreeHostContextTestLayersNotified()
867 : LayerTreeHostContextTest(), num_commits_(0) {}
869 virtual void SetupTree() OVERRIDE
{
870 root_
= FakeContentLayer::Create(&client_
);
871 child_
= FakeContentLayer::Create(&client_
);
872 grandchild_
= FakeContentLayer::Create(&client_
);
874 root_
->AddChild(child_
);
875 child_
->AddChild(grandchild_
);
877 layer_tree_host()->SetRootLayer(root_
);
878 LayerTreeHostContextTest::SetupTree();
881 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
883 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
884 LayerTreeHostContextTest::DidActivateTreeOnThread(host_impl
);
886 FakeContentLayerImpl
* root
= static_cast<FakeContentLayerImpl
*>(
887 host_impl
->active_tree()->root_layer());
888 FakeContentLayerImpl
* child
=
889 static_cast<FakeContentLayerImpl
*>(root
->children()[0]);
890 FakeContentLayerImpl
* grandchild
=
891 static_cast<FakeContentLayerImpl
*>(child
->children()[0]);
894 switch (num_commits_
) {
896 EXPECT_EQ(0u, root
->lost_output_surface_count());
897 EXPECT_EQ(0u, child
->lost_output_surface_count());
898 EXPECT_EQ(0u, grandchild
->lost_output_surface_count());
899 // Lose the context and struggle to recreate it.
901 times_to_fail_create_
= 1;
904 EXPECT_GE(1u, root
->lost_output_surface_count());
905 EXPECT_GE(1u, child
->lost_output_surface_count());
906 EXPECT_GE(1u, grandchild
->lost_output_surface_count());
914 virtual void AfterTest() OVERRIDE
{}
919 FakeContentLayerClient client_
;
920 scoped_refptr
<FakeContentLayer
> root_
;
921 scoped_refptr
<FakeContentLayer
> child_
;
922 scoped_refptr
<FakeContentLayer
> grandchild_
;
925 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLayersNotified
);
927 class LayerTreeHostContextTestDontUseLostResources
928 : public LayerTreeHostContextTest
{
930 LayerTreeHostContextTestDontUseLostResources() : lost_context_(false) {
931 context_should_support_io_surface_
= true;
933 child_output_surface_
= FakeOutputSurface::Create3d();
934 child_output_surface_
->BindToClient(&output_surface_client_
);
935 child_resource_provider_
= ResourceProvider::Create(
936 child_output_surface_
.get(), NULL
, 0, false, 1);
939 static void EmptyReleaseCallback(unsigned sync_point
, bool lost
) {}
941 virtual void SetupTree() OVERRIDE
{
942 gpu::gles2::GLES2Interface
* gl
=
943 child_output_surface_
->context_provider()->ContextGL();
945 scoped_ptr
<DelegatedFrameData
> frame_data(new DelegatedFrameData
);
947 scoped_ptr
<TestRenderPass
> pass_for_quad
= TestRenderPass::Create();
948 pass_for_quad
->SetNew(
949 // AppendOneOfEveryQuadType() makes a RenderPass quad with this id.
950 RenderPass::Id(2, 1),
951 gfx::Rect(0, 0, 10, 10),
952 gfx::Rect(0, 0, 10, 10),
955 scoped_ptr
<TestRenderPass
> pass
= TestRenderPass::Create();
956 pass
->SetNew(RenderPass::Id(1, 1),
957 gfx::Rect(0, 0, 10, 10),
958 gfx::Rect(0, 0, 10, 10),
960 pass
->AppendOneOfEveryQuadType(child_resource_provider_
.get(),
961 RenderPass::Id(2, 1));
963 frame_data
->render_pass_list
.push_back(pass_for_quad
.PassAs
<RenderPass
>());
964 frame_data
->render_pass_list
.push_back(pass
.PassAs
<RenderPass
>());
966 delegated_resource_collection_
= new DelegatedFrameResourceCollection
;
967 delegated_frame_provider_
= new DelegatedFrameProvider(
968 delegated_resource_collection_
.get(), frame_data
.Pass());
970 ResourceProvider::ResourceId resource
=
971 child_resource_provider_
->CreateResource(
974 ResourceProvider::TextureUsageAny
,
976 ResourceProvider::ScopedWriteLockGL
lock(child_resource_provider_
.get(),
979 gpu::Mailbox mailbox
;
980 gl
->GenMailboxCHROMIUM(mailbox
.name
);
981 GLuint sync_point
= gl
->InsertSyncPointCHROMIUM();
983 scoped_refptr
<Layer
> root
= Layer::Create();
984 root
->SetBounds(gfx::Size(10, 10));
985 root
->SetAnchorPoint(gfx::PointF());
986 root
->SetIsDrawable(true);
988 scoped_refptr
<FakeDelegatedRendererLayer
> delegated
=
989 FakeDelegatedRendererLayer::Create(delegated_frame_provider_
.get());
990 delegated
->SetBounds(gfx::Size(10, 10));
991 delegated
->SetAnchorPoint(gfx::PointF());
992 delegated
->SetIsDrawable(true);
993 root
->AddChild(delegated
);
995 scoped_refptr
<ContentLayer
> content
= ContentLayer::Create(&client_
);
996 content
->SetBounds(gfx::Size(10, 10));
997 content
->SetAnchorPoint(gfx::PointF());
998 content
->SetIsDrawable(true);
999 root
->AddChild(content
);
1001 scoped_refptr
<TextureLayer
> texture
= TextureLayer::CreateForMailbox(NULL
);
1002 texture
->SetBounds(gfx::Size(10, 10));
1003 texture
->SetAnchorPoint(gfx::PointF());
1004 texture
->SetIsDrawable(true);
1005 texture
->SetTextureMailbox(
1006 TextureMailbox(mailbox
, sync_point
),
1007 SingleReleaseCallback::Create(
1008 base::Bind(&LayerTreeHostContextTestDontUseLostResources::
1009 EmptyReleaseCallback
)));
1010 root
->AddChild(texture
);
1012 scoped_refptr
<ContentLayer
> mask
= ContentLayer::Create(&client_
);
1013 mask
->SetBounds(gfx::Size(10, 10));
1014 mask
->SetAnchorPoint(gfx::PointF());
1016 scoped_refptr
<ContentLayer
> content_with_mask
=
1017 ContentLayer::Create(&client_
);
1018 content_with_mask
->SetBounds(gfx::Size(10, 10));
1019 content_with_mask
->SetAnchorPoint(gfx::PointF());
1020 content_with_mask
->SetIsDrawable(true);
1021 content_with_mask
->SetMaskLayer(mask
.get());
1022 root
->AddChild(content_with_mask
);
1024 scoped_refptr
<VideoLayer
> video_color
=
1025 VideoLayer::Create(&color_frame_provider_
);
1026 video_color
->SetBounds(gfx::Size(10, 10));
1027 video_color
->SetAnchorPoint(gfx::PointF());
1028 video_color
->SetIsDrawable(true);
1029 root
->AddChild(video_color
);
1031 scoped_refptr
<VideoLayer
> video_hw
=
1032 VideoLayer::Create(&hw_frame_provider_
);
1033 video_hw
->SetBounds(gfx::Size(10, 10));
1034 video_hw
->SetAnchorPoint(gfx::PointF());
1035 video_hw
->SetIsDrawable(true);
1036 root
->AddChild(video_hw
);
1038 scoped_refptr
<VideoLayer
> video_scaled_hw
=
1039 VideoLayer::Create(&scaled_hw_frame_provider_
);
1040 video_scaled_hw
->SetBounds(gfx::Size(10, 10));
1041 video_scaled_hw
->SetAnchorPoint(gfx::PointF());
1042 video_scaled_hw
->SetIsDrawable(true);
1043 root
->AddChild(video_scaled_hw
);
1045 color_video_frame_
= VideoFrame::CreateColorFrame(
1046 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
1047 hw_video_frame_
= VideoFrame::WrapNativeTexture(
1048 make_scoped_ptr(new VideoFrame::MailboxHolder(
1051 VideoFrame::MailboxHolder::TextureNoLongerNeededCallback())),
1054 gfx::Rect(0, 0, 4, 4),
1057 VideoFrame::ReadPixelsCB(),
1059 scaled_hw_video_frame_
= VideoFrame::WrapNativeTexture(
1060 make_scoped_ptr(new VideoFrame::MailboxHolder(
1063 VideoFrame::MailboxHolder::TextureNoLongerNeededCallback())),
1066 gfx::Rect(0, 0, 3, 2),
1069 VideoFrame::ReadPixelsCB(),
1072 color_frame_provider_
.set_frame(color_video_frame_
);
1073 hw_frame_provider_
.set_frame(hw_video_frame_
);
1074 scaled_hw_frame_provider_
.set_frame(scaled_hw_video_frame_
);
1076 if (!delegating_renderer()) {
1077 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
1078 scoped_refptr
<IOSurfaceLayer
> io_surface
= IOSurfaceLayer::Create();
1079 io_surface
->SetBounds(gfx::Size(10, 10));
1080 io_surface
->SetAnchorPoint(gfx::PointF());
1081 io_surface
->SetIsDrawable(true);
1082 io_surface
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
1083 root
->AddChild(io_surface
);
1087 LayerTreeDebugState debug_state
;
1088 debug_state
.show_property_changed_rects
= true;
1089 layer_tree_host()->SetDebugState(debug_state
);
1091 scoped_refptr
<PaintedScrollbarLayer
> scrollbar
=
1092 PaintedScrollbarLayer::Create(
1093 scoped_ptr
<Scrollbar
>(new FakeScrollbar
).Pass(), content
->id());
1094 scrollbar
->SetBounds(gfx::Size(10, 10));
1095 scrollbar
->SetAnchorPoint(gfx::PointF());
1096 scrollbar
->SetIsDrawable(true);
1097 root
->AddChild(scrollbar
);
1099 layer_tree_host()->SetRootLayer(root
);
1100 LayerTreeHostContextTest::SetupTree();
1103 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1105 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1106 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
1108 if (host_impl
->active_tree()->source_frame_number() == 3) {
1109 // On the third commit we're recovering from context loss. Hardware
1110 // video frames should not be reused by the VideoFrameProvider, but
1111 // software frames can be.
1112 hw_frame_provider_
.set_frame(NULL
);
1113 scaled_hw_frame_provider_
.set_frame(NULL
);
1117 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1118 LayerTreeHostImpl::FrameData
* frame
,
1119 bool result
) OVERRIDE
{
1120 if (host_impl
->active_tree()->source_frame_number() == 2) {
1121 // Lose the context during draw on the second commit. This will cause
1122 // a third commit to recover.
1123 context3d_
->set_times_bind_texture_succeeds(0);
1128 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(bool fallback
)
1130 // This will get called twice:
1131 // First when we create the initial output surface...
1132 if (layer_tree_host()->source_frame_number() > 0) {
1133 // ... and then again after we forced the context to be lost on the third
1134 // frame. Verify this assumption here.
1135 lost_context_
= true;
1136 EXPECT_EQ(layer_tree_host()->source_frame_number(), 3);
1138 return LayerTreeHostContextTest::CreateOutputSurface(fallback
);
1141 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1142 ASSERT_TRUE(layer_tree_host()->hud_layer());
1143 // End the test once we know the 3nd frame drew.
1144 if (layer_tree_host()->source_frame_number() < 4) {
1145 layer_tree_host()->root_layer()->SetNeedsDisplay();
1146 layer_tree_host()->SetNeedsCommit();
1152 virtual void AfterTest() OVERRIDE
{ EXPECT_TRUE(lost_context_
); }
1155 FakeContentLayerClient client_
;
1158 FakeOutputSurfaceClient output_surface_client_
;
1159 scoped_ptr
<FakeOutputSurface
> child_output_surface_
;
1160 scoped_ptr
<ResourceProvider
> child_resource_provider_
;
1162 scoped_refptr
<DelegatedFrameResourceCollection
>
1163 delegated_resource_collection_
;
1164 scoped_refptr
<DelegatedFrameProvider
> delegated_frame_provider_
;
1166 scoped_refptr
<VideoFrame
> color_video_frame_
;
1167 scoped_refptr
<VideoFrame
> hw_video_frame_
;
1168 scoped_refptr
<VideoFrame
> scaled_hw_video_frame_
;
1170 FakeVideoFrameProvider color_frame_provider_
;
1171 FakeVideoFrameProvider hw_frame_provider_
;
1172 FakeVideoFrameProvider scaled_hw_frame_provider_
;
1175 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources
);
1177 class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
1178 : public LayerTreeHostContextTest
{
1180 virtual void BeginTest() OVERRIDE
{
1181 // This must be called immediately after creating LTH, before the first
1182 // OutputSurface is initialized.
1183 ASSERT_TRUE(layer_tree_host()->output_surface_lost());
1185 times_output_surface_created_
= 0;
1187 // Post the SetNeedsCommit before the readback to make sure it is run
1188 // on the main thread before the readback's replacement commit when
1189 // we have a threaded compositor.
1190 PostSetNeedsCommitToMainThread();
1194 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(1, 1));
1195 EXPECT_EQ(!delegating_renderer(), result
);
1196 EXPECT_EQ(1, times_output_surface_created_
);
1199 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1200 EXPECT_TRUE(succeeded
);
1201 ++times_output_surface_created_
;
1204 virtual void DidCommitAndDrawFrame() OVERRIDE
{ EndTest(); }
1206 virtual void AfterTest() OVERRIDE
{
1207 // Should not try to create output surface again after successfully
1208 // created by CompositeAndReadback.
1209 EXPECT_EQ(1, times_output_surface_created_
);
1212 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1213 LayerTreeHostImpl::FrameData
* frame_data
,
1214 bool result
) OVERRIDE
{
1215 EXPECT_GE(host_impl
->active_tree()->source_frame_number(), 0);
1216 EXPECT_LE(host_impl
->active_tree()->source_frame_number(), 1);
1220 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1221 // We should only draw for the readback and the replacement commit.
1222 // The replacement commit will also be the first commit after output
1223 // surface initialization.
1224 EXPECT_GE(host_impl
->active_tree()->source_frame_number(), 0);
1225 EXPECT_LE(host_impl
->active_tree()->source_frame_number(), 1);
1228 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1229 bool result
) OVERRIDE
{
1230 // We should only swap for the replacement commit.
1231 EXPECT_EQ(host_impl
->active_tree()->source_frame_number(), 1);
1236 int times_output_surface_created_
;
1239 SINGLE_AND_MULTI_THREAD_TEST_F(
1240 LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
);
1242 // This test verifies that losing an output surface during a
1243 // simultaneous readback and forced redraw works and does not deadlock.
1244 class LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw
1245 : public LayerTreeHostContextTest
{
1247 static const int kFirstOutputSurfaceInitSourceFrameNumber
= 0;
1248 static const int kReadbackSourceFrameNumber
= 1;
1249 static const int kReadbackReplacementSourceFrameNumber
= 2;
1250 static const int kSecondOutputSurfaceInitSourceFrameNumber
= 3;
1252 LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw()
1253 : did_react_to_first_commit_(false) {}
1255 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1256 // This enables forced draws after a single prepare to draw failure.
1257 settings
->timeout_and_draw_when_animation_checkerboards
= true;
1258 settings
->maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
1261 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1263 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1264 LayerTreeHostImpl::FrameData
* frame_data
,
1265 bool result
) OVERRIDE
{
1266 int sfn
= host_impl
->active_tree()->source_frame_number();
1267 EXPECT_TRUE(sfn
== kFirstOutputSurfaceInitSourceFrameNumber
||
1268 sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1269 sfn
== kReadbackSourceFrameNumber
)
1272 // Before we react to the failed draw by initiating the forced draw
1273 // sequence, start a readback on the main thread and then lose the context
1274 // to start output surface initialization all at the same time.
1275 if (sfn
== kFirstOutputSurfaceInitSourceFrameNumber
&&
1276 !did_react_to_first_commit_
) {
1277 did_react_to_first_commit_
= true;
1278 PostReadbackToMainThread();
1285 virtual void InitializedRendererOnThread(LayerTreeHostImpl
* host_impl
,
1286 bool success
) OVERRIDE
{
1287 // -1 is for the first output surface initialization.
1288 int sfn
= host_impl
->active_tree()->source_frame_number();
1289 EXPECT_TRUE(sfn
== -1 || sfn
== kReadbackReplacementSourceFrameNumber
)
1293 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1294 // We should only draw the first commit after output surface initialization
1295 // and attempt to draw the readback commit (which will fail).
1296 // All others should abort because the output surface is lost.
1297 int sfn
= host_impl
->active_tree()->source_frame_number();
1298 EXPECT_TRUE(sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1299 sfn
== kReadbackSourceFrameNumber
)
1303 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1304 bool result
) OVERRIDE
{
1305 // We should only swap the first commit after the second output surface
1307 int sfn
= host_impl
->active_tree()->source_frame_number();
1308 EXPECT_TRUE(sfn
== kSecondOutputSurfaceInitSourceFrameNumber
) << sfn
;
1312 virtual void AfterTest() OVERRIDE
{}
1314 int did_react_to_first_commit_
;
1317 MULTI_THREAD_TEST_F(
1318 LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw
);
1320 // This test verifies that losing an output surface right before a
1321 // simultaneous readback and forced redraw works and does not deadlock.
1322 class LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit
1323 : public LayerTreeHostContextTest
{
1325 static const int kFirstOutputSurfaceInitSourceFrameNumber
= 0;
1326 static const int kReadbackSourceFrameNumber
= 1;
1327 static const int kForcedDrawCommitSourceFrameNumber
= 2;
1328 static const int kSecondOutputSurfaceInitSourceFrameNumber
= 2;
1330 LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit()
1331 : did_lose_context_(false) {}
1333 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1334 // This enables forced draws after a single prepare to draw failure.
1335 settings
->timeout_and_draw_when_animation_checkerboards
= true;
1336 settings
->maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
1339 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1341 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1342 LayerTreeHostImpl::FrameData
* frame_data
,
1343 bool result
) OVERRIDE
{
1344 int sfn
= host_impl
->active_tree()->source_frame_number();
1345 EXPECT_TRUE(sfn
== kFirstOutputSurfaceInitSourceFrameNumber
||
1346 sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1347 sfn
== kReadbackSourceFrameNumber
)
1350 // Before we react to the failed draw by initiating the forced draw
1351 // sequence, start a readback on the main thread and then lose the context
1352 // to start output surface initialization all at the same time.
1353 if (sfn
== kFirstOutputSurfaceInitSourceFrameNumber
&& !did_lose_context_
) {
1354 did_lose_context_
= true;
1358 // Returning false will result in a forced draw.
1362 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1363 EXPECT_TRUE(succeeded
);
1364 if (layer_tree_host()->source_frame_number() > 0) {
1365 // Perform a readback right after the second output surface
1368 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
1372 virtual void InitializedRendererOnThread(LayerTreeHostImpl
* host_impl
,
1373 bool success
) OVERRIDE
{
1374 // -1 is for the first output surface initialization.
1375 int sfn
= host_impl
->active_tree()->source_frame_number();
1376 EXPECT_TRUE(sfn
== -1 || sfn
== kFirstOutputSurfaceInitSourceFrameNumber
)
1380 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1381 // We should only draw the first commit after output surface initialization
1382 // and attempt to draw the readback commit (which will fail).
1383 // All others should abort because the output surface is lost.
1384 int sfn
= host_impl
->active_tree()->source_frame_number();
1385 EXPECT_TRUE(sfn
== kForcedDrawCommitSourceFrameNumber
||
1386 sfn
== kReadbackSourceFrameNumber
)
1390 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1391 bool result
) OVERRIDE
{
1392 // We should only swap the first commit after the second output surface
1394 int sfn
= host_impl
->active_tree()->source_frame_number();
1395 EXPECT_TRUE(sfn
== kForcedDrawCommitSourceFrameNumber
) << sfn
;
1399 virtual void AfterTest() OVERRIDE
{}
1401 int did_lose_context_
;
1404 MULTI_THREAD_TEST_F(
1405 LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit
);
1407 class ImplSidePaintingLayerTreeHostContextTest
1408 : public LayerTreeHostContextTest
{
1410 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1411 settings
->impl_side_painting
= true;
1415 class LayerTreeHostContextTestImplSidePainting
1416 : public ImplSidePaintingLayerTreeHostContextTest
{
1418 virtual void SetupTree() OVERRIDE
{
1419 scoped_refptr
<Layer
> root
= Layer::Create();
1420 root
->SetBounds(gfx::Size(10, 10));
1421 root
->SetAnchorPoint(gfx::PointF());
1422 root
->SetIsDrawable(true);
1424 scoped_refptr
<PictureLayer
> picture
= PictureLayer::Create(&client_
);
1425 picture
->SetBounds(gfx::Size(10, 10));
1426 picture
->SetAnchorPoint(gfx::PointF());
1427 picture
->SetIsDrawable(true);
1428 root
->AddChild(picture
);
1430 layer_tree_host()->SetRootLayer(root
);
1431 LayerTreeHostContextTest::SetupTree();
1434 virtual void BeginTest() OVERRIDE
{
1435 times_to_lose_during_commit_
= 1;
1436 PostSetNeedsCommitToMainThread();
1439 virtual void AfterTest() OVERRIDE
{}
1441 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1442 EXPECT_TRUE(succeeded
);
1447 FakeContentLayerClient client_
;
1450 MULTI_THREAD_TEST_F(LayerTreeHostContextTestImplSidePainting
);
1452 class ScrollbarLayerLostContext
: public LayerTreeHostContextTest
{
1454 ScrollbarLayerLostContext() : commits_(0) {}
1456 virtual void BeginTest() OVERRIDE
{
1457 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
1459 FakePaintedScrollbarLayer::Create(false, true, scroll_layer
->id());
1460 scrollbar_layer_
->SetBounds(gfx::Size(10, 100));
1461 layer_tree_host()->root_layer()->AddChild(scrollbar_layer_
);
1462 layer_tree_host()->root_layer()->AddChild(scroll_layer
);
1463 PostSetNeedsCommitToMainThread();
1466 virtual void AfterTest() OVERRIDE
{}
1468 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1469 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1474 // First (regular) update, we should upload 2 resources (thumb, and
1476 EXPECT_EQ(1, scrollbar_layer_
->update_count());
1480 // Second update, after the lost context, we should still upload 2
1481 // resources even if the contents haven't changed.
1482 EXPECT_EQ(2, scrollbar_layer_
->update_count());
1486 // Single thread proxy issues extra commits after context lost.
1487 // http://crbug.com/287250
1488 if (HasImplThread())
1498 scoped_refptr
<FakePaintedScrollbarLayer
> scrollbar_layer_
;
1501 SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext
);
1503 class UIResourceLostTest
: public LayerTreeHostContextTest
{
1505 UIResourceLostTest() : time_step_(0) {}
1506 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1507 settings
->texture_id_allocation_chunk_size
= 1;
1509 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1510 virtual void AfterTest() OVERRIDE
{}
1512 // This is called on the main thread after each commit and
1513 // DidActivateTreeOnThread, with the value of time_step_ at the time
1514 // of the call to DidActivateTreeOnThread. Similar tests will do
1515 // work on the main thread in DidCommit but that is unsuitable because
1516 // the main thread work for these tests must happen after
1517 // DidActivateTreeOnThread, which happens after DidCommit with impl-side
1519 virtual void StepCompleteOnMainThread(int time_step
) = 0;
1521 // Called after DidActivateTreeOnThread. If this is done during the commit,
1522 // the call to StepCompleteOnMainThread will not occur until after
1523 // the commit completes, because the main thread is blocked.
1524 void PostStepCompleteToMainThread() {
1525 proxy()->MainThreadTaskRunner()->PostTask(
1527 base::Bind(&UIResourceLostTest::StepCompleteOnMainThreadInternal
,
1528 base::Unretained(this),
1532 void PostLoseContextToImplThread() {
1533 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1534 base::SingleThreadTaskRunner
* task_runner
=
1535 HasImplThread() ? ImplThreadTaskRunner()
1536 : base::MessageLoopProxy::current();
1537 task_runner
->PostTask(FROM_HERE
,
1538 base::Bind(&LayerTreeHostContextTest::LoseContext
,
1539 base::Unretained(this)));
1544 scoped_ptr
<FakeScopedUIResource
> ui_resource_
;
1547 void StepCompleteOnMainThreadInternal(int step
) {
1548 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1549 StepCompleteOnMainThread(step
);
1553 class UIResourceLostTestSimple
: public UIResourceLostTest
{
1555 // This is called when the commit is complete and the new layer tree has been
1557 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) = 0;
1559 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1560 if (!layer_tree_host()->settings().impl_side_painting
) {
1561 StepCompleteOnImplThread(impl
);
1562 PostStepCompleteToMainThread();
1567 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1568 if (layer_tree_host()->settings().impl_side_painting
) {
1569 StepCompleteOnImplThread(impl
);
1570 PostStepCompleteToMainThread();
1576 // Losing context after an UI resource has been created.
1577 class UIResourceLostAfterCommit
: public UIResourceLostTestSimple
{
1579 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1580 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1583 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1584 // Expects a valid UIResourceId.
1585 EXPECT_NE(0, ui_resource_
->id());
1586 PostSetNeedsCommitToMainThread();
1589 // Release resource before ending the test.
1590 ui_resource_
.reset();
1594 // Single thread proxy issues extra commits after context lost.
1595 // http://crbug.com/287250
1596 if (HasImplThread())
1604 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1605 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1606 switch (time_step_
) {
1608 // The resource should have been created on LTHI after the commit.
1609 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1610 PostSetNeedsCommitToMainThread();
1616 // The resources should have been recreated. The bitmap callback should
1617 // have been called once with the resource_lost flag set to true.
1618 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1619 // Resource Id on the impl-side have been recreated as well. Note
1620 // that the same UIResourceId persists after the context lost.
1621 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1622 PostSetNeedsCommitToMainThread();
1628 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostAfterCommit
);
1630 // Losing context before UI resource requests can be commited. Three sequences
1631 // of creation/deletion are considered:
1632 // 1. Create one resource -> Context Lost => Expect the resource to have been
1634 // 2. Delete an exisiting resource (test_id0_) -> create a second resource
1635 // (test_id1_) -> Context Lost => Expect the test_id0_ to be removed and
1636 // test_id1_ to have been created.
1637 // 3. Create one resource -> Delete that same resource -> Context Lost => Expect
1638 // the resource to not exist in the manager.
1639 class UIResourceLostBeforeCommit
: public UIResourceLostTestSimple
{
1641 UIResourceLostBeforeCommit() : test_id0_(0), test_id1_(0) {}
1643 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1646 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1647 // Lose the context on the impl thread before the commit.
1648 PostLoseContextToImplThread();
1652 // Currently one resource has been created.
1653 test_id0_
= ui_resource_
->id();
1654 // Delete this resource.
1655 ui_resource_
.reset();
1656 // Create another resource.
1657 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1658 test_id1_
= ui_resource_
->id();
1659 // Sanity check that two resource creations return different ids.
1660 EXPECT_NE(test_id0_
, test_id1_
);
1661 // Lose the context on the impl thread before the commit.
1662 PostLoseContextToImplThread();
1665 // Clear the manager of resources.
1666 ui_resource_
.reset();
1667 PostSetNeedsCommitToMainThread();
1671 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1672 test_id0_
= ui_resource_
->id();
1673 // Sanity check the UIResourceId should not be 0.
1674 EXPECT_NE(0, test_id0_
);
1675 // Usually ScopedUIResource are deleted from the manager in their
1676 // destructor (so usually ui_resource_.reset()). But here we need
1677 // ui_resource_ for the next step, so call DeleteUIResource directly.
1678 layer_tree_host()->DeleteUIResource(test_id0_
);
1679 // Delete the resouce and then lose the context.
1680 PostLoseContextToImplThread();
1683 // Release resource before ending the test.
1684 ui_resource_
.reset();
1688 // Single thread proxy issues extra commits after context lost.
1689 // http://crbug.com/287250
1690 if (HasImplThread())
1698 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1699 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1700 switch (time_step_
) {
1702 // Sequence 1 (continued):
1703 // The first context lost happens before the resources were created,
1704 // and because it resulted in no resources being destroyed, it does not
1705 // trigger resource re-creation.
1706 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1707 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1708 // Resource Id on the impl-side has been created.
1709 PostSetNeedsCommitToMainThread();
1712 // Sequence 2 (continued):
1713 // The previous resource should have been deleted.
1714 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id0_
));
1715 if (HasImplThread()) {
1716 // The second resource should have been created.
1717 EXPECT_NE(0u, impl
->ResourceIdForUIResource(test_id1_
));
1719 // The extra commit that happens at context lost in the single thread
1720 // proxy changes the timing so that the resource has been destroyed.
1721 // http://crbug.com/287250
1722 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id1_
));
1724 // The second resource called the resource callback once and since the
1725 // context is lost, a "resource lost" callback was also issued.
1726 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1727 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1730 // Sequence 3 (continued):
1731 // Expect the resource callback to have been called once.
1732 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1733 // No "resource lost" callbacks.
1734 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1735 // The UI resource id should not be valid
1736 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id0_
));
1742 UIResourceId test_id0_
;
1743 UIResourceId test_id1_
;
1746 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit
);
1748 // Losing UI resource before the pending trees is activated but after the
1749 // commit. Impl-side-painting only.
1750 class UIResourceLostBeforeActivateTree
: public UIResourceLostTest
{
1751 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1752 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1755 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1756 PostSetNeedsCommitToMainThread();
1759 test_id_
= ui_resource_
->id();
1760 ui_resource_
.reset();
1761 PostSetNeedsCommitToMainThread();
1764 // Release resource before ending the test.
1765 ui_resource_
.reset();
1769 // Make sure no extra commits happened.
1774 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1775 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1776 switch (time_step_
) {
1778 PostSetNeedsCommitToMainThread();
1781 PostSetNeedsCommitToMainThread();
1786 virtual void WillActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1787 switch (time_step_
) {
1789 // The resource creation callback has been called.
1790 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1791 // The resource is not yet lost (sanity check).
1792 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1793 // The resource should not have been created yet on the impl-side.
1794 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1803 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1804 LayerTreeHostContextTest::DidActivateTreeOnThread(impl
);
1805 switch (time_step_
) {
1807 // The pending requests on the impl-side should have been processed.
1808 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1811 // The "lost resource" callback should have been called once.
1812 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1815 // The resource is deleted and should not be in the manager. Use
1816 // test_id_ since ui_resource_ has been deleted.
1817 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id_
));
1821 PostStepCompleteToMainThread();
1826 UIResourceId test_id_
;
1829 TEST_F(UIResourceLostBeforeActivateTree
,
1830 RunMultiThread_DirectRenderer_ImplSidePaint
) {
1831 RunTest(true, false, true);
1834 TEST_F(UIResourceLostBeforeActivateTree
,
1835 RunMultiThread_DelegatingRenderer_ImplSidePaint
) {
1836 RunTest(true, true, true);
1839 // Resources evicted explicitly and by visibility changes.
1840 class UIResourceLostEviction
: public UIResourceLostTestSimple
{
1842 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1843 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1846 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1847 EXPECT_NE(0, ui_resource_
->id());
1848 PostSetNeedsCommitToMainThread();
1851 // Make the tree not visible.
1852 PostSetVisibleToMainThread(false);
1855 // Release resource before ending the test.
1856 ui_resource_
.reset();
1864 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl
* impl
,
1865 bool visible
) OVERRIDE
{
1866 TestWebGraphicsContext3D
* context
= TestContext();
1868 // All resources should have been evicted.
1869 ASSERT_EQ(0u, context
->NumTextures());
1870 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1871 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1872 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1873 // Drawing is disabled both because of the evicted resources and
1874 // because the renderer is not visible.
1875 EXPECT_FALSE(impl
->CanDraw());
1876 // Make the renderer visible again.
1877 PostSetVisibleToMainThread(true);
1881 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1882 TestWebGraphicsContext3D
* context
= TestContext();
1883 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1884 switch (time_step_
) {
1886 // The resource should have been created on LTHI after the commit.
1887 ASSERT_EQ(1u, context
->NumTextures());
1888 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1889 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1890 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1891 EXPECT_TRUE(impl
->CanDraw());
1892 // Evict all UI resources. This will trigger a commit.
1893 impl
->EvictAllUIResources();
1894 ASSERT_EQ(0u, context
->NumTextures());
1895 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1896 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1897 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1898 EXPECT_FALSE(impl
->CanDraw());
1901 // The resource should have been recreated.
1902 ASSERT_EQ(1u, context
->NumTextures());
1903 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1904 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1905 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1906 EXPECT_TRUE(impl
->CanDraw());
1909 // The resource should have been recreated after visibility was
1911 ASSERT_EQ(1u, context
->NumTextures());
1912 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1913 EXPECT_EQ(3, ui_resource_
->resource_create_count
);
1914 EXPECT_EQ(2, ui_resource_
->lost_resource_count
);
1915 EXPECT_TRUE(impl
->CanDraw());
1921 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostEviction
);
1923 class LayerTreeHostContextTestSurfaceCreateCallback
1924 : public LayerTreeHostContextTest
{
1926 LayerTreeHostContextTestSurfaceCreateCallback()
1927 : LayerTreeHostContextTest(),
1928 layer_(FakeContentLayer::Create(&client_
)) {}
1930 virtual void SetupTree() OVERRIDE
{
1931 layer_
->SetBounds(gfx::Size(10, 20));
1932 layer_tree_host()->SetRootLayer(layer_
);
1933 LayerTreeHostContextTest::SetupTree();
1936 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1938 virtual void DidCommit() OVERRIDE
{
1939 switch (layer_tree_host()->source_frame_number()) {
1941 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1942 layer_tree_host()->SetNeedsCommit();
1945 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1946 layer_tree_host()->SetNeedsCommit();
1949 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1952 EXPECT_EQ(2u, layer_
->output_surface_created_count());
1953 layer_tree_host()->SetNeedsCommit();
1958 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1959 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1960 switch (LastCommittedSourceFrameNumber(impl
)) {
1974 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1975 EXPECT_TRUE(succeeded
);
1978 virtual void AfterTest() OVERRIDE
{}
1981 FakeContentLayerClient client_
;
1982 scoped_refptr
<FakeContentLayer
> layer_
;
1985 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestSurfaceCreateCallback
);