Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: cc/trees/layer_tree_host_unittest_copyrequest.cc

Issue 99253004: cc: Allow copy requests to provide a texture. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: mailbox: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/trees/layer_tree_host_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
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"
13
14 namespace cc {
15 namespace {
16
17 // These tests only use direct rendering, as there is no output to copy for
18 // delegated renderers.
19 class LayerTreeHostCopyRequestTest : public LayerTreeTest {};
20
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));
27
28 child = FakeContentLayer::Create(&client_);
29 child->SetBounds(gfx::Size(10, 10));
30 root->AddChild(child);
31
32 layer_tree_host()->SetRootLayer(root);
33 LayerTreeHostCopyRequestTest::SetupTree();
34 }
35
36 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
37
38 virtual void DidCommitAndDrawFrame() OVERRIDE { WaitForCallback(); }
39
40 void WaitForCallback() {
41 base::MessageLoop::current()->PostTask(
42 FROM_HERE,
43 base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::NextStep,
44 base::Unretained(this)));
45 }
46
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;
61 }
62 EXPECT_EQ(1u, callbacks_.size());
63 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
64
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;
83 }
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;
92 }
93 }
94
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());
102 }
103
104 virtual void AfterTest() OVERRIDE { EXPECT_EQ(4u, callbacks_.size()); }
105
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();
114 }
115 return output_surface.PassAs<OutputSurface>();
116 }
117
118 bool use_gl_renderer_;
119 std::vector<gfx::Size> callbacks_;
120 FakeContentLayerClient client_;
121 scoped_refptr<FakeContentLayer> root;
122 scoped_refptr<FakeContentLayer> child;
123 };
124
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);
130 }
131
132 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
133 GLRenderer_RunMultiThread_MainThreadPainting) {
134 use_gl_renderer_ = true;
135 RunTest(true, false, false);
136 }
137
138 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
139 SoftwareRenderer_RunSingleThread) {
140 use_gl_renderer_ = false;
141 RunTest(false, false, false);
142 }
143
144 TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
145 SoftwareRenderer_RunMultiThread_MainThreadPainting) {
146 use_gl_renderer_ = false;
147 RunTest(true, false, false);
148 }
149
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));
156
157 main_destroyed_ = FakeContentLayer::Create(&client_);
158 main_destroyed_->SetBounds(gfx::Size(15, 15));
159 root_->AddChild(main_destroyed_);
160
161 impl_destroyed_ = FakeContentLayer::Create(&client_);
162 impl_destroyed_->SetBounds(gfx::Size(10, 10));
163 root_->AddChild(impl_destroyed_);
164
165 layer_tree_host()->SetRootLayer(root_);
166 LayerTreeHostCopyRequestTest::SetupTree();
167 }
168
169 virtual void BeginTest() OVERRIDE {
170 callback_count_ = 0;
171 PostSetNeedsCommitToMainThread();
172 }
173
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_);
187
188 // Destroy the main thread layer right away.
189 main_destroyed_->RemoveFromParent();
190 main_destroyed_ = NULL;
191
192 // Should callback with a NULL bitmap.
193 EXPECT_EQ(1, callback_count_);
194
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_);
205
206 // Destroy the impl thread layer.
207 impl_destroyed_->RemoveFromParent();
208 impl_destroyed_ = NULL;
209
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;
222 }
223 }
224
225 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
226 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
227 EXPECT_TRUE(result->IsEmpty());
228 ++callback_count_;
229 }
230
231 virtual void AfterTest() OVERRIDE {}
232
233 int callback_count_;
234 FakeContentLayerClient client_;
235 scoped_refptr<FakeContentLayer> root_;
236 scoped_refptr<FakeContentLayer> main_destroyed_;
237 scoped_refptr<FakeContentLayer> impl_destroyed_;
238 };
239
240 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed);
241
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));
248
249 grand_parent_layer_ = FakeContentLayer::Create(&client_);
250 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
251 root_->AddChild(grand_parent_layer_);
252
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_);
258
259 copy_layer_ = FakeContentLayer::Create(&client_);
260 copy_layer_->SetBounds(gfx::Size(10, 10));
261 parent_layer_->AddChild(copy_layer_);
262
263 layer_tree_host()->SetRootLayer(root_);
264 LayerTreeHostCopyRequestTest::SetupTree();
265 }
266
267 void AddCopyRequest(Layer* layer) {
268 layer->RequestCopyOfOutput(
269 CopyOutputRequest::CreateBitmapRequest(base::Bind(
270 &LayerTreeHostCopyRequestTestInHiddenSubtree::CopyOutputCallback,
271 base::Unretained(this))));
272 }
273
274 virtual void BeginTest() OVERRIDE {
275 callback_count_ = 0;
276 PostSetNeedsCommitToMainThread();
277
278 AddCopyRequest(copy_layer_.get());
279 }
280
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;
325 }
326 }
327
328 virtual void AfterTest() OVERRIDE {}
329
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_;
336 };
337
338 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
339 LayerTreeHostCopyRequestTestInHiddenSubtree);
340
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));
347
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_);
352
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_);
358
359 copy_layer_ = FakeContentLayer::Create(&client_);
360 copy_layer_->SetBounds(gfx::Size(10, 10));
361 parent_layer_->AddChild(copy_layer_);
362
363 layer_tree_host()->SetRootLayer(root_);
364 LayerTreeHostCopyRequestTest::SetupTree();
365 }
366
367 virtual void BeginTest() OVERRIDE {
368 did_draw_ = false;
369 PostSetNeedsCommitToMainThread();
370
371 copy_layer_->RequestCopyOfOutput(
372 CopyOutputRequest::CreateBitmapRequest(base::Bind(
373 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
374 CopyOutputCallback,
375 base::Unretained(this))));
376 }
377
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();
382 }
383
384 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
385 Renderer* renderer = host_impl->renderer();
386
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];
391
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()));
396
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()));
401
402 did_draw_ = true;
403 }
404
405 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
406
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_;
413 };
414
415 // No output to copy for delegated renderers.
416 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
417 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
418
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));
425
426 parent_layer_ = FakeContentLayer::Create(&client_);
427 parent_layer_->SetBounds(gfx::Size(15, 15));
428 parent_layer_->SetMasksToBounds(true);
429 root_->AddChild(parent_layer_);
430
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_);
435
436 layer_tree_host()->SetRootLayer(root_);
437 LayerTreeHostCopyRequestTest::SetupTree();
438 }
439
440 virtual void BeginTest() OVERRIDE {
441 PostSetNeedsCommitToMainThread();
442
443 copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
444 base::Bind(&LayerTreeHostCopyRequestTestClippedOut::CopyOutputCallback,
445 base::Unretained(this))));
446 }
447
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();
454 }
455
456 virtual void AfterTest() OVERRIDE {}
457
458 FakeContentLayerClient client_;
459 scoped_refptr<FakeContentLayer> root_;
460 scoped_refptr<FakeContentLayer> parent_layer_;
461 scoped_refptr<FakeContentLayer> copy_layer_;
462 };
463
464 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
465 LayerTreeHostCopyRequestTestClippedOut);
466
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));
473
474 copy_layer_ = FakeContentLayer::Create(&client_);
475 copy_layer_->SetBounds(gfx::Size(10, 10));
476 root_->AddChild(copy_layer_);
477
478 layer_tree_host()->SetRootLayer(root_);
479 LayerTreeHostCopyRequestTest::SetupTree();
480 }
481
482 void AddCopyRequest(Layer* layer) {
483 layer->RequestCopyOfOutput(
484 CopyOutputRequest::CreateBitmapRequest(base::Bind(
485 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
486 base::Unretained(this))));
487 }
488
489 virtual void BeginTest() OVERRIDE {
490 saw_copy_request_ = false;
491 callback_count_ = 0;
492 PostSetNeedsCommitToMainThread();
493
494 // Prevent drawing.
495 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
496
497 AddCopyRequest(copy_layer_.get());
498 }
499
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;
505 }
506 }
507
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()));
512
513 AddCopyRequest(copy_layer_.get());
514 }
515 }
516
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_;
521
522 if (callback_count_ == 2)
523 EndTest();
524 }
525
526 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
527
528 bool saw_copy_request_;
529 int callback_count_;
530 FakeContentLayerClient client_;
531 scoped_refptr<FakeContentLayer> root_;
532 scoped_refptr<FakeContentLayer> copy_layer_;
533 };
534
535 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
536 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
537
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>();
547 }
548
549 EXPECT_FALSE(second_context_provider_.get());
550 second_context_provider_ = TestContextProvider::Create();
551 return FakeOutputSurface::Create3d(second_context_provider_)
552 .PassAs<OutputSurface>();
553 }
554
555 virtual void SetupTree() OVERRIDE {
556 root_ = FakeContentLayer::Create(&client_);
557 root_->SetBounds(gfx::Size(20, 20));
558
559 copy_layer_ = FakeContentLayer::Create(&client_);
560 copy_layer_->SetBounds(gfx::Size(10, 10));
561 root_->AddChild(copy_layer_);
562
563 layer_tree_host()->SetRootLayer(root_);
564 LayerTreeHostCopyRequestTest::SetupTree();
565 }
566
567 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
568
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());
573
574 // Save the result for later.
575 EXPECT_FALSE(result_);
576 result_ = result.Pass();
577
578 // Post a commit to lose the output surface.
579 layer_tree_host()->SetNeedsCommit();
580 }
581
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.
587
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();
602
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;
611 }
612 }
613
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_);
631
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());
642
643 num_textures_after_loss_ =
644 first_context_provider_->TestContext3d()->NumTextures();
645 break;
646 }
647 }
648
649 void CheckNumTextures(size_t expected_num_textures) {
650 EXPECT_EQ(expected_num_textures,
651 first_context_provider_->TestContext3d()->NumTextures());
652 EndTest();
653 }
654
655 virtual void AfterTest() OVERRIDE {}
656
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_;
665 };
666
667 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
668 LayerTreeHostCopyRequestTestLostOutputSurface);
669
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>();
678 }
679
680 virtual void SetupTree() OVERRIDE {
681 root_ = FakeContentLayer::Create(&client_);
682 root_->SetBounds(gfx::Size(20, 20));
683
684 copy_layer_ = FakeContentLayer::Create(&client_);
685 copy_layer_->SetBounds(gfx::Size(10, 10));
686 root_->AddChild(copy_layer_);
687
688 layer_tree_host()->SetRootLayer(root_);
689 LayerTreeHostCopyRequestTest::SetupTree();
690 }
691
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();
697 }
698
699 virtual void RequestCopy(Layer* layer) = 0;
700
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;
708 }
709 }
710
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();
725
726 MainThreadTaskRunner()->PostTask(
727 FROM_HERE,
728 base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest,
729 base::Unretained(this)));
730 break;
731 }
732 }
733
734 virtual void DoEndTest() { EndTest(); }
735
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_;
743 };
744
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))));
754 }
755
756 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
757 EXPECT_FALSE(result->IsEmpty());
758 EXPECT_TRUE(result->HasTexture());
759
760 TextureMailbox mailbox;
761 scoped_ptr<SingleReleaseCallback> release;
762 result->TakeTexture(&mailbox, &release);
763 EXPECT_TRUE(release);
764
765 release->Run(0, false);
766 }
767
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_);
773 }
774 };
775
776 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
777 LayerTreeHostCopyRequestTestCreatesTexture);
778
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();
786 }
787
788 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
789 EXPECT_FALSE(result->IsEmpty());
790 EXPECT_TRUE(result->HasTexture());
791
792 TextureMailbox mailbox;
793 scoped_ptr<SingleReleaseCallback> release;
794 result->TakeTexture(&mailbox, &release);
795 EXPECT_FALSE(release);
796 }
797
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)));
805
806 gpu::Mailbox mailbox;
807 external_context_provider_->Context3d()->genMailboxCHROMIUM(mailbox.name);
808 sync_point_ = external_context_provider_->Context3d()->insertSyncPoint();
809 request->SetTextureMailbox(TextureMailbox(mailbox, sync_point_));
810 EXPECT_TRUE(request->has_texture_mailbox());
811
812 copy_layer_->RequestCopyOfOutput(request.Pass());
813 }
814
815 virtual void AfterTest() OVERRIDE {
816 // Expect the compositor to have waited for the sync point in the provided
817 // TextureMailbox.
818 EXPECT_EQ(sync_point_, waited_sync_point_after_readback_);
819 // Except the copy to have *not* made another texture.
820 EXPECT_EQ(num_textures_without_readback_, num_textures_with_readback_);
821 }
822
823 scoped_refptr<TestContextProvider> external_context_provider_;
824 unsigned sync_point_;
825 };
826
827 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
828 LayerTreeHostCopyRequestTestProvideTexture);
829
830 } // namespace
831 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/layer_tree_host_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698