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

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

Issue 1057283003: Remove parts of //cc we aren't using (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 8 months 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
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/trees/layer_tree_host.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/thread.h"
13 #include "base/time/time.h"
14 #include "cc/layers/delegated_frame_provider.h"
15 #include "cc/layers/delegated_frame_resource_collection.h"
16 #include "cc/layers/delegated_renderer_layer.h"
17 #include "cc/layers/delegated_renderer_layer_impl.h"
18 #include "cc/output/compositor_frame.h"
19 #include "cc/output/compositor_frame_ack.h"
20 #include "cc/output/delegated_frame_data.h"
21 #include "cc/quads/render_pass_draw_quad.h"
22 #include "cc/quads/shared_quad_state.h"
23 #include "cc/quads/texture_draw_quad.h"
24 #include "cc/resources/returned_resource.h"
25 #include "cc/test/fake_delegated_renderer_layer.h"
26 #include "cc/test/fake_delegated_renderer_layer_impl.h"
27 #include "cc/test/fake_output_surface.h"
28 #include "cc/test/layer_tree_test.h"
29 #include "cc/trees/layer_tree_impl.h"
30 #include "gpu/GLES2/gl2extchromium.h"
31
32 namespace cc {
33 namespace {
34
35 bool ReturnedResourceLower(const ReturnedResource& a,
36 const ReturnedResource& b) {
37 return a.id < b.id;
38 }
39
40 // Tests if the list of resources matches an expectation, modulo the order.
41 bool ResourcesMatch(ReturnedResourceArray actual,
42 unsigned* expected,
43 size_t expected_count) {
44 std::sort(actual.begin(), actual.end(), ReturnedResourceLower);
45 std::sort(expected, expected + expected_count);
46 size_t actual_index = 0;
47
48 // for each element of the expected array, count off one of the actual array
49 // (after checking it matches).
50 for (size_t expected_index = 0; expected_index < expected_count;
51 ++expected_index) {
52 EXPECT_LT(actual_index, actual.size());
53 if (actual_index >= actual.size())
54 return false;
55 EXPECT_EQ(actual[actual_index].id, expected[expected_index]);
56 if (actual[actual_index].id != expected[expected_index])
57 return false;
58 EXPECT_GT(actual[actual_index].count, 0);
59 if (actual[actual_index].count <= 0) {
60 return false;
61 } else {
62 --actual[actual_index].count;
63 if (actual[actual_index].count == 0)
64 ++actual_index;
65 }
66 }
67 EXPECT_EQ(actual_index, actual.size());
68 return actual_index == actual.size();
69 }
70
71 #define EXPECT_RESOURCES(expected, actual) \
72 EXPECT_TRUE(ResourcesMatch(actual, expected, arraysize(expected)));
73
74 // These tests deal with delegated renderer layers.
75 class LayerTreeHostDelegatedTest : public LayerTreeTest {
76 protected:
77 scoped_ptr<DelegatedFrameData> CreateFrameData(
78 const gfx::Rect& root_output_rect,
79 const gfx::Rect& root_damage_rect) {
80 scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
81
82 scoped_ptr<RenderPass> root_pass(RenderPass::Create());
83 root_pass->SetNew(RenderPassId(1, 1),
84 root_output_rect,
85 root_damage_rect,
86 gfx::Transform());
87 frame->render_pass_list.push_back(root_pass.Pass());
88 return frame.Pass();
89 }
90
91 scoped_ptr<DelegatedFrameData> CreateInvalidFrameData(
92 const gfx::Rect& root_output_rect,
93 const gfx::Rect& root_damage_rect) {
94 scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
95
96 scoped_ptr<RenderPass> root_pass(RenderPass::Create());
97 root_pass->SetNew(RenderPassId(1, 1),
98 root_output_rect,
99 root_damage_rect,
100 gfx::Transform());
101
102 SharedQuadState* shared_quad_state =
103 root_pass->CreateAndAppendSharedQuadState();
104
105 gfx::Rect rect = root_output_rect;
106 gfx::Rect opaque_rect = root_output_rect;
107 gfx::Rect visible_rect = root_output_rect;
108 // An invalid resource id! The resource isn't part of the frame.
109 unsigned resource_id = 5;
110 bool premultiplied_alpha = false;
111 gfx::PointF uv_top_left = gfx::PointF(0.f, 0.f);
112 gfx::PointF uv_bottom_right = gfx::PointF(1.f, 1.f);
113 SkColor background_color = 0;
114 float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
115 bool flipped = false;
116 bool nearest_neighbor = false;
117
118 TextureDrawQuad* invalid_draw_quad =
119 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
120 invalid_draw_quad->SetNew(shared_quad_state,
121 rect,
122 opaque_rect,
123 visible_rect,
124 resource_id,
125 premultiplied_alpha,
126 uv_top_left,
127 uv_bottom_right,
128 background_color,
129 vertex_opacity,
130 flipped,
131 nearest_neighbor);
132
133 frame->render_pass_list.push_back(root_pass.Pass());
134 return frame.Pass();
135 }
136
137 void AddTransferableResource(DelegatedFrameData* frame,
138 ResourceProvider::ResourceId resource_id) {
139 TransferableResource resource;
140 resource.id = resource_id;
141 resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
142 GLbyte arbitrary_mailbox[GL_MAILBOX_SIZE_CHROMIUM] = {
143 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
144 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
145 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4};
146 resource.mailbox_holder.mailbox.SetName(arbitrary_mailbox);
147 frame->resource_list.push_back(resource);
148 }
149
150 void AddTextureQuad(DelegatedFrameData* frame,
151 ResourceProvider::ResourceId resource_id) {
152 RenderPass* render_pass = frame->render_pass_list[0];
153 SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState();
154 TextureDrawQuad* quad =
155 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
156 float vertex_opacity[4] = { 1.f, 1.f, 1.f, 1.f };
157 quad->SetNew(sqs,
158 gfx::Rect(0, 0, 10, 10),
159 gfx::Rect(0, 0, 10, 10),
160 gfx::Rect(0, 0, 10, 10),
161 resource_id,
162 false,
163 gfx::PointF(0.f, 0.f),
164 gfx::PointF(1.f, 1.f),
165 SK_ColorTRANSPARENT,
166 vertex_opacity,
167 false,
168 false);
169 }
170
171 void AddRenderPass(DelegatedFrameData* frame,
172 RenderPassId id,
173 const gfx::Rect& output_rect,
174 const gfx::Rect& damage_rect,
175 const FilterOperations& filters,
176 const FilterOperations& background_filters) {
177 for (size_t i = 0; i < frame->render_pass_list.size(); ++i)
178 DCHECK(id != frame->render_pass_list[i]->id);
179
180 scoped_ptr<RenderPass> pass(RenderPass::Create());
181 pass->SetNew(id,
182 output_rect,
183 damage_rect,
184 gfx::Transform());
185 frame->render_pass_list.push_back(pass.Pass());
186
187 RenderPass* render_pass = frame->render_pass_list[0];
188 SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState();
189 RenderPassDrawQuad* quad =
190 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
191
192 quad->SetNew(sqs,
193 output_rect,
194 output_rect,
195 id,
196 0,
197 gfx::Vector2dF(),
198 gfx::Size(),
199 filters,
200 gfx::Vector2dF(),
201 background_filters);
202 }
203
204 static ResourceProvider::ResourceId AppendResourceId(
205 std::vector<ResourceProvider::ResourceId>* resources_in_last_sent_frame,
206 ResourceProvider::ResourceId resource_id) {
207 resources_in_last_sent_frame->push_back(resource_id);
208 return resource_id;
209 }
210
211 void ReturnUnusedResourcesFromParent(LayerTreeHostImpl* host_impl) {
212 DelegatedFrameData* delegated_frame_data =
213 output_surface()->last_sent_frame().delegated_frame_data.get();
214 if (!delegated_frame_data)
215 return;
216
217 std::vector<ResourceProvider::ResourceId> resources_in_last_sent_frame;
218 for (size_t i = 0; i < delegated_frame_data->resource_list.size(); ++i) {
219 resources_in_last_sent_frame.push_back(
220 delegated_frame_data->resource_list[i].id);
221 }
222
223 std::vector<ResourceProvider::ResourceId> resources_to_return;
224
225 const TransferableResourceArray& resources_held_by_parent =
226 output_surface()->resources_held_by_parent();
227 for (size_t i = 0; i < resources_held_by_parent.size(); ++i) {
228 ResourceProvider::ResourceId resource_in_parent =
229 resources_held_by_parent[i].id;
230 bool resource_in_parent_is_not_part_of_frame =
231 std::find(resources_in_last_sent_frame.begin(),
232 resources_in_last_sent_frame.end(),
233 resource_in_parent) == resources_in_last_sent_frame.end();
234 if (resource_in_parent_is_not_part_of_frame)
235 resources_to_return.push_back(resource_in_parent);
236 }
237
238 if (resources_to_return.empty())
239 return;
240
241 CompositorFrameAck ack;
242 for (size_t i = 0; i < resources_to_return.size(); ++i)
243 output_surface()->ReturnResource(resources_to_return[i], &ack);
244 host_impl->ReclaimResources(&ack);
245 }
246 };
247
248 class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
249 : public LayerTreeHostDelegatedTest,
250 public DelegatedFrameResourceCollectionClient {
251 public:
252 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer()
253 : resource_collection_(new DelegatedFrameResourceCollection),
254 available_(false) {
255 resource_collection_->SetClient(this);
256 }
257
258 void SetupTree() override {
259 root_ = Layer::Create();
260 root_->SetBounds(gfx::Size(15, 15));
261
262 layer_tree_host()->SetRootLayer(root_);
263 LayerTreeHostDelegatedTest::SetupTree();
264 }
265
266 void BeginTest() override {
267 resource_collection_->SetClient(this);
268 PostSetNeedsCommitToMainThread();
269 }
270
271 void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data) {
272 RenderPass* root_pass = frame_data->render_pass_list.back();
273 gfx::Size frame_size = root_pass->output_rect.size();
274
275 if (frame_provider_.get() && frame_size == frame_provider_->frame_size()) {
276 frame_provider_->SetFrameData(frame_data.Pass());
277 return;
278 }
279
280 if (delegated_.get()) {
281 delegated_->RemoveFromParent();
282 delegated_ = NULL;
283 frame_provider_ = NULL;
284 }
285
286 frame_provider_ = new DelegatedFrameProvider(resource_collection_.get(),
287 frame_data.Pass());
288
289 delegated_ = CreateDelegatedLayer(frame_provider_.get());
290 }
291
292 scoped_refptr<DelegatedRendererLayer> CreateDelegatedLayer(
293 DelegatedFrameProvider* frame_provider) {
294 scoped_refptr<DelegatedRendererLayer> delegated =
295 FakeDelegatedRendererLayer::Create(frame_provider);
296 delegated->SetBounds(gfx::Size(10, 10));
297 delegated->SetIsDrawable(true);
298
299 root_->AddChild(delegated);
300 return delegated;
301 }
302
303 void AfterTest() override { resource_collection_->SetClient(NULL); }
304
305 // DelegatedFrameProviderClient implementation.
306 void UnusedResourcesAreAvailable() override { available_ = true; }
307
308 bool TestAndResetAvailable() {
309 bool available = available_;
310 available_ = false;
311 return available;
312 }
313
314 protected:
315 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
316 scoped_refptr<DelegatedFrameProvider> frame_provider_;
317 scoped_refptr<Layer> root_;
318 scoped_refptr<DelegatedRendererLayer> delegated_;
319 bool available_;
320 };
321
322 class LayerTreeHostDelegatedTestCreateChildId
323 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
324 public:
325 LayerTreeHostDelegatedTestCreateChildId()
326 : LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(),
327 num_activates_(0),
328 did_reset_child_id_(false) {}
329
330 void DidCommit() override {
331 if (TestEnded())
332 return;
333 SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
334 }
335
336 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
337 if (host_impl->active_tree()->source_frame_number() < 1)
338 return;
339
340 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
341 FakeDelegatedRendererLayerImpl* delegated_impl =
342 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
343
344 TestContextProvider* context_provider = static_cast<TestContextProvider*>(
345 host_impl->output_surface()->context_provider());
346
347 ++num_activates_;
348 switch (num_activates_) {
349 case 2:
350 EXPECT_TRUE(delegated_impl->ChildId());
351 EXPECT_FALSE(did_reset_child_id_);
352
353 context_provider->ContextGL()->LoseContextCHROMIUM(
354 GL_GUILTY_CONTEXT_RESET_ARB,
355 GL_INNOCENT_CONTEXT_RESET_ARB);
356 context_provider->ContextGL()->Flush();
357 break;
358 case 3:
359 EXPECT_TRUE(delegated_impl->ChildId());
360 EXPECT_TRUE(did_reset_child_id_);
361 EndTest();
362 break;
363 }
364 }
365
366 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
367 bool success) override {
368 EXPECT_TRUE(success);
369
370 if (num_activates_ < 2)
371 return;
372
373 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
374 FakeDelegatedRendererLayerImpl* delegated_impl =
375 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
376
377 EXPECT_EQ(2, num_activates_);
378 EXPECT_FALSE(delegated_impl->ChildId());
379 did_reset_child_id_ = true;
380 }
381
382 protected:
383 int num_activates_;
384 bool did_reset_child_id_;
385 };
386
387 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCreateChildId);
388
389 // Test that we can gracefully handle invalid frames after the context was lost.
390 // For example, we might be trying to use the previous frame in that case and
391 // have to make sure we don't crash because our resource accounting goes wrong.
392 class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost
393 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
394 public:
395 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost()
396 : num_activates_(0), num_output_surfaces_initialized_(0) {}
397
398 void DidCommit() override {
399 if (TestEnded())
400 return;
401 scoped_ptr<DelegatedFrameData> frame1 =
402 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
403 AddTextureQuad(frame1.get(), 999);
404 AddTransferableResource(frame1.get(), 999);
405 SetFrameData(frame1.Pass());
406 }
407
408 void DidInitializeOutputSurface() override {
409 if (!num_output_surfaces_initialized_++)
410 return;
411
412 scoped_refptr<DelegatedRendererLayer> old_delegated = delegated_;
413 SetFrameData(
414 CreateInvalidFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
415 // Make sure we end up using the same layer, or we won't test the right
416 // thing, which is to make sure we can handle an invalid frame when using
417 // a stale layer from before the context was lost.
418 DCHECK(delegated_.get() == old_delegated.get());
419 }
420
421 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
422 if (host_impl->active_tree()->source_frame_number() < 1)
423 return;
424
425 TestContextProvider* context_provider = static_cast<TestContextProvider*>(
426 host_impl->output_surface()->context_provider());
427
428 ++num_activates_;
429 switch (num_activates_) {
430 case 2:
431 context_provider->ContextGL()->LoseContextCHROMIUM(
432 GL_GUILTY_CONTEXT_RESET_ARB,
433 GL_INNOCENT_CONTEXT_RESET_ARB);
434 break;
435 case 3:
436 EndTest();
437 break;
438 }
439 }
440
441 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
442 bool success) override {
443 EXPECT_TRUE(success);
444
445 if (num_activates_ < 2)
446 return;
447
448 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
449 FakeDelegatedRendererLayerImpl* delegated_impl =
450 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
451
452 EXPECT_EQ(2, num_activates_);
453 // Resources should have gotten cleared after the context was lost.
454 EXPECT_EQ(0U, delegated_impl->Resources().size());
455 }
456
457 void AfterTest() override {
458 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::AfterTest();
459 EXPECT_EQ(2, num_output_surfaces_initialized_);
460 }
461
462 protected:
463 int num_activates_;
464 int num_output_surfaces_initialized_;
465 };
466
467 SINGLE_AND_MULTI_THREAD_TEST_F(
468 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost);
469
470 class LayerTreeHostDelegatedTestLayerUsesFrameDamage
471 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
472 public:
473 void DidCommit() override {
474 int next_source_frame_number = layer_tree_host()->source_frame_number();
475 switch (next_source_frame_number) {
476 case 1:
477 // The first time the layer gets a frame the whole layer should be
478 // damaged.
479 SetFrameData(
480 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
481 break;
482 case 2:
483 // A different frame size will damage the whole layer.
484 SetFrameData(
485 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(0, 0, 0, 0)));
486 break;
487 case 3:
488 // Should create a total amount of gfx::Rect(2, 2, 8, 6) damage:
489 // (2, 2, 10, 6) clamped to the root output rect.
490 SetFrameData(
491 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(2, 2, 5, 5)));
492 SetFrameData(
493 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(7, 2, 5, 6)));
494 break;
495 case 4:
496 // Should create zero damage.
497 layer_tree_host()->SetNeedsCommit();
498 break;
499 case 5:
500 // Should damage the full viewport.
501 delegated_->SetBounds(gfx::Size(2, 2));
502 break;
503 case 6:
504 // Should create zero damage.
505 layer_tree_host()->SetNeedsCommit();
506 break;
507 case 7:
508 // Should damage the full layer, tho the frame size is not changing.
509 delegated_->SetBounds(gfx::Size(6, 6));
510 SetFrameData(
511 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(1, 1, 2, 2)));
512 break;
513 case 8:
514 // Should create zero damage.
515 layer_tree_host()->SetNeedsCommit();
516 break;
517 case 9:
518 // Should create zero damage.
519 layer_tree_host()->SetNeedsCommit();
520 break;
521 case 10:
522 // Changing the frame size damages the full layer.
523 SetFrameData(
524 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1)));
525 break;
526 case 11:
527 // An invalid frame isn't used, so it should not cause damage.
528 SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 5, 5),
529 gfx::Rect(4, 4, 1, 1)));
530 break;
531 case 12:
532 // Should create gfx::Rect(1, 1, 2, 2) of damage.
533 SetFrameData(
534 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
535 break;
536 case 13:
537 // Should create zero damage.
538 layer_tree_host()->SetNeedsCommit();
539 break;
540 case 14:
541 // Moving the layer out of the tree and back in will damage the whole
542 // impl layer.
543 delegated_->RemoveFromParent();
544 layer_tree_host()->root_layer()->AddChild(delegated_);
545 break;
546 case 15:
547 // Make a larger frame with lots of damage. Then a frame smaller than
548 // the first frame's damage. The entire layer should be damaged, but
549 // nothing more.
550 SetFrameData(
551 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
552 SetFrameData(
553 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
554 break;
555 case 16:
556 // Make a frame with lots of damage. Then replace it with a frame with
557 // no damage. The entire layer should be damaged, but nothing more.
558 SetFrameData(
559 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
560 SetFrameData(
561 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 0, 0)));
562 break;
563 case 17:
564 // Make another layer that uses the same frame provider. The new layer
565 // should be damaged.
566 delegated_copy_ = CreateDelegatedLayer(frame_provider_.get());
567 delegated_copy_->SetPosition(gfx::Point(5, 0));
568
569 // Also set a new frame.
570 SetFrameData(
571 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(4, 0, 1, 1)));
572 break;
573 case 18:
574 // Set another new frame, both layers should be damaged in the same
575 // ways.
576 SetFrameData(
577 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(3, 3, 1, 1)));
578 break;
579 }
580 }
581
582 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
583 LayerTreeHostImpl::FrameData* frame,
584 DrawResult draw_result) override {
585 EXPECT_EQ(DRAW_SUCCESS, draw_result);
586
587 gfx::Rect damage_rect;
588 if (!frame->has_no_damage) {
589 damage_rect = frame->render_passes.back()->damage_rect;
590 } else {
591 // If there is no damage, then we have no render passes to send.
592 EXPECT_TRUE(frame->render_passes.empty());
593 }
594
595 switch (host_impl->active_tree()->source_frame_number()) {
596 case 0:
597 // First frame is damaged because of viewport resize.
598 EXPECT_EQ(gfx::Rect(15, 15).ToString(), damage_rect.ToString());
599 break;
600 case 1:
601 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
602 break;
603 case 2:
604 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
605 break;
606 case 3:
607 EXPECT_EQ(gfx::Rect(2, 2, 8, 6).ToString(), damage_rect.ToString());
608 break;
609 case 4:
610 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
611 break;
612 case 5:
613 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
614 break;
615 case 6:
616 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
617 break;
618 case 7:
619 EXPECT_EQ(gfx::Rect(6, 6).ToString(), damage_rect.ToString());
620 break;
621 case 8:
622 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
623 break;
624 case 9:
625 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
626 break;
627 case 10:
628 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
629 break;
630 case 11:
631 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
632 break;
633 case 12:
634 EXPECT_EQ(gfx::Rect(1, 1, 2, 2).ToString(), damage_rect.ToString());
635 break;
636 case 13:
637 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
638 break;
639 case 14:
640 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
641 break;
642 case 15:
643 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
644 break;
645 case 16:
646 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
647 break;
648 case 17:
649 EXPECT_EQ(gfx::UnionRects(gfx::Rect(5, 0, 10, 10),
650 gfx::Rect(4, 0, 1, 1)).ToString(),
651 damage_rect.ToString());
652 break;
653 case 18:
654 EXPECT_EQ(gfx::Rect(3, 3, 6, 1).ToString(), damage_rect.ToString());
655 EndTest();
656 break;
657 }
658
659 return draw_result;
660 }
661
662 protected:
663 scoped_refptr<DelegatedRendererLayer> delegated_copy_;
664 };
665
666 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestLayerUsesFrameDamage);
667
668 class LayerTreeHostDelegatedTestMergeResources
669 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
670 public:
671 void BeginTest() override {
672 // Push two frames to the delegated renderer layer with no commit between.
673
674 // The first frame has resource 999.
675 scoped_ptr<DelegatedFrameData> frame1 =
676 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
677 AddTextureQuad(frame1.get(), 999);
678 AddTransferableResource(frame1.get(), 999);
679 SetFrameData(frame1.Pass());
680
681 // The second frame uses resource 999 still, but also adds 555.
682 scoped_ptr<DelegatedFrameData> frame2 =
683 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
684 AddTextureQuad(frame2.get(), 999);
685 AddTransferableResource(frame2.get(), 999);
686 AddTextureQuad(frame2.get(), 555);
687 AddTransferableResource(frame2.get(), 555);
688 SetFrameData(frame2.Pass());
689
690 // The resource 999 from frame1 is returned since it is still on the main
691 // thread.
692 ReturnedResourceArray returned_resources;
693 resource_collection_->TakeUnusedResourcesForChildCompositor(
694 &returned_resources);
695 {
696 unsigned expected[] = {999};
697 EXPECT_RESOURCES(expected, returned_resources);
698 EXPECT_TRUE(TestAndResetAvailable());
699 }
700
701 PostSetNeedsCommitToMainThread();
702 }
703
704 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
705 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
706 FakeDelegatedRendererLayerImpl* delegated_impl =
707 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
708
709 const ResourceProvider::ResourceIdMap& map =
710 host_impl->resource_provider()->GetChildToParentMap(
711 delegated_impl->ChildId());
712
713 // Both frames' resources should be in the parent's resource provider.
714 EXPECT_EQ(2u, map.size());
715 EXPECT_EQ(1u, map.count(999));
716 EXPECT_EQ(1u, map.count(555));
717
718 EXPECT_EQ(2u, delegated_impl->Resources().size());
719 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
720 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
721
722 EndTest();
723 }
724 };
725
726 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestMergeResources);
727
728 class LayerTreeHostDelegatedTestRemapResourcesInQuads
729 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
730 public:
731 void BeginTest() override {
732 // Generate a frame with two resources in it.
733 scoped_ptr<DelegatedFrameData> frame =
734 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
735 AddTextureQuad(frame.get(), 999);
736 AddTransferableResource(frame.get(), 999);
737 AddTextureQuad(frame.get(), 555);
738 AddTransferableResource(frame.get(), 555);
739 SetFrameData(frame.Pass());
740
741 PostSetNeedsCommitToMainThread();
742 }
743
744 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
745 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
746 FakeDelegatedRendererLayerImpl* delegated_impl =
747 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
748
749 const ResourceProvider::ResourceIdMap& map =
750 host_impl->resource_provider()->GetChildToParentMap(
751 delegated_impl->ChildId());
752
753 // The frame's resource should be in the parent's resource provider.
754 EXPECT_EQ(2u, map.size());
755 EXPECT_EQ(1u, map.count(999));
756 EXPECT_EQ(1u, map.count(555));
757
758 ResourceProvider::ResourceId parent_resource_id1 = map.find(999)->second;
759 EXPECT_NE(parent_resource_id1, 999u);
760 ResourceProvider::ResourceId parent_resource_id2 = map.find(555)->second;
761 EXPECT_NE(parent_resource_id2, 555u);
762
763 // The resources in the quads should be remapped to the parent's namespace.
764 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
765 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(0));
766 EXPECT_EQ(parent_resource_id1, quad1->resource_id);
767 const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
768 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(1));
769 EXPECT_EQ(parent_resource_id2, quad2->resource_id);
770
771 EndTest();
772 }
773 };
774
775 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemapResourcesInQuads);
776
777 class LayerTreeHostDelegatedTestReturnUnusedResources
778 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
779 public:
780 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
781
782 void DidCommitAndDrawFrame() override {
783 scoped_ptr<DelegatedFrameData> frame;
784 ReturnedResourceArray resources;
785
786 int next_source_frame_number = layer_tree_host()->source_frame_number();
787 switch (next_source_frame_number) {
788 case 1:
789 // Generate a frame with two resources in it.
790 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
791 AddTextureQuad(frame.get(), 999);
792 AddTransferableResource(frame.get(), 999);
793 AddTextureQuad(frame.get(), 555);
794 AddTransferableResource(frame.get(), 555);
795 SetFrameData(frame.Pass());
796 break;
797 case 2:
798 // All of the resources are in use.
799 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
800 EXPECT_EQ(0u, resources.size());
801 EXPECT_FALSE(TestAndResetAvailable());
802
803 // Keep using 999 but stop using 555.
804 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
805 AddTextureQuad(frame.get(), 999);
806 AddTransferableResource(frame.get(), 999);
807 AddTextureQuad(frame.get(), 444);
808 AddTransferableResource(frame.get(), 444);
809 SetFrameData(frame.Pass());
810 break;
811 case 3:
812 // 555 is no longer in use.
813 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
814 {
815 unsigned expected[] = {555};
816 EXPECT_RESOURCES(expected, resources);
817 EXPECT_TRUE(TestAndResetAvailable());
818 }
819
820 // Stop using any resources.
821 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
822 SetFrameData(frame.Pass());
823 break;
824 case 4:
825 // Postpone collecting resources for a frame. They should still be there
826 // the next frame.
827 layer_tree_host()->SetNeedsCommit();
828 return;
829 case 5:
830 // 444 and 999 are no longer in use. We sent two refs to 999, so we
831 // should get two back.
832 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
833 {
834 unsigned expected[] = {444, 999, 999};
835 EXPECT_RESOURCES(expected, resources);
836 EXPECT_TRUE(TestAndResetAvailable());
837 }
838 EndTest();
839 break;
840 }
841
842 // Resources are never immediately released.
843 ReturnedResourceArray empty_resources;
844 resource_collection_->TakeUnusedResourcesForChildCompositor(
845 &empty_resources);
846 EXPECT_EQ(0u, empty_resources.size());
847 EXPECT_FALSE(TestAndResetAvailable());
848 }
849
850 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
851 ReturnUnusedResourcesFromParent(host_impl);
852 }
853 };
854
855 SINGLE_AND_MULTI_THREAD_TEST_F(
856 LayerTreeHostDelegatedTestReturnUnusedResources);
857
858 class LayerTreeHostDelegatedTestReusedResources
859 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
860 public:
861 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
862
863 void DidCommitAndDrawFrame() override {
864 scoped_ptr<DelegatedFrameData> frame;
865 ReturnedResourceArray resources;
866
867 int next_source_frame_number = layer_tree_host()->source_frame_number();
868 switch (next_source_frame_number) {
869 case 1:
870 // Generate a frame with some resources in it.
871 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
872 AddTextureQuad(frame.get(), 999);
873 AddTransferableResource(frame.get(), 999);
874 AddTextureQuad(frame.get(), 555);
875 AddTransferableResource(frame.get(), 555);
876 AddTextureQuad(frame.get(), 444);
877 AddTransferableResource(frame.get(), 444);
878 SetFrameData(frame.Pass());
879 break;
880 case 2:
881 // All of the resources are in use.
882 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
883 EXPECT_EQ(0u, resources.size());
884 EXPECT_FALSE(TestAndResetAvailable());
885
886 // Keep using 999 but stop using 555 and 444.
887 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
888 AddTextureQuad(frame.get(), 999);
889 AddTransferableResource(frame.get(), 999);
890 SetFrameData(frame.Pass());
891
892 // Resource are not immediately released.
893 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
894 EXPECT_EQ(0u, resources.size());
895 EXPECT_FALSE(TestAndResetAvailable());
896
897 // Now using 555 and 444 again, but not 999.
898 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
899 AddTextureQuad(frame.get(), 555);
900 AddTransferableResource(frame.get(), 555);
901 AddTextureQuad(frame.get(), 444);
902 AddTransferableResource(frame.get(), 444);
903 SetFrameData(frame.Pass());
904 break;
905 case 3:
906 // The 999 resource is the only unused one. Two references were sent, so
907 // two should be returned.
908 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
909 {
910 unsigned expected[] = {999, 999};
911 EXPECT_RESOURCES(expected, resources);
912 EXPECT_TRUE(TestAndResetAvailable());
913 }
914 EndTest();
915 break;
916 }
917 }
918
919 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
920 ReturnUnusedResourcesFromParent(host_impl);
921 }
922 };
923
924 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources);
925
926 class LayerTreeHostDelegatedTestFrameBeforeAck
927 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
928 public:
929 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
930
931 void DidCommitAndDrawFrame() override {
932 scoped_ptr<DelegatedFrameData> frame;
933 ReturnedResourceArray resources;
934
935 int next_source_frame_number = layer_tree_host()->source_frame_number();
936 switch (next_source_frame_number) {
937 case 1:
938 // Generate a frame with some resources in it.
939 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
940 AddTextureQuad(frame.get(), 999);
941 AddTransferableResource(frame.get(), 999);
942 AddTextureQuad(frame.get(), 555);
943 AddTransferableResource(frame.get(), 555);
944 AddTextureQuad(frame.get(), 444);
945 AddTransferableResource(frame.get(), 444);
946 SetFrameData(frame.Pass());
947 break;
948 case 2:
949 // All of the resources are in use.
950 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
951 EXPECT_EQ(0u, resources.size());
952 EXPECT_FALSE(TestAndResetAvailable());
953
954 // Keep using 999 but stop using 555 and 444.
955 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
956 AddTextureQuad(frame.get(), 999);
957 AddTransferableResource(frame.get(), 999);
958 SetFrameData(frame.Pass());
959
960 // Resource are not immediately released.
961 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
962 EXPECT_EQ(0u, resources.size());
963 EXPECT_FALSE(TestAndResetAvailable());
964
965 // The parent compositor (this one) does a commit.
966 break;
967 case 3:
968 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
969 {
970 unsigned expected[] = {444, 555};
971 EXPECT_RESOURCES(expected, resources);
972 EXPECT_TRUE(TestAndResetAvailable());
973 }
974
975 // The child compositor sends a frame referring to resources not in the
976 // frame.
977 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
978 AddTextureQuad(frame.get(), 999);
979 AddTextureQuad(frame.get(), 555);
980 AddTextureQuad(frame.get(), 444);
981 SetFrameData(frame.Pass());
982 break;
983 }
984 }
985
986 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
987 if (host_impl->active_tree()->source_frame_number() != 3)
988 return;
989
990 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
991 FakeDelegatedRendererLayerImpl* delegated_impl =
992 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
993
994 const ResourceProvider::ResourceIdMap& map =
995 host_impl->resource_provider()->GetChildToParentMap(
996 delegated_impl->ChildId());
997
998 // The bad frame should be dropped. So we should only have one quad (the
999 // one with resource 999) on the impl tree. And only 999 will be present
1000 // in the parent's resource provider.
1001 EXPECT_EQ(1u, map.size());
1002 EXPECT_EQ(1u, map.count(999));
1003
1004 EXPECT_EQ(1u, delegated_impl->Resources().size());
1005 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1006
1007 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1008 EXPECT_EQ(1u, pass->quad_list.size());
1009 const TextureDrawQuad* quad =
1010 TextureDrawQuad::MaterialCast(pass->quad_list.front());
1011 EXPECT_EQ(map.find(999)->second, quad->resource_id);
1012
1013 EndTest();
1014 }
1015
1016 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1017 ReturnUnusedResourcesFromParent(host_impl);
1018 }
1019 };
1020
1021 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck);
1022
1023 class LayerTreeHostDelegatedTestFrameBeforeTakeResources
1024 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1025 public:
1026 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1027
1028 void DidCommitAndDrawFrame() override {
1029 scoped_ptr<DelegatedFrameData> frame;
1030 ReturnedResourceArray resources;
1031
1032 int next_source_frame_number = layer_tree_host()->source_frame_number();
1033 switch (next_source_frame_number) {
1034 case 1:
1035 // Generate a frame with some resources in it.
1036 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1037 AddTextureQuad(frame.get(), 999);
1038 AddTransferableResource(frame.get(), 999);
1039 AddTextureQuad(frame.get(), 555);
1040 AddTransferableResource(frame.get(), 555);
1041 AddTextureQuad(frame.get(), 444);
1042 AddTransferableResource(frame.get(), 444);
1043 SetFrameData(frame.Pass());
1044 break;
1045 case 2:
1046 // All of the resources are in use.
1047 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1048 EXPECT_EQ(0u, resources.size());
1049 EXPECT_FALSE(TestAndResetAvailable());
1050
1051 // Keep using 999 but stop using 555 and 444.
1052 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1053 AddTextureQuad(frame.get(), 999);
1054 AddTransferableResource(frame.get(), 999);
1055 SetFrameData(frame.Pass());
1056
1057 // Resource are not immediately released.
1058 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1059 EXPECT_EQ(0u, resources.size());
1060 EXPECT_FALSE(TestAndResetAvailable());
1061
1062 // The parent compositor (this one) does a commit.
1063 break;
1064 case 3:
1065 // The child compositor sends a frame before taking resources back
1066 // from the previous commit. This frame makes use of the resources 555
1067 // and 444, which were just released during commit.
1068 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1069 AddTextureQuad(frame.get(), 999);
1070 AddTransferableResource(frame.get(), 999);
1071 AddTextureQuad(frame.get(), 555);
1072 AddTransferableResource(frame.get(), 555);
1073 AddTextureQuad(frame.get(), 444);
1074 AddTransferableResource(frame.get(), 444);
1075 SetFrameData(frame.Pass());
1076
1077 // The resources are used by the new frame but are returned anyway since
1078 // we passed them again.
1079 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1080 {
1081 unsigned expected[] = {444, 555};
1082 EXPECT_RESOURCES(expected, resources);
1083 EXPECT_TRUE(TestAndResetAvailable());
1084 }
1085 break;
1086 case 4:
1087 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1088 EXPECT_EQ(0u, resources.size());
1089 EXPECT_FALSE(TestAndResetAvailable());
1090 EndTest();
1091 break;
1092 }
1093 }
1094
1095 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1096 if (host_impl->active_tree()->source_frame_number() != 3)
1097 return;
1098
1099 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1100 FakeDelegatedRendererLayerImpl* delegated_impl =
1101 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1102
1103 const ResourceProvider::ResourceIdMap& map =
1104 host_impl->resource_provider()->GetChildToParentMap(
1105 delegated_impl->ChildId());
1106
1107 // The third frame has all of the resources in it again, the delegated
1108 // renderer layer should continue to own the resources for it.
1109 EXPECT_EQ(3u, map.size());
1110 EXPECT_EQ(1u, map.count(999));
1111 EXPECT_EQ(1u, map.count(555));
1112 EXPECT_EQ(1u, map.count(444));
1113
1114 EXPECT_EQ(3u, delegated_impl->Resources().size());
1115 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1116 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1117 EXPECT_EQ(1u, delegated_impl->Resources().count(444));
1118
1119 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1120 EXPECT_EQ(3u, pass->quad_list.size());
1121 const TextureDrawQuad* quad1 =
1122 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1123 EXPECT_EQ(map.find(999)->second, quad1->resource_id);
1124 const TextureDrawQuad* quad2 =
1125 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1126 EXPECT_EQ(map.find(555)->second, quad2->resource_id);
1127 const TextureDrawQuad* quad3 =
1128 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(2));
1129 EXPECT_EQ(map.find(444)->second, quad3->resource_id);
1130 }
1131
1132 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1133 ReturnUnusedResourcesFromParent(host_impl);
1134 }
1135 };
1136
1137 SINGLE_AND_MULTI_THREAD_TEST_F(
1138 LayerTreeHostDelegatedTestFrameBeforeTakeResources);
1139
1140 class LayerTreeHostDelegatedTestBadFrame
1141 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1142 public:
1143 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1144
1145 void DidCommitAndDrawFrame() override {
1146 scoped_ptr<DelegatedFrameData> frame;
1147 ReturnedResourceArray resources;
1148
1149 int next_source_frame_number = layer_tree_host()->source_frame_number();
1150 switch (next_source_frame_number) {
1151 case 1:
1152 // Generate a frame with some resources in it.
1153 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1154 AddTextureQuad(frame.get(), 999);
1155 AddTransferableResource(frame.get(), 999);
1156 AddTextureQuad(frame.get(), 555);
1157 AddTransferableResource(frame.get(), 555);
1158 SetFrameData(frame.Pass());
1159 break;
1160 case 2:
1161 // All of the resources are in use.
1162 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1163 EXPECT_EQ(0u, resources.size());
1164 EXPECT_FALSE(TestAndResetAvailable());
1165
1166 // Generate a bad frame with a resource the layer doesn't have. The
1167 // 885 and 775 resources are unknown, while ownership of the legit 444
1168 // resource is passed in here. The bad frame does not use any of the
1169 // previous resources, 999 or 555.
1170 // A bad quad is present both before and after the good quad.
1171 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1172 AddTextureQuad(frame.get(), 885);
1173 AddTextureQuad(frame.get(), 444);
1174 AddTransferableResource(frame.get(), 444);
1175 AddTextureQuad(frame.get(), 775);
1176 SetFrameData(frame.Pass());
1177
1178 // The parent compositor (this one) does a commit.
1179 break;
1180 case 3:
1181 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1182 EXPECT_EQ(0u, resources.size());
1183 EXPECT_FALSE(TestAndResetAvailable());
1184
1185 // Now send a good frame with 999 again.
1186 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1187 AddTextureQuad(frame.get(), 999);
1188 SetFrameData(frame.Pass());
1189
1190 // The bad frame's resource is given back to the child compositor.
1191 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1192 {
1193 unsigned expected[] = {444};
1194 EXPECT_RESOURCES(expected, resources);
1195 EXPECT_TRUE(TestAndResetAvailable());
1196 }
1197 break;
1198 case 4:
1199 // The unused 555 from the last good frame is now released.
1200 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1201 {
1202 unsigned expected[] = {555};
1203 EXPECT_RESOURCES(expected, resources);
1204 EXPECT_TRUE(TestAndResetAvailable());
1205 }
1206
1207 EndTest();
1208 break;
1209 }
1210 }
1211
1212 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1213 if (host_impl->active_tree()->source_frame_number() < 1)
1214 return;
1215
1216 ReturnUnusedResourcesFromParent(host_impl);
1217
1218 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1219 FakeDelegatedRendererLayerImpl* delegated_impl =
1220 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1221
1222 const ResourceProvider::ResourceIdMap& map =
1223 host_impl->resource_provider()->GetChildToParentMap(
1224 delegated_impl->ChildId());
1225
1226 switch (host_impl->active_tree()->source_frame_number()) {
1227 case 1: {
1228 // We have the first good frame with just 990 and 555 in it.
1229 // layer.
1230 EXPECT_EQ(2u, map.size());
1231 EXPECT_EQ(1u, map.count(999));
1232 EXPECT_EQ(1u, map.count(555));
1233
1234 EXPECT_EQ(2u, delegated_impl->Resources().size());
1235 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1236 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1237
1238 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1239 EXPECT_EQ(2u, pass->quad_list.size());
1240 const TextureDrawQuad* quad1 =
1241 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1242 EXPECT_EQ(map.find(999)->second, quad1->resource_id);
1243 const TextureDrawQuad* quad2 =
1244 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1245 EXPECT_EQ(map.find(555)->second, quad2->resource_id);
1246 break;
1247 }
1248 case 2: {
1249 // We only keep resources from the last valid frame.
1250 EXPECT_EQ(2u, map.size());
1251 EXPECT_EQ(1u, map.count(999));
1252 EXPECT_EQ(1u, map.count(555));
1253
1254 EXPECT_EQ(2u, delegated_impl->Resources().size());
1255 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1256 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1257
1258 // The bad frame is dropped though, we still have the frame with 999 and
1259 // 555 in it.
1260 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1261 EXPECT_EQ(2u, pass->quad_list.size());
1262 const TextureDrawQuad* quad1 =
1263 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1264 EXPECT_EQ(map.find(999)->second, quad1->resource_id);
1265 const TextureDrawQuad* quad2 =
1266 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1267 EXPECT_EQ(map.find(555)->second, quad2->resource_id);
1268 break;
1269 }
1270 case 3: {
1271 // We have the new good frame with just 999 in it.
1272 EXPECT_EQ(1u, map.size());
1273 EXPECT_EQ(1u, map.count(999));
1274
1275 EXPECT_EQ(1u, delegated_impl->Resources().size());
1276 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1277
1278 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1279 EXPECT_EQ(1u, pass->quad_list.size());
1280 const TextureDrawQuad* quad1 =
1281 TextureDrawQuad::MaterialCast(pass->quad_list.front());
1282 EXPECT_EQ(map.find(999)->second, quad1->resource_id);
1283 break;
1284 }
1285 }
1286 }
1287 };
1288
1289 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame);
1290
1291 class LayerTreeHostDelegatedTestUnnamedResource
1292 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1293 public:
1294 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1295
1296 void DidCommit() override {
1297 scoped_ptr<DelegatedFrameData> frame;
1298 ReturnedResourceArray resources;
1299
1300 int next_source_frame_number = layer_tree_host()->source_frame_number();
1301 switch (next_source_frame_number) {
1302 case 1:
1303 // This frame includes two resources in it, but only uses one.
1304 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1305 AddTransferableResource(frame.get(), 999);
1306 AddTextureQuad(frame.get(), 555);
1307 AddTransferableResource(frame.get(), 555);
1308 SetFrameData(frame.Pass());
1309 break;
1310 case 2:
1311 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1312 EXPECT_EQ(0u, resources.size());
1313 EXPECT_FALSE(TestAndResetAvailable());
1314
1315 // Now send an empty frame.
1316 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1317 SetFrameData(frame.Pass());
1318
1319 // The unused resource should be returned.
1320 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1321 {
1322 unsigned expected[] = {999};
1323 EXPECT_RESOURCES(expected, resources);
1324 EXPECT_TRUE(TestAndResetAvailable());
1325 }
1326
1327 EndTest();
1328 break;
1329 }
1330 }
1331
1332 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1333 if (host_impl->active_tree()->source_frame_number() != 1)
1334 return;
1335
1336 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1337 FakeDelegatedRendererLayerImpl* delegated_impl =
1338 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1339
1340 const ResourceProvider::ResourceIdMap& map =
1341 host_impl->resource_provider()->GetChildToParentMap(
1342 delegated_impl->ChildId());
1343
1344 // The layer only held on to the resource that was used.
1345 EXPECT_EQ(1u, map.size());
1346 EXPECT_EQ(1u, map.count(555));
1347
1348 EXPECT_EQ(1u, delegated_impl->Resources().size());
1349 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1350 }
1351 };
1352
1353 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestUnnamedResource);
1354
1355 class LayerTreeHostDelegatedTestDontLeakResource
1356 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1357 public:
1358 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1359
1360 void DidCommitAndDrawFrame() override {
1361 scoped_ptr<DelegatedFrameData> frame;
1362 ReturnedResourceArray resources;
1363
1364 int next_source_frame_number = layer_tree_host()->source_frame_number();
1365 switch (next_source_frame_number) {
1366 case 1:
1367 // This frame includes two resources in it.
1368 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1369 AddTextureQuad(frame.get(), 999);
1370 AddTransferableResource(frame.get(), 999);
1371 AddTextureQuad(frame.get(), 555);
1372 AddTransferableResource(frame.get(), 555);
1373 SetFrameData(frame.Pass());
1374
1375 // But then we immediately stop using 999.
1376 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1377 AddTextureQuad(frame.get(), 555);
1378 AddTransferableResource(frame.get(), 555);
1379 SetFrameData(frame.Pass());
1380 break;
1381 case 2:
1382 // The unused resources should be returned. 555 is still used, but it's
1383 // returned once to account for the first frame.
1384 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1385 {
1386 unsigned expected[] = {555, 999};
1387 EXPECT_RESOURCES(expected, resources);
1388 EXPECT_TRUE(TestAndResetAvailable());
1389 }
1390 // Send a frame with no resources in it.
1391 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1392 SetFrameData(frame.Pass());
1393 break;
1394 case 3:
1395 // The now unused resource 555 should be returned.
1396 resources.clear();
1397 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1398 {
1399 unsigned expected[] = {555};
1400 EXPECT_RESOURCES(expected, resources);
1401 EXPECT_TRUE(TestAndResetAvailable());
1402 }
1403 EndTest();
1404 break;
1405 }
1406 }
1407
1408 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1409 if (host_impl->active_tree()->source_frame_number() != 1)
1410 return;
1411
1412 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1413 FakeDelegatedRendererLayerImpl* delegated_impl =
1414 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1415
1416 const ResourceProvider::ResourceIdMap& map =
1417 host_impl->resource_provider()->GetChildToParentMap(
1418 delegated_impl->ChildId());
1419
1420 // The layer only held on to the resource that was used.
1421 EXPECT_EQ(1u, map.size());
1422 EXPECT_EQ(1u, map.count(555));
1423
1424 EXPECT_EQ(1u, delegated_impl->Resources().size());
1425 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1426 }
1427
1428 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1429 ReturnUnusedResourcesFromParent(host_impl);
1430 }
1431 };
1432
1433 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource);
1434
1435 class LayerTreeHostDelegatedTestResourceSentToParent
1436 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1437 public:
1438 void DidCommitAndDrawFrame() override {
1439 scoped_ptr<DelegatedFrameData> frame;
1440 ReturnedResourceArray resources;
1441
1442 int next_source_frame_number = layer_tree_host()->source_frame_number();
1443 switch (next_source_frame_number) {
1444 case 1:
1445 // This frame includes two resources in it.
1446 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1447 AddTextureQuad(frame.get(), 999);
1448 AddTransferableResource(frame.get(), 999);
1449 AddTextureQuad(frame.get(), 555);
1450 AddTransferableResource(frame.get(), 555);
1451 SetFrameData(frame.Pass());
1452 break;
1453 case 2:
1454 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1455 EXPECT_EQ(0u, resources.size());
1456 EXPECT_FALSE(TestAndResetAvailable());
1457
1458 // 999 is in use in the grandparent compositor, generate a frame without
1459 // it present.
1460 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1461 AddTextureQuad(frame.get(), 555);
1462 AddTransferableResource(frame.get(), 555);
1463 SetFrameData(frame.Pass());
1464 break;
1465 case 3:
1466 // Since 999 is in the grandparent it is not returned.
1467 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1468 EXPECT_EQ(0u, resources.size());
1469 EXPECT_FALSE(TestAndResetAvailable());
1470
1471 // The impl side will get back the resource at some point.
1472 ImplThreadTaskRunner()->PostTask(FROM_HERE,
1473 receive_resource_on_thread_);
1474 break;
1475 }
1476 }
1477
1478 void ReceiveResourceOnThread(LayerTreeHostImpl* host_impl) {
1479 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1480 FakeDelegatedRendererLayerImpl* delegated_impl =
1481 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1482
1483 const ResourceProvider::ResourceIdMap& map =
1484 host_impl->resource_provider()->GetChildToParentMap(
1485 delegated_impl->ChildId());
1486
1487 // Receive 999 back from the grandparent.
1488 CompositorFrameAck ack;
1489 output_surface()->ReturnResource(map.find(999)->second, &ack);
1490 host_impl->ReclaimResources(&ack);
1491 }
1492
1493 void UnusedResourcesAreAvailable() override {
1494 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
1495
1496 ReturnedResourceArray resources;
1497
1498 // 999 was returned from the grandparent and could be released.
1499 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1500 {
1501 unsigned expected[] = {999};
1502 EXPECT_RESOURCES(expected, resources);
1503 }
1504
1505 EndTest();
1506 }
1507
1508 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1509 if (host_impl->active_tree()->source_frame_number() < 1)
1510 return;
1511
1512 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1513 FakeDelegatedRendererLayerImpl* delegated_impl =
1514 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1515
1516 const ResourceProvider::ResourceIdMap& map =
1517 host_impl->resource_provider()->GetChildToParentMap(
1518 delegated_impl->ChildId());
1519
1520 switch (host_impl->active_tree()->source_frame_number()) {
1521 case 1: {
1522 EXPECT_EQ(2u, map.size());
1523 EXPECT_EQ(1u, map.count(999));
1524 EXPECT_EQ(1u, map.count(555));
1525
1526 EXPECT_EQ(2u, delegated_impl->Resources().size());
1527 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1528 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1529
1530 // The 999 resource will be sent to a grandparent compositor.
1531 break;
1532 }
1533 case 2: {
1534 EXPECT_EQ(2u, map.size());
1535 EXPECT_EQ(1u, map.count(999));
1536 EXPECT_EQ(1u, map.count(555));
1537
1538 // 999 is in the parent, so not held by delegated renderer layer.
1539 EXPECT_EQ(1u, delegated_impl->Resources().size());
1540 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1541
1542 receive_resource_on_thread_ =
1543 base::Bind(&LayerTreeHostDelegatedTestResourceSentToParent::
1544 ReceiveResourceOnThread,
1545 base::Unretained(this),
1546 host_impl);
1547 break;
1548 }
1549 case 3:
1550 // 999 should be released.
1551 EXPECT_EQ(1u, map.size());
1552 EXPECT_EQ(1u, map.count(555));
1553
1554 EXPECT_EQ(1u, delegated_impl->Resources().size());
1555 EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second));
1556 break;
1557 }
1558 }
1559
1560 base::Closure receive_resource_on_thread_;
1561 };
1562
1563 SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(
1564 LayerTreeHostDelegatedTestResourceSentToParent);
1565
1566 class LayerTreeHostDelegatedTestCommitWithoutTake
1567 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1568 public:
1569 void BeginTest() override {
1570 // Prevent drawing with resources that are sent to the grandparent.
1571 layer_tree_host()->SetViewportSize(gfx::Size());
1572 PostSetNeedsCommitToMainThread();
1573 }
1574
1575 void DidCommit() override {
1576 scoped_ptr<DelegatedFrameData> frame;
1577 ReturnedResourceArray resources;
1578
1579 int next_source_frame_number = layer_tree_host()->source_frame_number();
1580 switch (next_source_frame_number) {
1581 case 1:
1582 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1583 AddTextureQuad(frame.get(), 999);
1584 AddTransferableResource(frame.get(), 999);
1585 AddTextureQuad(frame.get(), 555);
1586 AddTransferableResource(frame.get(), 555);
1587 AddTextureQuad(frame.get(), 444);
1588 AddTransferableResource(frame.get(), 444);
1589 SetFrameData(frame.Pass());
1590 break;
1591 case 2:
1592 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1593 EXPECT_EQ(0u, resources.size());
1594 EXPECT_FALSE(TestAndResetAvailable());
1595
1596 // Stop using 999 and 444 in this frame and commit.
1597 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1598 AddTextureQuad(frame.get(), 555);
1599 AddTransferableResource(frame.get(), 555);
1600 SetFrameData(frame.Pass());
1601 // 999 and 444 will be returned for frame 1, but not 555 since it's in
1602 // the current frame.
1603 break;
1604 case 3:
1605 // Don't take resources here, but set a new frame that uses 999 again.
1606 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1607 AddTextureQuad(frame.get(), 999);
1608 AddTransferableResource(frame.get(), 999);
1609 AddTextureQuad(frame.get(), 555);
1610 AddTransferableResource(frame.get(), 555);
1611 SetFrameData(frame.Pass());
1612 break;
1613 case 4:
1614 // 555 from frame 1 and 2 isn't returned since it's still in use. 999
1615 // from frame 1 is returned though.
1616 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1617 {
1618 unsigned expected[] = {444, 999};
1619 EXPECT_RESOURCES(expected, resources);
1620 EXPECT_TRUE(TestAndResetAvailable());
1621 }
1622
1623 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1624 SetFrameData(frame.Pass());
1625 // 555 will be returned 3 times for frames 1 2 and 3, and 999 will be
1626 // returned once for frame 3.
1627 break;
1628 case 5:
1629 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1630 {
1631 unsigned expected[] = {555, 555, 555, 999};
1632 EXPECT_RESOURCES(expected, resources);
1633 EXPECT_TRUE(TestAndResetAvailable());
1634 }
1635
1636 EndTest();
1637 break;
1638 }
1639 }
1640
1641 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1642 if (host_impl->active_tree()->source_frame_number() < 1)
1643 return;
1644
1645 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1646 FakeDelegatedRendererLayerImpl* delegated_impl =
1647 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1648
1649 const ResourceProvider::ResourceIdMap& map =
1650 host_impl->resource_provider()->GetChildToParentMap(
1651 delegated_impl->ChildId());
1652
1653 switch (host_impl->active_tree()->source_frame_number()) {
1654 case 1:
1655 EXPECT_EQ(3u, map.size());
1656 EXPECT_EQ(1u, map.count(999));
1657 EXPECT_EQ(1u, map.count(555));
1658 EXPECT_EQ(1u, map.count(444));
1659
1660 EXPECT_EQ(3u, delegated_impl->Resources().size());
1661 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1662 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1663 EXPECT_EQ(1u, delegated_impl->Resources().count(444));
1664 break;
1665 case 2:
1666 EXPECT_EQ(1u, map.size());
1667 EXPECT_EQ(1u, map.count(555));
1668
1669 EXPECT_EQ(1u, delegated_impl->Resources().size());
1670 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1671 break;
1672 case 3:
1673 EXPECT_EQ(2u, map.size());
1674 EXPECT_EQ(1u, map.count(999));
1675 EXPECT_EQ(1u, map.count(555));
1676
1677 EXPECT_EQ(2u, delegated_impl->Resources().size());
1678 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1679 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1680 }
1681 }
1682 };
1683
1684 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCommitWithoutTake);
1685
1686 class DelegatedFrameIsActivatedDuringCommit
1687 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1688 protected:
1689 DelegatedFrameIsActivatedDuringCommit() : returned_resource_count_(0) {}
1690
1691 void BeginTest() override {
1692 activate_count_ = 0;
1693
1694 scoped_ptr<DelegatedFrameData> frame =
1695 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1696 AddTextureQuad(frame.get(), 999);
1697 AddTransferableResource(frame.get(), 999);
1698 SetFrameData(frame.Pass());
1699
1700 PostSetNeedsCommitToMainThread();
1701 }
1702
1703 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1704 ++activate_count_;
1705 }
1706
1707 void DidCommit() override {
1708 switch (layer_tree_host()->source_frame_number()) {
1709 case 1: {
1710 // The first frame has been activated. Set a new frame, and
1711 // expect the next commit to finish *after* it is activated.
1712 scoped_ptr<DelegatedFrameData> frame =
1713 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1714 AddTextureQuad(frame.get(), 555);
1715 AddTransferableResource(frame.get(), 555);
1716 SetFrameData(frame.Pass());
1717 break;
1718 }
1719 case 2:
1720 // The second frame has been activated. Remove the layer from
1721 // the tree to cause another commit/activation. The commit should
1722 // finish *after* the layer is removed from the active tree.
1723 delegated_->RemoveFromParent();
1724 break;
1725 case 3:
1726 // Finish the test by releasing resources on the next frame.
1727 scoped_ptr<DelegatedFrameData> frame =
1728 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1729 SetFrameData(frame.Pass());
1730 break;
1731 }
1732 }
1733
1734 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1735 switch (host_impl->active_tree()->source_frame_number()) {
1736 case 0: {
1737 // The activate for the 1st frame should have happened before now.
1738 EXPECT_EQ(1, activate_count_);
1739 break;
1740 }
1741 case 1: {
1742 // The activate for the 2nd frame should have happened before now.
1743 EXPECT_EQ(2, activate_count_);
1744 break;
1745 }
1746 case 2: {
1747 // The activate to remove the layer should have happened before now.
1748 EXPECT_EQ(3, activate_count_);
1749 break;
1750 }
1751 case 3: {
1752 NOTREACHED();
1753 break;
1754 }
1755 }
1756 }
1757
1758 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1759 ReturnUnusedResourcesFromParent(host_impl);
1760 }
1761
1762 void UnusedResourcesAreAvailable() override {
1763 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::
1764 UnusedResourcesAreAvailable();
1765 ReturnedResourceArray resources;
1766 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1767 EXPECT_TRUE(TestAndResetAvailable());
1768 returned_resource_count_ += resources.size();
1769 if (returned_resource_count_ == 2)
1770 EndTest();
1771 }
1772
1773 int activate_count_;
1774 size_t returned_resource_count_;
1775 };
1776
1777 SINGLE_AND_MULTI_THREAD_TEST_F(
1778 DelegatedFrameIsActivatedDuringCommit);
1779
1780 class LayerTreeHostDelegatedTestTwoImplLayers
1781 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1782 public:
1783 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1784
1785 void DidCommitAndDrawFrame() override {
1786 scoped_ptr<DelegatedFrameData> frame;
1787 ReturnedResourceArray resources;
1788
1789 int next_source_frame_number = layer_tree_host()->source_frame_number();
1790 switch (next_source_frame_number) {
1791 case 1:
1792 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1793 AddTextureQuad(frame.get(), 999);
1794 AddTransferableResource(frame.get(), 999);
1795 AddTextureQuad(frame.get(), 555);
1796 AddTransferableResource(frame.get(), 555);
1797 SetFrameData(frame.Pass());
1798 break;
1799 case 2:
1800 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1801 EXPECT_EQ(0u, resources.size());
1802 EXPECT_FALSE(TestAndResetAvailable());
1803
1804 // Remove the delegated layer and replace it with a new one. Use the
1805 // same frame and resources for it.
1806 delegated_->RemoveFromParent();
1807 delegated_ = CreateDelegatedLayer(frame_provider_.get());
1808 break;
1809 case 3:
1810 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1811 EXPECT_EQ(0u, resources.size());
1812 EXPECT_FALSE(TestAndResetAvailable());
1813
1814 // Use a frame with no resources in it.
1815 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1816 SetFrameData(frame.Pass());
1817 break;
1818 case 4:
1819 // We gave one frame to the frame provider, so we should get one
1820 // ref back for each resource.
1821 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1822 {
1823 unsigned expected[] = {555, 999};
1824 EXPECT_RESOURCES(expected, resources);
1825 EXPECT_TRUE(TestAndResetAvailable());
1826 }
1827 EndTest();
1828 break;
1829 }
1830 }
1831
1832 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1833 ReturnUnusedResourcesFromParent(host_impl);
1834 }
1835 };
1836
1837 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoImplLayers);
1838
1839 class LayerTreeHostDelegatedTestTwoImplLayersTwoFrames
1840 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1841 public:
1842 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1843
1844 void DidCommitAndDrawFrame() override {
1845 scoped_ptr<DelegatedFrameData> frame;
1846 ReturnedResourceArray resources;
1847
1848 int next_source_frame_number = layer_tree_host()->source_frame_number();
1849 switch (next_source_frame_number) {
1850 case 1:
1851 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1852 AddTextureQuad(frame.get(), 999);
1853 AddTransferableResource(frame.get(), 999);
1854 AddTextureQuad(frame.get(), 555);
1855 AddTransferableResource(frame.get(), 555);
1856 SetFrameData(frame.Pass());
1857 break;
1858 case 2:
1859 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1860 EXPECT_EQ(0u, resources.size());
1861 EXPECT_FALSE(TestAndResetAvailable());
1862
1863 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1864 AddTextureQuad(frame.get(), 999);
1865 AddTransferableResource(frame.get(), 999);
1866 AddTextureQuad(frame.get(), 555);
1867 AddTransferableResource(frame.get(), 555);
1868
1869 // Remove the delegated layer and replace it with a new one. Make a new
1870 // frame but with the same resources for it.
1871 delegated_->RemoveFromParent();
1872 delegated_ = NULL;
1873
1874 frame_provider_->SetFrameData(frame.Pass());
1875 delegated_ = CreateDelegatedLayer(frame_provider_.get());
1876 break;
1877 case 3:
1878 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1879 EXPECT_EQ(0u, resources.size());
1880 EXPECT_FALSE(TestAndResetAvailable());
1881
1882 // Use a frame with no resources in it.
1883 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1884 SetFrameData(frame.Pass());
1885 break;
1886 case 4:
1887 // We gave two frames to the frame provider, so we should get two
1888 // refs back for each resource.
1889 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1890 {
1891 unsigned expected[] = {555, 555, 999, 999};
1892 EXPECT_RESOURCES(expected, resources);
1893 EXPECT_TRUE(TestAndResetAvailable());
1894 }
1895 EndTest();
1896 break;
1897 }
1898 }
1899
1900 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1901 ReturnUnusedResourcesFromParent(host_impl);
1902 }
1903 };
1904
1905 SINGLE_AND_MULTI_THREAD_TEST_F(
1906 LayerTreeHostDelegatedTestTwoImplLayersTwoFrames);
1907
1908 class LayerTreeHostDelegatedTestTwoLayers
1909 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1910 public:
1911 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1912
1913 void DidCommitAndDrawFrame() override {
1914 scoped_ptr<DelegatedFrameData> frame;
1915 ReturnedResourceArray resources;
1916
1917 int next_source_frame_number = layer_tree_host()->source_frame_number();
1918 switch (next_source_frame_number) {
1919 case 1:
1920 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1921 AddTextureQuad(frame.get(), 999);
1922 AddTransferableResource(frame.get(), 999);
1923 AddTextureQuad(frame.get(), 555);
1924 AddTransferableResource(frame.get(), 555);
1925
1926 // Create a DelegatedRendererLayer using the frame.
1927 SetFrameData(frame.Pass());
1928 break;
1929 case 2:
1930 // Create a second DelegatedRendererLayer using the same frame provider.
1931 delegated_thief_ = CreateDelegatedLayer(frame_provider_.get());
1932 root_->AddChild(delegated_thief_);
1933
1934 // And drop our ref on the frame provider so only the layers keep it
1935 // alive.
1936 frame_provider_ = NULL;
1937 break;
1938 case 3:
1939 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1940 EXPECT_EQ(0u, resources.size());
1941 EXPECT_FALSE(TestAndResetAvailable());
1942
1943 // Remove one delegated layer from the tree. No resources should be
1944 // returned yet.
1945 delegated_->RemoveFromParent();
1946 break;
1947 case 4:
1948 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1949 EXPECT_EQ(0u, resources.size());
1950 EXPECT_FALSE(TestAndResetAvailable());
1951
1952 // Put the first layer back, and remove the other layer and destroy it.
1953 // No resources should be returned yet.
1954 root_->AddChild(delegated_);
1955 delegated_thief_->RemoveFromParent();
1956 delegated_thief_ = NULL;
1957 break;
1958 case 5:
1959 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1960 EXPECT_EQ(0u, resources.size());
1961 EXPECT_FALSE(TestAndResetAvailable());
1962
1963 // Remove the first layer from the tree again. The resources are still
1964 // held by the main thread layer.
1965 delegated_->RemoveFromParent();
1966 break;
1967 case 6:
1968 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1969 EXPECT_EQ(0u, resources.size());
1970 EXPECT_FALSE(TestAndResetAvailable());
1971
1972 // Destroy the layer and the resources should be returned immediately.
1973 delegated_ = NULL;
1974
1975 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1976 {
1977 unsigned expected[] = {555, 999};
1978 EXPECT_RESOURCES(expected, resources);
1979 EXPECT_TRUE(TestAndResetAvailable());
1980 }
1981 EndTest();
1982 break;
1983 }
1984 }
1985
1986 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1987 ReturnUnusedResourcesFromParent(host_impl);
1988 }
1989
1990 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
1991 };
1992
1993 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoLayers);
1994
1995 class LayerTreeHostDelegatedTestRemoveAndAddToTree
1996 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1997 public:
1998 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1999
2000 void DidCommitAndDrawFrame() override {
2001 scoped_ptr<DelegatedFrameData> frame;
2002 ReturnedResourceArray resources;
2003
2004 int next_source_frame_number = layer_tree_host()->source_frame_number();
2005 switch (next_source_frame_number) {
2006 case 1:
2007 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2008 AddTextureQuad(frame.get(), 999);
2009 AddTransferableResource(frame.get(), 999);
2010 AddTextureQuad(frame.get(), 555);
2011 AddTransferableResource(frame.get(), 555);
2012
2013 // Create a DelegatedRendererLayer using the frame.
2014 SetFrameData(frame.Pass());
2015 break;
2016 case 2:
2017 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2018 EXPECT_EQ(0u, resources.size());
2019 EXPECT_FALSE(TestAndResetAvailable());
2020
2021 // Remove the layer from the tree. The resources should not be returned
2022 // since they are still on the main thread layer.
2023 delegated_->RemoveFromParent();
2024 break;
2025 case 3:
2026 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2027 EXPECT_EQ(0u, resources.size());
2028 EXPECT_FALSE(TestAndResetAvailable());
2029
2030 // Add the layer back to the tree.
2031 layer_tree_host()->root_layer()->AddChild(delegated_);
2032 break;
2033 case 4:
2034 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2035 EXPECT_EQ(0u, resources.size());
2036 EXPECT_FALSE(TestAndResetAvailable());
2037
2038 // Set a new frame. Resources should be returned.
2039 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2040 AddTextureQuad(frame.get(), 888);
2041 AddTransferableResource(frame.get(), 888);
2042 AddTextureQuad(frame.get(), 777);
2043 AddTransferableResource(frame.get(), 777);
2044 SetFrameData(frame.Pass());
2045 break;
2046 case 5:
2047 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2048 {
2049 unsigned expected[] = {555, 999};
2050 EXPECT_RESOURCES(expected, resources);
2051 EXPECT_TRUE(TestAndResetAvailable());
2052 }
2053
2054 // Destroy the layer.
2055 delegated_->RemoveFromParent();
2056 delegated_ = NULL;
2057 break;
2058 case 6:
2059 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2060 EXPECT_EQ(0u, resources.size());
2061 EXPECT_FALSE(TestAndResetAvailable());
2062
2063 // Destroy the frame provider. Resources should be returned.
2064 frame_provider_ = NULL;
2065
2066 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2067 {
2068 unsigned expected[] = {777, 888};
2069 EXPECT_RESOURCES(expected, resources);
2070 EXPECT_TRUE(TestAndResetAvailable());
2071 }
2072 EndTest();
2073 break;
2074 }
2075 }
2076
2077 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2078 ReturnUnusedResourcesFromParent(host_impl);
2079 }
2080
2081 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2082 };
2083
2084 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemoveAndAddToTree);
2085
2086 class LayerTreeHostDelegatedTestRemoveAndChangeResources
2087 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2088 public:
2089 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2090
2091 void DidCommitAndDrawFrame() override {
2092 scoped_ptr<DelegatedFrameData> frame;
2093 ReturnedResourceArray resources;
2094
2095 int next_source_frame_number = layer_tree_host()->source_frame_number();
2096 switch (next_source_frame_number) {
2097 case 1:
2098 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2099 AddTextureQuad(frame.get(), 999);
2100 AddTransferableResource(frame.get(), 999);
2101 AddTextureQuad(frame.get(), 555);
2102 AddTransferableResource(frame.get(), 555);
2103
2104 // Create a DelegatedRendererLayer using the frame.
2105 SetFrameData(frame.Pass());
2106 break;
2107 case 2:
2108 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2109 EXPECT_EQ(0u, resources.size());
2110 EXPECT_FALSE(TestAndResetAvailable());
2111
2112 // Remove the layer from the tree. The resources should not be returned
2113 // since they are still on the main thread layer.
2114 delegated_->RemoveFromParent();
2115 break;
2116 case 3:
2117 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2118 EXPECT_EQ(0u, resources.size());
2119 EXPECT_FALSE(TestAndResetAvailable());
2120
2121 // Set a new frame. Resources should be returned immediately.
2122 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2123 AddTextureQuad(frame.get(), 888);
2124 AddTransferableResource(frame.get(), 888);
2125 AddTextureQuad(frame.get(), 777);
2126 AddTransferableResource(frame.get(), 777);
2127 SetFrameData(frame.Pass());
2128
2129 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2130 {
2131 unsigned expected[] = {555, 999};
2132 EXPECT_RESOURCES(expected, resources);
2133 EXPECT_TRUE(TestAndResetAvailable());
2134 resources.clear();
2135 }
2136
2137 // Destroy the frame provider.
2138 frame_provider_ = NULL;
2139
2140 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2141 EXPECT_EQ(0u, resources.size());
2142 EXPECT_FALSE(TestAndResetAvailable());
2143
2144 // Destroy the layer. Resources should be returned.
2145 delegated_ = NULL;
2146
2147 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2148 {
2149 unsigned expected[] = {777, 888};
2150 EXPECT_RESOURCES(expected, resources);
2151 EXPECT_TRUE(TestAndResetAvailable());
2152 }
2153 EndTest();
2154 break;
2155 }
2156 }
2157
2158 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2159 ReturnUnusedResourcesFromParent(host_impl);
2160 }
2161
2162 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2163 };
2164
2165 SINGLE_AND_MULTI_THREAD_TEST_F(
2166 LayerTreeHostDelegatedTestRemoveAndChangeResources);
2167
2168 } // namespace
2169 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/layer_tree_host_unittest_damage.cc ('k') | cc/trees/layer_tree_host_unittest_no_message_loop.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698