Getting rid of GetDefaultProfile(), clean up of ProfileManager (which was in a seriou...
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_copyrequest.cc
blob2156c642b19736161cabfb0c7f17640486dbbb30
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"
14 namespace cc {
15 namespace {
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 {
23 protected:
24 virtual 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 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
38 virtual void DidCommitAndDrawFrame() OVERRIDE { WaitForCallback(); }
40 void WaitForCallback() {
41 base::MessageLoop::current()->PostTask(
42 FROM_HERE,
43 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::NextStep,
44 base::Unretained(this)));
47 void NextStep() {
48 int frame = layer_tree_host()->source_frame_number();
49 switch (frame) {
50 case 1:
51 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
52 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
53 CopyOutputCallback,
54 base::Unretained(this))));
55 EXPECT_EQ(0u, callbacks_.size());
56 break;
57 case 2:
58 if (callbacks_.size() < 1u) {
59 WaitForCallback();
60 return;
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::
67 CopyOutputCallback,
68 base::Unretained(this))));
69 root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
70 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
71 CopyOutputCallback,
72 base::Unretained(this))));
73 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
74 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
75 CopyOutputCallback,
76 base::Unretained(this))));
77 EXPECT_EQ(1u, callbacks_.size());
78 break;
79 case 3:
80 if (callbacks_.size() < 4u) {
81 WaitForCallback();
82 return;
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());
90 EndTest();
91 break;
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 virtual void AfterTest() OVERRIDE { EXPECT_EQ(4u, callbacks_.size()); }
106 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
107 OVERRIDE {
108 scoped_ptr<FakeOutputSurface> output_surface;
109 if (use_gl_renderer_) {
110 output_surface = FakeOutputSurface::Create3d().Pass();
111 } else {
112 output_surface = FakeOutputSurface::CreateSoftware(
113 make_scoped_ptr(new SoftwareOutputDevice)).Pass();
115 return output_surface.PassAs<OutputSurface>();
118 bool use_gl_renderer_;
119 std::vector<gfx::Size> callbacks_;
120 FakeContentLayerClient client_;
121 scoped_refptr<FakeContentLayer> root;
122 scoped_refptr<FakeContentLayer> child;
125 // Readback can't be done with a delegating renderer.
126 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
127 GLRenderer_RunSingleThread) {
128 use_gl_renderer_ = true;
129 RunTest(false, false, false);
132 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
133 GLRenderer_RunMultiThread_MainThreadPainting) {
134 use_gl_renderer_ = true;
135 RunTest(true, false, false);
138 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
139 SoftwareRenderer_RunSingleThread) {
140 use_gl_renderer_ = false;
141 RunTest(false, false, false);
144 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
145 SoftwareRenderer_RunMultiThread_MainThreadPainting) {
146 use_gl_renderer_ = false;
147 RunTest(true, false, false);
150 class LayerTreeHostCopyRequestTestLayerDestroyed
151 : public LayerTreeHostCopyRequestTest {
152 protected:
153 virtual void SetupTree() OVERRIDE {
154 root_ = FakeContentLayer::Create(&client_);
155 root_->SetBounds(gfx::Size(20, 20));
157 main_destroyed_ = FakeContentLayer::Create(&client_);
158 main_destroyed_->SetBounds(gfx::Size(15, 15));
159 root_->AddChild(main_destroyed_);
161 impl_destroyed_ = FakeContentLayer::Create(&client_);
162 impl_destroyed_->SetBounds(gfx::Size(10, 10));
163 root_->AddChild(impl_destroyed_);
165 layer_tree_host()->SetRootLayer(root_);
166 LayerTreeHostCopyRequestTest::SetupTree();
169 virtual void BeginTest() OVERRIDE {
170 callback_count_ = 0;
171 PostSetNeedsCommitToMainThread();
174 virtual void DidCommit() OVERRIDE {
175 int frame = layer_tree_host()->source_frame_number();
176 switch (frame) {
177 case 1:
178 main_destroyed_->RequestCopyOfOutput(
179 CopyOutputRequest::CreateBitmapRequest(base::Bind(
180 &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback,
181 base::Unretained(this))));
182 impl_destroyed_->RequestCopyOfOutput(
183 CopyOutputRequest::CreateBitmapRequest(base::Bind(
184 &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback,
185 base::Unretained(this))));
186 EXPECT_EQ(0, callback_count_);
188 // Destroy the main thread layer right away.
189 main_destroyed_->RemoveFromParent();
190 main_destroyed_ = NULL;
192 // Should callback with a NULL bitmap.
193 EXPECT_EQ(1, callback_count_);
195 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
196 layer_tree_host()->SetViewportSize(gfx::Size());
197 break;
198 case 2:
199 // Flush the message loops and make sure the callbacks run.
200 layer_tree_host()->SetNeedsCommit();
201 break;
202 case 3:
203 // No drawing means no readback yet.
204 EXPECT_EQ(1, callback_count_);
206 // Destroy the impl thread layer.
207 impl_destroyed_->RemoveFromParent();
208 impl_destroyed_ = NULL;
210 // No callback yet because it's on the impl side.
211 EXPECT_EQ(1, callback_count_);
212 break;
213 case 4:
214 // Flush the message loops and make sure the callbacks run.
215 layer_tree_host()->SetNeedsCommit();
216 break;
217 case 5:
218 // We should get another callback with a NULL bitmap.
219 EXPECT_EQ(2, callback_count_);
220 EndTest();
221 break;
225 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
226 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
227 EXPECT_TRUE(result->IsEmpty());
228 ++callback_count_;
231 virtual void AfterTest() OVERRIDE {}
233 int callback_count_;
234 FakeContentLayerClient client_;
235 scoped_refptr<FakeContentLayer> root_;
236 scoped_refptr<FakeContentLayer> main_destroyed_;
237 scoped_refptr<FakeContentLayer> impl_destroyed_;
240 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed);
242 class LayerTreeHostCopyRequestTestInHiddenSubtree
243 : public LayerTreeHostCopyRequestTest {
244 protected:
245 virtual void SetupTree() OVERRIDE {
246 root_ = FakeContentLayer::Create(&client_);
247 root_->SetBounds(gfx::Size(20, 20));
249 grand_parent_layer_ = FakeContentLayer::Create(&client_);
250 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
251 root_->AddChild(grand_parent_layer_);
253 // parent_layer_ owns a render surface.
254 parent_layer_ = FakeContentLayer::Create(&client_);
255 parent_layer_->SetBounds(gfx::Size(15, 15));
256 parent_layer_->SetForceRenderSurface(true);
257 grand_parent_layer_->AddChild(parent_layer_);
259 copy_layer_ = FakeContentLayer::Create(&client_);
260 copy_layer_->SetBounds(gfx::Size(10, 10));
261 parent_layer_->AddChild(copy_layer_);
263 layer_tree_host()->SetRootLayer(root_);
264 LayerTreeHostCopyRequestTest::SetupTree();
267 void AddCopyRequest(Layer* layer) {
268 layer->RequestCopyOfOutput(
269 CopyOutputRequest::CreateBitmapRequest(base::Bind(
270 &LayerTreeHostCopyRequestTestInHiddenSubtree::CopyOutputCallback,
271 base::Unretained(this))));
274 virtual void BeginTest() OVERRIDE {
275 callback_count_ = 0;
276 PostSetNeedsCommitToMainThread();
278 AddCopyRequest(copy_layer_.get());
281 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
282 ++callback_count_;
283 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
284 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString())
285 << callback_count_;
286 switch (callback_count_) {
287 case 1:
288 // Hide the copy request layer.
289 grand_parent_layer_->SetHideLayerAndSubtree(false);
290 parent_layer_->SetHideLayerAndSubtree(false);
291 copy_layer_->SetHideLayerAndSubtree(true);
292 AddCopyRequest(copy_layer_.get());
293 break;
294 case 2:
295 // Hide the copy request layer's parent only.
296 grand_parent_layer_->SetHideLayerAndSubtree(false);
297 parent_layer_->SetHideLayerAndSubtree(true);
298 copy_layer_->SetHideLayerAndSubtree(false);
299 AddCopyRequest(copy_layer_.get());
300 break;
301 case 3:
302 // Hide the copy request layer's grand parent only.
303 grand_parent_layer_->SetHideLayerAndSubtree(true);
304 parent_layer_->SetHideLayerAndSubtree(false);
305 copy_layer_->SetHideLayerAndSubtree(false);
306 AddCopyRequest(copy_layer_.get());
307 break;
308 case 4:
309 // Hide the copy request layer's parent and grandparent.
310 grand_parent_layer_->SetHideLayerAndSubtree(true);
311 parent_layer_->SetHideLayerAndSubtree(true);
312 copy_layer_->SetHideLayerAndSubtree(false);
313 AddCopyRequest(copy_layer_.get());
314 break;
315 case 5:
316 // Hide the copy request layer as well as its parent and grandparent.
317 grand_parent_layer_->SetHideLayerAndSubtree(true);
318 parent_layer_->SetHideLayerAndSubtree(true);
319 copy_layer_->SetHideLayerAndSubtree(true);
320 AddCopyRequest(copy_layer_.get());
321 break;
322 case 6:
323 EndTest();
324 break;
328 virtual void AfterTest() OVERRIDE {}
330 int callback_count_;
331 FakeContentLayerClient client_;
332 scoped_refptr<FakeContentLayer> root_;
333 scoped_refptr<FakeContentLayer> grand_parent_layer_;
334 scoped_refptr<FakeContentLayer> parent_layer_;
335 scoped_refptr<FakeContentLayer> copy_layer_;
338 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
339 LayerTreeHostCopyRequestTestInHiddenSubtree);
341 class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
342 : public LayerTreeHostCopyRequestTest {
343 protected:
344 virtual void SetupTree() OVERRIDE {
345 root_ = FakeContentLayer::Create(&client_);
346 root_->SetBounds(gfx::Size(20, 20));
348 grand_parent_layer_ = FakeContentLayer::Create(&client_);
349 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
350 grand_parent_layer_->SetHideLayerAndSubtree(true);
351 root_->AddChild(grand_parent_layer_);
353 // parent_layer_ owns a render surface.
354 parent_layer_ = FakeContentLayer::Create(&client_);
355 parent_layer_->SetBounds(gfx::Size(15, 15));
356 parent_layer_->SetForceRenderSurface(true);
357 grand_parent_layer_->AddChild(parent_layer_);
359 copy_layer_ = FakeContentLayer::Create(&client_);
360 copy_layer_->SetBounds(gfx::Size(10, 10));
361 parent_layer_->AddChild(copy_layer_);
363 layer_tree_host()->SetRootLayer(root_);
364 LayerTreeHostCopyRequestTest::SetupTree();
367 virtual void BeginTest() OVERRIDE {
368 did_draw_ = false;
369 PostSetNeedsCommitToMainThread();
371 copy_layer_->RequestCopyOfOutput(
372 CopyOutputRequest::CreateBitmapRequest(base::Bind(
373 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
374 CopyOutputCallback,
375 base::Unretained(this))));
378 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
379 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
380 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
381 EndTest();
384 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
385 Renderer* renderer = host_impl->renderer();
387 LayerImpl* root = host_impl->active_tree()->root_layer();
388 LayerImpl* grand_parent = root->children()[0];
389 LayerImpl* parent = grand_parent->children()[0];
390 LayerImpl* copy_layer = parent->children()[0];
392 // |parent| owns a surface, but it was hidden and not part of the copy
393 // request so it should not allocate any resource.
394 EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
395 parent->render_surface()->RenderPassId()));
397 // |copy_layer| should have been rendered to a texture since it was needed
398 // for a copy request.
399 EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
400 copy_layer->render_surface()->RenderPassId()));
402 did_draw_ = true;
405 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
407 FakeContentLayerClient client_;
408 bool did_draw_;
409 scoped_refptr<FakeContentLayer> root_;
410 scoped_refptr<FakeContentLayer> grand_parent_layer_;
411 scoped_refptr<FakeContentLayer> parent_layer_;
412 scoped_refptr<FakeContentLayer> copy_layer_;
415 // No output to copy for delegated renderers.
416 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
417 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
419 class LayerTreeHostCopyRequestTestClippedOut
420 : public LayerTreeHostCopyRequestTest {
421 protected:
422 virtual void SetupTree() OVERRIDE {
423 root_ = FakeContentLayer::Create(&client_);
424 root_->SetBounds(gfx::Size(20, 20));
426 parent_layer_ = FakeContentLayer::Create(&client_);
427 parent_layer_->SetBounds(gfx::Size(15, 15));
428 parent_layer_->SetMasksToBounds(true);
429 root_->AddChild(parent_layer_);
431 copy_layer_ = FakeContentLayer::Create(&client_);
432 copy_layer_->SetPosition(gfx::Point(15, 15));
433 copy_layer_->SetBounds(gfx::Size(10, 10));
434 parent_layer_->AddChild(copy_layer_);
436 layer_tree_host()->SetRootLayer(root_);
437 LayerTreeHostCopyRequestTest::SetupTree();
440 virtual void BeginTest() OVERRIDE {
441 PostSetNeedsCommitToMainThread();
443 copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
444 base::Bind(&LayerTreeHostCopyRequestTestClippedOut::CopyOutputCallback,
445 base::Unretained(this))));
448 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
449 // We should still get a callback with no output if the copy requested layer
450 // was completely clipped away.
451 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
452 EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
453 EndTest();
456 virtual void AfterTest() OVERRIDE {}
458 FakeContentLayerClient client_;
459 scoped_refptr<FakeContentLayer> root_;
460 scoped_refptr<FakeContentLayer> parent_layer_;
461 scoped_refptr<FakeContentLayer> copy_layer_;
464 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
465 LayerTreeHostCopyRequestTestClippedOut);
467 class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
468 : public LayerTreeHostCopyRequestTest {
469 protected:
470 virtual void SetupTree() OVERRIDE {
471 root_ = FakeContentLayer::Create(&client_);
472 root_->SetBounds(gfx::Size(20, 20));
474 copy_layer_ = FakeContentLayer::Create(&client_);
475 copy_layer_->SetBounds(gfx::Size(10, 10));
476 root_->AddChild(copy_layer_);
478 layer_tree_host()->SetRootLayer(root_);
479 LayerTreeHostCopyRequestTest::SetupTree();
482 void AddCopyRequest(Layer* layer) {
483 layer->RequestCopyOfOutput(
484 CopyOutputRequest::CreateBitmapRequest(base::Bind(
485 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
486 base::Unretained(this))));
489 virtual void BeginTest() OVERRIDE {
490 saw_copy_request_ = false;
491 callback_count_ = 0;
492 PostSetNeedsCommitToMainThread();
494 // Prevent drawing.
495 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
497 AddCopyRequest(copy_layer_.get());
500 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
501 if (impl->active_tree()->source_frame_number() == 0) {
502 LayerImpl* root = impl->active_tree()->root_layer();
503 EXPECT_TRUE(root->children()[0]->HasCopyRequest());
504 saw_copy_request_ = true;
508 virtual void DidCommit() OVERRIDE {
509 if (layer_tree_host()->source_frame_number() == 1) {
510 // Allow drawing.
511 layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
513 AddCopyRequest(copy_layer_.get());
517 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
518 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
519 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
520 ++callback_count_;
522 if (callback_count_ == 2)
523 EndTest();
526 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
528 bool saw_copy_request_;
529 int callback_count_;
530 FakeContentLayerClient client_;
531 scoped_refptr<FakeContentLayer> root_;
532 scoped_refptr<FakeContentLayer> copy_layer_;
535 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
536 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
538 class LayerTreeHostCopyRequestTestLostOutputSurface
539 : public LayerTreeHostCopyRequestTest {
540 protected:
541 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
542 OVERRIDE {
543 if (!first_context_provider_.get()) {
544 first_context_provider_ = TestContextProvider::Create();
545 return FakeOutputSurface::Create3d(first_context_provider_)
546 .PassAs<OutputSurface>();
549 EXPECT_FALSE(second_context_provider_.get());
550 second_context_provider_ = TestContextProvider::Create();
551 return FakeOutputSurface::Create3d(second_context_provider_)
552 .PassAs<OutputSurface>();
555 virtual void SetupTree() OVERRIDE {
556 root_ = FakeContentLayer::Create(&client_);
557 root_->SetBounds(gfx::Size(20, 20));
559 copy_layer_ = FakeContentLayer::Create(&client_);
560 copy_layer_->SetBounds(gfx::Size(10, 10));
561 root_->AddChild(copy_layer_);
563 layer_tree_host()->SetRootLayer(root_);
564 LayerTreeHostCopyRequestTest::SetupTree();
567 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
569 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
570 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
571 EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString());
572 EXPECT_TRUE(result->HasTexture());
574 // Save the result for later.
575 EXPECT_FALSE(result_);
576 result_ = result.Pass();
578 // Post a commit to lose the output surface.
579 layer_tree_host()->SetNeedsCommit();
582 virtual void DidCommitAndDrawFrame() OVERRIDE {
583 switch (layer_tree_host()->source_frame_number()) {
584 case 1:
585 // The layers have been pushed to the impl side. The layer textures have
586 // been allocated.
588 // Request a copy of the layer. This will use another texture.
589 copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
590 base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface::
591 CopyOutputCallback,
592 base::Unretained(this))));
593 break;
594 case 4:
595 // With SingleThreadProxy it takes two commits to finally swap after a
596 // context loss.
597 case 5:
598 // Now destroy the CopyOutputResult, releasing the texture inside back
599 // to the compositor.
600 EXPECT_TRUE(result_);
601 result_.reset();
603 // Check that it is released.
604 ImplThreadTaskRunner()->PostTask(
605 FROM_HERE,
606 base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface::
607 CheckNumTextures,
608 base::Unretained(this),
609 num_textures_after_loss_ - 1));
610 break;
614 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
615 bool result) OVERRIDE {
616 switch (impl->active_tree()->source_frame_number()) {
617 case 0:
618 // The layers have been drawn, so their textures have been allocated.
619 EXPECT_FALSE(result_);
620 num_textures_without_readback_ =
621 first_context_provider_->TestContext3d()->NumTextures();
622 break;
623 case 1:
624 // We did a readback, so there will be a readback texture around now.
625 EXPECT_LT(num_textures_without_readback_,
626 first_context_provider_->TestContext3d()->NumTextures());
627 break;
628 case 2:
629 // The readback texture is collected.
630 EXPECT_TRUE(result_);
632 // Lose the output surface.
633 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
634 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
635 break;
636 case 3:
637 // With SingleThreadProxy it takes two commits to finally swap after a
638 // context loss.
639 case 4:
640 // The output surface has been recreated.
641 EXPECT_TRUE(second_context_provider_.get());
643 num_textures_after_loss_ =
644 first_context_provider_->TestContext3d()->NumTextures();
645 break;
649 void CheckNumTextures(size_t expected_num_textures) {
650 EXPECT_EQ(expected_num_textures,
651 first_context_provider_->TestContext3d()->NumTextures());
652 EndTest();
655 virtual void AfterTest() OVERRIDE {}
657 scoped_refptr<TestContextProvider> first_context_provider_;
658 scoped_refptr<TestContextProvider> second_context_provider_;
659 size_t num_textures_without_readback_;
660 size_t num_textures_after_loss_;
661 FakeContentLayerClient client_;
662 scoped_refptr<FakeContentLayer> root_;
663 scoped_refptr<FakeContentLayer> copy_layer_;
664 scoped_ptr<CopyOutputResult> result_;
667 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
668 LayerTreeHostCopyRequestTestLostOutputSurface);
670 class LayerTreeHostCopyRequestTestCountTextures
671 : public LayerTreeHostCopyRequestTest {
672 protected:
673 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
674 OVERRIDE {
675 context_provider_ = TestContextProvider::Create();
676 return FakeOutputSurface::Create3d(context_provider_)
677 .PassAs<OutputSurface>();
680 virtual void SetupTree() OVERRIDE {
681 root_ = FakeContentLayer::Create(&client_);
682 root_->SetBounds(gfx::Size(20, 20));
684 copy_layer_ = FakeContentLayer::Create(&client_);
685 copy_layer_->SetBounds(gfx::Size(10, 10));
686 root_->AddChild(copy_layer_);
688 layer_tree_host()->SetRootLayer(root_);
689 LayerTreeHostCopyRequestTest::SetupTree();
692 virtual void BeginTest() OVERRIDE {
693 num_textures_without_readback_ = 0;
694 num_textures_with_readback_ = 0;
695 waited_sync_point_after_readback_ = 0;
696 PostSetNeedsCommitToMainThread();
699 virtual void RequestCopy(Layer* layer) = 0;
701 virtual void DidCommitAndDrawFrame() OVERRIDE {
702 switch (layer_tree_host()->source_frame_number()) {
703 case 1:
704 // The layers have been pushed to the impl side. The layer textures have
705 // been allocated.
706 RequestCopy(copy_layer_.get());
707 break;
711 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
712 bool result) OVERRIDE {
713 switch (impl->active_tree()->source_frame_number()) {
714 case 0:
715 // The layers have been drawn, so their textures have been allocated.
716 num_textures_without_readback_ =
717 context_provider_->TestContext3d()->NumTextures();
718 break;
719 case 1:
720 // We did a readback, so there will be a readback texture around now.
721 num_textures_with_readback_ =
722 context_provider_->TestContext3d()->NumTextures();
723 waited_sync_point_after_readback_ =
724 context_provider_->TestContext3d()->last_waited_sync_point();
726 MainThreadTaskRunner()->PostTask(
727 FROM_HERE,
728 base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest,
729 base::Unretained(this)));
730 break;
734 virtual void DoEndTest() { EndTest(); }
736 scoped_refptr<TestContextProvider> context_provider_;
737 size_t num_textures_without_readback_;
738 size_t num_textures_with_readback_;
739 unsigned waited_sync_point_after_readback_;
740 FakeContentLayerClient client_;
741 scoped_refptr<FakeContentLayer> root_;
742 scoped_refptr<FakeContentLayer> copy_layer_;
745 class LayerTreeHostCopyRequestTestCreatesTexture
746 : public LayerTreeHostCopyRequestTestCountTextures {
747 protected:
748 virtual void RequestCopy(Layer* layer) OVERRIDE {
749 // Request a normal texture copy. This should create a new texture.
750 copy_layer_->RequestCopyOfOutput(
751 CopyOutputRequest::CreateRequest(base::Bind(
752 &LayerTreeHostCopyRequestTestCreatesTexture::CopyOutputCallback,
753 base::Unretained(this))));
756 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
757 EXPECT_FALSE(result->IsEmpty());
758 EXPECT_TRUE(result->HasTexture());
760 TextureMailbox mailbox;
761 scoped_ptr<SingleReleaseCallback> release;
762 result->TakeTexture(&mailbox, &release);
763 EXPECT_TRUE(release);
765 release->Run(0, false);
768 virtual void AfterTest() OVERRIDE {
769 // No sync point was needed.
770 EXPECT_EQ(0u, waited_sync_point_after_readback_);
771 // Except the copy to have made another texture.
772 EXPECT_EQ(num_textures_without_readback_ + 1, num_textures_with_readback_);
776 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
777 LayerTreeHostCopyRequestTestCreatesTexture);
779 class LayerTreeHostCopyRequestTestProvideTexture
780 : public LayerTreeHostCopyRequestTestCountTextures {
781 protected:
782 virtual void BeginTest() OVERRIDE {
783 external_context_provider_ = TestContextProvider::Create();
784 EXPECT_TRUE(external_context_provider_->BindToCurrentThread());
785 LayerTreeHostCopyRequestTestCountTextures::BeginTest();
788 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
789 EXPECT_FALSE(result->IsEmpty());
790 EXPECT_TRUE(result->HasTexture());
792 TextureMailbox mailbox;
793 scoped_ptr<SingleReleaseCallback> release;
794 result->TakeTexture(&mailbox, &release);
795 EXPECT_FALSE(release);
798 virtual void RequestCopy(Layer* layer) OVERRIDE {
799 // Request a copy to a provided texture. This should not create a new
800 // texture.
801 scoped_ptr<CopyOutputRequest> request =
802 CopyOutputRequest::CreateRequest(base::Bind(
803 &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback,
804 base::Unretained(this)));
806 gpu::gles2::GLES2Interface* gl = external_context_provider_->ContextGL();
807 gpu::Mailbox mailbox;
808 gl->GenMailboxCHROMIUM(mailbox.name);
809 sync_point_ = gl->InsertSyncPointCHROMIUM();
810 request->SetTextureMailbox(TextureMailbox(mailbox, sync_point_));
811 EXPECT_TRUE(request->has_texture_mailbox());
813 copy_layer_->RequestCopyOfOutput(request.Pass());
816 virtual void AfterTest() OVERRIDE {
817 // Expect the compositor to have waited for the sync point in the provided
818 // TextureMailbox.
819 EXPECT_EQ(sync_point_, waited_sync_point_after_readback_);
820 // Except the copy to have *not* made another texture.
821 EXPECT_EQ(num_textures_without_readback_, num_textures_with_readback_);
824 scoped_refptr<TestContextProvider> external_context_provider_;
825 unsigned sync_point_;
828 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
829 LayerTreeHostCopyRequestTestProvideTexture);
831 class LayerTreeHostCopyRequestTestDestroyBeforeCopy
832 : public LayerTreeHostCopyRequestTest {
833 protected:
834 virtual void SetupTree() OVERRIDE {
835 root_ = FakeContentLayer::Create(&client_);
836 root_->SetBounds(gfx::Size(20, 20));
838 copy_layer_ = FakeContentLayer::Create(&client_);
839 copy_layer_->SetBounds(gfx::Size(10, 10));
840 root_->AddChild(copy_layer_);
842 layer_tree_host()->SetRootLayer(root_);
843 LayerTreeHostCopyRequestTest::SetupTree();
846 virtual void BeginTest() OVERRIDE {
847 callback_count_ = 0;
848 PostSetNeedsCommitToMainThread();
851 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
852 EXPECT_TRUE(result->IsEmpty());
853 ++callback_count_;
856 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
857 MainThreadTaskRunner()->PostTask(
858 FROM_HERE,
859 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate,
860 base::Unretained(this)));
863 void DidActivate() {
864 switch (layer_tree_host()->source_frame_number()) {
865 case 1: {
866 EXPECT_EQ(0, callback_count_);
867 // Put a copy request on the layer, but then don't allow any
868 // drawing to take place.
869 scoped_ptr<CopyOutputRequest> request =
870 CopyOutputRequest::CreateRequest(
871 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::
872 CopyOutputCallback,
873 base::Unretained(this)));
874 copy_layer_->RequestCopyOfOutput(request.Pass());
876 layer_tree_host()->SetViewportSize(gfx::Size());
877 break;
879 case 2:
880 EXPECT_EQ(0, callback_count_);
881 // Remove the copy layer before we were able to draw.
882 copy_layer_->RemoveFromParent();
883 break;
884 case 3:
885 EXPECT_EQ(1, callback_count_);
886 // Allow us to draw now.
887 layer_tree_host()->SetViewportSize(
888 layer_tree_host()->root_layer()->bounds());
889 break;
890 case 4:
891 EXPECT_EQ(1, callback_count_);
892 // We should not have crashed.
893 EndTest();
897 virtual void AfterTest() OVERRIDE {}
899 int callback_count_;
900 FakeContentLayerClient client_;
901 scoped_refptr<FakeContentLayer> root_;
902 scoped_refptr<FakeContentLayer> copy_layer_;
905 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
906 LayerTreeHostCopyRequestTestDestroyBeforeCopy);
908 } // namespace
909 } // namespace cc