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