Roll src/third_party/skia 4cd6713:0edd965
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_copyrequest.cc
blob440063d1d0c0c714361772323623a02829fc6f30
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"
15 namespace cc {
16 namespace {
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 {
24 protected:
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(
43 FROM_HERE,
44 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::NextStep,
45 base::Unretained(this)));
48 void NextStep() {
49 int frame = layer_tree_host()->source_frame_number();
50 switch (frame) {
51 case 1:
52 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
53 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
54 CopyOutputCallback,
55 base::Unretained(this))));
56 EXPECT_EQ(0u, callbacks_.size());
57 break;
58 case 2:
59 if (callbacks_.size() < 1u) {
60 WaitForCallback();
61 return;
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::
68 CopyOutputCallback,
69 base::Unretained(this))));
70 root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
71 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
72 CopyOutputCallback,
73 base::Unretained(this))));
74 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
75 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
76 CopyOutputCallback,
77 base::Unretained(this))));
78 EXPECT_EQ(1u, callbacks_.size());
79 break;
80 case 3:
81 if (callbacks_.size() < 4u) {
82 WaitForCallback();
83 return;
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());
91 EndTest();
92 break;
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 {
149 protected:
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 {
167 callback_count_ = 0;
168 PostSetNeedsCommitToMainThread();
171 void DidCommit() override {
172 int frame = layer_tree_host()->source_frame_number();
173 switch (frame) {
174 case 1:
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());
194 break;
195 case 2:
196 // Flush the message loops and make sure the callbacks run.
197 layer_tree_host()->SetNeedsCommit();
198 break;
199 case 3:
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_);
209 break;
210 case 4:
211 // Flush the message loops and make sure the callbacks run.
212 layer_tree_host()->SetNeedsCommit();
213 break;
214 case 5:
215 // We should get another callback with a NULL bitmap.
216 EXPECT_EQ(2, callback_count_);
217 EndTest();
218 break;
222 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
223 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
224 EXPECT_TRUE(result->IsEmpty());
225 ++callback_count_;
228 void AfterTest() override {}
230 int callback_count_;
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 {
241 protected:
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 {
272 callback_count_ = 0;
273 PostSetNeedsCommitToMainThread();
275 AddCopyRequest(copy_layer_.get());
278 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
279 ++callback_count_;
280 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
281 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString())
282 << callback_count_;
283 switch (callback_count_) {
284 case 1:
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());
290 break;
291 case 2:
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());
297 break;
298 case 3:
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());
304 break;
305 case 4:
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());
311 break;
312 case 5:
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());
318 break;
319 case 6:
320 EndTest();
321 break;
325 void AfterTest() override {}
327 int callback_count_;
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 {
340 protected:
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 {
365 did_draw_ = false;
366 PostSetNeedsCommitToMainThread();
368 copy_layer_->RequestCopyOfOutput(
369 CopyOutputRequest::CreateBitmapRequest(base::Bind(
370 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
371 CopyOutputCallback,
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());
378 EndTest();
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()));
399 did_draw_ = true;
402 void AfterTest() override { EXPECT_TRUE(did_draw_); }
404 FakeContentLayerClient client_;
405 bool did_draw_;
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 {
418 protected:
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());
450 EndTest();
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 {
466 protected:
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;
488 callback_count_ = 0;
489 PostSetNeedsCommitToMainThread();
491 // Prevent drawing.
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) {
507 // Allow drawing.
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());
517 ++callback_count_;
519 if (callback_count_ == 2)
520 EndTest();
523 void AfterTest() override { EXPECT_TRUE(saw_copy_request_); }
525 bool saw_copy_request_;
526 int callback_count_;
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 {
537 protected:
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()) {
578 case 1:
579 // The layers have been pushed to the impl side. The layer textures have
580 // been allocated.
582 // Request a copy of the layer. This will use another texture.
583 copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
584 base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface::
585 CopyOutputCallback,
586 base::Unretained(this))));
587 break;
588 case 4:
589 // With SingleThreadProxy it takes two commits to finally swap after a
590 // context loss.
591 case 5:
592 // Now destroy the CopyOutputResult, releasing the texture inside back
593 // to the compositor.
594 EXPECT_TRUE(result_);
595 result_ = nullptr;
597 // Check that it is released.
598 ImplThreadTaskRunner()->PostTask(
599 FROM_HERE,
600 base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface::
601 CheckNumTextures,
602 base::Unretained(this),
603 num_textures_after_loss_ - 1));
604 break;
608 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
609 switch (impl->active_tree()->source_frame_number()) {
610 case 0:
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();
615 break;
616 case 1:
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());
620 break;
621 case 2:
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);
628 break;
629 case 3:
630 // With SingleThreadProxy it takes two commits to finally swap after a
631 // context loss.
632 case 4:
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();
638 break;
642 void CheckNumTextures(size_t expected_num_textures) {
643 EXPECT_EQ(expected_num_textures,
644 first_context_provider_->TestContext3d()->NumTextures());
645 EndTest();
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 {
665 protected:
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()) {
696 case 1:
697 // The layers have been pushed to the impl side. The layer textures have
698 // been allocated.
699 RequestCopy(copy_layer_.get());
700 break;
704 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
705 switch (impl->active_tree()->source_frame_number()) {
706 case 0:
707 // The layers have been drawn, so their textures have been allocated.
708 num_textures_without_readback_ =
709 context_provider_->TestContext3d()->NumTextures();
710 break;
711 case 1:
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(
719 FROM_HERE,
720 base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest,
721 base::Unretained(this)));
722 break;
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 {
739 protected:
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 {
773 protected:
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
792 // texture.
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
811 // TextureMailbox.
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 {
826 protected:
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 {
840 callback_count_ = 0;
841 PostSetNeedsCommitToMainThread();
844 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
845 EXPECT_TRUE(result->IsEmpty());
846 ++callback_count_;
849 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
850 MainThreadTaskRunner()->PostTask(
851 FROM_HERE,
852 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate,
853 base::Unretained(this)));
856 void DidActivate() {
857 switch (layer_tree_host()->source_frame_number()) {
858 case 1: {
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::
865 CopyOutputCallback,
866 base::Unretained(this)));
867 copy_layer_->RequestCopyOfOutput(request.Pass());
869 layer_tree_host()->SetViewportSize(gfx::Size());
870 break;
872 case 2:
873 EXPECT_EQ(0, callback_count_);
874 // Remove the copy layer before we were able to draw.
875 copy_layer_->RemoveFromParent();
876 break;
877 case 3:
878 EXPECT_EQ(1, callback_count_);
879 // Allow us to draw now.
880 layer_tree_host()->SetViewportSize(
881 layer_tree_host()->root_layer()->bounds());
882 break;
883 case 4:
884 EXPECT_EQ(1, callback_count_);
885 // We should not have crashed.
886 EndTest();
890 void AfterTest() override {}
892 int callback_count_;
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 {
903 protected:
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 {
917 callback_count_ = 0;
918 PostSetNeedsCommitToMainThread();
921 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
922 EXPECT_TRUE(result->IsEmpty());
923 ++callback_count_;
926 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
927 MainThreadTaskRunner()->PostTask(
928 FROM_HERE,
929 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::DidActivate,
930 base::Unretained(this)));
933 void DidActivate() {
934 switch (layer_tree_host()->source_frame_number()) {
935 case 1: {
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::
942 CopyOutputCallback,
943 base::Unretained(this)));
944 copy_layer_->RequestCopyOfOutput(request.Pass());
946 layer_tree_host()->SetViewportSize(gfx::Size());
947 break;
949 case 2:
950 DestroyLayerTreeHost();
951 // End the test after the copy result has had a chance to get back to
952 // the main thread.
953 MainThreadTaskRunner()->PostTask(
954 FROM_HERE,
955 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::EndTest,
956 base::Unretained(this)));
957 break;
961 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
963 int 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 {
974 protected:
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 {
990 num_draws_ = 0;
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::
1002 CopyOutputCallback,
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);
1019 ++it) {
1020 if (it.represents_itself()) {
1021 if (*it == root)
1022 saw_root = true;
1023 else if (*it == child)
1024 saw_child = true;
1025 else
1026 NOTREACHED();
1030 ++num_draws_;
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_) {
1034 case 1:
1035 // Only the root layer draws, the child is hidden.
1036 EXPECT_TRUE(saw_root);
1037 EXPECT_FALSE(saw_child);
1038 break;
1039 case 2:
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));
1045 break;
1046 case 3:
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(
1056 FROM_HERE,
1057 base::Bind(
1058 &LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest::
1059 TryEndTest,
1060 base::Unretained(this)));
1061 break;
1063 return draw_result;
1066 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
1067 EXPECT_FALSE(TestEnded());
1068 copy_happened_ = true;
1069 TryEndTest();
1072 void TryEndTest() {
1073 if (draw_happened_ && copy_happened_)
1074 EndTest();
1077 void AfterTest() override {}
1079 scoped_refptr<FakePictureLayer> child_;
1080 FakeContentLayerClient client_;
1081 int num_draws_;
1082 bool copy_happened_;
1083 bool draw_happened_;
1086 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1087 LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest);
1089 } // namespace
1090 } // namespace cc