Changes to RenderFrameProxy:
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_copyrequest.cc
blob12fc63128f060cae65b923a4a6ce081728da9a4b
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<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
107 OVERRIDE {
108 if (use_gl_renderer_)
109 return FakeOutputSurface::Create3d();
110 return FakeOutputSurface::CreateSoftware(
111 make_scoped_ptr(new SoftwareOutputDevice));
114 bool use_gl_renderer_;
115 std::vector<gfx::Size> callbacks_;
116 FakeContentLayerClient client_;
117 scoped_refptr<FakeContentLayer> root;
118 scoped_refptr<FakeContentLayer> child;
121 // Readback can't be done with a delegating renderer.
122 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
123 GLRenderer_RunSingleThread) {
124 use_gl_renderer_ = true;
125 RunTest(false, false, false);
128 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
129 GLRenderer_RunMultiThread_MainThreadPainting) {
130 use_gl_renderer_ = true;
131 RunTest(true, false, false);
134 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
135 SoftwareRenderer_RunSingleThread) {
136 use_gl_renderer_ = false;
137 RunTest(false, false, false);
140 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
141 SoftwareRenderer_RunMultiThread_MainThreadPainting) {
142 use_gl_renderer_ = false;
143 RunTest(true, false, false);
146 class LayerTreeHostCopyRequestTestLayerDestroyed
147 : public LayerTreeHostCopyRequestTest {
148 protected:
149 virtual void SetupTree() OVERRIDE {
150 root_ = FakeContentLayer::Create(&client_);
151 root_->SetBounds(gfx::Size(20, 20));
153 main_destroyed_ = FakeContentLayer::Create(&client_);
154 main_destroyed_->SetBounds(gfx::Size(15, 15));
155 root_->AddChild(main_destroyed_);
157 impl_destroyed_ = FakeContentLayer::Create(&client_);
158 impl_destroyed_->SetBounds(gfx::Size(10, 10));
159 root_->AddChild(impl_destroyed_);
161 layer_tree_host()->SetRootLayer(root_);
162 LayerTreeHostCopyRequestTest::SetupTree();
165 virtual void BeginTest() OVERRIDE {
166 callback_count_ = 0;
167 PostSetNeedsCommitToMainThread();
170 virtual void DidCommit() OVERRIDE {
171 int frame = layer_tree_host()->source_frame_number();
172 switch (frame) {
173 case 1:
174 main_destroyed_->RequestCopyOfOutput(
175 CopyOutputRequest::CreateBitmapRequest(base::Bind(
176 &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback,
177 base::Unretained(this))));
178 impl_destroyed_->RequestCopyOfOutput(
179 CopyOutputRequest::CreateBitmapRequest(base::Bind(
180 &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback,
181 base::Unretained(this))));
182 EXPECT_EQ(0, callback_count_);
184 // Destroy the main thread layer right away.
185 main_destroyed_->RemoveFromParent();
186 main_destroyed_ = NULL;
188 // Should callback with a NULL bitmap.
189 EXPECT_EQ(1, callback_count_);
191 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
192 layer_tree_host()->SetViewportSize(gfx::Size());
193 break;
194 case 2:
195 // Flush the message loops and make sure the callbacks run.
196 layer_tree_host()->SetNeedsCommit();
197 break;
198 case 3:
199 // No drawing means no readback yet.
200 EXPECT_EQ(1, callback_count_);
202 // Destroy the impl thread layer.
203 impl_destroyed_->RemoveFromParent();
204 impl_destroyed_ = NULL;
206 // No callback yet because it's on the impl side.
207 EXPECT_EQ(1, callback_count_);
208 break;
209 case 4:
210 // Flush the message loops and make sure the callbacks run.
211 layer_tree_host()->SetNeedsCommit();
212 break;
213 case 5:
214 // We should get another callback with a NULL bitmap.
215 EXPECT_EQ(2, callback_count_);
216 EndTest();
217 break;
221 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
222 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
223 EXPECT_TRUE(result->IsEmpty());
224 ++callback_count_;
227 virtual void AfterTest() OVERRIDE {}
229 int callback_count_;
230 FakeContentLayerClient client_;
231 scoped_refptr<FakeContentLayer> root_;
232 scoped_refptr<FakeContentLayer> main_destroyed_;
233 scoped_refptr<FakeContentLayer> impl_destroyed_;
236 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed);
238 class LayerTreeHostCopyRequestTestInHiddenSubtree
239 : public LayerTreeHostCopyRequestTest {
240 protected:
241 virtual void SetupTree() OVERRIDE {
242 root_ = FakeContentLayer::Create(&client_);
243 root_->SetBounds(gfx::Size(20, 20));
245 grand_parent_layer_ = FakeContentLayer::Create(&client_);
246 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
247 root_->AddChild(grand_parent_layer_);
249 // parent_layer_ owns a render surface.
250 parent_layer_ = FakeContentLayer::Create(&client_);
251 parent_layer_->SetBounds(gfx::Size(15, 15));
252 parent_layer_->SetForceRenderSurface(true);
253 grand_parent_layer_->AddChild(parent_layer_);
255 copy_layer_ = FakeContentLayer::Create(&client_);
256 copy_layer_->SetBounds(gfx::Size(10, 10));
257 parent_layer_->AddChild(copy_layer_);
259 layer_tree_host()->SetRootLayer(root_);
260 LayerTreeHostCopyRequestTest::SetupTree();
263 void AddCopyRequest(Layer* layer) {
264 layer->RequestCopyOfOutput(
265 CopyOutputRequest::CreateBitmapRequest(base::Bind(
266 &LayerTreeHostCopyRequestTestInHiddenSubtree::CopyOutputCallback,
267 base::Unretained(this))));
270 virtual void BeginTest() OVERRIDE {
271 callback_count_ = 0;
272 PostSetNeedsCommitToMainThread();
274 AddCopyRequest(copy_layer_.get());
277 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
278 ++callback_count_;
279 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
280 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString())
281 << callback_count_;
282 switch (callback_count_) {
283 case 1:
284 // Hide the copy request layer.
285 grand_parent_layer_->SetHideLayerAndSubtree(false);
286 parent_layer_->SetHideLayerAndSubtree(false);
287 copy_layer_->SetHideLayerAndSubtree(true);
288 AddCopyRequest(copy_layer_.get());
289 break;
290 case 2:
291 // Hide the copy request layer's parent only.
292 grand_parent_layer_->SetHideLayerAndSubtree(false);
293 parent_layer_->SetHideLayerAndSubtree(true);
294 copy_layer_->SetHideLayerAndSubtree(false);
295 AddCopyRequest(copy_layer_.get());
296 break;
297 case 3:
298 // Hide the copy request layer's grand parent only.
299 grand_parent_layer_->SetHideLayerAndSubtree(true);
300 parent_layer_->SetHideLayerAndSubtree(false);
301 copy_layer_->SetHideLayerAndSubtree(false);
302 AddCopyRequest(copy_layer_.get());
303 break;
304 case 4:
305 // Hide the copy request layer's parent and grandparent.
306 grand_parent_layer_->SetHideLayerAndSubtree(true);
307 parent_layer_->SetHideLayerAndSubtree(true);
308 copy_layer_->SetHideLayerAndSubtree(false);
309 AddCopyRequest(copy_layer_.get());
310 break;
311 case 5:
312 // Hide the copy request layer as well as its parent and grandparent.
313 grand_parent_layer_->SetHideLayerAndSubtree(true);
314 parent_layer_->SetHideLayerAndSubtree(true);
315 copy_layer_->SetHideLayerAndSubtree(true);
316 AddCopyRequest(copy_layer_.get());
317 break;
318 case 6:
319 EndTest();
320 break;
324 virtual void AfterTest() OVERRIDE {}
326 int callback_count_;
327 FakeContentLayerClient client_;
328 scoped_refptr<FakeContentLayer> root_;
329 scoped_refptr<FakeContentLayer> grand_parent_layer_;
330 scoped_refptr<FakeContentLayer> parent_layer_;
331 scoped_refptr<FakeContentLayer> copy_layer_;
334 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
335 LayerTreeHostCopyRequestTestInHiddenSubtree);
337 class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
338 : public LayerTreeHostCopyRequestTest {
339 protected:
340 virtual void SetupTree() OVERRIDE {
341 root_ = FakeContentLayer::Create(&client_);
342 root_->SetBounds(gfx::Size(20, 20));
344 grand_parent_layer_ = FakeContentLayer::Create(&client_);
345 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
346 grand_parent_layer_->SetHideLayerAndSubtree(true);
347 root_->AddChild(grand_parent_layer_);
349 // parent_layer_ owns a render surface.
350 parent_layer_ = FakeContentLayer::Create(&client_);
351 parent_layer_->SetBounds(gfx::Size(15, 15));
352 parent_layer_->SetForceRenderSurface(true);
353 grand_parent_layer_->AddChild(parent_layer_);
355 copy_layer_ = FakeContentLayer::Create(&client_);
356 copy_layer_->SetBounds(gfx::Size(10, 10));
357 parent_layer_->AddChild(copy_layer_);
359 layer_tree_host()->SetRootLayer(root_);
360 LayerTreeHostCopyRequestTest::SetupTree();
363 virtual void BeginTest() OVERRIDE {
364 did_draw_ = false;
365 PostSetNeedsCommitToMainThread();
367 copy_layer_->RequestCopyOfOutput(
368 CopyOutputRequest::CreateBitmapRequest(base::Bind(
369 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
370 CopyOutputCallback,
371 base::Unretained(this))));
374 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
375 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
376 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
377 EndTest();
380 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
381 Renderer* renderer = host_impl->renderer();
383 LayerImpl* root = host_impl->active_tree()->root_layer();
384 LayerImpl* grand_parent = root->children()[0];
385 LayerImpl* parent = grand_parent->children()[0];
386 LayerImpl* copy_layer = parent->children()[0];
388 // |parent| owns a surface, but it was hidden and not part of the copy
389 // request so it should not allocate any resource.
390 EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
391 parent->render_surface()->RenderPassId()));
393 // |copy_layer| should have been rendered to a texture since it was needed
394 // for a copy request.
395 EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
396 copy_layer->render_surface()->RenderPassId()));
398 did_draw_ = true;
401 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
403 FakeContentLayerClient client_;
404 bool did_draw_;
405 scoped_refptr<FakeContentLayer> root_;
406 scoped_refptr<FakeContentLayer> grand_parent_layer_;
407 scoped_refptr<FakeContentLayer> parent_layer_;
408 scoped_refptr<FakeContentLayer> copy_layer_;
411 // No output to copy for delegated renderers.
412 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
413 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
415 class LayerTreeHostCopyRequestTestClippedOut
416 : public LayerTreeHostCopyRequestTest {
417 protected:
418 virtual void SetupTree() OVERRIDE {
419 root_ = FakeContentLayer::Create(&client_);
420 root_->SetBounds(gfx::Size(20, 20));
422 parent_layer_ = FakeContentLayer::Create(&client_);
423 parent_layer_->SetBounds(gfx::Size(15, 15));
424 parent_layer_->SetMasksToBounds(true);
425 root_->AddChild(parent_layer_);
427 copy_layer_ = FakeContentLayer::Create(&client_);
428 copy_layer_->SetPosition(gfx::Point(15, 15));
429 copy_layer_->SetBounds(gfx::Size(10, 10));
430 parent_layer_->AddChild(copy_layer_);
432 layer_tree_host()->SetRootLayer(root_);
433 LayerTreeHostCopyRequestTest::SetupTree();
436 virtual void BeginTest() OVERRIDE {
437 PostSetNeedsCommitToMainThread();
439 copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
440 base::Bind(&LayerTreeHostCopyRequestTestClippedOut::CopyOutputCallback,
441 base::Unretained(this))));
444 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
445 // We should still get a callback with no output if the copy requested layer
446 // was completely clipped away.
447 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
448 EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
449 EndTest();
452 virtual void AfterTest() OVERRIDE {}
454 FakeContentLayerClient client_;
455 scoped_refptr<FakeContentLayer> root_;
456 scoped_refptr<FakeContentLayer> parent_layer_;
457 scoped_refptr<FakeContentLayer> copy_layer_;
460 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
461 LayerTreeHostCopyRequestTestClippedOut);
463 class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
464 : public LayerTreeHostCopyRequestTest {
465 protected:
466 virtual void SetupTree() OVERRIDE {
467 root_ = FakeContentLayer::Create(&client_);
468 root_->SetBounds(gfx::Size(20, 20));
470 copy_layer_ = FakeContentLayer::Create(&client_);
471 copy_layer_->SetBounds(gfx::Size(10, 10));
472 root_->AddChild(copy_layer_);
474 layer_tree_host()->SetRootLayer(root_);
475 LayerTreeHostCopyRequestTest::SetupTree();
478 void AddCopyRequest(Layer* layer) {
479 layer->RequestCopyOfOutput(
480 CopyOutputRequest::CreateBitmapRequest(base::Bind(
481 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
482 base::Unretained(this))));
485 virtual void BeginTest() OVERRIDE {
486 saw_copy_request_ = false;
487 callback_count_ = 0;
488 PostSetNeedsCommitToMainThread();
490 // Prevent drawing.
491 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
493 AddCopyRequest(copy_layer_.get());
496 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
497 if (impl->active_tree()->source_frame_number() == 0) {
498 LayerImpl* root = impl->active_tree()->root_layer();
499 EXPECT_TRUE(root->children()[0]->HasCopyRequest());
500 saw_copy_request_ = true;
504 virtual void DidCommit() OVERRIDE {
505 if (layer_tree_host()->source_frame_number() == 1) {
506 // Allow drawing.
507 layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
509 AddCopyRequest(copy_layer_.get());
513 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
514 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
515 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
516 ++callback_count_;
518 if (callback_count_ == 2)
519 EndTest();
522 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
524 bool saw_copy_request_;
525 int callback_count_;
526 FakeContentLayerClient client_;
527 scoped_refptr<FakeContentLayer> root_;
528 scoped_refptr<FakeContentLayer> copy_layer_;
531 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
532 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
534 class LayerTreeHostCopyRequestTestLostOutputSurface
535 : public LayerTreeHostCopyRequestTest {
536 protected:
537 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
538 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 virtual void SetupTree() OVERRIDE {
550 root_ = FakeContentLayer::Create(&client_);
551 root_->SetBounds(gfx::Size(20, 20));
553 copy_layer_ = FakeContentLayer::Create(&client_);
554 copy_layer_->SetBounds(gfx::Size(10, 10));
555 root_->AddChild(copy_layer_);
557 layer_tree_host()->SetRootLayer(root_);
558 LayerTreeHostCopyRequestTest::SetupTree();
561 virtual 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 virtual 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_.reset();
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 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
609 bool result) OVERRIDE {
610 switch (impl->active_tree()->source_frame_number()) {
611 case 0:
612 // The layers have been drawn, so their textures have been allocated.
613 EXPECT_FALSE(result_);
614 num_textures_without_readback_ =
615 first_context_provider_->TestContext3d()->NumTextures();
616 break;
617 case 1:
618 // We did a readback, so there will be a readback texture around now.
619 EXPECT_LT(num_textures_without_readback_,
620 first_context_provider_->TestContext3d()->NumTextures());
621 break;
622 case 2:
623 // The readback texture is collected.
624 EXPECT_TRUE(result_);
626 // Lose the output surface.
627 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
628 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
629 break;
630 case 3:
631 // With SingleThreadProxy it takes two commits to finally swap after a
632 // context loss.
633 case 4:
634 // The output surface has been recreated.
635 EXPECT_TRUE(second_context_provider_.get());
637 num_textures_after_loss_ =
638 first_context_provider_->TestContext3d()->NumTextures();
639 break;
643 void CheckNumTextures(size_t expected_num_textures) {
644 EXPECT_EQ(expected_num_textures,
645 first_context_provider_->TestContext3d()->NumTextures());
646 EndTest();
649 virtual void AfterTest() OVERRIDE {}
651 scoped_refptr<TestContextProvider> first_context_provider_;
652 scoped_refptr<TestContextProvider> second_context_provider_;
653 size_t num_textures_without_readback_;
654 size_t num_textures_after_loss_;
655 FakeContentLayerClient client_;
656 scoped_refptr<FakeContentLayer> root_;
657 scoped_refptr<FakeContentLayer> copy_layer_;
658 scoped_ptr<CopyOutputResult> result_;
661 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
662 LayerTreeHostCopyRequestTestLostOutputSurface);
664 class LayerTreeHostCopyRequestTestCountTextures
665 : public LayerTreeHostCopyRequestTest {
666 protected:
667 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
668 OVERRIDE {
669 context_provider_ = TestContextProvider::Create();
670 return FakeOutputSurface::Create3d(context_provider_);
673 virtual void SetupTree() OVERRIDE {
674 root_ = FakeContentLayer::Create(&client_);
675 root_->SetBounds(gfx::Size(20, 20));
677 copy_layer_ = FakeContentLayer::Create(&client_);
678 copy_layer_->SetBounds(gfx::Size(10, 10));
679 root_->AddChild(copy_layer_);
681 layer_tree_host()->SetRootLayer(root_);
682 LayerTreeHostCopyRequestTest::SetupTree();
685 virtual 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 virtual 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 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
705 bool result) OVERRIDE {
706 switch (impl->active_tree()->source_frame_number()) {
707 case 0:
708 // The layers have been drawn, so their textures have been allocated.
709 num_textures_without_readback_ =
710 context_provider_->TestContext3d()->NumTextures();
711 break;
712 case 1:
713 // We did a readback, so there will be a readback texture around now.
714 num_textures_with_readback_ =
715 context_provider_->TestContext3d()->NumTextures();
716 waited_sync_point_after_readback_ =
717 context_provider_->TestContext3d()->last_waited_sync_point();
719 MainThreadTaskRunner()->PostTask(
720 FROM_HERE,
721 base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest,
722 base::Unretained(this)));
723 break;
727 virtual void DoEndTest() { EndTest(); }
729 scoped_refptr<TestContextProvider> context_provider_;
730 size_t num_textures_without_readback_;
731 size_t num_textures_with_readback_;
732 unsigned waited_sync_point_after_readback_;
733 FakeContentLayerClient client_;
734 scoped_refptr<FakeContentLayer> root_;
735 scoped_refptr<FakeContentLayer> copy_layer_;
738 class LayerTreeHostCopyRequestTestCreatesTexture
739 : public LayerTreeHostCopyRequestTestCountTextures {
740 protected:
741 virtual void RequestCopy(Layer* layer) OVERRIDE {
742 // Request a normal texture copy. This should create a new texture.
743 copy_layer_->RequestCopyOfOutput(
744 CopyOutputRequest::CreateRequest(base::Bind(
745 &LayerTreeHostCopyRequestTestCreatesTexture::CopyOutputCallback,
746 base::Unretained(this))));
749 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
750 EXPECT_FALSE(result->IsEmpty());
751 EXPECT_TRUE(result->HasTexture());
753 TextureMailbox mailbox;
754 scoped_ptr<SingleReleaseCallback> release;
755 result->TakeTexture(&mailbox, &release);
756 EXPECT_TRUE(release);
758 release->Run(0, false);
761 virtual void AfterTest() OVERRIDE {
762 // No sync point was needed.
763 EXPECT_EQ(0u, waited_sync_point_after_readback_);
764 // Except the copy to have made another texture.
765 EXPECT_EQ(num_textures_without_readback_ + 1, num_textures_with_readback_);
769 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
770 LayerTreeHostCopyRequestTestCreatesTexture);
772 class LayerTreeHostCopyRequestTestProvideTexture
773 : public LayerTreeHostCopyRequestTestCountTextures {
774 protected:
775 virtual void BeginTest() OVERRIDE {
776 external_context_provider_ = TestContextProvider::Create();
777 EXPECT_TRUE(external_context_provider_->BindToCurrentThread());
778 LayerTreeHostCopyRequestTestCountTextures::BeginTest();
781 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
782 EXPECT_FALSE(result->IsEmpty());
783 EXPECT_TRUE(result->HasTexture());
785 TextureMailbox mailbox;
786 scoped_ptr<SingleReleaseCallback> release;
787 result->TakeTexture(&mailbox, &release);
788 EXPECT_FALSE(release);
791 virtual void RequestCopy(Layer* layer) OVERRIDE {
792 // Request a copy to a provided texture. This should not create a new
793 // texture.
794 scoped_ptr<CopyOutputRequest> request =
795 CopyOutputRequest::CreateRequest(base::Bind(
796 &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback,
797 base::Unretained(this)));
799 gpu::gles2::GLES2Interface* gl = external_context_provider_->ContextGL();
800 gpu::Mailbox mailbox;
801 gl->GenMailboxCHROMIUM(mailbox.name);
802 sync_point_ = gl->InsertSyncPointCHROMIUM();
803 request->SetTextureMailbox(
804 TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point_));
805 EXPECT_TRUE(request->has_texture_mailbox());
807 copy_layer_->RequestCopyOfOutput(request.Pass());
810 virtual void AfterTest() OVERRIDE {
811 // Expect the compositor to have waited for the sync point in the provided
812 // TextureMailbox.
813 EXPECT_EQ(sync_point_, waited_sync_point_after_readback_);
814 // Except the copy to have *not* made another texture.
815 EXPECT_EQ(num_textures_without_readback_, num_textures_with_readback_);
818 scoped_refptr<TestContextProvider> external_context_provider_;
819 unsigned sync_point_;
822 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
823 LayerTreeHostCopyRequestTestProvideTexture);
825 class LayerTreeHostCopyRequestTestDestroyBeforeCopy
826 : public LayerTreeHostCopyRequestTest {
827 protected:
828 virtual void SetupTree() OVERRIDE {
829 root_ = FakeContentLayer::Create(&client_);
830 root_->SetBounds(gfx::Size(20, 20));
832 copy_layer_ = FakeContentLayer::Create(&client_);
833 copy_layer_->SetBounds(gfx::Size(10, 10));
834 root_->AddChild(copy_layer_);
836 layer_tree_host()->SetRootLayer(root_);
837 LayerTreeHostCopyRequestTest::SetupTree();
840 virtual void BeginTest() OVERRIDE {
841 callback_count_ = 0;
842 PostSetNeedsCommitToMainThread();
845 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
846 EXPECT_TRUE(result->IsEmpty());
847 ++callback_count_;
850 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
851 MainThreadTaskRunner()->PostTask(
852 FROM_HERE,
853 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate,
854 base::Unretained(this)));
857 void DidActivate() {
858 switch (layer_tree_host()->source_frame_number()) {
859 case 1: {
860 EXPECT_EQ(0, callback_count_);
861 // Put a copy request on the layer, but then don't allow any
862 // drawing to take place.
863 scoped_ptr<CopyOutputRequest> request =
864 CopyOutputRequest::CreateRequest(
865 base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::
866 CopyOutputCallback,
867 base::Unretained(this)));
868 copy_layer_->RequestCopyOfOutput(request.Pass());
870 layer_tree_host()->SetViewportSize(gfx::Size());
871 break;
873 case 2:
874 EXPECT_EQ(0, callback_count_);
875 // Remove the copy layer before we were able to draw.
876 copy_layer_->RemoveFromParent();
877 break;
878 case 3:
879 EXPECT_EQ(1, callback_count_);
880 // Allow us to draw now.
881 layer_tree_host()->SetViewportSize(
882 layer_tree_host()->root_layer()->bounds());
883 break;
884 case 4:
885 EXPECT_EQ(1, callback_count_);
886 // We should not have crashed.
887 EndTest();
891 virtual void AfterTest() OVERRIDE {}
893 int callback_count_;
894 FakeContentLayerClient client_;
895 scoped_refptr<FakeContentLayer> root_;
896 scoped_refptr<FakeContentLayer> copy_layer_;
899 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
900 LayerTreeHostCopyRequestTestDestroyBeforeCopy);
902 class LayerTreeHostCopyRequestTestShutdownBeforeCopy
903 : public LayerTreeHostCopyRequestTest {
904 protected:
905 virtual void SetupTree() OVERRIDE {
906 root_ = FakeContentLayer::Create(&client_);
907 root_->SetBounds(gfx::Size(20, 20));
909 copy_layer_ = FakeContentLayer::Create(&client_);
910 copy_layer_->SetBounds(gfx::Size(10, 10));
911 root_->AddChild(copy_layer_);
913 layer_tree_host()->SetRootLayer(root_);
914 LayerTreeHostCopyRequestTest::SetupTree();
917 virtual void BeginTest() OVERRIDE {
918 callback_count_ = 0;
919 PostSetNeedsCommitToMainThread();
922 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
923 EXPECT_TRUE(result->IsEmpty());
924 ++callback_count_;
927 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
928 MainThreadTaskRunner()->PostTask(
929 FROM_HERE,
930 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::DidActivate,
931 base::Unretained(this)));
934 void DidActivate() {
935 switch (layer_tree_host()->source_frame_number()) {
936 case 1: {
937 EXPECT_EQ(0, callback_count_);
938 // Put a copy request on the layer, but then don't allow any
939 // drawing to take place.
940 scoped_ptr<CopyOutputRequest> request =
941 CopyOutputRequest::CreateRequest(
942 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::
943 CopyOutputCallback,
944 base::Unretained(this)));
945 copy_layer_->RequestCopyOfOutput(request.Pass());
947 layer_tree_host()->SetViewportSize(gfx::Size());
948 break;
950 case 2:
951 DestroyLayerTreeHost();
952 // End the test after the copy result has had a chance to get back to
953 // the main thread.
954 MainThreadTaskRunner()->PostTask(
955 FROM_HERE,
956 base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::EndTest,
957 base::Unretained(this)));
958 break;
962 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, callback_count_); }
964 int callback_count_;
965 FakeContentLayerClient client_;
966 scoped_refptr<FakeContentLayer> root_;
967 scoped_refptr<FakeContentLayer> copy_layer_;
970 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
971 LayerTreeHostCopyRequestTestShutdownBeforeCopy);
973 } // namespace
974 } // namespace cc