OLD | NEW |
| (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 | |
OLD | NEW |