1 // Copyright 2013 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/output/copy_output_request.h"
6 #include "cc/output/copy_output_result.h"
7 #include "cc/test/fake_content_layer.h"
8 #include "cc/test/fake_content_layer_client.h"
9 #include "cc/test/fake_output_surface.h"
10 #include "cc/test/layer_tree_test.h"
11 #include "cc/trees/layer_tree_impl.h"
12 #include "gpu/GLES2/gl2extchromium.h"
17 // These tests only use direct rendering, as there is no output to copy for
18 // delegated renderers.
19 class LayerTreeHostCopyRequestTest
: public LayerTreeTest
{};
21 class LayerTreeHostCopyRequestTestMultipleRequests
22 : public LayerTreeHostCopyRequestTest
{
24 void SetupTree() override
{
25 root
= FakeContentLayer::Create(&client_
);
26 root
->SetBounds(gfx::Size(20, 20));
28 child
= FakeContentLayer::Create(&client_
);
29 child
->SetBounds(gfx::Size(10, 10));
30 root
->AddChild(child
);
32 layer_tree_host()->SetRootLayer(root
);
33 LayerTreeHostCopyRequestTest::SetupTree();
36 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
38 void DidCommitAndDrawFrame() override
{ WaitForCallback(); }
40 void WaitForCallback() {
41 base::MessageLoop::current()->PostTask(
43 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::NextStep
,
44 base::Unretained(this)));
48 int frame
= layer_tree_host()->source_frame_number();
51 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
52 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
54 base::Unretained(this))));
55 EXPECT_EQ(0u, callbacks_
.size());
58 if (callbacks_
.size() < 1u) {
62 EXPECT_EQ(1u, callbacks_
.size());
63 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[0].ToString());
65 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
66 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
68 base::Unretained(this))));
69 root
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
70 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
72 base::Unretained(this))));
73 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
74 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
76 base::Unretained(this))));
77 EXPECT_EQ(1u, callbacks_
.size());
80 if (callbacks_
.size() < 4u) {
84 EXPECT_EQ(4u, callbacks_
.size());
85 // The child was copied to a bitmap and passed back twice.
86 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[1].ToString());
87 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[2].ToString());
88 // The root was copied to a bitmap and passed back also.
89 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_
[3].ToString());
95 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
96 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
97 EXPECT_TRUE(result
->HasBitmap());
98 scoped_ptr
<SkBitmap
> bitmap
= result
->TakeBitmap().Pass();
99 EXPECT_EQ(result
->size().ToString(),
100 gfx::Size(bitmap
->width(), bitmap
->height()).ToString());
101 callbacks_
.push_back(result
->size());
104 void AfterTest() override
{ EXPECT_EQ(4u, callbacks_
.size()); }
106 scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(
107 bool fallback
) override
{
108 if (use_gl_renderer_
)
109 return FakeOutputSurface::Create3d();
110 return FakeOutputSurface::CreateSoftware(
111 make_scoped_ptr(new SoftwareOutputDevice
));
114 bool use_gl_renderer_
;
115 std::vector
<gfx::Size
> callbacks_
;
116 FakeContentLayerClient client_
;
117 scoped_refptr
<FakeContentLayer
> root
;
118 scoped_refptr
<FakeContentLayer
> child
;
121 // Readback can't be done with a delegating renderer.
122 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests
,
123 GLRenderer_RunSingleThread
) {
124 use_gl_renderer_
= true;
125 RunTest(false, false, false);
128 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests
,
129 GLRenderer_RunMultiThread_MainThreadPainting
) {
130 use_gl_renderer_
= true;
131 RunTest(true, false, false);
134 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests
,
135 SoftwareRenderer_RunSingleThread
) {
136 use_gl_renderer_
= false;
137 RunTest(false, false, false);
140 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests
,
141 SoftwareRenderer_RunMultiThread_MainThreadPainting
) {
142 use_gl_renderer_
= false;
143 RunTest(true, false, false);
146 class LayerTreeHostCopyRequestTestLayerDestroyed
147 : public LayerTreeHostCopyRequestTest
{
149 void SetupTree() override
{
150 root_
= FakeContentLayer::Create(&client_
);
151 root_
->SetBounds(gfx::Size(20, 20));
153 main_destroyed_
= FakeContentLayer::Create(&client_
);
154 main_destroyed_
->SetBounds(gfx::Size(15, 15));
155 root_
->AddChild(main_destroyed_
);
157 impl_destroyed_
= FakeContentLayer::Create(&client_
);
158 impl_destroyed_
->SetBounds(gfx::Size(10, 10));
159 root_
->AddChild(impl_destroyed_
);
161 layer_tree_host()->SetRootLayer(root_
);
162 LayerTreeHostCopyRequestTest::SetupTree();
165 void BeginTest() override
{
167 PostSetNeedsCommitToMainThread();
170 void DidCommit() override
{
171 int frame
= layer_tree_host()->source_frame_number();
174 main_destroyed_
->RequestCopyOfOutput(
175 CopyOutputRequest::CreateBitmapRequest(base::Bind(
176 &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback
,
177 base::Unretained(this))));
178 impl_destroyed_
->RequestCopyOfOutput(
179 CopyOutputRequest::CreateBitmapRequest(base::Bind(
180 &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback
,
181 base::Unretained(this))));
182 EXPECT_EQ(0, callback_count_
);
184 // Destroy the main thread layer right away.
185 main_destroyed_
->RemoveFromParent();
186 main_destroyed_
= NULL
;
188 // Should callback with a NULL bitmap.
189 EXPECT_EQ(1, callback_count_
);
191 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
192 layer_tree_host()->SetViewportSize(gfx::Size());
195 // Flush the message loops and make sure the callbacks run.
196 layer_tree_host()->SetNeedsCommit();
199 // No drawing means no readback yet.
200 EXPECT_EQ(1, callback_count_
);
202 // Destroy the impl thread layer.
203 impl_destroyed_
->RemoveFromParent();
204 impl_destroyed_
= NULL
;
206 // No callback yet because it's on the impl side.
207 EXPECT_EQ(1, callback_count_
);
210 // Flush the message loops and make sure the callbacks run.
211 layer_tree_host()->SetNeedsCommit();
214 // We should get another callback with a NULL bitmap.
215 EXPECT_EQ(2, callback_count_
);
221 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
222 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
223 EXPECT_TRUE(result
->IsEmpty());
227 void AfterTest() override
{}
230 FakeContentLayerClient client_
;
231 scoped_refptr
<FakeContentLayer
> root_
;
232 scoped_refptr
<FakeContentLayer
> main_destroyed_
;
233 scoped_refptr
<FakeContentLayer
> impl_destroyed_
;
236 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed
);
238 class LayerTreeHostCopyRequestTestInHiddenSubtree
239 : public LayerTreeHostCopyRequestTest
{
241 void SetupTree() override
{
242 root_
= FakeContentLayer::Create(&client_
);
243 root_
->SetBounds(gfx::Size(20, 20));
245 grand_parent_layer_
= FakeContentLayer::Create(&client_
);
246 grand_parent_layer_
->SetBounds(gfx::Size(15, 15));
247 root_
->AddChild(grand_parent_layer_
);
249 // parent_layer_ owns a render surface.
250 parent_layer_
= FakeContentLayer::Create(&client_
);
251 parent_layer_
->SetBounds(gfx::Size(15, 15));
252 parent_layer_
->SetForceRenderSurface(true);
253 grand_parent_layer_
->AddChild(parent_layer_
);
255 copy_layer_
= FakeContentLayer::Create(&client_
);
256 copy_layer_
->SetBounds(gfx::Size(10, 10));
257 parent_layer_
->AddChild(copy_layer_
);
259 layer_tree_host()->SetRootLayer(root_
);
260 LayerTreeHostCopyRequestTest::SetupTree();
263 void AddCopyRequest(Layer
* layer
) {
264 layer
->RequestCopyOfOutput(
265 CopyOutputRequest::CreateBitmapRequest(base::Bind(
266 &LayerTreeHostCopyRequestTestInHiddenSubtree::CopyOutputCallback
,
267 base::Unretained(this))));
270 void BeginTest() override
{
272 PostSetNeedsCommitToMainThread();
274 AddCopyRequest(copy_layer_
.get());
277 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
279 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
280 EXPECT_EQ(copy_layer_
->bounds().ToString(), result
->size().ToString())
282 switch (callback_count_
) {
284 // Hide the copy request layer.
285 grand_parent_layer_
->SetHideLayerAndSubtree(false);
286 parent_layer_
->SetHideLayerAndSubtree(false);
287 copy_layer_
->SetHideLayerAndSubtree(true);
288 AddCopyRequest(copy_layer_
.get());
291 // Hide the copy request layer's parent only.
292 grand_parent_layer_
->SetHideLayerAndSubtree(false);
293 parent_layer_
->SetHideLayerAndSubtree(true);
294 copy_layer_
->SetHideLayerAndSubtree(false);
295 AddCopyRequest(copy_layer_
.get());
298 // Hide the copy request layer's grand parent only.
299 grand_parent_layer_
->SetHideLayerAndSubtree(true);
300 parent_layer_
->SetHideLayerAndSubtree(false);
301 copy_layer_
->SetHideLayerAndSubtree(false);
302 AddCopyRequest(copy_layer_
.get());
305 // Hide the copy request layer's parent and grandparent.
306 grand_parent_layer_
->SetHideLayerAndSubtree(true);
307 parent_layer_
->SetHideLayerAndSubtree(true);
308 copy_layer_
->SetHideLayerAndSubtree(false);
309 AddCopyRequest(copy_layer_
.get());
312 // Hide the copy request layer as well as its parent and grandparent.
313 grand_parent_layer_
->SetHideLayerAndSubtree(true);
314 parent_layer_
->SetHideLayerAndSubtree(true);
315 copy_layer_
->SetHideLayerAndSubtree(true);
316 AddCopyRequest(copy_layer_
.get());
324 void AfterTest() override
{}
327 FakeContentLayerClient client_
;
328 scoped_refptr
<FakeContentLayer
> root_
;
329 scoped_refptr
<FakeContentLayer
> grand_parent_layer_
;
330 scoped_refptr
<FakeContentLayer
> parent_layer_
;
331 scoped_refptr
<FakeContentLayer
> copy_layer_
;
334 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
335 LayerTreeHostCopyRequestTestInHiddenSubtree
);
337 class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
338 : public LayerTreeHostCopyRequestTest
{
340 void SetupTree() override
{
341 root_
= FakeContentLayer::Create(&client_
);
342 root_
->SetBounds(gfx::Size(20, 20));
344 grand_parent_layer_
= FakeContentLayer::Create(&client_
);
345 grand_parent_layer_
->SetBounds(gfx::Size(15, 15));
346 grand_parent_layer_
->SetHideLayerAndSubtree(true);
347 root_
->AddChild(grand_parent_layer_
);
349 // parent_layer_ owns a render surface.
350 parent_layer_
= FakeContentLayer::Create(&client_
);
351 parent_layer_
->SetBounds(gfx::Size(15, 15));
352 parent_layer_
->SetForceRenderSurface(true);
353 grand_parent_layer_
->AddChild(parent_layer_
);
355 copy_layer_
= FakeContentLayer::Create(&client_
);
356 copy_layer_
->SetBounds(gfx::Size(10, 10));
357 parent_layer_
->AddChild(copy_layer_
);
359 layer_tree_host()->SetRootLayer(root_
);
360 LayerTreeHostCopyRequestTest::SetupTree();
363 void BeginTest() override
{
365 PostSetNeedsCommitToMainThread();
367 copy_layer_
->RequestCopyOfOutput(
368 CopyOutputRequest::CreateBitmapRequest(base::Bind(
369 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
371 base::Unretained(this))));
374 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
375 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
376 EXPECT_EQ(copy_layer_
->bounds().ToString(), result
->size().ToString());
380 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
381 Renderer
* renderer
= host_impl
->renderer();
383 LayerImpl
* root
= host_impl
->active_tree()->root_layer();
384 LayerImpl
* grand_parent
= root
->children()[0];
385 LayerImpl
* parent
= grand_parent
->children()[0];
386 LayerImpl
* copy_layer
= parent
->children()[0];
388 // |parent| owns a surface, but it was hidden and not part of the copy
389 // request so it should not allocate any resource.
390 EXPECT_FALSE(renderer
->HasAllocatedResourcesForTesting(
391 parent
->render_surface()->GetRenderPassId()));
393 // |copy_layer| should have been rendered to a texture since it was needed
394 // for a copy request.
395 EXPECT_TRUE(renderer
->HasAllocatedResourcesForTesting(
396 copy_layer
->render_surface()->GetRenderPassId()));
401 void AfterTest() override
{ EXPECT_TRUE(did_draw_
); }
403 FakeContentLayerClient client_
;
405 scoped_refptr
<FakeContentLayer
> root_
;
406 scoped_refptr
<FakeContentLayer
> grand_parent_layer_
;
407 scoped_refptr
<FakeContentLayer
> parent_layer_
;
408 scoped_refptr
<FakeContentLayer
> copy_layer_
;
411 // No output to copy for delegated renderers.
412 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
413 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
);
415 class LayerTreeHostCopyRequestTestClippedOut
416 : public LayerTreeHostCopyRequestTest
{
418 void SetupTree() override
{
419 root_
= FakeContentLayer::Create(&client_
);
420 root_
->SetBounds(gfx::Size(20, 20));
422 parent_layer_
= FakeContentLayer::Create(&client_
);
423 parent_layer_
->SetBounds(gfx::Size(15, 15));
424 parent_layer_
->SetMasksToBounds(true);
425 root_
->AddChild(parent_layer_
);
427 copy_layer_
= FakeContentLayer::Create(&client_
);
428 copy_layer_
->SetPosition(gfx::Point(15, 15));
429 copy_layer_
->SetBounds(gfx::Size(10, 10));
430 parent_layer_
->AddChild(copy_layer_
);
432 layer_tree_host()->SetRootLayer(root_
);
433 LayerTreeHostCopyRequestTest::SetupTree();
436 void BeginTest() override
{
437 PostSetNeedsCommitToMainThread();
439 copy_layer_
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
440 base::Bind(&LayerTreeHostCopyRequestTestClippedOut::CopyOutputCallback
,
441 base::Unretained(this))));
444 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
445 // We should still get a callback with no output if the copy requested layer
446 // was completely clipped away.
447 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
448 EXPECT_EQ(gfx::Size().ToString(), result
->size().ToString());
452 void AfterTest() override
{}
454 FakeContentLayerClient client_
;
455 scoped_refptr
<FakeContentLayer
> root_
;
456 scoped_refptr
<FakeContentLayer
> parent_layer_
;
457 scoped_refptr
<FakeContentLayer
> copy_layer_
;
460 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
461 LayerTreeHostCopyRequestTestClippedOut
);
463 class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
464 : public LayerTreeHostCopyRequestTest
{
466 void SetupTree() override
{
467 root_
= FakeContentLayer::Create(&client_
);
468 root_
->SetBounds(gfx::Size(20, 20));
470 copy_layer_
= FakeContentLayer::Create(&client_
);
471 copy_layer_
->SetBounds(gfx::Size(10, 10));
472 root_
->AddChild(copy_layer_
);
474 layer_tree_host()->SetRootLayer(root_
);
475 LayerTreeHostCopyRequestTest::SetupTree();
478 void AddCopyRequest(Layer
* layer
) {
479 layer
->RequestCopyOfOutput(
480 CopyOutputRequest::CreateBitmapRequest(base::Bind(
481 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback
,
482 base::Unretained(this))));
485 void BeginTest() override
{
486 saw_copy_request_
= false;
488 PostSetNeedsCommitToMainThread();
491 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
493 AddCopyRequest(copy_layer_
.get());
496 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
497 if (impl
->active_tree()->source_frame_number() == 0) {
498 LayerImpl
* root
= impl
->active_tree()->root_layer();
499 EXPECT_TRUE(root
->children()[0]->HasCopyRequest());
500 saw_copy_request_
= true;
504 void DidCommit() override
{
505 if (layer_tree_host()->source_frame_number() == 1) {
507 layer_tree_host()->SetViewportSize(gfx::Size(root_
->bounds()));
509 AddCopyRequest(copy_layer_
.get());
513 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
514 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
515 EXPECT_EQ(copy_layer_
->bounds().ToString(), result
->size().ToString());
518 if (callback_count_
== 2)
522 void AfterTest() override
{ EXPECT_TRUE(saw_copy_request_
); }
524 bool saw_copy_request_
;
526 FakeContentLayerClient client_
;
527 scoped_refptr
<FakeContentLayer
> root_
;
528 scoped_refptr
<FakeContentLayer
> copy_layer_
;
531 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
532 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
);
534 class LayerTreeHostCopyRequestTestLostOutputSurface
535 : public LayerTreeHostCopyRequestTest
{
537 scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(
538 bool fallback
) override
{
539 if (!first_context_provider_
.get()) {
540 first_context_provider_
= TestContextProvider::Create();
541 return FakeOutputSurface::Create3d(first_context_provider_
);
544 EXPECT_FALSE(second_context_provider_
.get());
545 second_context_provider_
= TestContextProvider::Create();
546 return FakeOutputSurface::Create3d(second_context_provider_
);
549 void SetupTree() override
{
550 root_
= FakeContentLayer::Create(&client_
);
551 root_
->SetBounds(gfx::Size(20, 20));
553 copy_layer_
= FakeContentLayer::Create(&client_
);
554 copy_layer_
->SetBounds(gfx::Size(10, 10));
555 root_
->AddChild(copy_layer_
);
557 layer_tree_host()->SetRootLayer(root_
);
558 LayerTreeHostCopyRequestTest::SetupTree();
561 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
563 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
564 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
565 EXPECT_EQ(gfx::Size(10, 10).ToString(), result
->size().ToString());
566 EXPECT_TRUE(result
->HasTexture());
568 // Save the result for later.
569 EXPECT_FALSE(result_
);
570 result_
= result
.Pass();
572 // Post a commit to lose the output surface.
573 layer_tree_host()->SetNeedsCommit();
576 void DidCommitAndDrawFrame() override
{
577 switch (layer_tree_host()->source_frame_number()) {
579 // The layers have been pushed to the impl side. The layer textures have
582 // Request a copy of the layer. This will use another texture.
583 copy_layer_
->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
584 base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface::
586 base::Unretained(this))));
589 // With SingleThreadProxy it takes two commits to finally swap after a
592 // Now destroy the CopyOutputResult, releasing the texture inside back
593 // to the compositor.
594 EXPECT_TRUE(result_
);
597 // Check that it is released.
598 ImplThreadTaskRunner()->PostTask(
600 base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface::
602 base::Unretained(this),
603 num_textures_after_loss_
- 1));
608 void SwapBuffersOnThread(LayerTreeHostImpl
* impl
, bool result
) override
{
609 switch (impl
->active_tree()->source_frame_number()) {
611 // The layers have been drawn, so their textures have been allocated.
612 EXPECT_FALSE(result_
);
613 num_textures_without_readback_
=
614 first_context_provider_
->TestContext3d()->NumTextures();
617 // We did a readback, so there will be a readback texture around now.
618 EXPECT_LT(num_textures_without_readback_
,
619 first_context_provider_
->TestContext3d()->NumTextures());
622 // The readback texture is collected.
623 EXPECT_TRUE(result_
);
625 // Lose the output surface.
626 first_context_provider_
->TestContext3d()->loseContextCHROMIUM(
627 GL_GUILTY_CONTEXT_RESET_ARB
, GL_INNOCENT_CONTEXT_RESET_ARB
);
630 // With SingleThreadProxy it takes two commits to finally swap after a
633 // The output surface has been recreated.
634 EXPECT_TRUE(second_context_provider_
.get());
636 num_textures_after_loss_
=
637 first_context_provider_
->TestContext3d()->NumTextures();
642 void CheckNumTextures(size_t expected_num_textures
) {
643 EXPECT_EQ(expected_num_textures
,
644 first_context_provider_
->TestContext3d()->NumTextures());
648 void AfterTest() override
{}
650 scoped_refptr
<TestContextProvider
> first_context_provider_
;
651 scoped_refptr
<TestContextProvider
> second_context_provider_
;
652 size_t num_textures_without_readback_
;
653 size_t num_textures_after_loss_
;
654 FakeContentLayerClient client_
;
655 scoped_refptr
<FakeContentLayer
> root_
;
656 scoped_refptr
<FakeContentLayer
> copy_layer_
;
657 scoped_ptr
<CopyOutputResult
> result_
;
660 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
661 LayerTreeHostCopyRequestTestLostOutputSurface
);
663 class LayerTreeHostCopyRequestTestCountTextures
664 : public LayerTreeHostCopyRequestTest
{
666 scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(
667 bool fallback
) override
{
668 context_provider_
= TestContextProvider::Create();
669 return FakeOutputSurface::Create3d(context_provider_
);
672 void SetupTree() override
{
673 root_
= FakeContentLayer::Create(&client_
);
674 root_
->SetBounds(gfx::Size(20, 20));
676 copy_layer_
= FakeContentLayer::Create(&client_
);
677 copy_layer_
->SetBounds(gfx::Size(10, 10));
678 root_
->AddChild(copy_layer_
);
680 layer_tree_host()->SetRootLayer(root_
);
681 LayerTreeHostCopyRequestTest::SetupTree();
684 void BeginTest() override
{
685 num_textures_without_readback_
= 0;
686 num_textures_with_readback_
= 0;
687 waited_sync_point_after_readback_
= 0;
688 PostSetNeedsCommitToMainThread();
691 virtual void RequestCopy(Layer
* layer
) = 0;
693 void DidCommitAndDrawFrame() override
{
694 switch (layer_tree_host()->source_frame_number()) {
696 // The layers have been pushed to the impl side. The layer textures have
698 RequestCopy(copy_layer_
.get());
703 void SwapBuffersOnThread(LayerTreeHostImpl
* impl
, bool result
) override
{
704 switch (impl
->active_tree()->source_frame_number()) {
706 // The layers have been drawn, so their textures have been allocated.
707 num_textures_without_readback_
=
708 context_provider_
->TestContext3d()->NumTextures();
711 // We did a readback, so there will be a readback texture around now.
712 num_textures_with_readback_
=
713 context_provider_
->TestContext3d()->NumTextures();
714 waited_sync_point_after_readback_
=
715 context_provider_
->TestContext3d()->last_waited_sync_point();
717 MainThreadTaskRunner()->PostTask(
719 base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest
,
720 base::Unretained(this)));
725 virtual void DoEndTest() { EndTest(); }
727 scoped_refptr
<TestContextProvider
> context_provider_
;
728 size_t num_textures_without_readback_
;
729 size_t num_textures_with_readback_
;
730 unsigned waited_sync_point_after_readback_
;
731 FakeContentLayerClient client_
;
732 scoped_refptr
<FakeContentLayer
> root_
;
733 scoped_refptr
<FakeContentLayer
> copy_layer_
;
736 class LayerTreeHostCopyRequestTestCreatesTexture
737 : public LayerTreeHostCopyRequestTestCountTextures
{
739 void RequestCopy(Layer
* layer
) override
{
740 // Request a normal texture copy. This should create a new texture.
741 copy_layer_
->RequestCopyOfOutput(
742 CopyOutputRequest::CreateRequest(base::Bind(
743 &LayerTreeHostCopyRequestTestCreatesTexture::CopyOutputCallback
,
744 base::Unretained(this))));
747 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
748 EXPECT_FALSE(result
->IsEmpty());
749 EXPECT_TRUE(result
->HasTexture());
751 TextureMailbox mailbox
;
752 scoped_ptr
<SingleReleaseCallback
> release
;
753 result
->TakeTexture(&mailbox
, &release
);
754 EXPECT_TRUE(release
);
756 release
->Run(0, false);
759 void AfterTest() override
{
760 // No sync point was needed.
761 EXPECT_EQ(0u, waited_sync_point_after_readback_
);
762 // Except the copy to have made another texture.
763 EXPECT_EQ(num_textures_without_readback_
+ 1, num_textures_with_readback_
);
767 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
768 LayerTreeHostCopyRequestTestCreatesTexture
);
770 class LayerTreeHostCopyRequestTestProvideTexture
771 : public LayerTreeHostCopyRequestTestCountTextures
{
773 void BeginTest() override
{
774 external_context_provider_
= TestContextProvider::Create();
775 EXPECT_TRUE(external_context_provider_
->BindToCurrentThread());
776 LayerTreeHostCopyRequestTestCountTextures::BeginTest();
779 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
780 EXPECT_FALSE(result
->IsEmpty());
781 EXPECT_TRUE(result
->HasTexture());
783 TextureMailbox mailbox
;
784 scoped_ptr
<SingleReleaseCallback
> release
;
785 result
->TakeTexture(&mailbox
, &release
);
786 EXPECT_FALSE(release
);
789 void RequestCopy(Layer
* layer
) override
{
790 // Request a copy to a provided texture. This should not create a new
792 scoped_ptr
<CopyOutputRequest
> request
=
793 CopyOutputRequest::CreateRequest(base::Bind(
794 &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback
,
795 base::Unretained(this)));
797 gpu::gles2::GLES2Interface
* gl
= external_context_provider_
->ContextGL();
798 gpu::Mailbox mailbox
;
799 gl
->GenMailboxCHROMIUM(mailbox
.name
);
800 sync_point_
= gl
->InsertSyncPointCHROMIUM();
801 request
->SetTextureMailbox(
802 TextureMailbox(mailbox
, GL_TEXTURE_2D
, sync_point_
));
803 EXPECT_TRUE(request
->has_texture_mailbox());
805 copy_layer_
->RequestCopyOfOutput(request
.Pass());
808 void AfterTest() override
{
809 // Expect the compositor to have waited for the sync point in the provided
811 EXPECT_EQ(sync_point_
, waited_sync_point_after_readback_
);
812 // Except the copy to have *not* made another texture.
813 EXPECT_EQ(num_textures_without_readback_
, num_textures_with_readback_
);
816 scoped_refptr
<TestContextProvider
> external_context_provider_
;
817 unsigned sync_point_
;
820 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
821 LayerTreeHostCopyRequestTestProvideTexture
);
823 class LayerTreeHostCopyRequestTestDestroyBeforeCopy
824 : public LayerTreeHostCopyRequestTest
{
826 void SetupTree() override
{
827 root_
= FakeContentLayer::Create(&client_
);
828 root_
->SetBounds(gfx::Size(20, 20));
830 copy_layer_
= FakeContentLayer::Create(&client_
);
831 copy_layer_
->SetBounds(gfx::Size(10, 10));
832 root_
->AddChild(copy_layer_
);
834 layer_tree_host()->SetRootLayer(root_
);
835 LayerTreeHostCopyRequestTest::SetupTree();
838 void BeginTest() override
{
840 PostSetNeedsCommitToMainThread();
843 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
844 EXPECT_TRUE(result
->IsEmpty());
848 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
849 MainThreadTaskRunner()->PostTask(
851 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate
,
852 base::Unretained(this)));
856 switch (layer_tree_host()->source_frame_number()) {
858 EXPECT_EQ(0, callback_count_
);
859 // Put a copy request on the layer, but then don't allow any
860 // drawing to take place.
861 scoped_ptr
<CopyOutputRequest
> request
=
862 CopyOutputRequest::CreateRequest(
863 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::
865 base::Unretained(this)));
866 copy_layer_
->RequestCopyOfOutput(request
.Pass());
868 layer_tree_host()->SetViewportSize(gfx::Size());
872 EXPECT_EQ(0, callback_count_
);
873 // Remove the copy layer before we were able to draw.
874 copy_layer_
->RemoveFromParent();
877 EXPECT_EQ(1, callback_count_
);
878 // Allow us to draw now.
879 layer_tree_host()->SetViewportSize(
880 layer_tree_host()->root_layer()->bounds());
883 EXPECT_EQ(1, callback_count_
);
884 // We should not have crashed.
889 void AfterTest() override
{}
892 FakeContentLayerClient client_
;
893 scoped_refptr
<FakeContentLayer
> root_
;
894 scoped_refptr
<FakeContentLayer
> copy_layer_
;
897 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
898 LayerTreeHostCopyRequestTestDestroyBeforeCopy
);
900 class LayerTreeHostCopyRequestTestShutdownBeforeCopy
901 : public LayerTreeHostCopyRequestTest
{
903 void SetupTree() override
{
904 root_
= FakeContentLayer::Create(&client_
);
905 root_
->SetBounds(gfx::Size(20, 20));
907 copy_layer_
= FakeContentLayer::Create(&client_
);
908 copy_layer_
->SetBounds(gfx::Size(10, 10));
909 root_
->AddChild(copy_layer_
);
911 layer_tree_host()->SetRootLayer(root_
);
912 LayerTreeHostCopyRequestTest::SetupTree();
915 void BeginTest() override
{
917 PostSetNeedsCommitToMainThread();
920 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
921 EXPECT_TRUE(result
->IsEmpty());
925 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
926 MainThreadTaskRunner()->PostTask(
928 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::DidActivate
,
929 base::Unretained(this)));
933 switch (layer_tree_host()->source_frame_number()) {
935 EXPECT_EQ(0, callback_count_
);
936 // Put a copy request on the layer, but then don't allow any
937 // drawing to take place.
938 scoped_ptr
<CopyOutputRequest
> request
=
939 CopyOutputRequest::CreateRequest(
940 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::
942 base::Unretained(this)));
943 copy_layer_
->RequestCopyOfOutput(request
.Pass());
945 layer_tree_host()->SetViewportSize(gfx::Size());
949 DestroyLayerTreeHost();
950 // End the test after the copy result has had a chance to get back to
952 MainThreadTaskRunner()->PostTask(
954 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::EndTest
,
955 base::Unretained(this)));
960 void AfterTest() override
{ EXPECT_EQ(1, callback_count_
); }
963 FakeContentLayerClient client_
;
964 scoped_refptr
<FakeContentLayer
> root_
;
965 scoped_refptr
<FakeContentLayer
> copy_layer_
;
968 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
969 LayerTreeHostCopyRequestTestShutdownBeforeCopy
);