Roll src/third_party/skia 4cd6713:0edd965
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_delegated.cc
blob9b0a58a32b30ae7ca48f057df434b675a0151991
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include <algorithm>
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"
32 namespace cc {
33 namespace {
35 bool ReturnedResourceLower(const ReturnedResource& a,
36 const ReturnedResource& b) {
37 return a.id < b.id;
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;
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;
67 EXPECT_EQ(actual_index, actual.size());
68 return actual_index == actual.size();
71 #define EXPECT_RESOURCES(expected, actual) \
72 EXPECT_TRUE(ResourcesMatch(actual, expected, arraysize(expected)));
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);
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();
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);
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());
102 SharedQuadState* shared_quad_state =
103 root_pass->CreateAndAppendSharedQuadState();
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;
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);
133 frame->render_pass_list.push_back(root_pass.Pass());
134 return frame.Pass();
137 void AddTransferableResource(DelegatedFrameData* frame,
138 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);
150 void AddTextureQuad(DelegatedFrameData* frame, ResourceId resource_id) {
151 RenderPass* render_pass = frame->render_pass_list[0];
152 SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState();
153 TextureDrawQuad* quad =
154 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
155 float vertex_opacity[4] = { 1.f, 1.f, 1.f, 1.f };
156 quad->SetNew(sqs,
157 gfx::Rect(0, 0, 10, 10),
158 gfx::Rect(0, 0, 10, 10),
159 gfx::Rect(0, 0, 10, 10),
160 resource_id,
161 false,
162 gfx::PointF(0.f, 0.f),
163 gfx::PointF(1.f, 1.f),
164 SK_ColorTRANSPARENT,
165 vertex_opacity,
166 false,
167 false);
170 void AddRenderPass(DelegatedFrameData* frame,
171 RenderPassId id,
172 const gfx::Rect& output_rect,
173 const gfx::Rect& damage_rect,
174 const FilterOperations& filters,
175 const FilterOperations& background_filters) {
176 for (size_t i = 0; i < frame->render_pass_list.size(); ++i)
177 DCHECK(id != frame->render_pass_list[i]->id);
179 scoped_ptr<RenderPass> pass(RenderPass::Create());
180 pass->SetNew(id,
181 output_rect,
182 damage_rect,
183 gfx::Transform());
184 frame->render_pass_list.push_back(pass.Pass());
186 RenderPass* render_pass = frame->render_pass_list[0];
187 SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState();
188 RenderPassDrawQuad* quad =
189 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
191 quad->SetNew(sqs,
192 output_rect,
193 output_rect,
196 gfx::Vector2dF(),
197 gfx::Size(),
198 filters,
199 gfx::Vector2dF(),
200 background_filters);
203 static ResourceId AppendResourceId(
204 std::vector<ResourceId>* resources_in_last_sent_frame,
205 ResourceId resource_id) {
206 resources_in_last_sent_frame->push_back(resource_id);
207 return resource_id;
210 void ReturnUnusedResourcesFromParent(LayerTreeHostImpl* host_impl) {
211 DelegatedFrameData* delegated_frame_data =
212 output_surface()->last_sent_frame().delegated_frame_data.get();
213 if (!delegated_frame_data)
214 return;
216 std::vector<ResourceId> resources_in_last_sent_frame;
217 for (size_t i = 0; i < delegated_frame_data->resource_list.size(); ++i) {
218 resources_in_last_sent_frame.push_back(
219 delegated_frame_data->resource_list[i].id);
222 std::vector<ResourceId> resources_to_return;
224 const TransferableResourceArray& resources_held_by_parent =
225 output_surface()->resources_held_by_parent();
226 for (size_t i = 0; i < resources_held_by_parent.size(); ++i) {
227 ResourceId resource_in_parent = resources_held_by_parent[i].id;
228 bool resource_in_parent_is_not_part_of_frame =
229 std::find(resources_in_last_sent_frame.begin(),
230 resources_in_last_sent_frame.end(),
231 resource_in_parent) == resources_in_last_sent_frame.end();
232 if (resource_in_parent_is_not_part_of_frame)
233 resources_to_return.push_back(resource_in_parent);
236 if (resources_to_return.empty())
237 return;
239 CompositorFrameAck ack;
240 for (size_t i = 0; i < resources_to_return.size(); ++i)
241 output_surface()->ReturnResource(resources_to_return[i], &ack);
242 host_impl->ReclaimResources(&ack);
245 void ReturnAllResourcesFromParent(LayerTreeHostImpl* host_impl) {
246 DelegatedFrameData* delegated_frame_data =
247 output_surface()->last_sent_frame().delegated_frame_data.get();
248 if (!delegated_frame_data)
249 return;
251 const TransferableResourceArray& resources_held_by_parent =
252 output_surface()->resources_held_by_parent();
254 if (resources_held_by_parent.empty())
255 return;
257 CompositorFrameAck ack;
258 for (size_t i = 0; i < resources_held_by_parent.size(); ++i)
259 output_surface()->ReturnResource(resources_held_by_parent[i].id, &ack);
260 host_impl->ReclaimResources(&ack);
264 class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
265 : public LayerTreeHostDelegatedTest,
266 public DelegatedFrameResourceCollectionClient {
267 public:
268 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer()
269 : resource_collection_(new DelegatedFrameResourceCollection),
270 available_(false) {
271 resource_collection_->SetClient(this);
274 void SetupTree() override {
275 root_ = Layer::Create(layer_settings());
276 root_->SetBounds(gfx::Size(15, 15));
278 layer_tree_host()->SetRootLayer(root_);
279 LayerTreeHostDelegatedTest::SetupTree();
282 void BeginTest() override {
283 resource_collection_->SetClient(this);
284 PostSetNeedsCommitToMainThread();
287 void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data) {
288 RenderPass* root_pass = frame_data->render_pass_list.back();
289 gfx::Size frame_size = root_pass->output_rect.size();
291 if (frame_provider_.get() && frame_size == frame_provider_->frame_size()) {
292 frame_provider_->SetFrameData(frame_data.Pass());
293 return;
296 if (delegated_.get()) {
297 delegated_->RemoveFromParent();
298 delegated_ = NULL;
299 frame_provider_ = NULL;
302 frame_provider_ = new DelegatedFrameProvider(resource_collection_.get(),
303 frame_data.Pass());
305 delegated_ = CreateDelegatedLayer(frame_provider_.get());
308 scoped_refptr<DelegatedRendererLayer> CreateDelegatedLayer(
309 DelegatedFrameProvider* frame_provider) {
310 scoped_refptr<DelegatedRendererLayer> delegated =
311 FakeDelegatedRendererLayer::Create(layer_settings(), frame_provider);
312 delegated->SetBounds(gfx::Size(10, 10));
313 delegated->SetIsDrawable(true);
315 root_->AddChild(delegated);
316 return delegated;
319 void AfterTest() override { resource_collection_->SetClient(NULL); }
321 // DelegatedFrameProviderClient implementation.
322 void UnusedResourcesAreAvailable() override { available_ = true; }
324 bool TestAndResetAvailable() {
325 bool available = available_;
326 available_ = false;
327 return available;
330 protected:
331 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
332 scoped_refptr<DelegatedFrameProvider> frame_provider_;
333 scoped_refptr<Layer> root_;
334 scoped_refptr<DelegatedRendererLayer> delegated_;
335 bool available_;
338 class LayerTreeHostDelegatedTestCreateChildId
339 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
340 public:
341 LayerTreeHostDelegatedTestCreateChildId()
342 : LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(),
343 num_activates_(0),
344 did_reset_child_id_(false) {}
346 void DidCommit() override {
347 if (TestEnded())
348 return;
349 SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
352 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
353 if (host_impl->active_tree()->source_frame_number() < 1)
354 return;
356 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
357 FakeDelegatedRendererLayerImpl* delegated_impl =
358 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
360 TestContextProvider* context_provider = static_cast<TestContextProvider*>(
361 host_impl->output_surface()->context_provider());
363 ++num_activates_;
364 switch (num_activates_) {
365 case 2:
366 EXPECT_TRUE(delegated_impl->ChildId());
367 EXPECT_FALSE(did_reset_child_id_);
369 context_provider->ContextGL()->LoseContextCHROMIUM(
370 GL_GUILTY_CONTEXT_RESET_ARB,
371 GL_INNOCENT_CONTEXT_RESET_ARB);
372 context_provider->ContextGL()->Flush();
373 break;
374 case 3:
375 EXPECT_TRUE(delegated_impl->ChildId());
376 EXPECT_TRUE(did_reset_child_id_);
377 EndTest();
378 break;
382 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
383 bool success) override {
384 EXPECT_TRUE(success);
386 if (num_activates_ < 2)
387 return;
389 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
390 FakeDelegatedRendererLayerImpl* delegated_impl =
391 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
393 EXPECT_EQ(2, num_activates_);
394 EXPECT_FALSE(delegated_impl->ChildId());
395 did_reset_child_id_ = true;
398 protected:
399 int num_activates_;
400 bool did_reset_child_id_;
403 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCreateChildId);
405 class LayerTreeHostDelegatedTestDontUseLostChildIdAfterCommit
406 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
407 protected:
408 void BeginTest() override {
409 SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
410 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::BeginTest();
413 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
414 // Act like the context was lost while the layer is in the pending tree.
415 LayerImpl* root_impl = host_impl->sync_tree()->root_layer();
416 FakeDelegatedRendererLayerImpl* delegated_impl =
417 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
418 delegated_impl->ReleaseResources();
421 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
422 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
423 FakeDelegatedRendererLayerImpl* delegated_impl =
424 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
426 // Should not try to activate a frame without a child id. If we did try to
427 // activate we would crash.
428 EXPECT_FALSE(delegated_impl->ChildId());
429 EndTest();
433 MULTI_THREAD_IMPL_TEST_F(
434 LayerTreeHostDelegatedTestDontUseLostChildIdAfterCommit);
436 // Test that we can gracefully handle invalid frames after the context was lost.
437 // For example, we might be trying to use the previous frame in that case and
438 // have to make sure we don't crash because our resource accounting goes wrong.
439 class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost
440 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
441 public:
442 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost()
443 : num_activates_(0), num_output_surfaces_initialized_(0) {}
445 void DidCommit() override {
446 if (TestEnded())
447 return;
448 scoped_ptr<DelegatedFrameData> frame1 =
449 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
450 AddTextureQuad(frame1.get(), 999);
451 AddTransferableResource(frame1.get(), 999);
452 SetFrameData(frame1.Pass());
455 void DidInitializeOutputSurface() override {
456 if (!num_output_surfaces_initialized_++)
457 return;
459 scoped_refptr<DelegatedRendererLayer> old_delegated = delegated_;
460 SetFrameData(
461 CreateInvalidFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
462 // Make sure we end up using the same layer, or we won't test the right
463 // thing, which is to make sure we can handle an invalid frame when using
464 // a stale layer from before the context was lost.
465 DCHECK(delegated_.get() == old_delegated.get());
468 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
469 if (host_impl->active_tree()->source_frame_number() < 1)
470 return;
472 TestContextProvider* context_provider = static_cast<TestContextProvider*>(
473 host_impl->output_surface()->context_provider());
475 ++num_activates_;
476 switch (num_activates_) {
477 case 2:
478 context_provider->ContextGL()->LoseContextCHROMIUM(
479 GL_GUILTY_CONTEXT_RESET_ARB,
480 GL_INNOCENT_CONTEXT_RESET_ARB);
481 break;
482 case 3:
483 EndTest();
484 break;
488 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
489 bool success) override {
490 EXPECT_TRUE(success);
492 if (num_activates_ < 2)
493 return;
495 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
496 FakeDelegatedRendererLayerImpl* delegated_impl =
497 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
499 EXPECT_EQ(2, num_activates_);
500 // Resources should have gotten cleared after the context was lost.
501 EXPECT_EQ(0U, delegated_impl->Resources().size());
504 void AfterTest() override {
505 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::AfterTest();
506 EXPECT_EQ(2, num_output_surfaces_initialized_);
509 protected:
510 int num_activates_;
511 int num_output_surfaces_initialized_;
514 SINGLE_AND_MULTI_THREAD_TEST_F(
515 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost);
517 class LayerTreeHostDelegatedTestLayerUsesFrameDamage
518 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
519 public:
520 void DidCommit() override {
521 int next_source_frame_number = layer_tree_host()->source_frame_number();
522 switch (next_source_frame_number) {
523 case 1:
524 // The first time the layer gets a frame the whole layer should be
525 // damaged.
526 SetFrameData(
527 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
528 break;
529 case 2:
530 // A different frame size will damage the whole layer.
531 SetFrameData(
532 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(0, 0, 0, 0)));
533 break;
534 case 3:
535 // Should create a total amount of gfx::Rect(2, 2, 8, 6) damage:
536 // (2, 2, 10, 6) clamped to the root output rect.
537 SetFrameData(
538 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(2, 2, 5, 5)));
539 SetFrameData(
540 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(7, 2, 5, 6)));
541 break;
542 case 4:
543 // Should create zero damage.
544 layer_tree_host()->SetNeedsCommit();
545 break;
546 case 5:
547 // Should damage the full viewport.
548 delegated_->SetBounds(gfx::Size(2, 2));
549 break;
550 case 6:
551 // Should create zero damage.
552 layer_tree_host()->SetNeedsCommit();
553 break;
554 case 7:
555 // Should damage the full layer, tho the frame size is not changing.
556 delegated_->SetBounds(gfx::Size(6, 6));
557 SetFrameData(
558 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(1, 1, 2, 2)));
559 break;
560 case 8:
561 // Should create zero damage.
562 layer_tree_host()->SetNeedsCommit();
563 break;
564 case 9:
565 // Should create zero damage.
566 layer_tree_host()->SetNeedsCommit();
567 break;
568 case 10:
569 // Changing the frame size damages the full layer.
570 SetFrameData(
571 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1)));
572 break;
573 case 11:
574 // An invalid frame isn't used, so it should not cause damage.
575 SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 5, 5),
576 gfx::Rect(4, 4, 1, 1)));
577 break;
578 case 12:
579 // Should create gfx::Rect(1, 1, 2, 2) of damage.
580 SetFrameData(
581 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
582 break;
583 case 13:
584 // Should create zero damage.
585 layer_tree_host()->SetNeedsCommit();
586 break;
587 case 14:
588 // Moving the layer out of the tree and back in will damage the whole
589 // impl layer.
590 delegated_->RemoveFromParent();
591 layer_tree_host()->root_layer()->AddChild(delegated_);
592 break;
593 case 15:
594 // Make a larger frame with lots of damage. Then a frame smaller than
595 // the first frame's damage. The entire layer should be damaged, but
596 // nothing more.
597 SetFrameData(
598 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
599 SetFrameData(
600 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
601 break;
602 case 16:
603 // Make a frame with lots of damage. Then replace it with a frame with
604 // no damage. The entire layer should be damaged, but nothing more.
605 SetFrameData(
606 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
607 SetFrameData(
608 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 0, 0)));
609 break;
610 case 17:
611 // Make another layer that uses the same frame provider. The new layer
612 // should be damaged.
613 delegated_copy_ = CreateDelegatedLayer(frame_provider_.get());
614 delegated_copy_->SetPosition(gfx::Point(5, 0));
616 // Also set a new frame.
617 SetFrameData(
618 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(4, 0, 1, 1)));
619 break;
620 case 18:
621 // Set another new frame, both layers should be damaged in the same
622 // ways.
623 SetFrameData(
624 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(3, 3, 1, 1)));
625 break;
629 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
630 LayerTreeHostImpl::FrameData* frame,
631 DrawResult draw_result) override {
632 EXPECT_EQ(DRAW_SUCCESS, draw_result);
634 gfx::Rect damage_rect;
635 if (!frame->has_no_damage) {
636 damage_rect = frame->render_passes.back()->damage_rect;
637 } else {
638 // If there is no damage, then we have no render passes to send.
639 EXPECT_TRUE(frame->render_passes.empty());
642 switch (host_impl->active_tree()->source_frame_number()) {
643 case 0:
644 // First frame is damaged because of viewport resize.
645 EXPECT_EQ(gfx::Rect(15, 15).ToString(), damage_rect.ToString());
646 break;
647 case 1:
648 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
649 break;
650 case 2:
651 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
652 break;
653 case 3:
654 EXPECT_EQ(gfx::Rect(2, 2, 8, 6).ToString(), damage_rect.ToString());
655 break;
656 case 4:
657 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
658 break;
659 case 5:
660 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
661 break;
662 case 6:
663 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
664 break;
665 case 7:
666 EXPECT_EQ(gfx::Rect(6, 6).ToString(), damage_rect.ToString());
667 break;
668 case 8:
669 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
670 break;
671 case 9:
672 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
673 break;
674 case 10:
675 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
676 break;
677 case 11:
678 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
679 break;
680 case 12:
681 EXPECT_EQ(gfx::Rect(1, 1, 2, 2).ToString(), damage_rect.ToString());
682 break;
683 case 13:
684 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
685 break;
686 case 14:
687 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
688 break;
689 case 15:
690 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
691 break;
692 case 16:
693 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
694 break;
695 case 17:
696 EXPECT_EQ(gfx::UnionRects(gfx::Rect(5, 0, 10, 10),
697 gfx::Rect(4, 0, 1, 1)).ToString(),
698 damage_rect.ToString());
699 break;
700 case 18:
701 EXPECT_EQ(gfx::Rect(3, 3, 6, 1).ToString(), damage_rect.ToString());
702 EndTest();
703 break;
706 return draw_result;
709 protected:
710 scoped_refptr<DelegatedRendererLayer> delegated_copy_;
713 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestLayerUsesFrameDamage);
715 class LayerTreeHostDelegatedTestMergeResources
716 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
717 public:
718 void BeginTest() override {
719 // Push two frames to the delegated renderer layer with no commit between.
721 // The first frame has resource 999.
722 scoped_ptr<DelegatedFrameData> frame1 =
723 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
724 AddTextureQuad(frame1.get(), 999);
725 AddTransferableResource(frame1.get(), 999);
726 SetFrameData(frame1.Pass());
728 // The second frame uses resource 999 still, but also adds 555.
729 scoped_ptr<DelegatedFrameData> frame2 =
730 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
731 AddTextureQuad(frame2.get(), 999);
732 AddTransferableResource(frame2.get(), 999);
733 AddTextureQuad(frame2.get(), 555);
734 AddTransferableResource(frame2.get(), 555);
735 SetFrameData(frame2.Pass());
737 // The resource 999 from frame1 is returned since it is still on the main
738 // thread.
739 ReturnedResourceArray returned_resources;
740 resource_collection_->TakeUnusedResourcesForChildCompositor(
741 &returned_resources);
743 unsigned expected[] = {999};
744 EXPECT_RESOURCES(expected, returned_resources);
745 EXPECT_TRUE(TestAndResetAvailable());
748 PostSetNeedsCommitToMainThread();
751 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
752 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
753 FakeDelegatedRendererLayerImpl* delegated_impl =
754 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
756 const ResourceProvider::ResourceIdMap& map =
757 host_impl->resource_provider()->GetChildToParentMap(
758 delegated_impl->ChildId());
760 // Both frames' resources should be in the parent's resource provider.
761 EXPECT_EQ(2u, map.size());
762 EXPECT_EQ(1u, map.count(999));
763 EXPECT_EQ(1u, map.count(555));
765 EXPECT_EQ(2u, delegated_impl->Resources().size());
766 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
767 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
769 EndTest();
773 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestMergeResources);
775 class LayerTreeHostDelegatedTestRemapResourcesInQuads
776 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
777 public:
778 void BeginTest() override {
779 // Generate a frame with two resources in it.
780 scoped_ptr<DelegatedFrameData> frame =
781 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
782 AddTextureQuad(frame.get(), 999);
783 AddTransferableResource(frame.get(), 999);
784 AddTextureQuad(frame.get(), 555);
785 AddTransferableResource(frame.get(), 555);
786 SetFrameData(frame.Pass());
788 PostSetNeedsCommitToMainThread();
791 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
792 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
793 FakeDelegatedRendererLayerImpl* delegated_impl =
794 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
796 const ResourceProvider::ResourceIdMap& map =
797 host_impl->resource_provider()->GetChildToParentMap(
798 delegated_impl->ChildId());
800 // The frame's resource should be in the parent's resource provider.
801 EXPECT_EQ(2u, map.size());
802 EXPECT_EQ(1u, map.count(999));
803 EXPECT_EQ(1u, map.count(555));
805 ResourceId parent_resource_id1 = map.find(999)->second;
806 EXPECT_NE(parent_resource_id1, 999u);
807 ResourceId parent_resource_id2 = map.find(555)->second;
808 EXPECT_NE(parent_resource_id2, 555u);
810 // The resources in the quads should be remapped to the parent's namespace.
811 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
812 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(0));
813 EXPECT_EQ(parent_resource_id1, quad1->resource_id());
814 const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
815 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(1));
816 EXPECT_EQ(parent_resource_id2, quad2->resource_id());
818 EndTest();
822 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemapResourcesInQuads);
824 class LayerTreeHostDelegatedTestReturnUnusedResources
825 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
826 public:
827 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
829 void DidCommitAndDrawFrame() override {
830 scoped_ptr<DelegatedFrameData> frame;
831 ReturnedResourceArray resources;
833 int next_source_frame_number = layer_tree_host()->source_frame_number();
834 switch (next_source_frame_number) {
835 case 1:
836 // Generate a frame with two resources in it.
837 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
838 AddTextureQuad(frame.get(), 999);
839 AddTransferableResource(frame.get(), 999);
840 AddTextureQuad(frame.get(), 555);
841 AddTransferableResource(frame.get(), 555);
842 SetFrameData(frame.Pass());
843 break;
844 case 2:
845 // All of the resources are in use.
846 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
847 EXPECT_EQ(0u, resources.size());
848 EXPECT_FALSE(TestAndResetAvailable());
850 // Keep using 999 but stop using 555.
851 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
852 AddTextureQuad(frame.get(), 999);
853 AddTransferableResource(frame.get(), 999);
854 AddTextureQuad(frame.get(), 444);
855 AddTransferableResource(frame.get(), 444);
856 SetFrameData(frame.Pass());
857 break;
858 case 3:
859 // 555 is no longer in use.
860 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
862 unsigned expected[] = {555};
863 EXPECT_RESOURCES(expected, resources);
864 EXPECT_TRUE(TestAndResetAvailable());
867 // Stop using any resources.
868 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
869 SetFrameData(frame.Pass());
870 break;
871 case 4:
872 // Postpone collecting resources for a frame. They should still be there
873 // the next frame.
874 layer_tree_host()->SetNeedsCommit();
875 return;
876 case 5:
877 // 444 and 999 are no longer in use. We sent two refs to 999, so we
878 // should get two back.
879 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
881 unsigned expected[] = {444, 999, 999};
882 EXPECT_RESOURCES(expected, resources);
883 EXPECT_TRUE(TestAndResetAvailable());
885 EndTest();
886 break;
889 // Resources are never immediately released.
890 ReturnedResourceArray empty_resources;
891 resource_collection_->TakeUnusedResourcesForChildCompositor(
892 &empty_resources);
893 EXPECT_EQ(0u, empty_resources.size());
894 EXPECT_FALSE(TestAndResetAvailable());
897 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
898 ReturnUnusedResourcesFromParent(host_impl);
902 SINGLE_AND_MULTI_THREAD_TEST_F(
903 LayerTreeHostDelegatedTestReturnUnusedResources);
905 class LayerTreeHostDelegatedTestReusedResources
906 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
907 public:
908 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
910 void DidCommitAndDrawFrame() override {
911 scoped_ptr<DelegatedFrameData> frame;
912 ReturnedResourceArray resources;
914 int next_source_frame_number = layer_tree_host()->source_frame_number();
915 switch (next_source_frame_number) {
916 case 1:
917 // Generate a frame with some resources in it.
918 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
919 AddTextureQuad(frame.get(), 999);
920 AddTransferableResource(frame.get(), 999);
921 AddTextureQuad(frame.get(), 555);
922 AddTransferableResource(frame.get(), 555);
923 AddTextureQuad(frame.get(), 444);
924 AddTransferableResource(frame.get(), 444);
925 SetFrameData(frame.Pass());
926 break;
927 case 2:
928 // All of the resources are in use.
929 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
930 EXPECT_EQ(0u, resources.size());
931 EXPECT_FALSE(TestAndResetAvailable());
933 // Keep using 999 but stop using 555 and 444.
934 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
935 AddTextureQuad(frame.get(), 999);
936 AddTransferableResource(frame.get(), 999);
937 SetFrameData(frame.Pass());
939 // Resource are not immediately released.
940 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
941 EXPECT_EQ(0u, resources.size());
942 EXPECT_FALSE(TestAndResetAvailable());
944 // Now using 555 and 444 again, but not 999.
945 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
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 3:
953 // The 999 resource is the only unused one. Two references were sent, so
954 // two should be returned.
955 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
957 unsigned expected[] = {999, 999};
958 EXPECT_RESOURCES(expected, resources);
959 EXPECT_TRUE(TestAndResetAvailable());
961 EndTest();
962 break;
966 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
967 ReturnUnusedResourcesFromParent(host_impl);
971 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources);
973 class LayerTreeHostDelegatedTestFrameBeforeAck
974 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
975 public:
976 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
978 void DidCommitAndDrawFrame() override {
979 scoped_ptr<DelegatedFrameData> frame;
980 ReturnedResourceArray resources;
982 int next_source_frame_number = layer_tree_host()->source_frame_number();
983 switch (next_source_frame_number) {
984 case 1:
985 // Generate a frame with some resources in it.
986 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
987 AddTextureQuad(frame.get(), 999);
988 AddTransferableResource(frame.get(), 999);
989 AddTextureQuad(frame.get(), 555);
990 AddTransferableResource(frame.get(), 555);
991 AddTextureQuad(frame.get(), 444);
992 AddTransferableResource(frame.get(), 444);
993 SetFrameData(frame.Pass());
994 break;
995 case 2:
996 // All of the resources are in use.
997 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
998 EXPECT_EQ(0u, resources.size());
999 EXPECT_FALSE(TestAndResetAvailable());
1001 // Keep using 999 but stop using 555 and 444.
1002 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1003 AddTextureQuad(frame.get(), 999);
1004 AddTransferableResource(frame.get(), 999);
1005 SetFrameData(frame.Pass());
1007 // Resource are not immediately released.
1008 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1009 EXPECT_EQ(0u, resources.size());
1010 EXPECT_FALSE(TestAndResetAvailable());
1012 // The parent compositor (this one) does a commit.
1013 break;
1014 case 3:
1015 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1017 unsigned expected[] = {444, 555};
1018 EXPECT_RESOURCES(expected, resources);
1019 EXPECT_TRUE(TestAndResetAvailable());
1022 // The child compositor sends a frame referring to resources not in the
1023 // frame.
1024 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1025 AddTextureQuad(frame.get(), 999);
1026 AddTextureQuad(frame.get(), 555);
1027 AddTextureQuad(frame.get(), 444);
1028 SetFrameData(frame.Pass());
1029 break;
1033 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1034 if (host_impl->active_tree()->source_frame_number() != 3)
1035 return;
1037 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1038 FakeDelegatedRendererLayerImpl* delegated_impl =
1039 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1041 const ResourceProvider::ResourceIdMap& map =
1042 host_impl->resource_provider()->GetChildToParentMap(
1043 delegated_impl->ChildId());
1045 // The bad frame should be dropped. So we should only have one quad (the
1046 // one with resource 999) on the impl tree. And only 999 will be present
1047 // in the parent's resource provider.
1048 EXPECT_EQ(1u, map.size());
1049 EXPECT_EQ(1u, map.count(999));
1051 EXPECT_EQ(1u, delegated_impl->Resources().size());
1052 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1054 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1055 EXPECT_EQ(1u, pass->quad_list.size());
1056 const TextureDrawQuad* quad =
1057 TextureDrawQuad::MaterialCast(pass->quad_list.front());
1058 EXPECT_EQ(map.find(999)->second, quad->resource_id());
1060 EndTest();
1063 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1064 ReturnUnusedResourcesFromParent(host_impl);
1068 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck);
1070 class LayerTreeHostDelegatedTestFrameBeforeTakeResources
1071 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1072 public:
1073 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1075 void DidCommitAndDrawFrame() override {
1076 scoped_ptr<DelegatedFrameData> frame;
1077 ReturnedResourceArray resources;
1079 int next_source_frame_number = layer_tree_host()->source_frame_number();
1080 switch (next_source_frame_number) {
1081 case 1:
1082 // Generate a frame with some resources in it.
1083 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1084 AddTextureQuad(frame.get(), 999);
1085 AddTransferableResource(frame.get(), 999);
1086 AddTextureQuad(frame.get(), 555);
1087 AddTransferableResource(frame.get(), 555);
1088 AddTextureQuad(frame.get(), 444);
1089 AddTransferableResource(frame.get(), 444);
1090 SetFrameData(frame.Pass());
1091 break;
1092 case 2:
1093 // All of the resources are in use.
1094 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1095 EXPECT_EQ(0u, resources.size());
1096 EXPECT_FALSE(TestAndResetAvailable());
1098 // Keep using 999 but stop using 555 and 444.
1099 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1100 AddTextureQuad(frame.get(), 999);
1101 AddTransferableResource(frame.get(), 999);
1102 SetFrameData(frame.Pass());
1104 // Resource are not immediately released.
1105 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1106 EXPECT_EQ(0u, resources.size());
1107 EXPECT_FALSE(TestAndResetAvailable());
1109 // The parent compositor (this one) does a commit.
1110 break;
1111 case 3:
1112 // The child compositor sends a frame before taking resources back
1113 // from the previous commit. This frame makes use of the resources 555
1114 // and 444, which were just released during commit.
1115 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1116 AddTextureQuad(frame.get(), 999);
1117 AddTransferableResource(frame.get(), 999);
1118 AddTextureQuad(frame.get(), 555);
1119 AddTransferableResource(frame.get(), 555);
1120 AddTextureQuad(frame.get(), 444);
1121 AddTransferableResource(frame.get(), 444);
1122 SetFrameData(frame.Pass());
1124 // The resources are used by the new frame but are returned anyway since
1125 // we passed them again.
1126 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1128 unsigned expected[] = {444, 555};
1129 EXPECT_RESOURCES(expected, resources);
1130 EXPECT_TRUE(TestAndResetAvailable());
1132 break;
1133 case 4:
1134 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1135 EXPECT_EQ(0u, resources.size());
1136 EXPECT_FALSE(TestAndResetAvailable());
1137 EndTest();
1138 break;
1142 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1143 if (host_impl->active_tree()->source_frame_number() != 3)
1144 return;
1146 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1147 FakeDelegatedRendererLayerImpl* delegated_impl =
1148 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1150 const ResourceProvider::ResourceIdMap& map =
1151 host_impl->resource_provider()->GetChildToParentMap(
1152 delegated_impl->ChildId());
1154 // The third frame has all of the resources in it again, the delegated
1155 // renderer layer should continue to own the resources for it.
1156 EXPECT_EQ(3u, map.size());
1157 EXPECT_EQ(1u, map.count(999));
1158 EXPECT_EQ(1u, map.count(555));
1159 EXPECT_EQ(1u, map.count(444));
1161 EXPECT_EQ(3u, delegated_impl->Resources().size());
1162 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1163 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1164 EXPECT_EQ(1u, delegated_impl->Resources().count(444));
1166 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1167 EXPECT_EQ(3u, pass->quad_list.size());
1168 const TextureDrawQuad* quad1 =
1169 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1170 EXPECT_EQ(map.find(999)->second, quad1->resource_id());
1171 const TextureDrawQuad* quad2 =
1172 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1173 EXPECT_EQ(map.find(555)->second, quad2->resource_id());
1174 const TextureDrawQuad* quad3 =
1175 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(2));
1176 EXPECT_EQ(map.find(444)->second, quad3->resource_id());
1179 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1180 ReturnUnusedResourcesFromParent(host_impl);
1184 SINGLE_AND_MULTI_THREAD_TEST_F(
1185 LayerTreeHostDelegatedTestFrameBeforeTakeResources);
1187 class LayerTreeHostDelegatedTestBadFrame
1188 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1189 public:
1190 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1192 void DidCommitAndDrawFrame() override {
1193 scoped_ptr<DelegatedFrameData> frame;
1194 ReturnedResourceArray resources;
1196 int next_source_frame_number = layer_tree_host()->source_frame_number();
1197 switch (next_source_frame_number) {
1198 case 1:
1199 // Generate a frame with some resources in it.
1200 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1201 AddTextureQuad(frame.get(), 999);
1202 AddTransferableResource(frame.get(), 999);
1203 AddTextureQuad(frame.get(), 555);
1204 AddTransferableResource(frame.get(), 555);
1205 SetFrameData(frame.Pass());
1206 break;
1207 case 2:
1208 // All of the resources are in use.
1209 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1210 EXPECT_EQ(0u, resources.size());
1211 EXPECT_FALSE(TestAndResetAvailable());
1213 // Generate a bad frame with a resource the layer doesn't have. The
1214 // 885 and 775 resources are unknown, while ownership of the legit 444
1215 // resource is passed in here. The bad frame does not use any of the
1216 // previous resources, 999 or 555.
1217 // A bad quad is present both before and after the good quad.
1218 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1219 AddTextureQuad(frame.get(), 885);
1220 AddTextureQuad(frame.get(), 444);
1221 AddTransferableResource(frame.get(), 444);
1222 AddTextureQuad(frame.get(), 775);
1223 SetFrameData(frame.Pass());
1225 // The parent compositor (this one) does a commit.
1226 break;
1227 case 3:
1228 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1229 EXPECT_EQ(0u, resources.size());
1230 EXPECT_FALSE(TestAndResetAvailable());
1232 // Now send a good frame with 999 again.
1233 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1234 AddTextureQuad(frame.get(), 999);
1235 SetFrameData(frame.Pass());
1237 // The bad frame's resource is given back to the child compositor.
1238 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1240 unsigned expected[] = {444};
1241 EXPECT_RESOURCES(expected, resources);
1242 EXPECT_TRUE(TestAndResetAvailable());
1244 break;
1245 case 4:
1246 // The unused 555 from the last good frame is now released.
1247 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1249 unsigned expected[] = {555};
1250 EXPECT_RESOURCES(expected, resources);
1251 EXPECT_TRUE(TestAndResetAvailable());
1254 EndTest();
1255 break;
1259 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1260 if (host_impl->active_tree()->source_frame_number() < 1)
1261 return;
1263 ReturnUnusedResourcesFromParent(host_impl);
1265 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1266 FakeDelegatedRendererLayerImpl* delegated_impl =
1267 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1269 const ResourceProvider::ResourceIdMap& map =
1270 host_impl->resource_provider()->GetChildToParentMap(
1271 delegated_impl->ChildId());
1273 switch (host_impl->active_tree()->source_frame_number()) {
1274 case 1: {
1275 // We have the first good frame with just 999 and 555 in it.
1276 // layer.
1277 EXPECT_EQ(2u, map.size());
1278 EXPECT_EQ(1u, map.count(999));
1279 EXPECT_EQ(1u, map.count(555));
1281 EXPECT_EQ(2u, delegated_impl->Resources().size());
1282 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1283 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1285 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1286 EXPECT_EQ(2u, pass->quad_list.size());
1287 const TextureDrawQuad* quad1 =
1288 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1289 EXPECT_EQ(map.find(999)->second, quad1->resource_id());
1290 const TextureDrawQuad* quad2 =
1291 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1292 EXPECT_EQ(map.find(555)->second, quad2->resource_id());
1293 break;
1295 case 2: {
1296 // We only keep resources from the last valid frame.
1297 EXPECT_EQ(2u, map.size());
1298 EXPECT_EQ(1u, map.count(999));
1299 EXPECT_EQ(1u, map.count(555));
1301 EXPECT_EQ(2u, delegated_impl->Resources().size());
1302 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1303 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1305 // The bad frame is dropped though, we still have the frame with 999 and
1306 // 555 in it.
1307 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1308 EXPECT_EQ(2u, pass->quad_list.size());
1309 const TextureDrawQuad* quad1 =
1310 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1311 EXPECT_EQ(map.find(999)->second, quad1->resource_id());
1312 const TextureDrawQuad* quad2 =
1313 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1314 EXPECT_EQ(map.find(555)->second, quad2->resource_id());
1315 break;
1317 case 3: {
1318 // We have the new good frame with just 999 in it.
1319 EXPECT_EQ(1u, map.size());
1320 EXPECT_EQ(1u, map.count(999));
1322 EXPECT_EQ(1u, delegated_impl->Resources().size());
1323 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1325 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1326 EXPECT_EQ(1u, pass->quad_list.size());
1327 const TextureDrawQuad* quad1 =
1328 TextureDrawQuad::MaterialCast(pass->quad_list.front());
1329 EXPECT_EQ(map.find(999)->second, quad1->resource_id());
1330 break;
1336 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame);
1338 class LayerTreeHostDelegatedTestUnnamedResource
1339 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1340 public:
1341 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1343 void DidCommitAndDrawFrame() override {
1344 scoped_ptr<DelegatedFrameData> frame;
1345 ReturnedResourceArray resources;
1347 int next_source_frame_number = layer_tree_host()->source_frame_number();
1348 switch (next_source_frame_number) {
1349 case 1:
1350 // This frame includes two resources in it, but only uses one.
1351 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1352 AddTransferableResource(frame.get(), 999);
1353 AddTextureQuad(frame.get(), 555);
1354 AddTransferableResource(frame.get(), 555);
1355 SetFrameData(frame.Pass());
1356 break;
1357 case 2:
1358 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1359 EXPECT_EQ(0u, resources.size());
1360 EXPECT_FALSE(TestAndResetAvailable());
1362 // Now send an empty frame.
1363 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1364 SetFrameData(frame.Pass());
1366 // The unused resource should be returned.
1367 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1369 unsigned expected[] = {999};
1370 EXPECT_RESOURCES(expected, resources);
1371 EXPECT_TRUE(TestAndResetAvailable());
1374 EndTest();
1375 break;
1379 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1380 if (host_impl->active_tree()->source_frame_number() != 1)
1381 return;
1383 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1384 FakeDelegatedRendererLayerImpl* delegated_impl =
1385 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1387 const ResourceProvider::ResourceIdMap& map =
1388 host_impl->resource_provider()->GetChildToParentMap(
1389 delegated_impl->ChildId());
1391 // The layer only held on to the resource that was used.
1392 EXPECT_EQ(1u, map.size());
1393 EXPECT_EQ(1u, map.count(555));
1395 EXPECT_EQ(1u, delegated_impl->Resources().size());
1396 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1400 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestUnnamedResource);
1402 class LayerTreeHostDelegatedTestDontLeakResource
1403 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1404 public:
1405 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1407 void DidCommitAndDrawFrame() override {
1408 scoped_ptr<DelegatedFrameData> frame;
1409 ReturnedResourceArray resources;
1411 int next_source_frame_number = layer_tree_host()->source_frame_number();
1412 switch (next_source_frame_number) {
1413 case 1:
1414 // This frame includes two resources in it.
1415 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1416 AddTextureQuad(frame.get(), 999);
1417 AddTransferableResource(frame.get(), 999);
1418 AddTextureQuad(frame.get(), 555);
1419 AddTransferableResource(frame.get(), 555);
1420 SetFrameData(frame.Pass());
1422 // But then we immediately stop using 999.
1423 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1424 AddTextureQuad(frame.get(), 555);
1425 AddTransferableResource(frame.get(), 555);
1426 SetFrameData(frame.Pass());
1427 break;
1428 case 2:
1429 // The unused resources should be returned. 555 is still used, but it's
1430 // returned once to account for the first frame.
1431 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1433 unsigned expected[] = {555, 999};
1434 EXPECT_RESOURCES(expected, resources);
1435 EXPECT_TRUE(TestAndResetAvailable());
1437 // Send a frame with no resources in it.
1438 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1439 SetFrameData(frame.Pass());
1440 break;
1441 case 3:
1442 // The now unused resource 555 should be returned.
1443 resources.clear();
1444 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1446 unsigned expected[] = {555};
1447 EXPECT_RESOURCES(expected, resources);
1448 EXPECT_TRUE(TestAndResetAvailable());
1450 EndTest();
1451 break;
1455 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1456 if (host_impl->active_tree()->source_frame_number() != 1)
1457 return;
1459 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1460 FakeDelegatedRendererLayerImpl* delegated_impl =
1461 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1463 const ResourceProvider::ResourceIdMap& map =
1464 host_impl->resource_provider()->GetChildToParentMap(
1465 delegated_impl->ChildId());
1467 // The layer only held on to the resource that was used.
1468 EXPECT_EQ(1u, map.size());
1469 EXPECT_EQ(1u, map.count(555));
1471 EXPECT_EQ(1u, delegated_impl->Resources().size());
1472 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1475 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1476 ReturnUnusedResourcesFromParent(host_impl);
1480 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource);
1482 class LayerTreeHostDelegatedTestResourceSentToParent
1483 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1484 public:
1485 void DidCommitAndDrawFrame() override {
1486 scoped_ptr<DelegatedFrameData> frame;
1487 ReturnedResourceArray resources;
1489 int next_source_frame_number = layer_tree_host()->source_frame_number();
1490 switch (next_source_frame_number) {
1491 case 1:
1492 // This frame includes two resources in it.
1493 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1494 AddTextureQuad(frame.get(), 999);
1495 AddTransferableResource(frame.get(), 999);
1496 AddTextureQuad(frame.get(), 555);
1497 AddTransferableResource(frame.get(), 555);
1498 SetFrameData(frame.Pass());
1499 break;
1500 case 2:
1501 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1502 EXPECT_EQ(0u, resources.size());
1503 EXPECT_FALSE(TestAndResetAvailable());
1505 // 999 is in use in the grandparent compositor, generate a frame without
1506 // it present.
1507 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1508 AddTextureQuad(frame.get(), 555);
1509 AddTransferableResource(frame.get(), 555);
1510 SetFrameData(frame.Pass());
1511 break;
1512 case 3:
1513 // Since 999 is in the grandparent it is not returned.
1514 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1515 EXPECT_EQ(0u, resources.size());
1516 EXPECT_FALSE(TestAndResetAvailable());
1518 // The impl side will get back the resource at some point.
1519 ImplThreadTaskRunner()->PostTask(FROM_HERE,
1520 receive_resource_on_thread_);
1521 break;
1525 void ReceiveResourceOnThread(LayerTreeHostImpl* host_impl) {
1526 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1527 FakeDelegatedRendererLayerImpl* delegated_impl =
1528 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1530 const ResourceProvider::ResourceIdMap& map =
1531 host_impl->resource_provider()->GetChildToParentMap(
1532 delegated_impl->ChildId());
1534 // Receive 999 back from the grandparent.
1535 CompositorFrameAck ack;
1536 output_surface()->ReturnResource(map.find(999)->second, &ack);
1537 host_impl->ReclaimResources(&ack);
1540 void UnusedResourcesAreAvailable() override {
1541 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
1543 ReturnedResourceArray resources;
1545 // 999 was returned from the grandparent and could be released.
1546 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1548 unsigned expected[] = {999};
1549 EXPECT_RESOURCES(expected, resources);
1552 EndTest();
1555 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1556 if (host_impl->active_tree()->source_frame_number() < 1)
1557 return;
1559 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1560 FakeDelegatedRendererLayerImpl* delegated_impl =
1561 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1563 const ResourceProvider::ResourceIdMap& map =
1564 host_impl->resource_provider()->GetChildToParentMap(
1565 delegated_impl->ChildId());
1567 switch (host_impl->active_tree()->source_frame_number()) {
1568 case 1: {
1569 EXPECT_EQ(2u, map.size());
1570 EXPECT_EQ(1u, map.count(999));
1571 EXPECT_EQ(1u, map.count(555));
1573 EXPECT_EQ(2u, delegated_impl->Resources().size());
1574 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1575 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1577 // The 999 resource will be sent to a grandparent compositor.
1578 break;
1580 case 2: {
1581 EXPECT_EQ(2u, map.size());
1582 EXPECT_EQ(1u, map.count(999));
1583 EXPECT_EQ(1u, map.count(555));
1585 // 999 is in the parent, so not held by delegated renderer layer.
1586 EXPECT_EQ(1u, delegated_impl->Resources().size());
1587 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1589 receive_resource_on_thread_ =
1590 base::Bind(&LayerTreeHostDelegatedTestResourceSentToParent::
1591 ReceiveResourceOnThread,
1592 base::Unretained(this),
1593 host_impl);
1594 break;
1596 case 3:
1597 // 999 should be released.
1598 EXPECT_EQ(1u, map.size());
1599 EXPECT_EQ(1u, map.count(555));
1601 EXPECT_EQ(1u, delegated_impl->Resources().size());
1602 EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second));
1603 break;
1607 base::Closure receive_resource_on_thread_;
1610 SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(
1611 LayerTreeHostDelegatedTestResourceSentToParent);
1613 class LayerTreeHostDelegatedTestCommitWithoutTake
1614 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1615 public:
1616 void BeginTest() override {
1617 // Prevent drawing with resources that are sent to the grandparent.
1618 layer_tree_host()->SetViewportSize(gfx::Size());
1619 PostSetNeedsCommitToMainThread();
1622 void DidCommit() override {
1623 scoped_ptr<DelegatedFrameData> frame;
1624 ReturnedResourceArray resources;
1626 int next_source_frame_number = layer_tree_host()->source_frame_number();
1627 switch (next_source_frame_number) {
1628 case 1:
1629 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1630 AddTextureQuad(frame.get(), 999);
1631 AddTransferableResource(frame.get(), 999);
1632 AddTextureQuad(frame.get(), 555);
1633 AddTransferableResource(frame.get(), 555);
1634 AddTextureQuad(frame.get(), 444);
1635 AddTransferableResource(frame.get(), 444);
1636 SetFrameData(frame.Pass());
1637 break;
1638 case 2:
1639 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1640 EXPECT_EQ(0u, resources.size());
1641 EXPECT_FALSE(TestAndResetAvailable());
1643 // Stop using 999 and 444 in this frame and commit.
1644 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1645 AddTextureQuad(frame.get(), 555);
1646 AddTransferableResource(frame.get(), 555);
1647 SetFrameData(frame.Pass());
1648 // 999 and 444 will be returned for frame 1, but not 555 since it's in
1649 // the current frame.
1650 break;
1651 case 3:
1652 // Don't take resources here, but set a new frame that uses 999 again.
1653 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1654 AddTextureQuad(frame.get(), 999);
1655 AddTransferableResource(frame.get(), 999);
1656 AddTextureQuad(frame.get(), 555);
1657 AddTransferableResource(frame.get(), 555);
1658 SetFrameData(frame.Pass());
1659 break;
1660 case 4:
1661 // 555 from frame 1 and 2 isn't returned since it's still in use. 999
1662 // from frame 1 is returned though.
1663 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1665 unsigned expected[] = {444, 999};
1666 EXPECT_RESOURCES(expected, resources);
1667 EXPECT_TRUE(TestAndResetAvailable());
1670 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1671 SetFrameData(frame.Pass());
1672 // 555 will be returned 3 times for frames 1 2 and 3, and 999 will be
1673 // returned once for frame 3.
1674 break;
1675 case 5:
1676 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1678 unsigned expected[] = {555, 555, 555, 999};
1679 EXPECT_RESOURCES(expected, resources);
1680 EXPECT_TRUE(TestAndResetAvailable());
1683 EndTest();
1684 break;
1688 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1689 if (host_impl->active_tree()->source_frame_number() < 1)
1690 return;
1692 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1693 FakeDelegatedRendererLayerImpl* delegated_impl =
1694 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1696 const ResourceProvider::ResourceIdMap& map =
1697 host_impl->resource_provider()->GetChildToParentMap(
1698 delegated_impl->ChildId());
1700 switch (host_impl->active_tree()->source_frame_number()) {
1701 case 1:
1702 EXPECT_EQ(3u, map.size());
1703 EXPECT_EQ(1u, map.count(999));
1704 EXPECT_EQ(1u, map.count(555));
1705 EXPECT_EQ(1u, map.count(444));
1707 EXPECT_EQ(3u, delegated_impl->Resources().size());
1708 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1709 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1710 EXPECT_EQ(1u, delegated_impl->Resources().count(444));
1711 break;
1712 case 2:
1713 EXPECT_EQ(1u, map.size());
1714 EXPECT_EQ(1u, map.count(555));
1716 EXPECT_EQ(1u, delegated_impl->Resources().size());
1717 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1718 break;
1719 case 3:
1720 EXPECT_EQ(2u, map.size());
1721 EXPECT_EQ(1u, map.count(999));
1722 EXPECT_EQ(1u, map.count(555));
1724 EXPECT_EQ(2u, delegated_impl->Resources().size());
1725 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1726 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1731 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCommitWithoutTake);
1733 class DelegatedFrameIsActivatedDuringCommit
1734 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1735 protected:
1736 DelegatedFrameIsActivatedDuringCommit() : returned_resource_count_(0) {}
1738 void BeginTest() override {
1739 activate_count_ = 0;
1741 scoped_ptr<DelegatedFrameData> frame =
1742 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1743 AddTextureQuad(frame.get(), 999);
1744 AddTransferableResource(frame.get(), 999);
1745 SetFrameData(frame.Pass());
1747 PostSetNeedsCommitToMainThread();
1750 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1751 ++activate_count_;
1754 void DidCommit() override {
1755 switch (layer_tree_host()->source_frame_number()) {
1756 case 1: {
1757 // The first frame has been activated. Set a new frame, and
1758 // expect the next commit to finish *after* it is activated.
1759 scoped_ptr<DelegatedFrameData> frame =
1760 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1761 AddTextureQuad(frame.get(), 555);
1762 AddTransferableResource(frame.get(), 555);
1763 SetFrameData(frame.Pass());
1764 break;
1766 case 2:
1767 // The second frame has been activated. Remove the layer from
1768 // the tree to cause another commit/activation. The commit should
1769 // finish *after* the layer is removed from the active tree.
1770 delegated_->RemoveFromParent();
1771 break;
1772 case 3:
1773 // Finish the test by releasing resources on the next frame.
1774 scoped_ptr<DelegatedFrameData> frame =
1775 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1776 SetFrameData(frame.Pass());
1777 break;
1781 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1782 switch (host_impl->active_tree()->source_frame_number()) {
1783 case 0: {
1784 // The activate for the 1st frame should have happened before now.
1785 EXPECT_EQ(1, activate_count_);
1786 break;
1788 case 1: {
1789 // The activate for the 2nd frame should have happened before now.
1790 EXPECT_EQ(2, activate_count_);
1791 break;
1793 case 2: {
1794 // The activate to remove the layer should have happened before now.
1795 EXPECT_EQ(3, activate_count_);
1796 break;
1798 case 3: {
1799 NOTREACHED();
1800 break;
1805 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1806 ReturnUnusedResourcesFromParent(host_impl);
1809 void UnusedResourcesAreAvailable() override {
1810 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::
1811 UnusedResourcesAreAvailable();
1812 ReturnedResourceArray resources;
1813 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1814 EXPECT_TRUE(TestAndResetAvailable());
1815 returned_resource_count_ += resources.size();
1816 if (returned_resource_count_ == 2)
1817 EndTest();
1820 int activate_count_;
1821 size_t returned_resource_count_;
1824 SINGLE_AND_MULTI_THREAD_TEST_F(
1825 DelegatedFrameIsActivatedDuringCommit);
1827 class LayerTreeHostDelegatedTestTwoImplLayers
1828 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1829 public:
1830 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1832 void DidCommitAndDrawFrame() override {
1833 scoped_ptr<DelegatedFrameData> frame;
1834 ReturnedResourceArray resources;
1836 int next_source_frame_number = layer_tree_host()->source_frame_number();
1837 switch (next_source_frame_number) {
1838 case 1:
1839 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1840 AddTextureQuad(frame.get(), 999);
1841 AddTransferableResource(frame.get(), 999);
1842 AddTextureQuad(frame.get(), 555);
1843 AddTransferableResource(frame.get(), 555);
1844 SetFrameData(frame.Pass());
1845 break;
1846 case 2:
1847 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1848 EXPECT_EQ(0u, resources.size());
1849 EXPECT_FALSE(TestAndResetAvailable());
1851 // Remove the delegated layer and replace it with a new one. Use the
1852 // same frame and resources for it.
1853 delegated_->RemoveFromParent();
1854 delegated_ = CreateDelegatedLayer(frame_provider_.get());
1855 break;
1856 case 3:
1857 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1858 EXPECT_EQ(0u, resources.size());
1859 EXPECT_FALSE(TestAndResetAvailable());
1861 // Use a frame with no resources in it.
1862 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1863 SetFrameData(frame.Pass());
1864 break;
1865 case 4:
1866 // We gave one frame to the frame provider, so we should get one
1867 // ref back for each resource.
1868 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1870 unsigned expected[] = {555, 999};
1871 EXPECT_RESOURCES(expected, resources);
1872 EXPECT_TRUE(TestAndResetAvailable());
1874 EndTest();
1875 break;
1879 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1880 ReturnUnusedResourcesFromParent(host_impl);
1884 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoImplLayers);
1886 class LayerTreeHostDelegatedTestTwoImplLayersTwoFrames
1887 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1888 public:
1889 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1891 void DidCommitAndDrawFrame() override {
1892 scoped_ptr<DelegatedFrameData> frame;
1893 ReturnedResourceArray resources;
1895 int next_source_frame_number = layer_tree_host()->source_frame_number();
1896 switch (next_source_frame_number) {
1897 case 1:
1898 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1899 AddTextureQuad(frame.get(), 999);
1900 AddTransferableResource(frame.get(), 999);
1901 AddTextureQuad(frame.get(), 555);
1902 AddTransferableResource(frame.get(), 555);
1903 SetFrameData(frame.Pass());
1904 break;
1905 case 2:
1906 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1907 EXPECT_EQ(0u, resources.size());
1908 EXPECT_FALSE(TestAndResetAvailable());
1910 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1911 AddTextureQuad(frame.get(), 999);
1912 AddTransferableResource(frame.get(), 999);
1913 AddTextureQuad(frame.get(), 555);
1914 AddTransferableResource(frame.get(), 555);
1916 // Remove the delegated layer and replace it with a new one. Make a new
1917 // frame but with the same resources for it.
1918 delegated_->RemoveFromParent();
1919 delegated_ = NULL;
1921 frame_provider_->SetFrameData(frame.Pass());
1922 delegated_ = CreateDelegatedLayer(frame_provider_.get());
1923 break;
1924 case 3:
1925 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1926 EXPECT_EQ(0u, resources.size());
1927 EXPECT_FALSE(TestAndResetAvailable());
1929 // Use a frame with no resources in it.
1930 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1931 SetFrameData(frame.Pass());
1932 break;
1933 case 4:
1934 // We gave two frames to the frame provider, so we should get two
1935 // refs back for each resource.
1936 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1938 unsigned expected[] = {555, 555, 999, 999};
1939 EXPECT_RESOURCES(expected, resources);
1940 EXPECT_TRUE(TestAndResetAvailable());
1942 EndTest();
1943 break;
1947 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1948 ReturnUnusedResourcesFromParent(host_impl);
1952 SINGLE_AND_MULTI_THREAD_TEST_F(
1953 LayerTreeHostDelegatedTestTwoImplLayersTwoFrames);
1955 class LayerTreeHostDelegatedTestTwoLayers
1956 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1957 public:
1958 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1960 void DidCommitAndDrawFrame() override {
1961 scoped_ptr<DelegatedFrameData> frame;
1962 ReturnedResourceArray resources;
1964 int next_source_frame_number = layer_tree_host()->source_frame_number();
1965 switch (next_source_frame_number) {
1966 case 1:
1967 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1968 AddTextureQuad(frame.get(), 999);
1969 AddTransferableResource(frame.get(), 999);
1970 AddTextureQuad(frame.get(), 555);
1971 AddTransferableResource(frame.get(), 555);
1973 // Create a DelegatedRendererLayer using the frame.
1974 SetFrameData(frame.Pass());
1975 break;
1976 case 2:
1977 // Create a second DelegatedRendererLayer using the same frame provider.
1978 delegated_thief_ = CreateDelegatedLayer(frame_provider_.get());
1979 root_->AddChild(delegated_thief_);
1981 // And drop our ref on the frame provider so only the layers keep it
1982 // alive.
1983 frame_provider_ = NULL;
1984 break;
1985 case 3:
1986 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1987 EXPECT_EQ(0u, resources.size());
1988 EXPECT_FALSE(TestAndResetAvailable());
1990 // Remove one delegated layer from the tree. No resources should be
1991 // returned yet.
1992 delegated_->RemoveFromParent();
1993 break;
1994 case 4:
1995 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1996 EXPECT_EQ(0u, resources.size());
1997 EXPECT_FALSE(TestAndResetAvailable());
1999 // Put the first layer back, and remove the other layer and destroy it.
2000 // No resources should be returned yet.
2001 root_->AddChild(delegated_);
2002 delegated_thief_->RemoveFromParent();
2003 delegated_thief_ = NULL;
2004 break;
2005 case 5:
2006 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2007 EXPECT_EQ(0u, resources.size());
2008 EXPECT_FALSE(TestAndResetAvailable());
2010 // Remove the first layer from the tree again. The resources are still
2011 // held by the main thread layer.
2012 delegated_->RemoveFromParent();
2013 break;
2014 case 6:
2015 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2016 EXPECT_EQ(0u, resources.size());
2017 EXPECT_FALSE(TestAndResetAvailable());
2019 // Destroy the layer and the resources should be returned immediately.
2020 delegated_ = NULL;
2022 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2024 unsigned expected[] = {555, 999};
2025 EXPECT_RESOURCES(expected, resources);
2026 EXPECT_TRUE(TestAndResetAvailable());
2028 EndTest();
2029 break;
2033 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2034 ReturnUnusedResourcesFromParent(host_impl);
2037 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2040 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoLayers);
2042 class LayerTreeHostDelegatedTestRemoveAndAddToTree
2043 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2044 public:
2045 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2047 void DidCommitAndDrawFrame() override {
2048 scoped_ptr<DelegatedFrameData> frame;
2049 ReturnedResourceArray resources;
2051 int next_source_frame_number = layer_tree_host()->source_frame_number();
2052 switch (next_source_frame_number) {
2053 case 1:
2054 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2055 AddTextureQuad(frame.get(), 999);
2056 AddTransferableResource(frame.get(), 999);
2057 AddTextureQuad(frame.get(), 555);
2058 AddTransferableResource(frame.get(), 555);
2060 // Create a DelegatedRendererLayer using the frame.
2061 SetFrameData(frame.Pass());
2062 break;
2063 case 2:
2064 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2065 EXPECT_EQ(0u, resources.size());
2066 EXPECT_FALSE(TestAndResetAvailable());
2068 // Remove the layer from the tree. The resources should not be returned
2069 // since they are still on the main thread layer.
2070 delegated_->RemoveFromParent();
2071 break;
2072 case 3:
2073 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2074 EXPECT_EQ(0u, resources.size());
2075 EXPECT_FALSE(TestAndResetAvailable());
2077 // Add the layer back to the tree.
2078 layer_tree_host()->root_layer()->AddChild(delegated_);
2079 break;
2080 case 4:
2081 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2082 EXPECT_EQ(0u, resources.size());
2083 EXPECT_FALSE(TestAndResetAvailable());
2085 // Set a new frame. Resources should be returned.
2086 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2087 AddTextureQuad(frame.get(), 888);
2088 AddTransferableResource(frame.get(), 888);
2089 AddTextureQuad(frame.get(), 777);
2090 AddTransferableResource(frame.get(), 777);
2091 SetFrameData(frame.Pass());
2092 break;
2093 case 5:
2094 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2096 unsigned expected[] = {555, 999};
2097 EXPECT_RESOURCES(expected, resources);
2098 EXPECT_TRUE(TestAndResetAvailable());
2101 // Destroy the layer.
2102 delegated_->RemoveFromParent();
2103 delegated_ = NULL;
2104 break;
2105 case 6:
2106 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2107 EXPECT_EQ(0u, resources.size());
2108 EXPECT_FALSE(TestAndResetAvailable());
2110 // Destroy the frame provider. Resources should be returned.
2111 frame_provider_ = NULL;
2113 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2115 unsigned expected[] = {777, 888};
2116 EXPECT_RESOURCES(expected, resources);
2117 EXPECT_TRUE(TestAndResetAvailable());
2119 EndTest();
2120 break;
2124 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2125 ReturnUnusedResourcesFromParent(host_impl);
2128 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2131 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemoveAndAddToTree);
2133 class LayerTreeHostDelegatedTestRemoveAndChangeResources
2134 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2135 public:
2136 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2138 void DidCommitAndDrawFrame() override {
2139 scoped_ptr<DelegatedFrameData> frame;
2140 ReturnedResourceArray resources;
2142 int next_source_frame_number = layer_tree_host()->source_frame_number();
2143 switch (next_source_frame_number) {
2144 case 1:
2145 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2146 AddTextureQuad(frame.get(), 999);
2147 AddTransferableResource(frame.get(), 999);
2148 AddTextureQuad(frame.get(), 555);
2149 AddTransferableResource(frame.get(), 555);
2151 // Create a DelegatedRendererLayer using the frame.
2152 SetFrameData(frame.Pass());
2153 break;
2154 case 2:
2155 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2156 EXPECT_EQ(0u, resources.size());
2157 EXPECT_FALSE(TestAndResetAvailable());
2159 // Remove the layer from the tree. The resources should not be returned
2160 // since they are still on the main thread layer.
2161 delegated_->RemoveFromParent();
2162 break;
2163 case 3:
2164 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2165 EXPECT_EQ(0u, resources.size());
2166 EXPECT_FALSE(TestAndResetAvailable());
2168 // Set a new frame. Resources should be returned immediately.
2169 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2170 AddTextureQuad(frame.get(), 888);
2171 AddTransferableResource(frame.get(), 888);
2172 AddTextureQuad(frame.get(), 777);
2173 AddTransferableResource(frame.get(), 777);
2174 SetFrameData(frame.Pass());
2176 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2178 unsigned expected[] = {555, 999};
2179 EXPECT_RESOURCES(expected, resources);
2180 EXPECT_TRUE(TestAndResetAvailable());
2181 resources.clear();
2184 // Destroy the frame provider.
2185 frame_provider_ = NULL;
2187 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2188 EXPECT_EQ(0u, resources.size());
2189 EXPECT_FALSE(TestAndResetAvailable());
2191 // Destroy the layer. Resources should be returned.
2192 delegated_ = NULL;
2194 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2196 unsigned expected[] = {777, 888};
2197 EXPECT_RESOURCES(expected, resources);
2198 EXPECT_TRUE(TestAndResetAvailable());
2200 EndTest();
2201 break;
2205 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2206 ReturnUnusedResourcesFromParent(host_impl);
2209 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2212 SINGLE_AND_MULTI_THREAD_TEST_F(
2213 LayerTreeHostDelegatedTestRemoveAndChangeResources);
2215 class LayerTreeHostDelegatedTestActiveFrameIsValid
2216 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2217 public:
2218 LayerTreeHostDelegatedTestActiveFrameIsValid()
2219 : drew_with_pending_tree_(false) {}
2221 void DidCommitAndDrawFrame() override {
2222 scoped_ptr<DelegatedFrameData> frame;
2223 switch (layer_tree_host()->source_frame_number()) {
2224 case 1:
2225 // This frame goes to the active tree.
2226 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2227 AddTextureQuad(frame.get(), 999);
2228 AddTransferableResource(frame.get(), 999);
2229 SetFrameData(frame.Pass());
2230 break;
2231 case 2:
2232 // This frame stops in the pending tree while we redraw the active tree.
2233 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2234 AddTextureQuad(frame.get(), 555);
2235 AddTransferableResource(frame.get(), 555);
2236 SetFrameData(frame.Pass());
2237 break;
2241 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2242 if (host_impl->active_tree()->source_frame_number() < 1)
2243 return;
2245 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
2246 FakeDelegatedRendererLayerImpl* delegated_impl =
2247 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
2248 const ResourceProvider::ResourceIdMap& map =
2249 host_impl->resource_provider()->GetChildToParentMap(
2250 delegated_impl->ChildId());
2252 switch (host_impl->active_tree()->source_frame_number()) {
2253 case 1:
2254 if (!host_impl->pending_tree()) {
2255 // Frame 2 is blocked from activating until another draw happens with
2256 // Frame 1. This ensures we draw a different active frame from
2257 // what's in the pending tree.
2258 host_impl->BlockNotifyReadyToActivateForTesting(true);
2259 host_impl->SetNeedsRedrawRect(gfx::Rect(1, 1));
2260 break;
2263 // The resources in the active tree should be valid.
2264 EXPECT_EQ(1u, map.count(999));
2266 host_impl->BlockNotifyReadyToActivateForTesting(false);
2267 drew_with_pending_tree_ = true;
2268 break;
2269 case 2:
2270 EXPECT_TRUE(drew_with_pending_tree_);
2272 // The resources in the active tree should be valid.
2273 EXPECT_EQ(1u, map.count(555));
2274 EndTest();
2275 break;
2279 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2280 // Return everything so that we can reliably delete resources that lose
2281 // their references. This would happen if the tab was backgrounded or
2282 // the parent decided to drop all resources for some reason.
2283 ReturnAllResourcesFromParent(host_impl);
2286 bool drew_with_pending_tree_;
2289 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostDelegatedTestActiveFrameIsValid);
2291 } // namespace
2292 } // namespace cc