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/layers/layer_iterator.h"
6 #include "cc/output/copy_output_request.h"
7 #include "cc/output/copy_output_result.h"
8 #include "cc/test/fake_content_layer_client.h"
9 #include "cc/test/fake_output_surface.h"
10 #include "cc/test/fake_picture_layer.h"
11 #include "cc/test/layer_tree_test.h"
12 #include "cc/trees/layer_tree_impl.h"
13 #include "gpu/GLES2/gl2extchromium.h"
18 // These tests only use direct rendering, as there is no output to copy for
19 // delegated renderers.
20 class LayerTreeHostCopyRequestTest
: public LayerTreeTest
{};
22 class LayerTreeHostCopyRequestTestMultipleRequests
23 : public LayerTreeHostCopyRequestTest
{
25 void SetupTree() override
{
26 root
= FakePictureLayer::Create(layer_settings(), &client_
);
27 root
->SetBounds(gfx::Size(20, 20));
29 child
= FakePictureLayer::Create(layer_settings(), &client_
);
30 child
->SetBounds(gfx::Size(10, 10));
31 root
->AddChild(child
);
33 layer_tree_host()->SetRootLayer(root
);
34 LayerTreeHostCopyRequestTest::SetupTree();
37 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
39 void DidCommitAndDrawFrame() override
{ WaitForCallback(); }
41 void WaitForCallback() {
42 base::MessageLoop::current()->PostTask(
44 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::NextStep
,
45 base::Unretained(this)));
49 int frame
= layer_tree_host()->source_frame_number();
52 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
53 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
55 base::Unretained(this))));
56 EXPECT_EQ(0u, callbacks_
.size());
59 if (callbacks_
.size() < 1u) {
63 EXPECT_EQ(1u, callbacks_
.size());
64 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[0].ToString());
66 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
67 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
69 base::Unretained(this))));
70 root
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
71 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
73 base::Unretained(this))));
74 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
75 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
77 base::Unretained(this))));
78 EXPECT_EQ(1u, callbacks_
.size());
81 if (callbacks_
.size() < 4u) {
85 EXPECT_EQ(4u, callbacks_
.size());
86 // The child was copied to a bitmap and passed back twice.
87 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[1].ToString());
88 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[2].ToString());
89 // The root was copied to a bitmap and passed back also.
90 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_
[3].ToString());
96 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
97 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
98 EXPECT_TRUE(result
->HasBitmap());
99 scoped_ptr
<SkBitmap
> bitmap
= result
->TakeBitmap().Pass();
100 EXPECT_EQ(result
->size().ToString(),
101 gfx::Size(bitmap
->width(), bitmap
->height()).ToString());
102 callbacks_
.push_back(result
->size());
105 void AfterTest() override
{ EXPECT_EQ(4u, callbacks_
.size()); }
107 scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface() 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
<FakePictureLayer
> root
;
118 scoped_refptr
<FakePictureLayer
> child
;
121 // Readback can't be done with a delegating renderer.
122 // Disabled due to flake: http://crbug.com/448521
123 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests
,
124 DISABLED_GLRenderer_RunSingleThread
) {
125 use_gl_renderer_
= true;
126 RunTest(false, false, false);
129 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests
,
130 GLRenderer_RunMultiThread_MainThreadPainting
) {
131 use_gl_renderer_
= true;
132 RunTest(true, false, false);
135 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests
,
136 SoftwareRenderer_RunSingleThread
) {
137 use_gl_renderer_
= false;
138 RunTest(false, false, false);
141 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests
,
142 SoftwareRenderer_RunMultiThread_MainThreadPainting
) {
143 use_gl_renderer_
= false;
144 RunTest(true, false, false);
147 class LayerTreeHostCopyRequestTestLayerDestroyed
148 : public LayerTreeHostCopyRequestTest
{
150 void SetupTree() override
{
151 root_
= FakePictureLayer::Create(layer_settings(), &client_
);
152 root_
->SetBounds(gfx::Size(20, 20));
154 main_destroyed_
= FakePictureLayer::Create(layer_settings(), &client_
);
155 main_destroyed_
->SetBounds(gfx::Size(15, 15));
156 root_
->AddChild(main_destroyed_
);
158 impl_destroyed_
= FakePictureLayer::Create(layer_settings(), &client_
);
159 impl_destroyed_
->SetBounds(gfx::Size(10, 10));
160 root_
->AddChild(impl_destroyed_
);
162 layer_tree_host()->SetRootLayer(root_
);
163 LayerTreeHostCopyRequestTest::SetupTree();
166 void BeginTest() override
{
168 PostSetNeedsCommitToMainThread();
171 void DidCommit() override
{
172 int frame
= layer_tree_host()->source_frame_number();
175 main_destroyed_
->RequestCopyOfOutput(
176 CopyOutputRequest::CreateBitmapRequest(base::Bind(
177 &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback
,
178 base::Unretained(this))));
179 impl_destroyed_
->RequestCopyOfOutput(
180 CopyOutputRequest::CreateBitmapRequest(base::Bind(
181 &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback
,
182 base::Unretained(this))));
183 EXPECT_EQ(0, callback_count_
);
185 // Destroy the main thread layer right away.
186 main_destroyed_
->RemoveFromParent();
187 main_destroyed_
= NULL
;
189 // Should callback with a NULL bitmap.
190 EXPECT_EQ(1, callback_count_
);
192 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
193 layer_tree_host()->SetViewportSize(gfx::Size());
196 // Flush the message loops and make sure the callbacks run.
197 layer_tree_host()->SetNeedsCommit();
200 // No drawing means no readback yet.
201 EXPECT_EQ(1, callback_count_
);
203 // Destroy the impl thread layer.
204 impl_destroyed_
->RemoveFromParent();
205 impl_destroyed_
= NULL
;
207 // No callback yet because it's on the impl side.
208 EXPECT_EQ(1, callback_count_
);
211 // Flush the message loops and make sure the callbacks run.
212 layer_tree_host()->SetNeedsCommit();
215 // We should get another callback with a NULL bitmap.
216 EXPECT_EQ(2, callback_count_
);
222 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
223 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
224 EXPECT_TRUE(result
->IsEmpty());
228 void AfterTest() override
{}
231 FakeContentLayerClient client_
;
232 scoped_refptr
<FakePictureLayer
> root_
;
233 scoped_refptr
<FakePictureLayer
> main_destroyed_
;
234 scoped_refptr
<FakePictureLayer
> impl_destroyed_
;
237 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed
);
239 class LayerTreeHostCopyRequestTestInHiddenSubtree
240 : public LayerTreeHostCopyRequestTest
{
242 void SetupTree() override
{
243 root_
= FakePictureLayer::Create(layer_settings(), &client_
);
244 root_
->SetBounds(gfx::Size(20, 20));
246 grand_parent_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
247 grand_parent_layer_
->SetBounds(gfx::Size(15, 15));
248 root_
->AddChild(grand_parent_layer_
);
250 // parent_layer_ owns a render surface.
251 parent_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
252 parent_layer_
->SetBounds(gfx::Size(15, 15));
253 parent_layer_
->SetForceRenderSurface(true);
254 grand_parent_layer_
->AddChild(parent_layer_
);
256 copy_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
257 copy_layer_
->SetBounds(gfx::Size(10, 10));
258 parent_layer_
->AddChild(copy_layer_
);
260 layer_tree_host()->SetRootLayer(root_
);
261 LayerTreeHostCopyRequestTest::SetupTree();
264 void AddCopyRequest(Layer
* layer
) {
265 layer
->RequestCopyOfOutput(
266 CopyOutputRequest::CreateBitmapRequest(base::Bind(
267 &LayerTreeHostCopyRequestTestInHiddenSubtree::CopyOutputCallback
,
268 base::Unretained(this))));
271 void BeginTest() override
{
273 PostSetNeedsCommitToMainThread();
275 AddCopyRequest(copy_layer_
.get());
278 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
280 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
281 EXPECT_EQ(copy_layer_
->bounds().ToString(), result
->size().ToString())
283 switch (callback_count_
) {
285 // Hide the copy request layer.
286 grand_parent_layer_
->SetHideLayerAndSubtree(false);
287 parent_layer_
->SetHideLayerAndSubtree(false);
288 copy_layer_
->SetHideLayerAndSubtree(true);
289 AddCopyRequest(copy_layer_
.get());
292 // Hide the copy request layer's parent only.
293 grand_parent_layer_
->SetHideLayerAndSubtree(false);
294 parent_layer_
->SetHideLayerAndSubtree(true);
295 copy_layer_
->SetHideLayerAndSubtree(false);
296 AddCopyRequest(copy_layer_
.get());
299 // Hide the copy request layer's grand parent only.
300 grand_parent_layer_
->SetHideLayerAndSubtree(true);
301 parent_layer_
->SetHideLayerAndSubtree(false);
302 copy_layer_
->SetHideLayerAndSubtree(false);
303 AddCopyRequest(copy_layer_
.get());
306 // Hide the copy request layer's parent and grandparent.
307 grand_parent_layer_
->SetHideLayerAndSubtree(true);
308 parent_layer_
->SetHideLayerAndSubtree(true);
309 copy_layer_
->SetHideLayerAndSubtree(false);
310 AddCopyRequest(copy_layer_
.get());
313 // Hide the copy request layer as well as its parent and grandparent.
314 grand_parent_layer_
->SetHideLayerAndSubtree(true);
315 parent_layer_
->SetHideLayerAndSubtree(true);
316 copy_layer_
->SetHideLayerAndSubtree(true);
317 AddCopyRequest(copy_layer_
.get());
325 void AfterTest() override
{}
328 FakeContentLayerClient client_
;
329 scoped_refptr
<FakePictureLayer
> root_
;
330 scoped_refptr
<FakePictureLayer
> grand_parent_layer_
;
331 scoped_refptr
<FakePictureLayer
> parent_layer_
;
332 scoped_refptr
<FakePictureLayer
> copy_layer_
;
335 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_IMPL_TEST_F(
336 LayerTreeHostCopyRequestTestInHiddenSubtree
);
338 class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
339 : public LayerTreeHostCopyRequestTest
{
341 void SetupTree() override
{
342 root_
= FakePictureLayer::Create(layer_settings(), &client_
);
343 root_
->SetBounds(gfx::Size(20, 20));
345 grand_parent_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
346 grand_parent_layer_
->SetBounds(gfx::Size(15, 15));
347 grand_parent_layer_
->SetHideLayerAndSubtree(true);
348 root_
->AddChild(grand_parent_layer_
);
350 // parent_layer_ owns a render surface.
351 parent_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
352 parent_layer_
->SetBounds(gfx::Size(15, 15));
353 parent_layer_
->SetForceRenderSurface(true);
354 grand_parent_layer_
->AddChild(parent_layer_
);
356 copy_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
357 copy_layer_
->SetBounds(gfx::Size(10, 10));
358 parent_layer_
->AddChild(copy_layer_
);
360 layer_tree_host()->SetRootLayer(root_
);
361 LayerTreeHostCopyRequestTest::SetupTree();
364 void BeginTest() override
{
366 PostSetNeedsCommitToMainThread();
368 copy_layer_
->RequestCopyOfOutput(
369 CopyOutputRequest::CreateBitmapRequest(base::Bind(
370 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
372 base::Unretained(this))));
375 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
376 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
377 EXPECT_EQ(copy_layer_
->bounds().ToString(), result
->size().ToString());
381 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
382 Renderer
* renderer
= host_impl
->renderer();
384 LayerImpl
* root
= host_impl
->active_tree()->root_layer();
385 LayerImpl
* grand_parent
= root
->children()[0];
386 LayerImpl
* parent
= grand_parent
->children()[0];
387 LayerImpl
* copy_layer
= parent
->children()[0];
389 // |parent| owns a surface, but it was hidden and not part of the copy
390 // request so it should not allocate any resource.
391 EXPECT_FALSE(renderer
->HasAllocatedResourcesForTesting(
392 parent
->render_surface()->GetRenderPassId()));
394 // |copy_layer| should have been rendered to a texture since it was needed
395 // for a copy request.
396 EXPECT_TRUE(renderer
->HasAllocatedResourcesForTesting(
397 copy_layer
->render_surface()->GetRenderPassId()));
402 void AfterTest() override
{ EXPECT_TRUE(did_draw_
); }
404 FakeContentLayerClient client_
;
406 scoped_refptr
<FakePictureLayer
> root_
;
407 scoped_refptr
<FakePictureLayer
> grand_parent_layer_
;
408 scoped_refptr
<FakePictureLayer
> parent_layer_
;
409 scoped_refptr
<FakePictureLayer
> copy_layer_
;
412 // No output to copy for delegated renderers.
413 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
414 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
);
416 class LayerTreeHostCopyRequestTestClippedOut
417 : public LayerTreeHostCopyRequestTest
{
419 void SetupTree() override
{
420 root_
= FakePictureLayer::Create(layer_settings(), &client_
);
421 root_
->SetBounds(gfx::Size(20, 20));
423 parent_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
424 parent_layer_
->SetBounds(gfx::Size(15, 15));
425 parent_layer_
->SetMasksToBounds(true);
426 root_
->AddChild(parent_layer_
);
428 copy_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
429 copy_layer_
->SetPosition(gfx::Point(15, 15));
430 copy_layer_
->SetBounds(gfx::Size(10, 10));
431 parent_layer_
->AddChild(copy_layer_
);
433 layer_tree_host()->SetRootLayer(root_
);
434 LayerTreeHostCopyRequestTest::SetupTree();
437 void BeginTest() override
{
438 PostSetNeedsCommitToMainThread();
440 copy_layer_
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
441 base::Bind(&LayerTreeHostCopyRequestTestClippedOut::CopyOutputCallback
,
442 base::Unretained(this))));
445 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
446 // We should still get a callback with no output if the copy requested layer
447 // was completely clipped away.
448 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
449 EXPECT_EQ(gfx::Size().ToString(), result
->size().ToString());
453 void AfterTest() override
{}
455 FakeContentLayerClient client_
;
456 scoped_refptr
<FakePictureLayer
> root_
;
457 scoped_refptr
<FakePictureLayer
> parent_layer_
;
458 scoped_refptr
<FakePictureLayer
> copy_layer_
;
461 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
462 LayerTreeHostCopyRequestTestClippedOut
);
464 class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
465 : public LayerTreeHostCopyRequestTest
{
467 void SetupTree() override
{
468 root_
= FakePictureLayer::Create(layer_settings(), &client_
);
469 root_
->SetBounds(gfx::Size(20, 20));
471 copy_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
472 copy_layer_
->SetBounds(gfx::Size(10, 10));
473 root_
->AddChild(copy_layer_
);
475 layer_tree_host()->SetRootLayer(root_
);
476 LayerTreeHostCopyRequestTest::SetupTree();
479 void AddCopyRequest(Layer
* layer
) {
480 layer
->RequestCopyOfOutput(
481 CopyOutputRequest::CreateBitmapRequest(base::Bind(
482 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback
,
483 base::Unretained(this))));
486 void BeginTest() override
{
487 saw_copy_request_
= false;
489 PostSetNeedsCommitToMainThread();
492 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
494 AddCopyRequest(copy_layer_
.get());
497 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
498 if (impl
->active_tree()->source_frame_number() == 0) {
499 LayerImpl
* root
= impl
->active_tree()->root_layer();
500 EXPECT_TRUE(root
->children()[0]->HasCopyRequest());
501 saw_copy_request_
= true;
505 void DidCommit() override
{
506 if (layer_tree_host()->source_frame_number() == 1) {
508 layer_tree_host()->SetViewportSize(gfx::Size(root_
->bounds()));
510 AddCopyRequest(copy_layer_
.get());
514 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
515 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
516 EXPECT_EQ(copy_layer_
->bounds().ToString(), result
->size().ToString());
519 if (callback_count_
== 2)
523 void AfterTest() override
{ EXPECT_TRUE(saw_copy_request_
); }
525 bool saw_copy_request_
;
527 FakeContentLayerClient client_
;
528 scoped_refptr
<FakePictureLayer
> root_
;
529 scoped_refptr
<FakePictureLayer
> copy_layer_
;
532 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_IMPL_TEST_F(
533 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
);
535 class LayerTreeHostCopyRequestTestLostOutputSurface
536 : public LayerTreeHostCopyRequestTest
{
538 scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface() 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_
= FakePictureLayer::Create(layer_settings(), &client_
);
551 root_
->SetBounds(gfx::Size(20, 20));
553 copy_layer_
= FakePictureLayer::Create(layer_settings(), &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
<FakePictureLayer
> root_
;
656 scoped_refptr
<FakePictureLayer
> copy_layer_
;
657 scoped_ptr
<CopyOutputResult
> result_
;
660 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_IMPL_TEST_F(
661 LayerTreeHostCopyRequestTestLostOutputSurface
);
663 class LayerTreeHostCopyRequestTestCountTextures
664 : public LayerTreeHostCopyRequestTest
{
666 scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface() override
{
667 context_provider_
= TestContextProvider::Create();
668 return FakeOutputSurface::Create3d(context_provider_
);
671 void SetupTree() override
{
672 client_
.set_fill_with_nonsolid_color(true);
674 root_
= FakePictureLayer::Create(layer_settings(), &client_
);
675 root_
->SetBounds(gfx::Size(20, 20));
677 copy_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
678 copy_layer_
->SetBounds(gfx::Size(10, 10));
679 root_
->AddChild(copy_layer_
);
681 layer_tree_host()->SetRootLayer(root_
);
682 LayerTreeHostCopyRequestTest::SetupTree();
685 void BeginTest() override
{
686 num_textures_without_readback_
= 0;
687 num_textures_with_readback_
= 0;
688 waited_sync_point_after_readback_
= 0;
689 PostSetNeedsCommitToMainThread();
692 virtual void RequestCopy(Layer
* layer
) = 0;
694 void DidCommitAndDrawFrame() override
{
695 switch (layer_tree_host()->source_frame_number()) {
697 // The layers have been pushed to the impl side. The layer textures have
699 RequestCopy(copy_layer_
.get());
704 void SwapBuffersOnThread(LayerTreeHostImpl
* impl
, bool result
) override
{
705 switch (impl
->active_tree()->source_frame_number()) {
707 // The layers have been drawn, so their textures have been allocated.
708 num_textures_without_readback_
=
709 context_provider_
->TestContext3d()->NumTextures();
712 // We did a readback, so there will be a readback texture around now.
713 num_textures_with_readback_
=
714 context_provider_
->TestContext3d()->NumTextures();
715 waited_sync_point_after_readback_
=
716 context_provider_
->TestContext3d()->last_waited_sync_point();
718 MainThreadTaskRunner()->PostTask(
720 base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest
,
721 base::Unretained(this)));
726 virtual void DoEndTest() { EndTest(); }
728 scoped_refptr
<TestContextProvider
> context_provider_
;
729 size_t num_textures_without_readback_
;
730 size_t num_textures_with_readback_
;
731 unsigned waited_sync_point_after_readback_
;
732 FakeContentLayerClient client_
;
733 scoped_refptr
<FakePictureLayer
> root_
;
734 scoped_refptr
<FakePictureLayer
> copy_layer_
;
737 class LayerTreeHostCopyRequestTestCreatesTexture
738 : public LayerTreeHostCopyRequestTestCountTextures
{
740 void RequestCopy(Layer
* layer
) override
{
741 // Request a normal texture copy. This should create a new texture.
742 copy_layer_
->RequestCopyOfOutput(
743 CopyOutputRequest::CreateRequest(base::Bind(
744 &LayerTreeHostCopyRequestTestCreatesTexture::CopyOutputCallback
,
745 base::Unretained(this))));
748 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
749 EXPECT_FALSE(result
->IsEmpty());
750 EXPECT_TRUE(result
->HasTexture());
752 TextureMailbox mailbox
;
753 scoped_ptr
<SingleReleaseCallback
> release
;
754 result
->TakeTexture(&mailbox
, &release
);
755 EXPECT_TRUE(release
);
757 release
->Run(0, false);
760 void AfterTest() override
{
761 // No sync point was needed.
762 EXPECT_EQ(0u, waited_sync_point_after_readback_
);
763 // Except the copy to have made another texture.
764 EXPECT_EQ(num_textures_without_readback_
+ 1, num_textures_with_readback_
);
768 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_IMPL_TEST_F(
769 LayerTreeHostCopyRequestTestCreatesTexture
);
771 class LayerTreeHostCopyRequestTestProvideTexture
772 : public LayerTreeHostCopyRequestTestCountTextures
{
774 void BeginTest() override
{
775 external_context_provider_
= TestContextProvider::Create();
776 EXPECT_TRUE(external_context_provider_
->BindToCurrentThread());
777 LayerTreeHostCopyRequestTestCountTextures::BeginTest();
780 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
781 EXPECT_FALSE(result
->IsEmpty());
782 EXPECT_TRUE(result
->HasTexture());
784 TextureMailbox mailbox
;
785 scoped_ptr
<SingleReleaseCallback
> release
;
786 result
->TakeTexture(&mailbox
, &release
);
787 EXPECT_FALSE(release
);
790 void RequestCopy(Layer
* layer
) override
{
791 // Request a copy to a provided texture. This should not create a new
793 scoped_ptr
<CopyOutputRequest
> request
=
794 CopyOutputRequest::CreateRequest(base::Bind(
795 &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback
,
796 base::Unretained(this)));
798 gpu::gles2::GLES2Interface
* gl
= external_context_provider_
->ContextGL();
799 gpu::Mailbox mailbox
;
800 gl
->GenMailboxCHROMIUM(mailbox
.name
);
801 sync_point_
= gl
->InsertSyncPointCHROMIUM();
802 request
->SetTextureMailbox(
803 TextureMailbox(mailbox
, GL_TEXTURE_2D
, sync_point_
));
804 EXPECT_TRUE(request
->has_texture_mailbox());
806 copy_layer_
->RequestCopyOfOutput(request
.Pass());
809 void AfterTest() override
{
810 // Expect the compositor to have waited for the sync point in the provided
812 EXPECT_EQ(sync_point_
, waited_sync_point_after_readback_
);
813 // Except the copy to have *not* made another texture.
814 EXPECT_EQ(num_textures_without_readback_
, num_textures_with_readback_
);
817 scoped_refptr
<TestContextProvider
> external_context_provider_
;
818 unsigned sync_point_
;
821 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_IMPL_TEST_F(
822 LayerTreeHostCopyRequestTestProvideTexture
);
824 class LayerTreeHostCopyRequestTestDestroyBeforeCopy
825 : public LayerTreeHostCopyRequestTest
{
827 void SetupTree() override
{
828 root_
= FakePictureLayer::Create(layer_settings(), &client_
);
829 root_
->SetBounds(gfx::Size(20, 20));
831 copy_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
832 copy_layer_
->SetBounds(gfx::Size(10, 10));
833 root_
->AddChild(copy_layer_
);
835 layer_tree_host()->SetRootLayer(root_
);
836 LayerTreeHostCopyRequestTest::SetupTree();
839 void BeginTest() override
{
841 PostSetNeedsCommitToMainThread();
844 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
845 EXPECT_TRUE(result
->IsEmpty());
849 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
850 MainThreadTaskRunner()->PostTask(
852 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate
,
853 base::Unretained(this)));
857 switch (layer_tree_host()->source_frame_number()) {
859 EXPECT_EQ(0, callback_count_
);
860 // Put a copy request on the layer, but then don't allow any
861 // drawing to take place.
862 scoped_ptr
<CopyOutputRequest
> request
=
863 CopyOutputRequest::CreateRequest(
864 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::
866 base::Unretained(this)));
867 copy_layer_
->RequestCopyOfOutput(request
.Pass());
869 layer_tree_host()->SetViewportSize(gfx::Size());
873 EXPECT_EQ(0, callback_count_
);
874 // Remove the copy layer before we were able to draw.
875 copy_layer_
->RemoveFromParent();
878 EXPECT_EQ(1, callback_count_
);
879 // Allow us to draw now.
880 layer_tree_host()->SetViewportSize(
881 layer_tree_host()->root_layer()->bounds());
884 EXPECT_EQ(1, callback_count_
);
885 // We should not have crashed.
890 void AfterTest() override
{}
893 FakeContentLayerClient client_
;
894 scoped_refptr
<FakePictureLayer
> root_
;
895 scoped_refptr
<FakePictureLayer
> copy_layer_
;
898 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
899 LayerTreeHostCopyRequestTestDestroyBeforeCopy
);
901 class LayerTreeHostCopyRequestTestShutdownBeforeCopy
902 : public LayerTreeHostCopyRequestTest
{
904 void SetupTree() override
{
905 root_
= FakePictureLayer::Create(layer_settings(), &client_
);
906 root_
->SetBounds(gfx::Size(20, 20));
908 copy_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
909 copy_layer_
->SetBounds(gfx::Size(10, 10));
910 root_
->AddChild(copy_layer_
);
912 layer_tree_host()->SetRootLayer(root_
);
913 LayerTreeHostCopyRequestTest::SetupTree();
916 void BeginTest() override
{
918 PostSetNeedsCommitToMainThread();
921 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
922 EXPECT_TRUE(result
->IsEmpty());
926 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
927 MainThreadTaskRunner()->PostTask(
929 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::DidActivate
,
930 base::Unretained(this)));
934 switch (layer_tree_host()->source_frame_number()) {
936 EXPECT_EQ(0, callback_count_
);
937 // Put a copy request on the layer, but then don't allow any
938 // drawing to take place.
939 scoped_ptr
<CopyOutputRequest
> request
=
940 CopyOutputRequest::CreateRequest(
941 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::
943 base::Unretained(this)));
944 copy_layer_
->RequestCopyOfOutput(request
.Pass());
946 layer_tree_host()->SetViewportSize(gfx::Size());
950 DestroyLayerTreeHost();
951 // End the test after the copy result has had a chance to get back to
953 MainThreadTaskRunner()->PostTask(
955 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::EndTest
,
956 base::Unretained(this)));
961 void AfterTest() override
{ EXPECT_EQ(1, callback_count_
); }
964 FakeContentLayerClient client_
;
965 scoped_refptr
<FakePictureLayer
> root_
;
966 scoped_refptr
<FakePictureLayer
> copy_layer_
;
969 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
970 LayerTreeHostCopyRequestTestShutdownBeforeCopy
);
972 class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
973 : public LayerTreeHostCopyRequestTest
{
975 void SetupTree() override
{
976 scoped_refptr
<FakePictureLayer
> root
=
977 FakePictureLayer::Create(layer_settings(), &client_
);
978 root
->SetBounds(gfx::Size(20, 20));
980 child_
= FakePictureLayer::Create(layer_settings(), &client_
);
981 child_
->SetBounds(gfx::Size(10, 10));
982 root
->AddChild(child_
);
983 child_
->SetHideLayerAndSubtree(true);
985 layer_tree_host()->SetRootLayer(root
);
986 LayerTreeHostCopyRequestTest::SetupTree();
989 void BeginTest() override
{
991 copy_happened_
= false;
992 draw_happened_
= false;
993 PostSetNeedsCommitToMainThread();
996 void DidCommitAndDrawFrame() override
{
997 // Send a copy request after the first commit.
998 if (layer_tree_host()->source_frame_number() == 1) {
999 child_
->RequestCopyOfOutput(
1000 CopyOutputRequest::CreateBitmapRequest(base::Bind(
1001 &LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest::
1003 base::Unretained(this))));
1007 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1008 LayerTreeHostImpl::FrameData
* frame_data
,
1009 DrawResult draw_result
) override
{
1010 LayerImpl
* root
= host_impl
->active_tree()->root_layer();
1011 LayerImpl
* child
= root
->children()[0];
1013 bool saw_root
= false;
1014 bool saw_child
= false;
1015 for (LayerIterator
<LayerImpl
> it
= LayerIterator
<LayerImpl
>::Begin(
1016 frame_data
->render_surface_layer_list
);
1017 it
!= LayerIterator
<LayerImpl
>::End(
1018 frame_data
->render_surface_layer_list
);
1020 if (it
.represents_itself()) {
1023 else if (*it
== child
)
1031 // The first draw has no copy request. The 2nd draw has a copy request, the
1032 // 3rd should not again.
1033 switch (num_draws_
) {
1035 // Only the root layer draws, the child is hidden.
1036 EXPECT_TRUE(saw_root
);
1037 EXPECT_FALSE(saw_child
);
1040 // Copy happening here, the child will draw.
1041 EXPECT_TRUE(saw_root
);
1042 EXPECT_TRUE(saw_child
);
1043 // Make another draw happen after doing the copy request.
1044 host_impl
->SetNeedsRedrawRect(gfx::Rect(1, 1));
1047 // If LayerTreeHostImpl does the wrong thing, it will try to draw the
1048 // layer which had a copy request. But only the root should draw.
1049 EXPECT_TRUE(saw_root
);
1050 EXPECT_FALSE(saw_child
);
1052 // End the test! Don't race with copy request callbacks, so post the end
1053 // to the main thread.
1054 draw_happened_
= true;
1055 MainThreadTaskRunner()->PostTask(
1058 &LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest::
1060 base::Unretained(this)));
1066 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
1067 EXPECT_FALSE(TestEnded());
1068 copy_happened_
= true;
1073 if (draw_happened_
&& copy_happened_
)
1077 void AfterTest() override
{}
1079 scoped_refptr
<FakePictureLayer
> child_
;
1080 FakeContentLayerClient client_
;
1082 bool copy_happened_
;
1083 bool draw_happened_
;
1086 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1087 LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
);