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
> CreateFakeOutputSurface(bool fallback
)
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 DrawSwapReadbackResult::DrawResult
PrepareToDrawOnThread(
131 LayerTreeHostImpl
* host_impl
,
132 LayerTreeHostImpl::FrameData
* frame
,
133 DrawSwapReadbackResult::DrawResult draw_result
) OVERRIDE
{
134 EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS
, draw_result
);
135 if (!times_to_lose_during_draw_
)
138 --times_to_lose_during_draw_
;
141 times_to_fail_create_
= times_to_fail_recreate_
;
142 times_to_fail_recreate_
= 0;
143 times_to_fail_create_offscreen_
= times_to_fail_recreate_offscreen_
;
144 times_to_fail_recreate_offscreen_
= 0;
149 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
150 committed_at_least_once_
= true;
152 if (!times_to_lose_during_commit_
)
154 --times_to_lose_during_commit_
;
157 times_to_fail_create_
= times_to_fail_recreate_
;
158 times_to_fail_recreate_
= 0;
159 times_to_fail_create_offscreen_
= times_to_fail_recreate_offscreen_
;
160 times_to_fail_recreate_offscreen_
= 0;
163 virtual void DidFailToInitializeOutputSurface() OVERRIDE
{
164 ++times_create_failed_
;
167 virtual void TearDown() OVERRIDE
{
168 LayerTreeTest::TearDown();
169 EXPECT_EQ(times_to_expect_create_failed_
, times_create_failed_
);
172 void ExpectCreateToFail() { ++times_to_expect_create_failed_
; }
175 TestWebGraphicsContext3D
* context3d_
;
176 int times_to_fail_create_
;
177 int times_to_lose_during_commit_
;
178 int times_to_lose_during_draw_
;
179 int times_to_fail_recreate_
;
180 int times_to_fail_create_offscreen_
;
181 int times_to_fail_recreate_offscreen_
;
182 int times_to_expect_create_failed_
;
183 int times_create_failed_
;
184 int times_offscreen_created_
;
185 bool committed_at_least_once_
;
186 bool context_should_support_io_surface_
;
187 bool fallback_context_works_
;
189 scoped_refptr
<TestContextProvider
> offscreen_contexts_
;
192 class LayerTreeHostContextTestLostContextSucceeds
193 : public LayerTreeHostContextTest
{
195 LayerTreeHostContextTestLostContextSucceeds()
196 : LayerTreeHostContextTest(),
199 num_losses_last_test_case_(-1),
200 recovered_context_(true),
201 first_initialized_(false) {}
203 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
205 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
206 EXPECT_TRUE(succeeded
);
208 if (first_initialized_
)
211 first_initialized_
= true;
213 recovered_context_
= true;
216 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(9u, test_case_
); }
218 virtual void DidCommitAndDrawFrame() OVERRIDE
{
219 // If the last frame had a context loss, then we'll commit again to
221 if (!recovered_context_
)
223 if (times_to_lose_during_commit_
)
225 if (times_to_lose_during_draw_
)
228 recovered_context_
= false;
230 InvalidateAndSetNeedsCommit();
235 virtual void InvalidateAndSetNeedsCommit() {
236 // Cause damage so we try to draw.
237 layer_tree_host()->root_layer()->SetNeedsDisplay();
238 layer_tree_host()->SetNeedsCommit();
241 bool NextTestCase() {
242 static const TestCase kTests
[] = {
243 // Losing the context and failing to recreate it (or losing it again
244 // immediately) a small number of times should succeed.
245 {1, // times_to_lose_during_commit
246 0, // times_to_lose_during_draw
247 0, // times_to_fail_recreate
248 0, // times_to_fail_recreate_offscreen
249 false, // fallback_context_works
251 {0, // times_to_lose_during_commit
252 1, // times_to_lose_during_draw
253 0, // times_to_fail_recreate
254 0, // times_to_fail_recreate_offscreen
255 false, // fallback_context_works
257 {1, // times_to_lose_during_commit
258 0, // times_to_lose_during_draw
259 3, // times_to_fail_recreate
260 0, // times_to_fail_recreate_offscreen
261 false, // fallback_context_works
263 {0, // times_to_lose_during_commit
264 1, // times_to_lose_during_draw
265 3, // times_to_fail_recreate
266 0, // times_to_fail_recreate_offscreen
267 false, // fallback_context_works
269 {1, // times_to_lose_during_commit
270 0, // times_to_lose_during_draw
271 0, // times_to_fail_recreate
272 3, // times_to_fail_recreate_offscreen
273 false, // fallback_context_works
275 {0, // times_to_lose_during_commit
276 1, // times_to_lose_during_draw
277 0, // times_to_fail_recreate
278 3, // times_to_fail_recreate_offscreen
279 false, // fallback_context_works
281 // Losing the context and recreating it any number of times should
283 {10, // times_to_lose_during_commit
284 0, // times_to_lose_during_draw
285 0, // times_to_fail_recreate
286 0, // times_to_fail_recreate_offscreen
287 false, // fallback_context_works
289 {0, // times_to_lose_during_commit
290 10, // times_to_lose_during_draw
291 0, // times_to_fail_recreate
292 0, // times_to_fail_recreate_offscreen
293 false, // fallback_context_works
295 // Losing the context, failing to reinitialize it, and making a fallback
296 // context should work.
297 {0, // times_to_lose_during_commit
298 1, // times_to_lose_during_draw
299 0, // times_to_fail_recreate
300 0, // times_to_fail_recreate_offscreen
301 true, // fallback_context_works
304 if (test_case_
>= arraysize(kTests
))
306 // Make sure that we lost our context at least once in the last test run so
307 // the test did something.
308 EXPECT_GT(num_losses_
, num_losses_last_test_case_
);
309 num_losses_last_test_case_
= num_losses_
;
311 times_to_lose_during_commit_
=
312 kTests
[test_case_
].times_to_lose_during_commit
;
313 times_to_lose_during_draw_
= kTests
[test_case_
].times_to_lose_during_draw
;
314 times_to_fail_recreate_
= kTests
[test_case_
].times_to_fail_recreate
;
315 times_to_fail_recreate_offscreen_
=
316 kTests
[test_case_
].times_to_fail_recreate_offscreen
;
317 fallback_context_works_
= kTests
[test_case_
].fallback_context_works
;
323 int times_to_lose_during_commit
;
324 int times_to_lose_during_draw
;
325 int times_to_fail_recreate
;
326 int times_to_fail_recreate_offscreen
;
327 bool fallback_context_works
;
333 int num_losses_last_test_case_
;
334 bool recovered_context_
;
335 bool first_initialized_
;
338 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds
);
340 class LayerTreeHostClientNotReadyDoesNotCreateOutputSurface
341 : public LayerTreeHostContextTest
{
343 LayerTreeHostClientNotReadyDoesNotCreateOutputSurface()
344 : LayerTreeHostContextTest() {}
346 virtual void WillBeginTest() OVERRIDE
{
347 // Override and do not signal SetLayerTreeHostClientReady.
350 virtual void BeginTest() OVERRIDE
{
351 PostSetNeedsCommitToMainThread();
355 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(bool fallback
)
358 return scoped_ptr
<OutputSurface
>();
361 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
365 virtual void AfterTest() OVERRIDE
{
369 MULTI_THREAD_TEST_F(LayerTreeHostClientNotReadyDoesNotCreateOutputSurface
);
371 class LayerTreeHostContextTestLostContextSucceedsWithContent
372 : public LayerTreeHostContextTestLostContextSucceeds
{
374 LayerTreeHostContextTestLostContextSucceedsWithContent()
375 : LayerTreeHostContextTestLostContextSucceeds() {}
377 virtual void SetupTree() OVERRIDE
{
378 root_
= Layer::Create();
379 root_
->SetBounds(gfx::Size(10, 10));
380 root_
->SetAnchorPoint(gfx::PointF());
381 root_
->SetIsDrawable(true);
383 content_
= FakeContentLayer::Create(&client_
);
384 content_
->SetBounds(gfx::Size(10, 10));
385 content_
->SetAnchorPoint(gfx::PointF());
386 content_
->SetIsDrawable(true);
388 content_
->SetForceRenderSurface(true);
389 // Filters require us to create an offscreen context.
390 FilterOperations filters
;
391 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
392 content_
->SetFilters(filters
);
393 content_
->SetBackgroundFilters(filters
);
396 root_
->AddChild(content_
);
398 layer_tree_host()->SetRootLayer(root_
);
399 LayerTreeHostContextTest::SetupTree();
402 virtual void InvalidateAndSetNeedsCommit() OVERRIDE
{
403 // Invalidate the render surface so we don't try to use a cached copy of the
404 // surface. We want to make sure to test the drawing paths for drawing to
406 content_
->SetNeedsDisplay();
407 LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit();
410 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
411 FakeContentLayerImpl
* content_impl
= static_cast<FakeContentLayerImpl
*>(
412 host_impl
->active_tree()->root_layer()->children()[0]);
413 // Even though the context was lost, we should have a resource. The
414 // TestWebGraphicsContext3D ensures that this resource is created with
415 // the active context.
416 EXPECT_TRUE(content_impl
->HaveResourceForTileAt(0, 0));
418 ContextProvider
* contexts
= host_impl
->offscreen_context_provider();
420 ASSERT_TRUE(contexts
);
421 EXPECT_TRUE(contexts
->ContextGL());
422 // TODO(danakj): Make a fake GrContext.
423 // EXPECT_TRUE(contexts->GrContext());
425 EXPECT_FALSE(contexts
);
429 virtual void AfterTest() OVERRIDE
{
430 LayerTreeHostContextTestLostContextSucceeds::AfterTest();
432 // 1 create to start with +
433 // 4 from test cases that lose the offscreen context directly +
434 // 2 from test cases that create a fallback +
435 // All the test cases that recreate both contexts only once
436 // per time it is lost.
437 EXPECT_EQ(4 + 1 + 2 + num_losses_
, times_offscreen_created_
);
439 EXPECT_EQ(0, times_offscreen_created_
);
445 FakeContentLayerClient client_
;
446 scoped_refptr
<Layer
> root_
;
447 scoped_refptr
<ContentLayer
> content_
;
450 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
451 NoSurface_SingleThread_DirectRenderer
) {
452 use_surface_
= false;
453 RunTest(false, false, false);
456 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
457 NoSurface_SingleThread_DelegatingRenderer
) {
458 use_surface_
= false;
459 RunTest(false, true, false);
462 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
463 NoSurface_MultiThread_DirectRenderer_MainThreadPaint
) {
464 use_surface_
= false;
465 RunTest(true, false, false);
468 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
469 NoSurface_MultiThread_DelegatingRenderer_MainThreadPaint
) {
470 use_surface_
= false;
471 RunTest(true, true, false);
474 // Surfaces don't exist with a delegating renderer.
475 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
476 WithSurface_SingleThread_DirectRenderer
) {
478 RunTest(false, false, false);
481 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent
,
482 WithSurface_MultiThread_DirectRenderer_MainThreadPaint
) {
484 RunTest(true, false, false);
487 class LayerTreeHostContextTestCreateOutputSurfaceFails
488 : public LayerTreeHostContextTest
{
490 // Run a test that initially fails OutputSurface creation |times_to_fail|
491 // times. If |expect_fallback_attempt| is |true|, an attempt to create a
492 // fallback/software OutputSurface is expected to occur.
493 LayerTreeHostContextTestCreateOutputSurfaceFails(int times_to_fail
,
494 bool expect_fallback_attempt
,
495 bool expect_to_give_up
)
496 : times_to_fail_(times_to_fail
),
497 expect_fallback_attempt_(expect_fallback_attempt
),
498 expect_to_give_up_(expect_to_give_up
),
499 did_attempt_fallback_(false),
500 times_initialized_(0) {}
502 virtual void BeginTest() OVERRIDE
{
503 times_to_fail_create_
= times_to_fail_
;
504 PostSetNeedsCommitToMainThread();
507 virtual scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(bool fallback
)
509 scoped_ptr
<FakeOutputSurface
> surface
=
510 LayerTreeHostContextTest::CreateFakeOutputSurface(fallback
);
513 EXPECT_EQ(times_to_fail_
, times_create_failed_
);
515 did_attempt_fallback_
= fallback
;
516 return surface
.Pass();
519 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
521 times_initialized_
++;
526 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
530 virtual void AfterTest() OVERRIDE
{
531 EXPECT_EQ(times_to_fail_
, times_create_failed_
);
532 EXPECT_EQ(expect_to_give_up_
, times_initialized_
== 0);
533 EXPECT_EQ(expect_fallback_attempt_
, did_attempt_fallback_
);
538 bool expect_fallback_attempt_
;
539 bool expect_to_give_up_
;
540 bool did_attempt_fallback_
;
541 int times_initialized_
;
544 class LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
545 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
547 LayerTreeHostContextTestCreateOutputSurfaceFailsOnce()
548 : LayerTreeHostContextTestCreateOutputSurfaceFails(1, false, false) {}
551 SINGLE_AND_MULTI_THREAD_TEST_F(
552 LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
);
554 // After 4 failures we expect an attempt to create a fallback/software
556 class LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback
557 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
559 LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback()
560 : LayerTreeHostContextTestCreateOutputSurfaceFails(4, true, false) {}
563 SINGLE_AND_MULTI_THREAD_TEST_F(
564 LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback
);
566 // If we fail that often, we should be giving up cleanly.
567 class LayerTreeHostContextTestCreateOutputSurfaceIsHopeless
568 : public LayerTreeHostContextTestCreateOutputSurfaceFails
{
570 LayerTreeHostContextTestCreateOutputSurfaceIsHopeless()
571 : LayerTreeHostContextTestCreateOutputSurfaceFails(5, true, true) {}
574 SINGLE_AND_MULTI_THREAD_TEST_F(
575 LayerTreeHostContextTestCreateOutputSurfaceIsHopeless
);
578 class LayerTreeHostContextTestOffscreenContextFails
579 : public LayerTreeHostContextTest
{
581 virtual void SetupTree() OVERRIDE
{
582 root_
= Layer::Create();
583 root_
->SetBounds(gfx::Size(10, 10));
584 root_
->SetAnchorPoint(gfx::PointF());
585 root_
->SetIsDrawable(true);
587 content_
= FakeContentLayer::Create(&client_
);
588 content_
->SetBounds(gfx::Size(10, 10));
589 content_
->SetAnchorPoint(gfx::PointF());
590 content_
->SetIsDrawable(true);
591 content_
->SetForceRenderSurface(true);
592 // Filters require us to create an offscreen context.
593 FilterOperations filters
;
594 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
595 content_
->SetFilters(filters
);
596 content_
->SetBackgroundFilters(filters
);
598 root_
->AddChild(content_
);
600 layer_tree_host()->SetRootLayer(root_
);
601 LayerTreeHostContextTest::SetupTree();
604 virtual void BeginTest() OVERRIDE
{
605 times_to_fail_create_offscreen_
= 1;
606 PostSetNeedsCommitToMainThread();
609 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
610 ContextProvider
* contexts
= host_impl
->offscreen_context_provider();
611 EXPECT_FALSE(contexts
);
613 // This did not lead to create failure.
614 times_to_expect_create_failed_
= 0;
618 virtual void AfterTest() OVERRIDE
{}
621 FakeContentLayerClient client_
;
622 scoped_refptr
<Layer
> root_
;
623 scoped_refptr
<ContentLayer
> content_
;
626 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestOffscreenContextFails
);
628 class LayerTreeHostContextTestLostContextFails
629 : public LayerTreeHostContextTest
{
631 LayerTreeHostContextTestLostContextFails()
632 : LayerTreeHostContextTest(), num_commits_(0), first_initialized_(false) {
633 times_to_lose_during_commit_
= 1;
636 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
638 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
639 if (first_initialized_
) {
640 EXPECT_FALSE(succeeded
);
643 first_initialized_
= true;
647 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
648 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
651 if (num_commits_
== 1) {
652 // When the context is ok, we should have these things.
653 EXPECT_TRUE(host_impl
->output_surface());
654 EXPECT_TRUE(host_impl
->renderer());
655 EXPECT_TRUE(host_impl
->resource_provider());
659 // When context recreation fails we shouldn't be left with any of them.
660 EXPECT_FALSE(host_impl
->output_surface());
661 EXPECT_FALSE(host_impl
->renderer());
662 EXPECT_FALSE(host_impl
->resource_provider());
665 virtual void AfterTest() OVERRIDE
{}
669 bool first_initialized_
;
672 class LayerTreeHostContextTestLostContextAndEvictTextures
673 : public LayerTreeHostContextTest
{
675 LayerTreeHostContextTestLostContextAndEvictTextures()
676 : LayerTreeHostContextTest(),
677 layer_(FakeContentLayer::Create(&client_
)),
681 virtual void SetupTree() OVERRIDE
{
682 layer_
->SetBounds(gfx::Size(10, 20));
683 layer_tree_host()->SetRootLayer(layer_
);
684 LayerTreeHostContextTest::SetupTree();
687 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
689 void PostEvictTextures() {
690 if (HasImplThread()) {
691 ImplThreadTaskRunner()->PostTask(
693 base::Bind(&LayerTreeHostContextTestLostContextAndEvictTextures::
694 EvictTexturesOnImplThread
,
695 base::Unretained(this)));
697 DebugScopedSetImplThread
impl(proxy());
698 EvictTexturesOnImplThread();
702 void EvictTexturesOnImplThread() {
703 impl_host_
->EvictTexturesForTesting();
704 if (lose_after_evict_
)
708 virtual void DidCommitAndDrawFrame() OVERRIDE
{
709 if (num_commits_
> 1)
711 EXPECT_TRUE(layer_
->HaveBackingAt(0, 0));
715 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
716 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
717 if (num_commits_
> 1)
720 if (!lose_after_evict_
)
725 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
726 EXPECT_TRUE(succeeded
);
730 virtual void AfterTest() OVERRIDE
{}
733 bool lose_after_evict_
;
734 FakeContentLayerClient client_
;
735 scoped_refptr
<FakeContentLayer
> layer_
;
736 LayerTreeHostImpl
* impl_host_
;
740 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
741 LoseAfterEvict_SingleThread_DirectRenderer
) {
742 lose_after_evict_
= true;
743 RunTest(false, false, false);
746 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
747 LoseAfterEvict_SingleThread_DelegatingRenderer
) {
748 lose_after_evict_
= true;
749 RunTest(false, true, false);
752 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
753 LoseAfterEvict_MultiThread_DirectRenderer_MainThreadPaint
) {
754 lose_after_evict_
= true;
755 RunTest(true, false, false);
758 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
759 LoseAfterEvict_MultiThread_DelegatingRenderer_MainThreadPaint
) {
760 lose_after_evict_
= true;
761 RunTest(true, true, false);
764 // Flaky on all platforms, http://crbug.com/310979
765 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
766 DISABLED_LoseAfterEvict_MultiThread_DelegatingRenderer_ImplSidePaint
) {
767 lose_after_evict_
= true;
768 RunTest(true, true, true);
771 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
772 LoseBeforeEvict_SingleThread_DirectRenderer
) {
773 lose_after_evict_
= false;
774 RunTest(false, false, false);
777 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
778 LoseBeforeEvict_SingleThread_DelegatingRenderer
) {
779 lose_after_evict_
= false;
780 RunTest(false, true, false);
783 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
784 LoseBeforeEvict_MultiThread_DirectRenderer_MainThreadPaint
) {
785 lose_after_evict_
= false;
786 RunTest(true, false, false);
789 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
790 LoseBeforeEvict_MultiThread_DirectRenderer_ImplSidePaint
) {
791 lose_after_evict_
= false;
792 RunTest(true, false, true);
795 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
796 LoseBeforeEvict_MultiThread_DelegatingRenderer_MainThreadPaint
) {
797 lose_after_evict_
= false;
798 RunTest(true, true, false);
801 TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures
,
802 LoseBeforeEvict_MultiThread_DelegatingRenderer_ImplSidePaint
) {
803 lose_after_evict_
= false;
804 RunTest(true, true, true);
807 class LayerTreeHostContextTestLostContextWhileUpdatingResources
808 : public LayerTreeHostContextTest
{
810 LayerTreeHostContextTestLostContextWhileUpdatingResources()
811 : parent_(FakeContentLayer::Create(&client_
)),
813 times_to_lose_on_end_query_(3) {}
815 virtual scoped_ptr
<TestWebGraphicsContext3D
> CreateContext3d() OVERRIDE
{
816 scoped_ptr
<TestWebGraphicsContext3D
> context
=
817 LayerTreeHostContextTest::CreateContext3d();
818 if (times_to_lose_on_end_query_
) {
819 --times_to_lose_on_end_query_
;
820 context
->set_times_end_query_succeeds(5);
822 return context
.Pass();
825 virtual void SetupTree() OVERRIDE
{
826 parent_
->SetBounds(gfx::Size(num_children_
, 1));
828 for (int i
= 0; i
< num_children_
; i
++) {
829 scoped_refptr
<FakeContentLayer
> child
=
830 FakeContentLayer::Create(&client_
);
831 child
->SetPosition(gfx::PointF(i
, 0.f
));
832 child
->SetBounds(gfx::Size(1, 1));
833 parent_
->AddChild(child
);
836 layer_tree_host()->SetRootLayer(parent_
);
837 LayerTreeHostContextTest::SetupTree();
840 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
842 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
843 EXPECT_EQ(0, times_to_lose_on_end_query_
);
847 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
848 EXPECT_TRUE(succeeded
);
851 virtual void AfterTest() OVERRIDE
{
852 EXPECT_EQ(0, times_to_lose_on_end_query_
);
856 FakeContentLayerClient client_
;
857 scoped_refptr
<FakeContentLayer
> parent_
;
859 int times_to_lose_on_end_query_
;
862 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
863 LayerTreeHostContextTestLostContextWhileUpdatingResources
);
865 class LayerTreeHostContextTestLayersNotified
: public LayerTreeHostContextTest
{
867 LayerTreeHostContextTestLayersNotified()
868 : LayerTreeHostContextTest(), num_commits_(0) {}
870 virtual void SetupTree() OVERRIDE
{
871 root_
= FakeContentLayer::Create(&client_
);
872 child_
= FakeContentLayer::Create(&client_
);
873 grandchild_
= FakeContentLayer::Create(&client_
);
875 root_
->AddChild(child_
);
876 child_
->AddChild(grandchild_
);
878 layer_tree_host()->SetRootLayer(root_
);
879 LayerTreeHostContextTest::SetupTree();
882 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
884 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
885 LayerTreeHostContextTest::DidActivateTreeOnThread(host_impl
);
887 FakeContentLayerImpl
* root
= static_cast<FakeContentLayerImpl
*>(
888 host_impl
->active_tree()->root_layer());
889 FakeContentLayerImpl
* child
=
890 static_cast<FakeContentLayerImpl
*>(root
->children()[0]);
891 FakeContentLayerImpl
* grandchild
=
892 static_cast<FakeContentLayerImpl
*>(child
->children()[0]);
895 switch (num_commits_
) {
897 EXPECT_EQ(0u, root
->lost_output_surface_count());
898 EXPECT_EQ(0u, child
->lost_output_surface_count());
899 EXPECT_EQ(0u, grandchild
->lost_output_surface_count());
900 // Lose the context and struggle to recreate it.
902 times_to_fail_create_
= 1;
905 EXPECT_GE(1u, root
->lost_output_surface_count());
906 EXPECT_GE(1u, child
->lost_output_surface_count());
907 EXPECT_GE(1u, grandchild
->lost_output_surface_count());
915 virtual void AfterTest() OVERRIDE
{}
920 FakeContentLayerClient client_
;
921 scoped_refptr
<FakeContentLayer
> root_
;
922 scoped_refptr
<FakeContentLayer
> child_
;
923 scoped_refptr
<FakeContentLayer
> grandchild_
;
926 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLayersNotified
);
928 class LayerTreeHostContextTestDontUseLostResources
929 : public LayerTreeHostContextTest
{
931 LayerTreeHostContextTestDontUseLostResources() : lost_context_(false) {
932 context_should_support_io_surface_
= true;
934 child_output_surface_
= FakeOutputSurface::Create3d();
935 child_output_surface_
->BindToClient(&output_surface_client_
);
936 child_resource_provider_
= ResourceProvider::Create(
937 child_output_surface_
.get(), NULL
, 0, false, 1);
940 static void EmptyReleaseCallback(unsigned sync_point
, bool lost
) {}
942 virtual void SetupTree() OVERRIDE
{
943 gpu::gles2::GLES2Interface
* gl
=
944 child_output_surface_
->context_provider()->ContextGL();
946 scoped_ptr
<DelegatedFrameData
> frame_data(new DelegatedFrameData
);
948 scoped_ptr
<TestRenderPass
> pass_for_quad
= TestRenderPass::Create();
949 pass_for_quad
->SetNew(
950 // AppendOneOfEveryQuadType() makes a RenderPass quad with this id.
951 RenderPass::Id(2, 1),
952 gfx::Rect(0, 0, 10, 10),
953 gfx::Rect(0, 0, 10, 10),
956 scoped_ptr
<TestRenderPass
> pass
= TestRenderPass::Create();
957 pass
->SetNew(RenderPass::Id(1, 1),
958 gfx::Rect(0, 0, 10, 10),
959 gfx::Rect(0, 0, 10, 10),
961 pass
->AppendOneOfEveryQuadType(child_resource_provider_
.get(),
962 RenderPass::Id(2, 1));
964 frame_data
->render_pass_list
.push_back(pass_for_quad
.PassAs
<RenderPass
>());
965 frame_data
->render_pass_list
.push_back(pass
.PassAs
<RenderPass
>());
967 delegated_resource_collection_
= new DelegatedFrameResourceCollection
;
968 delegated_frame_provider_
= new DelegatedFrameProvider(
969 delegated_resource_collection_
.get(), frame_data
.Pass());
971 ResourceProvider::ResourceId resource
=
972 child_resource_provider_
->CreateResource(
975 ResourceProvider::TextureUsageAny
,
977 ResourceProvider::ScopedWriteLockGL
lock(child_resource_provider_
.get(),
980 gpu::Mailbox mailbox
;
981 gl
->GenMailboxCHROMIUM(mailbox
.name
);
982 GLuint sync_point
= gl
->InsertSyncPointCHROMIUM();
984 scoped_refptr
<Layer
> root
= Layer::Create();
985 root
->SetBounds(gfx::Size(10, 10));
986 root
->SetAnchorPoint(gfx::PointF());
987 root
->SetIsDrawable(true);
989 scoped_refptr
<FakeDelegatedRendererLayer
> delegated
=
990 FakeDelegatedRendererLayer::Create(delegated_frame_provider_
.get());
991 delegated
->SetBounds(gfx::Size(10, 10));
992 delegated
->SetAnchorPoint(gfx::PointF());
993 delegated
->SetIsDrawable(true);
994 root
->AddChild(delegated
);
996 scoped_refptr
<ContentLayer
> content
= ContentLayer::Create(&client_
);
997 content
->SetBounds(gfx::Size(10, 10));
998 content
->SetAnchorPoint(gfx::PointF());
999 content
->SetIsDrawable(true);
1000 root
->AddChild(content
);
1002 scoped_refptr
<TextureLayer
> texture
= TextureLayer::CreateForMailbox(NULL
);
1003 texture
->SetBounds(gfx::Size(10, 10));
1004 texture
->SetAnchorPoint(gfx::PointF());
1005 texture
->SetIsDrawable(true);
1006 texture
->SetTextureMailbox(
1007 TextureMailbox(mailbox
, GL_TEXTURE_2D
, sync_point
),
1008 SingleReleaseCallback::Create(
1009 base::Bind(&LayerTreeHostContextTestDontUseLostResources::
1010 EmptyReleaseCallback
)));
1011 root
->AddChild(texture
);
1013 scoped_refptr
<ContentLayer
> mask
= ContentLayer::Create(&client_
);
1014 mask
->SetBounds(gfx::Size(10, 10));
1015 mask
->SetAnchorPoint(gfx::PointF());
1017 scoped_refptr
<ContentLayer
> content_with_mask
=
1018 ContentLayer::Create(&client_
);
1019 content_with_mask
->SetBounds(gfx::Size(10, 10));
1020 content_with_mask
->SetAnchorPoint(gfx::PointF());
1021 content_with_mask
->SetIsDrawable(true);
1022 content_with_mask
->SetMaskLayer(mask
.get());
1023 root
->AddChild(content_with_mask
);
1025 scoped_refptr
<VideoLayer
> video_color
=
1026 VideoLayer::Create(&color_frame_provider_
);
1027 video_color
->SetBounds(gfx::Size(10, 10));
1028 video_color
->SetAnchorPoint(gfx::PointF());
1029 video_color
->SetIsDrawable(true);
1030 root
->AddChild(video_color
);
1032 scoped_refptr
<VideoLayer
> video_hw
=
1033 VideoLayer::Create(&hw_frame_provider_
);
1034 video_hw
->SetBounds(gfx::Size(10, 10));
1035 video_hw
->SetAnchorPoint(gfx::PointF());
1036 video_hw
->SetIsDrawable(true);
1037 root
->AddChild(video_hw
);
1039 scoped_refptr
<VideoLayer
> video_scaled_hw
=
1040 VideoLayer::Create(&scaled_hw_frame_provider_
);
1041 video_scaled_hw
->SetBounds(gfx::Size(10, 10));
1042 video_scaled_hw
->SetAnchorPoint(gfx::PointF());
1043 video_scaled_hw
->SetIsDrawable(true);
1044 root
->AddChild(video_scaled_hw
);
1046 color_video_frame_
= VideoFrame::CreateColorFrame(
1047 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
1049 VideoFrame::WrapNativeTexture(make_scoped_ptr(new gpu::MailboxHolder(
1050 mailbox
, GL_TEXTURE_2D
, sync_point
)),
1051 media::VideoFrame::ReleaseMailboxCB(),
1053 gfx::Rect(0, 0, 4, 4),
1056 VideoFrame::ReadPixelsCB());
1057 scaled_hw_video_frame_
=
1058 VideoFrame::WrapNativeTexture(make_scoped_ptr(new gpu::MailboxHolder(
1059 mailbox
, GL_TEXTURE_2D
, sync_point
)),
1060 media::VideoFrame::ReleaseMailboxCB(),
1062 gfx::Rect(0, 0, 3, 2),
1065 VideoFrame::ReadPixelsCB());
1067 color_frame_provider_
.set_frame(color_video_frame_
);
1068 hw_frame_provider_
.set_frame(hw_video_frame_
);
1069 scaled_hw_frame_provider_
.set_frame(scaled_hw_video_frame_
);
1071 if (!delegating_renderer()) {
1072 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
1073 scoped_refptr
<IOSurfaceLayer
> io_surface
= IOSurfaceLayer::Create();
1074 io_surface
->SetBounds(gfx::Size(10, 10));
1075 io_surface
->SetAnchorPoint(gfx::PointF());
1076 io_surface
->SetIsDrawable(true);
1077 io_surface
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
1078 root
->AddChild(io_surface
);
1082 LayerTreeDebugState debug_state
;
1083 debug_state
.show_property_changed_rects
= true;
1084 layer_tree_host()->SetDebugState(debug_state
);
1086 scoped_refptr
<PaintedScrollbarLayer
> scrollbar
=
1087 PaintedScrollbarLayer::Create(
1088 scoped_ptr
<Scrollbar
>(new FakeScrollbar
).Pass(), content
->id());
1089 scrollbar
->SetBounds(gfx::Size(10, 10));
1090 scrollbar
->SetAnchorPoint(gfx::PointF());
1091 scrollbar
->SetIsDrawable(true);
1092 root
->AddChild(scrollbar
);
1094 layer_tree_host()->SetRootLayer(root
);
1095 LayerTreeHostContextTest::SetupTree();
1098 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1100 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1101 LayerTreeHostContextTest::CommitCompleteOnThread(host_impl
);
1103 if (host_impl
->active_tree()->source_frame_number() == 3) {
1104 // On the third commit we're recovering from context loss. Hardware
1105 // video frames should not be reused by the VideoFrameProvider, but
1106 // software frames can be.
1107 hw_frame_provider_
.set_frame(NULL
);
1108 scaled_hw_frame_provider_
.set_frame(NULL
);
1112 virtual DrawSwapReadbackResult::DrawResult
PrepareToDrawOnThread(
1113 LayerTreeHostImpl
* host_impl
,
1114 LayerTreeHostImpl::FrameData
* frame
,
1115 DrawSwapReadbackResult::DrawResult draw_result
) OVERRIDE
{
1116 if (host_impl
->active_tree()->source_frame_number() == 2) {
1117 // Lose the context during draw on the second commit. This will cause
1118 // a third commit to recover.
1119 context3d_
->set_times_bind_texture_succeeds(0);
1124 virtual scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(bool fallback
)
1126 // This will get called twice:
1127 // First when we create the initial output surface...
1128 if (layer_tree_host()->source_frame_number() > 0) {
1129 // ... and then again after we forced the context to be lost on the third
1130 // frame. Verify this assumption here.
1131 lost_context_
= true;
1132 EXPECT_EQ(layer_tree_host()->source_frame_number(), 3);
1134 return LayerTreeHostContextTest::CreateFakeOutputSurface(fallback
);
1137 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1138 ASSERT_TRUE(layer_tree_host()->hud_layer());
1139 // End the test once we know the 3nd frame drew.
1140 if (layer_tree_host()->source_frame_number() < 4) {
1141 layer_tree_host()->root_layer()->SetNeedsDisplay();
1142 layer_tree_host()->SetNeedsCommit();
1148 virtual void AfterTest() OVERRIDE
{ EXPECT_TRUE(lost_context_
); }
1151 FakeContentLayerClient client_
;
1154 FakeOutputSurfaceClient output_surface_client_
;
1155 scoped_ptr
<FakeOutputSurface
> child_output_surface_
;
1156 scoped_ptr
<ResourceProvider
> child_resource_provider_
;
1158 scoped_refptr
<DelegatedFrameResourceCollection
>
1159 delegated_resource_collection_
;
1160 scoped_refptr
<DelegatedFrameProvider
> delegated_frame_provider_
;
1162 scoped_refptr
<VideoFrame
> color_video_frame_
;
1163 scoped_refptr
<VideoFrame
> hw_video_frame_
;
1164 scoped_refptr
<VideoFrame
> scaled_hw_video_frame_
;
1166 FakeVideoFrameProvider color_frame_provider_
;
1167 FakeVideoFrameProvider hw_frame_provider_
;
1168 FakeVideoFrameProvider scaled_hw_frame_provider_
;
1171 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources
);
1173 class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
1174 : public LayerTreeHostContextTest
{
1176 virtual void BeginTest() OVERRIDE
{
1177 // This must be called immediately after creating LTH, before the first
1178 // OutputSurface is initialized.
1179 ASSERT_TRUE(layer_tree_host()->output_surface_lost());
1181 times_output_surface_created_
= 0;
1183 // Post the SetNeedsCommit before the readback to make sure it is run
1184 // on the main thread before the readback's replacement commit when
1185 // we have a threaded compositor.
1186 PostSetNeedsCommitToMainThread();
1190 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(1, 1));
1191 EXPECT_EQ(!delegating_renderer(), result
);
1192 EXPECT_EQ(1, times_output_surface_created_
);
1195 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1196 EXPECT_TRUE(succeeded
);
1197 ++times_output_surface_created_
;
1200 virtual void DidCommitAndDrawFrame() OVERRIDE
{ EndTest(); }
1202 virtual void AfterTest() OVERRIDE
{
1203 // Should not try to create output surface again after successfully
1204 // created by CompositeAndReadback.
1205 EXPECT_EQ(1, times_output_surface_created_
);
1208 virtual DrawSwapReadbackResult::DrawResult
PrepareToDrawOnThread(
1209 LayerTreeHostImpl
* host_impl
,
1210 LayerTreeHostImpl::FrameData
* frame_data
,
1211 DrawSwapReadbackResult::DrawResult draw_result
) OVERRIDE
{
1212 EXPECT_GE(host_impl
->active_tree()->source_frame_number(), 0);
1213 EXPECT_LE(host_impl
->active_tree()->source_frame_number(), 1);
1217 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1218 // We should only draw for the readback and the replacement commit.
1219 // The replacement commit will also be the first commit after output
1220 // surface initialization.
1221 EXPECT_GE(host_impl
->active_tree()->source_frame_number(), 0);
1222 EXPECT_LE(host_impl
->active_tree()->source_frame_number(), 1);
1225 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1226 bool result
) OVERRIDE
{
1227 // We should only swap for the replacement commit.
1228 EXPECT_EQ(host_impl
->active_tree()->source_frame_number(), 1);
1233 int times_output_surface_created_
;
1236 SINGLE_AND_MULTI_THREAD_TEST_F(
1237 LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
);
1239 // This test verifies that losing an output surface during a
1240 // simultaneous readback and forced redraw works and does not deadlock.
1241 class LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw
1242 : public LayerTreeHostContextTest
{
1244 static const int kFirstOutputSurfaceInitSourceFrameNumber
= 0;
1245 static const int kReadbackSourceFrameNumber
= 1;
1246 static const int kReadbackReplacementSourceFrameNumber
= 2;
1247 static const int kSecondOutputSurfaceInitSourceFrameNumber
= 3;
1249 LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw()
1250 : did_react_to_first_commit_(false) {}
1252 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1253 // This enables forced draws after a single prepare to draw failure.
1254 settings
->timeout_and_draw_when_animation_checkerboards
= true;
1255 settings
->maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
1258 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1260 virtual DrawSwapReadbackResult::DrawResult
PrepareToDrawOnThread(
1261 LayerTreeHostImpl
* host_impl
,
1262 LayerTreeHostImpl::FrameData
* frame_data
,
1263 DrawSwapReadbackResult::DrawResult draw_result
) OVERRIDE
{
1264 int sfn
= host_impl
->active_tree()->source_frame_number();
1265 EXPECT_TRUE(sfn
== kFirstOutputSurfaceInitSourceFrameNumber
||
1266 sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1267 sfn
== kReadbackSourceFrameNumber
)
1270 // Before we react to the failed draw by initiating the forced draw
1271 // sequence, start a readback on the main thread and then lose the context
1272 // to start output surface initialization all at the same time.
1273 if (sfn
== kFirstOutputSurfaceInitSourceFrameNumber
&&
1274 !did_react_to_first_commit_
) {
1275 did_react_to_first_commit_
= true;
1276 PostReadbackToMainThread();
1280 return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
1283 virtual void InitializedRendererOnThread(LayerTreeHostImpl
* host_impl
,
1284 bool success
) OVERRIDE
{
1285 // -1 is for the first output surface initialization.
1286 int sfn
= host_impl
->active_tree()->source_frame_number();
1287 EXPECT_TRUE(sfn
== -1 || sfn
== kReadbackReplacementSourceFrameNumber
)
1291 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1292 // We should only draw the first commit after output surface initialization
1293 // and attempt to draw the readback commit (which will fail).
1294 // All others should abort because the output surface is lost.
1295 int sfn
= host_impl
->active_tree()->source_frame_number();
1296 EXPECT_TRUE(sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1297 sfn
== kReadbackSourceFrameNumber
)
1301 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1302 bool result
) OVERRIDE
{
1303 // We should only swap the first commit after the second output surface
1305 int sfn
= host_impl
->active_tree()->source_frame_number();
1306 EXPECT_TRUE(sfn
== kSecondOutputSurfaceInitSourceFrameNumber
) << sfn
;
1310 virtual void AfterTest() OVERRIDE
{}
1312 int did_react_to_first_commit_
;
1315 MULTI_THREAD_TEST_F(
1316 LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw
);
1318 // This test verifies that losing an output surface right before a
1319 // simultaneous readback and forced redraw works and does not deadlock.
1320 class LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit
1321 : public LayerTreeHostContextTest
{
1323 static const int kFirstOutputSurfaceInitSourceFrameNumber
= 0;
1324 static const int kReadbackSourceFrameNumber
= 1;
1325 static const int kForcedDrawCommitSourceFrameNumber
= 2;
1326 static const int kSecondOutputSurfaceInitSourceFrameNumber
= 2;
1328 LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit()
1329 : did_lose_context_(false) {}
1331 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1332 // This enables forced draws after a single prepare to draw failure.
1333 settings
->timeout_and_draw_when_animation_checkerboards
= true;
1334 settings
->maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
1337 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1339 virtual DrawSwapReadbackResult::DrawResult
PrepareToDrawOnThread(
1340 LayerTreeHostImpl
* host_impl
,
1341 LayerTreeHostImpl::FrameData
* frame_data
,
1342 DrawSwapReadbackResult::DrawResult draw_result
) OVERRIDE
{
1343 int sfn
= host_impl
->active_tree()->source_frame_number();
1344 EXPECT_TRUE(sfn
== kFirstOutputSurfaceInitSourceFrameNumber
||
1345 sfn
== kSecondOutputSurfaceInitSourceFrameNumber
||
1346 sfn
== kReadbackSourceFrameNumber
)
1349 // Before we react to the failed draw by initiating the forced draw
1350 // sequence, start a readback on the main thread and then lose the context
1351 // to start output surface initialization all at the same time.
1352 if (sfn
== kFirstOutputSurfaceInitSourceFrameNumber
&& !did_lose_context_
) {
1353 did_lose_context_
= true;
1357 // Returning false will result in a forced draw.
1358 return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
1361 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1362 EXPECT_TRUE(succeeded
);
1363 if (layer_tree_host()->source_frame_number() > 0) {
1364 // Perform a readback right after the second output surface
1367 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
1371 virtual void InitializedRendererOnThread(LayerTreeHostImpl
* host_impl
,
1372 bool success
) OVERRIDE
{
1373 // -1 is for the first output surface initialization.
1374 int sfn
= host_impl
->active_tree()->source_frame_number();
1375 EXPECT_TRUE(sfn
== -1 || sfn
== kFirstOutputSurfaceInitSourceFrameNumber
)
1379 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1380 // We should only draw the first commit after output surface initialization
1381 // and attempt to draw the readback commit (which will fail).
1382 // All others should abort because the output surface is lost.
1383 int sfn
= host_impl
->active_tree()->source_frame_number();
1384 EXPECT_TRUE(sfn
== kForcedDrawCommitSourceFrameNumber
||
1385 sfn
== kReadbackSourceFrameNumber
)
1389 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1390 bool result
) OVERRIDE
{
1391 // We should only swap the first commit after the second output surface
1393 int sfn
= host_impl
->active_tree()->source_frame_number();
1394 EXPECT_TRUE(sfn
== kForcedDrawCommitSourceFrameNumber
) << sfn
;
1398 virtual void AfterTest() OVERRIDE
{}
1400 int did_lose_context_
;
1403 MULTI_THREAD_TEST_F(
1404 LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit
);
1406 class ImplSidePaintingLayerTreeHostContextTest
1407 : public LayerTreeHostContextTest
{
1409 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1410 settings
->impl_side_painting
= true;
1414 class LayerTreeHostContextTestImplSidePainting
1415 : public ImplSidePaintingLayerTreeHostContextTest
{
1417 virtual void SetupTree() OVERRIDE
{
1418 scoped_refptr
<Layer
> root
= Layer::Create();
1419 root
->SetBounds(gfx::Size(10, 10));
1420 root
->SetAnchorPoint(gfx::PointF());
1421 root
->SetIsDrawable(true);
1423 scoped_refptr
<PictureLayer
> picture
= PictureLayer::Create(&client_
);
1424 picture
->SetBounds(gfx::Size(10, 10));
1425 picture
->SetAnchorPoint(gfx::PointF());
1426 picture
->SetIsDrawable(true);
1427 root
->AddChild(picture
);
1429 layer_tree_host()->SetRootLayer(root
);
1430 LayerTreeHostContextTest::SetupTree();
1433 virtual void BeginTest() OVERRIDE
{
1434 times_to_lose_during_commit_
= 1;
1435 PostSetNeedsCommitToMainThread();
1438 virtual void AfterTest() OVERRIDE
{}
1440 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1441 EXPECT_TRUE(succeeded
);
1446 FakeContentLayerClient client_
;
1449 MULTI_THREAD_TEST_F(LayerTreeHostContextTestImplSidePainting
);
1451 class ScrollbarLayerLostContext
: public LayerTreeHostContextTest
{
1453 ScrollbarLayerLostContext() : commits_(0) {}
1455 virtual void BeginTest() OVERRIDE
{
1456 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
1458 FakePaintedScrollbarLayer::Create(false, true, scroll_layer
->id());
1459 scrollbar_layer_
->SetBounds(gfx::Size(10, 100));
1460 layer_tree_host()->root_layer()->AddChild(scrollbar_layer_
);
1461 layer_tree_host()->root_layer()->AddChild(scroll_layer
);
1462 PostSetNeedsCommitToMainThread();
1465 virtual void AfterTest() OVERRIDE
{}
1467 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1468 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1473 // First (regular) update, we should upload 2 resources (thumb, and
1475 EXPECT_EQ(1, scrollbar_layer_
->update_count());
1479 // Second update, after the lost context, we should still upload 2
1480 // resources even if the contents haven't changed.
1481 EXPECT_EQ(2, scrollbar_layer_
->update_count());
1485 // Single thread proxy issues extra commits after context lost.
1486 // http://crbug.com/287250
1487 if (HasImplThread())
1497 scoped_refptr
<FakePaintedScrollbarLayer
> scrollbar_layer_
;
1500 SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext
);
1502 class UIResourceLostTest
: public LayerTreeHostContextTest
{
1504 UIResourceLostTest() : time_step_(0) {}
1505 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1506 settings
->texture_id_allocation_chunk_size
= 1;
1508 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1509 virtual void AfterTest() OVERRIDE
{}
1511 // This is called on the main thread after each commit and
1512 // DidActivateTreeOnThread, with the value of time_step_ at the time
1513 // of the call to DidActivateTreeOnThread. Similar tests will do
1514 // work on the main thread in DidCommit but that is unsuitable because
1515 // the main thread work for these tests must happen after
1516 // DidActivateTreeOnThread, which happens after DidCommit with impl-side
1518 virtual void StepCompleteOnMainThread(int time_step
) = 0;
1520 // Called after DidActivateTreeOnThread. If this is done during the commit,
1521 // the call to StepCompleteOnMainThread will not occur until after
1522 // the commit completes, because the main thread is blocked.
1523 void PostStepCompleteToMainThread() {
1524 proxy()->MainThreadTaskRunner()->PostTask(
1526 base::Bind(&UIResourceLostTest::StepCompleteOnMainThreadInternal
,
1527 base::Unretained(this),
1531 void PostLoseContextToImplThread() {
1532 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1533 base::SingleThreadTaskRunner
* task_runner
=
1534 HasImplThread() ? ImplThreadTaskRunner()
1535 : base::MessageLoopProxy::current();
1536 task_runner
->PostTask(FROM_HERE
,
1537 base::Bind(&LayerTreeHostContextTest::LoseContext
,
1538 base::Unretained(this)));
1543 scoped_ptr
<FakeScopedUIResource
> ui_resource_
;
1546 void StepCompleteOnMainThreadInternal(int step
) {
1547 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1548 StepCompleteOnMainThread(step
);
1552 class UIResourceLostTestSimple
: public UIResourceLostTest
{
1554 // This is called when the commit is complete and the new layer tree has been
1556 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) = 0;
1558 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1559 if (!layer_tree_host()->settings().impl_side_painting
) {
1560 StepCompleteOnImplThread(impl
);
1561 PostStepCompleteToMainThread();
1566 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1567 if (layer_tree_host()->settings().impl_side_painting
) {
1568 StepCompleteOnImplThread(impl
);
1569 PostStepCompleteToMainThread();
1575 // Losing context after an UI resource has been created.
1576 class UIResourceLostAfterCommit
: public UIResourceLostTestSimple
{
1578 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1579 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1582 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1583 // Expects a valid UIResourceId.
1584 EXPECT_NE(0, ui_resource_
->id());
1585 PostSetNeedsCommitToMainThread();
1588 // Release resource before ending the test.
1589 ui_resource_
.reset();
1593 // Single thread proxy issues extra commits after context lost.
1594 // http://crbug.com/287250
1595 if (HasImplThread())
1603 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1604 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1605 switch (time_step_
) {
1607 // The resource should have been created on LTHI after the commit.
1608 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1609 PostSetNeedsCommitToMainThread();
1615 // The resources should have been recreated. The bitmap callback should
1616 // have been called once with the resource_lost flag set to true.
1617 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1618 // Resource Id on the impl-side have been recreated as well. Note
1619 // that the same UIResourceId persists after the context lost.
1620 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1621 PostSetNeedsCommitToMainThread();
1627 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostAfterCommit
);
1629 // Losing context before UI resource requests can be commited. Three sequences
1630 // of creation/deletion are considered:
1631 // 1. Create one resource -> Context Lost => Expect the resource to have been
1633 // 2. Delete an exisiting resource (test_id0_) -> create a second resource
1634 // (test_id1_) -> Context Lost => Expect the test_id0_ to be removed and
1635 // test_id1_ to have been created.
1636 // 3. Create one resource -> Delete that same resource -> Context Lost => Expect
1637 // the resource to not exist in the manager.
1638 class UIResourceLostBeforeCommit
: public UIResourceLostTestSimple
{
1640 UIResourceLostBeforeCommit() : test_id0_(0), test_id1_(0) {}
1642 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1645 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1646 // Lose the context on the impl thread before the commit.
1647 PostLoseContextToImplThread();
1651 // Currently one resource has been created.
1652 test_id0_
= ui_resource_
->id();
1653 // Delete this resource.
1654 ui_resource_
.reset();
1655 // Create another resource.
1656 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1657 test_id1_
= ui_resource_
->id();
1658 // Sanity check that two resource creations return different ids.
1659 EXPECT_NE(test_id0_
, test_id1_
);
1660 // Lose the context on the impl thread before the commit.
1661 PostLoseContextToImplThread();
1664 // Clear the manager of resources.
1665 ui_resource_
.reset();
1666 PostSetNeedsCommitToMainThread();
1670 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1671 test_id0_
= ui_resource_
->id();
1672 // Sanity check the UIResourceId should not be 0.
1673 EXPECT_NE(0, test_id0_
);
1674 // Usually ScopedUIResource are deleted from the manager in their
1675 // destructor (so usually ui_resource_.reset()). But here we need
1676 // ui_resource_ for the next step, so call DeleteUIResource directly.
1677 layer_tree_host()->DeleteUIResource(test_id0_
);
1678 // Delete the resouce and then lose the context.
1679 PostLoseContextToImplThread();
1682 // Release resource before ending the test.
1683 ui_resource_
.reset();
1687 // Single thread proxy issues extra commits after context lost.
1688 // http://crbug.com/287250
1689 if (HasImplThread())
1697 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1698 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1699 switch (time_step_
) {
1701 // Sequence 1 (continued):
1702 // The first context lost happens before the resources were created,
1703 // and because it resulted in no resources being destroyed, it does not
1704 // trigger resource re-creation.
1705 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1706 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1707 // Resource Id on the impl-side has been created.
1708 PostSetNeedsCommitToMainThread();
1711 // Sequence 2 (continued):
1712 // The previous resource should have been deleted.
1713 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id0_
));
1714 if (HasImplThread()) {
1715 // The second resource should have been created.
1716 EXPECT_NE(0u, impl
->ResourceIdForUIResource(test_id1_
));
1718 // The extra commit that happens at context lost in the single thread
1719 // proxy changes the timing so that the resource has been destroyed.
1720 // http://crbug.com/287250
1721 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id1_
));
1723 // The second resource called the resource callback once and since the
1724 // context is lost, a "resource lost" callback was also issued.
1725 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1726 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1729 // Sequence 3 (continued):
1730 // Expect the resource callback to have been called once.
1731 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1732 // No "resource lost" callbacks.
1733 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1734 // The UI resource id should not be valid
1735 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id0_
));
1741 UIResourceId test_id0_
;
1742 UIResourceId test_id1_
;
1745 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit
);
1747 // Losing UI resource before the pending trees is activated but after the
1748 // commit. Impl-side-painting only.
1749 class UIResourceLostBeforeActivateTree
: public UIResourceLostTest
{
1750 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1751 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1754 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1755 PostSetNeedsCommitToMainThread();
1758 test_id_
= ui_resource_
->id();
1759 ui_resource_
.reset();
1760 PostSetNeedsCommitToMainThread();
1763 // Release resource before ending the test.
1764 ui_resource_
.reset();
1768 // Make sure no extra commits happened.
1773 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1774 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1775 switch (time_step_
) {
1777 PostSetNeedsCommitToMainThread();
1780 PostSetNeedsCommitToMainThread();
1785 virtual void WillActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1786 switch (time_step_
) {
1788 // The resource creation callback has been called.
1789 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1790 // The resource is not yet lost (sanity check).
1791 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1792 // The resource should not have been created yet on the impl-side.
1793 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1802 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1803 LayerTreeHostContextTest::DidActivateTreeOnThread(impl
);
1804 switch (time_step_
) {
1806 // The pending requests on the impl-side should have been processed.
1807 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1810 // The "lost resource" callback should have been called once.
1811 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1814 // The resource is deleted and should not be in the manager. Use
1815 // test_id_ since ui_resource_ has been deleted.
1816 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(test_id_
));
1820 PostStepCompleteToMainThread();
1825 UIResourceId test_id_
;
1828 TEST_F(UIResourceLostBeforeActivateTree
,
1829 RunMultiThread_DirectRenderer_ImplSidePaint
) {
1830 RunTest(true, false, true);
1833 TEST_F(UIResourceLostBeforeActivateTree
,
1834 RunMultiThread_DelegatingRenderer_ImplSidePaint
) {
1835 RunTest(true, true, true);
1838 // Resources evicted explicitly and by visibility changes.
1839 class UIResourceLostEviction
: public UIResourceLostTestSimple
{
1841 virtual void StepCompleteOnMainThread(int step
) OVERRIDE
{
1842 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
1845 ui_resource_
= FakeScopedUIResource::Create(layer_tree_host());
1846 EXPECT_NE(0, ui_resource_
->id());
1847 PostSetNeedsCommitToMainThread();
1850 // Make the tree not visible.
1851 PostSetVisibleToMainThread(false);
1854 // Release resource before ending the test.
1855 ui_resource_
.reset();
1863 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl
* impl
,
1864 bool visible
) OVERRIDE
{
1865 TestWebGraphicsContext3D
* context
= TestContext();
1867 // All resources should have been evicted.
1868 ASSERT_EQ(0u, context
->NumTextures());
1869 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1870 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1871 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1872 // Drawing is disabled both because of the evicted resources and
1873 // because the renderer is not visible.
1874 EXPECT_FALSE(impl
->CanDraw());
1875 // Make the renderer visible again.
1876 PostSetVisibleToMainThread(true);
1880 virtual void StepCompleteOnImplThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1881 TestWebGraphicsContext3D
* context
= TestContext();
1882 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1883 switch (time_step_
) {
1885 // The resource should have been created on LTHI after the commit.
1886 ASSERT_EQ(1u, context
->NumTextures());
1887 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1888 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1889 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1890 EXPECT_TRUE(impl
->CanDraw());
1891 // Evict all UI resources. This will trigger a commit.
1892 impl
->EvictAllUIResources();
1893 ASSERT_EQ(0u, context
->NumTextures());
1894 EXPECT_EQ(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1895 EXPECT_EQ(1, ui_resource_
->resource_create_count
);
1896 EXPECT_EQ(0, ui_resource_
->lost_resource_count
);
1897 EXPECT_FALSE(impl
->CanDraw());
1900 // The resource should have been recreated.
1901 ASSERT_EQ(1u, context
->NumTextures());
1902 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1903 EXPECT_EQ(2, ui_resource_
->resource_create_count
);
1904 EXPECT_EQ(1, ui_resource_
->lost_resource_count
);
1905 EXPECT_TRUE(impl
->CanDraw());
1908 // The resource should have been recreated after visibility was
1910 ASSERT_EQ(1u, context
->NumTextures());
1911 EXPECT_NE(0u, impl
->ResourceIdForUIResource(ui_resource_
->id()));
1912 EXPECT_EQ(3, ui_resource_
->resource_create_count
);
1913 EXPECT_EQ(2, ui_resource_
->lost_resource_count
);
1914 EXPECT_TRUE(impl
->CanDraw());
1920 SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostEviction
);
1922 class LayerTreeHostContextTestSurfaceCreateCallback
1923 : public LayerTreeHostContextTest
{
1925 LayerTreeHostContextTestSurfaceCreateCallback()
1926 : LayerTreeHostContextTest(),
1927 layer_(FakeContentLayer::Create(&client_
)) {}
1929 virtual void SetupTree() OVERRIDE
{
1930 layer_
->SetBounds(gfx::Size(10, 20));
1931 layer_tree_host()->SetRootLayer(layer_
);
1932 LayerTreeHostContextTest::SetupTree();
1935 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1937 virtual void DidCommit() OVERRIDE
{
1938 switch (layer_tree_host()->source_frame_number()) {
1940 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1941 layer_tree_host()->SetNeedsCommit();
1944 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1945 layer_tree_host()->SetNeedsCommit();
1948 EXPECT_EQ(1u, layer_
->output_surface_created_count());
1951 EXPECT_EQ(2u, layer_
->output_surface_created_count());
1952 layer_tree_host()->SetNeedsCommit();
1957 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1958 LayerTreeHostContextTest::CommitCompleteOnThread(impl
);
1959 switch (LastCommittedSourceFrameNumber(impl
)) {
1973 virtual void DidInitializeOutputSurface(bool succeeded
) OVERRIDE
{
1974 EXPECT_TRUE(succeeded
);
1977 virtual void AfterTest() OVERRIDE
{}
1980 FakeContentLayerClient client_
;
1981 scoped_refptr
<FakeContentLayer
> layer_
;
1984 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestSurfaceCreateCallback
);