Infobar material design refresh: bg color
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_delegated.cc
blobf5aafaf2efce4d9648618510a882cd90e9b80e6e
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/lock.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/threading/thread.h"
14 #include "base/time/time.h"
15 #include "cc/layers/delegated_frame_provider.h"
16 #include "cc/layers/delegated_frame_resource_collection.h"
17 #include "cc/layers/delegated_renderer_layer.h"
18 #include "cc/layers/delegated_renderer_layer_impl.h"
19 #include "cc/output/compositor_frame.h"
20 #include "cc/output/compositor_frame_ack.h"
21 #include "cc/output/delegated_frame_data.h"
22 #include "cc/quads/render_pass_draw_quad.h"
23 #include "cc/quads/shared_quad_state.h"
24 #include "cc/quads/texture_draw_quad.h"
25 #include "cc/resources/returned_resource.h"
26 #include "cc/test/fake_delegated_renderer_layer.h"
27 #include "cc/test/fake_delegated_renderer_layer_impl.h"
28 #include "cc/test/fake_output_surface.h"
29 #include "cc/test/layer_tree_test.h"
30 #include "cc/trees/layer_tree_impl.h"
31 #include "gpu/GLES2/gl2extchromium.h"
33 namespace cc {
34 namespace {
36 bool ReturnedResourceLower(const ReturnedResource& a,
37 const ReturnedResource& b) {
38 return a.id < b.id;
41 // Tests if the list of resources matches an expectation, modulo the order.
42 bool ResourcesMatch(ReturnedResourceArray actual,
43 unsigned* expected,
44 size_t expected_count) {
45 std::sort(actual.begin(), actual.end(), ReturnedResourceLower);
46 std::sort(expected, expected + expected_count);
47 size_t actual_index = 0;
49 // for each element of the expected array, count off one of the actual array
50 // (after checking it matches).
51 for (size_t expected_index = 0; expected_index < expected_count;
52 ++expected_index) {
53 EXPECT_LT(actual_index, actual.size());
54 if (actual_index >= actual.size())
55 return false;
56 EXPECT_EQ(actual[actual_index].id, expected[expected_index]);
57 if (actual[actual_index].id != expected[expected_index])
58 return false;
59 EXPECT_GT(actual[actual_index].count, 0);
60 if (actual[actual_index].count <= 0) {
61 return false;
62 } else {
63 --actual[actual_index].count;
64 if (actual[actual_index].count == 0)
65 ++actual_index;
68 EXPECT_EQ(actual_index, actual.size());
69 return actual_index == actual.size();
72 #define EXPECT_RESOURCES(expected, actual) \
73 EXPECT_TRUE(ResourcesMatch(actual, expected, arraysize(expected)));
75 // These tests deal with delegated renderer layers.
76 class LayerTreeHostDelegatedTest : public LayerTreeTest {
77 protected:
78 scoped_ptr<DelegatedFrameData> CreateFrameData(
79 const gfx::Rect& root_output_rect,
80 const gfx::Rect& root_damage_rect) {
81 scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
83 scoped_ptr<RenderPass> root_pass(RenderPass::Create());
84 root_pass->SetNew(RenderPassId(1, 1),
85 root_output_rect,
86 root_damage_rect,
87 gfx::Transform());
88 frame->render_pass_list.push_back(root_pass.Pass());
89 return frame.Pass();
92 scoped_ptr<DelegatedFrameData> CreateInvalidFrameData(
93 const gfx::Rect& root_output_rect,
94 const gfx::Rect& root_damage_rect) {
95 scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
97 scoped_ptr<RenderPass> root_pass(RenderPass::Create());
98 root_pass->SetNew(RenderPassId(1, 1),
99 root_output_rect,
100 root_damage_rect,
101 gfx::Transform());
103 SharedQuadState* shared_quad_state =
104 root_pass->CreateAndAppendSharedQuadState();
106 gfx::Rect rect = root_output_rect;
107 gfx::Rect opaque_rect = root_output_rect;
108 gfx::Rect visible_rect = root_output_rect;
109 // An invalid resource id! The resource isn't part of the frame.
110 unsigned resource_id = 5;
111 bool premultiplied_alpha = false;
112 gfx::PointF uv_top_left = gfx::PointF(0.f, 0.f);
113 gfx::PointF uv_bottom_right = gfx::PointF(1.f, 1.f);
114 SkColor background_color = 0;
115 float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
116 bool flipped = false;
117 bool nearest_neighbor = false;
119 TextureDrawQuad* invalid_draw_quad =
120 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
121 invalid_draw_quad->SetNew(shared_quad_state,
122 rect,
123 opaque_rect,
124 visible_rect,
125 resource_id,
126 premultiplied_alpha,
127 uv_top_left,
128 uv_bottom_right,
129 background_color,
130 vertex_opacity,
131 flipped,
132 nearest_neighbor);
134 frame->render_pass_list.push_back(root_pass.Pass());
135 return frame.Pass();
138 void AddTransferableResource(DelegatedFrameData* frame,
139 ResourceId resource_id) {
140 TransferableResource resource;
141 resource.id = resource_id;
142 resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
143 GLbyte arbitrary_mailbox[GL_MAILBOX_SIZE_CHROMIUM] = {
144 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
145 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
146 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4};
147 resource.mailbox_holder.mailbox.SetName(arbitrary_mailbox);
148 frame->resource_list.push_back(resource);
151 void AddTextureQuad(DelegatedFrameData* frame, 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);
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);
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());
187 RenderPass* render_pass = frame->render_pass_list[0];
188 SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState();
189 RenderPassDrawQuad* quad =
190 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
192 quad->SetNew(sqs,
193 output_rect,
194 output_rect,
197 gfx::Vector2dF(),
198 gfx::Size(),
199 filters,
200 gfx::Vector2dF(),
201 background_filters);
204 static ResourceId AppendResourceId(
205 std::vector<ResourceId>* resources_in_last_sent_frame,
206 ResourceId resource_id) {
207 resources_in_last_sent_frame->push_back(resource_id);
208 return resource_id;
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;
217 std::vector<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);
223 std::vector<ResourceId> resources_to_return;
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 ResourceId resource_in_parent = resources_held_by_parent[i].id;
229 bool resource_in_parent_is_not_part_of_frame =
230 std::find(resources_in_last_sent_frame.begin(),
231 resources_in_last_sent_frame.end(),
232 resource_in_parent) == resources_in_last_sent_frame.end();
233 if (resource_in_parent_is_not_part_of_frame)
234 resources_to_return.push_back(resource_in_parent);
237 if (resources_to_return.empty())
238 return;
240 CompositorFrameAck ack;
241 for (size_t i = 0; i < resources_to_return.size(); ++i)
242 output_surface()->ReturnResource(resources_to_return[i], &ack);
243 host_impl->ReclaimResources(&ack);
246 void ReturnAllResourcesFromParent(LayerTreeHostImpl* host_impl) {
247 DelegatedFrameData* delegated_frame_data =
248 output_surface()->last_sent_frame().delegated_frame_data.get();
249 if (!delegated_frame_data)
250 return;
252 const TransferableResourceArray& resources_held_by_parent =
253 output_surface()->resources_held_by_parent();
255 if (resources_held_by_parent.empty())
256 return;
258 CompositorFrameAck ack;
259 for (size_t i = 0; i < resources_held_by_parent.size(); ++i)
260 output_surface()->ReturnResource(resources_held_by_parent[i].id, &ack);
261 host_impl->ReclaimResources(&ack);
265 class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
266 : public LayerTreeHostDelegatedTest,
267 public DelegatedFrameResourceCollectionClient {
268 public:
269 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer()
270 : resource_collection_(new DelegatedFrameResourceCollection),
271 available_(false) {
272 resource_collection_->SetClient(this);
275 void SetupTree() override {
276 root_ = Layer::Create(layer_settings());
277 root_->SetBounds(gfx::Size(15, 15));
279 layer_tree_host()->SetRootLayer(root_);
280 LayerTreeHostDelegatedTest::SetupTree();
283 void BeginTest() override {
284 resource_collection_->SetClient(this);
285 PostSetNeedsCommitToMainThread();
288 void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data) {
289 RenderPass* root_pass = frame_data->render_pass_list.back();
290 gfx::Size frame_size = root_pass->output_rect.size();
292 if (frame_provider_.get() && frame_size == frame_provider_->frame_size()) {
293 frame_provider_->SetFrameData(frame_data.Pass());
294 return;
297 if (delegated_.get()) {
298 delegated_->RemoveFromParent();
299 delegated_ = NULL;
300 frame_provider_ = NULL;
303 frame_provider_ = new DelegatedFrameProvider(resource_collection_.get(),
304 frame_data.Pass());
306 delegated_ = CreateDelegatedLayer(frame_provider_.get());
309 scoped_refptr<DelegatedRendererLayer> CreateDelegatedLayer(
310 DelegatedFrameProvider* frame_provider) {
311 scoped_refptr<DelegatedRendererLayer> delegated =
312 FakeDelegatedRendererLayer::Create(layer_settings(), frame_provider);
313 delegated->SetBounds(gfx::Size(10, 10));
314 delegated->SetIsDrawable(true);
316 root_->AddChild(delegated);
317 return delegated;
320 void AfterTest() override { resource_collection_->SetClient(NULL); }
322 // DelegatedFrameProviderClient implementation.
323 void UnusedResourcesAreAvailable() override { available_ = true; }
325 bool TestAndResetAvailable() {
326 bool available = available_;
327 available_ = false;
328 return available;
331 protected:
332 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
333 scoped_refptr<DelegatedFrameProvider> frame_provider_;
334 scoped_refptr<Layer> root_;
335 scoped_refptr<DelegatedRendererLayer> delegated_;
336 bool available_;
339 class LayerTreeHostDelegatedTestCreateChildId
340 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
341 public:
342 LayerTreeHostDelegatedTestCreateChildId()
343 : LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(),
344 num_activates_(0),
345 did_reset_child_id_(false) {}
347 void DidCommit() override {
348 if (TestEnded())
349 return;
350 SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
353 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
354 if (host_impl->active_tree()->source_frame_number() < 1)
355 return;
357 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
358 FakeDelegatedRendererLayerImpl* delegated_impl =
359 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
361 TestContextProvider* context_provider = static_cast<TestContextProvider*>(
362 host_impl->output_surface()->context_provider());
364 ++num_activates_;
365 switch (num_activates_) {
366 case 2:
367 EXPECT_TRUE(delegated_impl->ChildId());
368 EXPECT_FALSE(did_reset_child_id_);
370 context_provider->ContextGL()->LoseContextCHROMIUM(
371 GL_GUILTY_CONTEXT_RESET_ARB,
372 GL_INNOCENT_CONTEXT_RESET_ARB);
373 context_provider->ContextGL()->Flush();
374 break;
375 case 3:
376 EXPECT_TRUE(delegated_impl->ChildId());
377 EXPECT_TRUE(did_reset_child_id_);
378 EndTest();
379 break;
383 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
384 bool success) override {
385 EXPECT_TRUE(success);
387 if (num_activates_ < 2)
388 return;
390 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
391 FakeDelegatedRendererLayerImpl* delegated_impl =
392 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
394 EXPECT_EQ(2, num_activates_);
395 EXPECT_FALSE(delegated_impl->ChildId());
396 did_reset_child_id_ = true;
399 protected:
400 int num_activates_;
401 bool did_reset_child_id_;
404 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCreateChildId);
406 class LayerTreeHostDelegatedTestDontUseLostChildIdAfterCommit
407 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
408 protected:
409 void BeginTest() override {
410 SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
411 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::BeginTest();
414 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
415 // Act like the context was lost while the layer is in the pending tree.
416 LayerImpl* root_impl = host_impl->sync_tree()->root_layer();
417 FakeDelegatedRendererLayerImpl* delegated_impl =
418 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
419 delegated_impl->ReleaseResources();
422 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
423 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
424 FakeDelegatedRendererLayerImpl* delegated_impl =
425 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
427 // Should not try to activate a frame without a child id. If we did try to
428 // activate we would crash.
429 EXPECT_FALSE(delegated_impl->ChildId());
430 EndTest();
434 SINGLE_AND_MULTI_THREAD_TEST_F(
435 LayerTreeHostDelegatedTestDontUseLostChildIdAfterCommit);
437 // Test that we can gracefully handle invalid frames after the context was lost.
438 // For example, we might be trying to use the previous frame in that case and
439 // have to make sure we don't crash because our resource accounting goes wrong.
440 class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost
441 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
442 public:
443 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost()
444 : num_activates_(0), num_output_surfaces_initialized_(0) {}
446 void DidCommit() override {
447 if (TestEnded())
448 return;
449 scoped_ptr<DelegatedFrameData> frame1 =
450 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
451 AddTextureQuad(frame1.get(), 999);
452 AddTransferableResource(frame1.get(), 999);
453 SetFrameData(frame1.Pass());
456 void DidInitializeOutputSurface() override {
457 if (!num_output_surfaces_initialized_++)
458 return;
460 scoped_refptr<DelegatedRendererLayer> old_delegated = delegated_;
461 SetFrameData(
462 CreateInvalidFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
463 // Make sure we end up using the same layer, or we won't test the right
464 // thing, which is to make sure we can handle an invalid frame when using
465 // a stale layer from before the context was lost.
466 DCHECK(delegated_.get() == old_delegated.get());
469 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
470 if (host_impl->active_tree()->source_frame_number() < 1)
471 return;
473 TestContextProvider* context_provider = static_cast<TestContextProvider*>(
474 host_impl->output_surface()->context_provider());
476 ++num_activates_;
477 switch (num_activates_) {
478 case 2:
479 context_provider->ContextGL()->LoseContextCHROMIUM(
480 GL_GUILTY_CONTEXT_RESET_ARB,
481 GL_INNOCENT_CONTEXT_RESET_ARB);
482 break;
483 case 3:
484 EndTest();
485 break;
489 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
490 bool success) override {
491 EXPECT_TRUE(success);
493 if (num_activates_ < 2)
494 return;
496 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
497 FakeDelegatedRendererLayerImpl* delegated_impl =
498 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
500 EXPECT_EQ(2, num_activates_);
501 // Resources should have gotten cleared after the context was lost.
502 EXPECT_EQ(0U, delegated_impl->Resources().size());
505 void AfterTest() override {
506 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::AfterTest();
507 EXPECT_EQ(2, num_output_surfaces_initialized_);
510 protected:
511 int num_activates_;
512 int num_output_surfaces_initialized_;
515 SINGLE_AND_MULTI_THREAD_TEST_F(
516 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost);
518 class LayerTreeHostDelegatedTestLayerUsesFrameDamage
519 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
520 public:
521 void DidCommit() override {
522 int next_source_frame_number = layer_tree_host()->source_frame_number();
523 switch (next_source_frame_number) {
524 case 1:
525 // The first time the layer gets a frame the whole layer should be
526 // damaged.
527 SetFrameData(
528 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
529 break;
530 case 2:
531 // A different frame size will damage the whole layer.
532 SetFrameData(
533 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(0, 0, 0, 0)));
534 break;
535 case 3:
536 // Should create a total amount of gfx::Rect(2, 2, 8, 6) damage:
537 // (2, 2, 10, 6) clamped to the root output rect.
538 SetFrameData(
539 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(2, 2, 5, 5)));
540 SetFrameData(
541 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(7, 2, 5, 6)));
542 break;
543 case 4:
544 // Should create zero damage.
545 layer_tree_host()->SetNeedsCommit();
546 break;
547 case 5:
548 // Should damage the full viewport.
549 delegated_->SetBounds(gfx::Size(2, 2));
550 break;
551 case 6:
552 // Should create zero damage.
553 layer_tree_host()->SetNeedsCommit();
554 break;
555 case 7:
556 // Should damage the full layer, tho the frame size is not changing.
557 delegated_->SetBounds(gfx::Size(6, 6));
558 SetFrameData(
559 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(1, 1, 2, 2)));
560 break;
561 case 8:
562 // Should create zero damage.
563 layer_tree_host()->SetNeedsCommit();
564 break;
565 case 9:
566 // Should create zero damage.
567 layer_tree_host()->SetNeedsCommit();
568 break;
569 case 10:
570 // Changing the frame size damages the full layer.
571 SetFrameData(
572 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1)));
573 break;
574 case 11:
575 // An invalid frame isn't used, so it should not cause damage.
576 SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 5, 5),
577 gfx::Rect(4, 4, 1, 1)));
578 break;
579 case 12:
580 // Should create gfx::Rect(1, 1, 2, 2) of damage.
581 SetFrameData(
582 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
583 break;
584 case 13:
585 // Should create zero damage.
586 layer_tree_host()->SetNeedsCommit();
587 break;
588 case 14:
589 // Moving the layer out of the tree and back in will damage the whole
590 // impl layer.
591 delegated_->RemoveFromParent();
592 layer_tree_host()->root_layer()->AddChild(delegated_);
593 break;
594 case 15:
595 // Make a larger frame with lots of damage. Then a frame smaller than
596 // the first frame's damage. The entire layer should be damaged, but
597 // nothing more.
598 SetFrameData(
599 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
600 SetFrameData(
601 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
602 break;
603 case 16:
604 // Make a frame with lots of damage. Then replace it with a frame with
605 // no damage. The entire layer should be damaged, but nothing more.
606 SetFrameData(
607 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
608 SetFrameData(
609 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 0, 0)));
610 break;
611 case 17:
612 // Make another layer that uses the same frame provider. The new layer
613 // should be damaged.
614 delegated_copy_ = CreateDelegatedLayer(frame_provider_.get());
615 delegated_copy_->SetPosition(gfx::Point(5, 0));
617 // Also set a new frame.
618 SetFrameData(
619 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(4, 0, 1, 1)));
620 break;
621 case 18:
622 // Set another new frame, both layers should be damaged in the same
623 // ways.
624 SetFrameData(
625 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(3, 3, 1, 1)));
626 break;
630 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
631 LayerTreeHostImpl::FrameData* frame,
632 DrawResult draw_result) override {
633 EXPECT_EQ(DRAW_SUCCESS, draw_result);
635 gfx::Rect damage_rect;
636 if (!frame->has_no_damage) {
637 damage_rect = frame->render_passes.back()->damage_rect;
638 } else {
639 // If there is no damage, then we have no render passes to send.
640 EXPECT_TRUE(frame->render_passes.empty());
643 switch (host_impl->active_tree()->source_frame_number()) {
644 case 0:
645 // First frame is damaged because of viewport resize.
646 EXPECT_EQ(gfx::Rect(15, 15).ToString(), damage_rect.ToString());
647 break;
648 case 1:
649 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
650 break;
651 case 2:
652 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
653 break;
654 case 3:
655 EXPECT_EQ(gfx::Rect(2, 2, 8, 6).ToString(), damage_rect.ToString());
656 break;
657 case 4:
658 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
659 break;
660 case 5:
661 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
662 break;
663 case 6:
664 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
665 break;
666 case 7:
667 EXPECT_EQ(gfx::Rect(6, 6).ToString(), damage_rect.ToString());
668 break;
669 case 8:
670 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
671 break;
672 case 9:
673 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
674 break;
675 case 10:
676 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
677 break;
678 case 11:
679 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
680 break;
681 case 12:
682 EXPECT_EQ(gfx::Rect(1, 1, 2, 2).ToString(), damage_rect.ToString());
683 break;
684 case 13:
685 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
686 break;
687 case 14:
688 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
689 break;
690 case 15:
691 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
692 break;
693 case 16:
694 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
695 break;
696 case 17:
697 EXPECT_EQ(gfx::UnionRects(gfx::Rect(5, 0, 10, 10),
698 gfx::Rect(4, 0, 1, 1)).ToString(),
699 damage_rect.ToString());
700 break;
701 case 18:
702 EXPECT_EQ(gfx::Rect(3, 3, 6, 1).ToString(), damage_rect.ToString());
703 EndTest();
704 break;
707 return draw_result;
710 protected:
711 scoped_refptr<DelegatedRendererLayer> delegated_copy_;
714 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestLayerUsesFrameDamage);
716 class LayerTreeHostDelegatedTestMergeResources
717 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
718 public:
719 void BeginTest() override {
720 // Push two frames to the delegated renderer layer with no commit between.
722 // The first frame has resource 999.
723 scoped_ptr<DelegatedFrameData> frame1 =
724 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
725 AddTextureQuad(frame1.get(), 999);
726 AddTransferableResource(frame1.get(), 999);
727 SetFrameData(frame1.Pass());
729 // The second frame uses resource 999 still, but also adds 555.
730 scoped_ptr<DelegatedFrameData> frame2 =
731 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
732 AddTextureQuad(frame2.get(), 999);
733 AddTransferableResource(frame2.get(), 999);
734 AddTextureQuad(frame2.get(), 555);
735 AddTransferableResource(frame2.get(), 555);
736 SetFrameData(frame2.Pass());
738 // The resource 999 from frame1 is returned since it is still on the main
739 // thread.
740 ReturnedResourceArray returned_resources;
741 resource_collection_->TakeUnusedResourcesForChildCompositor(
742 &returned_resources);
744 unsigned expected[] = {999};
745 EXPECT_RESOURCES(expected, returned_resources);
746 EXPECT_TRUE(TestAndResetAvailable());
749 PostSetNeedsCommitToMainThread();
752 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
753 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
754 FakeDelegatedRendererLayerImpl* delegated_impl =
755 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
757 const ResourceProvider::ResourceIdMap& map =
758 host_impl->resource_provider()->GetChildToParentMap(
759 delegated_impl->ChildId());
761 // Both frames' resources should be in the parent's resource provider.
762 EXPECT_EQ(2u, map.size());
763 EXPECT_EQ(1u, map.count(999));
764 EXPECT_EQ(1u, map.count(555));
766 EXPECT_EQ(2u, delegated_impl->Resources().size());
767 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
768 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
770 EndTest();
774 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestMergeResources);
776 class LayerTreeHostDelegatedTestRemapResourcesInQuads
777 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
778 public:
779 void BeginTest() override {
780 // Generate a frame with two resources in it.
781 scoped_ptr<DelegatedFrameData> frame =
782 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
783 AddTextureQuad(frame.get(), 999);
784 AddTransferableResource(frame.get(), 999);
785 AddTextureQuad(frame.get(), 555);
786 AddTransferableResource(frame.get(), 555);
787 SetFrameData(frame.Pass());
789 PostSetNeedsCommitToMainThread();
792 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
793 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
794 FakeDelegatedRendererLayerImpl* delegated_impl =
795 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
797 const ResourceProvider::ResourceIdMap& map =
798 host_impl->resource_provider()->GetChildToParentMap(
799 delegated_impl->ChildId());
801 // The frame's resource should be in the parent's resource provider.
802 EXPECT_EQ(2u, map.size());
803 EXPECT_EQ(1u, map.count(999));
804 EXPECT_EQ(1u, map.count(555));
806 ResourceId parent_resource_id1 = map.find(999)->second;
807 EXPECT_NE(parent_resource_id1, 999u);
808 ResourceId parent_resource_id2 = map.find(555)->second;
809 EXPECT_NE(parent_resource_id2, 555u);
811 // The resources in the quads should be remapped to the parent's namespace.
812 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
813 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(0));
814 EXPECT_EQ(parent_resource_id1, quad1->resource_id());
815 const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
816 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(1));
817 EXPECT_EQ(parent_resource_id2, quad2->resource_id());
819 EndTest();
823 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemapResourcesInQuads);
825 class LayerTreeHostDelegatedTestReturnUnusedResources
826 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
827 public:
828 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
830 void DidCommitAndDrawFrame() override {
831 scoped_ptr<DelegatedFrameData> frame;
832 ReturnedResourceArray resources;
834 int next_source_frame_number = layer_tree_host()->source_frame_number();
835 switch (next_source_frame_number) {
836 case 1:
837 // Generate a frame with two resources in it.
838 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
839 AddTextureQuad(frame.get(), 999);
840 AddTransferableResource(frame.get(), 999);
841 AddTextureQuad(frame.get(), 555);
842 AddTransferableResource(frame.get(), 555);
843 SetFrameData(frame.Pass());
844 break;
845 case 2:
846 // All of the resources are in use.
847 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
848 EXPECT_EQ(0u, resources.size());
849 EXPECT_FALSE(TestAndResetAvailable());
851 // Keep using 999 but stop using 555.
852 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
853 AddTextureQuad(frame.get(), 999);
854 AddTransferableResource(frame.get(), 999);
855 AddTextureQuad(frame.get(), 444);
856 AddTransferableResource(frame.get(), 444);
857 SetFrameData(frame.Pass());
858 break;
859 case 3:
860 // 555 is no longer in use.
861 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
863 unsigned expected[] = {555};
864 EXPECT_RESOURCES(expected, resources);
865 EXPECT_TRUE(TestAndResetAvailable());
868 // Stop using any resources.
869 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
870 SetFrameData(frame.Pass());
871 break;
872 case 4:
873 // Postpone collecting resources for a frame. They should still be there
874 // the next frame.
875 layer_tree_host()->SetNeedsCommit();
876 return;
877 case 5:
878 // 444 and 999 are no longer in use. We sent two refs to 999, so we
879 // should get two back.
880 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
882 unsigned expected[] = {444, 999, 999};
883 EXPECT_RESOURCES(expected, resources);
884 EXPECT_TRUE(TestAndResetAvailable());
886 EndTest();
887 break;
890 // Resources are never immediately released.
891 ReturnedResourceArray empty_resources;
892 resource_collection_->TakeUnusedResourcesForChildCompositor(
893 &empty_resources);
894 EXPECT_EQ(0u, empty_resources.size());
895 EXPECT_FALSE(TestAndResetAvailable());
898 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
899 ReturnUnusedResourcesFromParent(host_impl);
903 SINGLE_AND_MULTI_THREAD_TEST_F(
904 LayerTreeHostDelegatedTestReturnUnusedResources);
906 class LayerTreeHostDelegatedTestReusedResources
907 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
908 public:
909 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
911 void DidCommitAndDrawFrame() override {
912 scoped_ptr<DelegatedFrameData> frame;
913 ReturnedResourceArray resources;
915 int next_source_frame_number = layer_tree_host()->source_frame_number();
916 switch (next_source_frame_number) {
917 case 1:
918 // Generate a frame with some resources in it.
919 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
920 AddTextureQuad(frame.get(), 999);
921 AddTransferableResource(frame.get(), 999);
922 AddTextureQuad(frame.get(), 555);
923 AddTransferableResource(frame.get(), 555);
924 AddTextureQuad(frame.get(), 444);
925 AddTransferableResource(frame.get(), 444);
926 SetFrameData(frame.Pass());
927 break;
928 case 2:
929 // All of the resources are in use.
930 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
931 EXPECT_EQ(0u, resources.size());
932 EXPECT_FALSE(TestAndResetAvailable());
934 // Keep using 999 but stop using 555 and 444.
935 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
936 AddTextureQuad(frame.get(), 999);
937 AddTransferableResource(frame.get(), 999);
938 SetFrameData(frame.Pass());
940 // Resource are not immediately released.
941 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
942 EXPECT_EQ(0u, resources.size());
943 EXPECT_FALSE(TestAndResetAvailable());
945 // Now using 555 and 444 again, but not 999.
946 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
947 AddTextureQuad(frame.get(), 555);
948 AddTransferableResource(frame.get(), 555);
949 AddTextureQuad(frame.get(), 444);
950 AddTransferableResource(frame.get(), 444);
951 SetFrameData(frame.Pass());
952 break;
953 case 3:
954 // The 999 resource is the only unused one. Two references were sent, so
955 // two should be returned.
956 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
958 unsigned expected[] = {999, 999};
959 EXPECT_RESOURCES(expected, resources);
960 EXPECT_TRUE(TestAndResetAvailable());
962 EndTest();
963 break;
967 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
968 ReturnUnusedResourcesFromParent(host_impl);
972 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources);
974 class LayerTreeHostDelegatedTestFrameBeforeAck
975 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
976 public:
977 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
979 void DidCommitAndDrawFrame() override {
980 scoped_ptr<DelegatedFrameData> frame;
981 ReturnedResourceArray resources;
983 int next_source_frame_number = layer_tree_host()->source_frame_number();
984 switch (next_source_frame_number) {
985 case 1:
986 // Generate a frame with some resources in it.
987 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
988 AddTextureQuad(frame.get(), 999);
989 AddTransferableResource(frame.get(), 999);
990 AddTextureQuad(frame.get(), 555);
991 AddTransferableResource(frame.get(), 555);
992 AddTextureQuad(frame.get(), 444);
993 AddTransferableResource(frame.get(), 444);
994 SetFrameData(frame.Pass());
995 break;
996 case 2:
997 // All of the resources are in use.
998 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
999 EXPECT_EQ(0u, resources.size());
1000 EXPECT_FALSE(TestAndResetAvailable());
1002 // Keep using 999 but stop using 555 and 444.
1003 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1004 AddTextureQuad(frame.get(), 999);
1005 AddTransferableResource(frame.get(), 999);
1006 SetFrameData(frame.Pass());
1008 // Resource are not immediately released.
1009 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1010 EXPECT_EQ(0u, resources.size());
1011 EXPECT_FALSE(TestAndResetAvailable());
1013 // The parent compositor (this one) does a commit.
1014 break;
1015 case 3:
1016 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1018 unsigned expected[] = {444, 555};
1019 EXPECT_RESOURCES(expected, resources);
1020 EXPECT_TRUE(TestAndResetAvailable());
1023 // The child compositor sends a frame referring to resources not in the
1024 // frame.
1025 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1026 AddTextureQuad(frame.get(), 999);
1027 AddTextureQuad(frame.get(), 555);
1028 AddTextureQuad(frame.get(), 444);
1029 SetFrameData(frame.Pass());
1030 break;
1034 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1035 if (host_impl->active_tree()->source_frame_number() != 3)
1036 return;
1038 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1039 FakeDelegatedRendererLayerImpl* delegated_impl =
1040 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1042 const ResourceProvider::ResourceIdMap& map =
1043 host_impl->resource_provider()->GetChildToParentMap(
1044 delegated_impl->ChildId());
1046 // The bad frame should be dropped. So we should only have one quad (the
1047 // one with resource 999) on the impl tree. And only 999 will be present
1048 // in the parent's resource provider.
1049 EXPECT_EQ(1u, map.size());
1050 EXPECT_EQ(1u, map.count(999));
1052 EXPECT_EQ(1u, delegated_impl->Resources().size());
1053 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1055 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1056 EXPECT_EQ(1u, pass->quad_list.size());
1057 const TextureDrawQuad* quad =
1058 TextureDrawQuad::MaterialCast(pass->quad_list.front());
1059 EXPECT_EQ(map.find(999)->second, quad->resource_id());
1061 EndTest();
1064 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1065 ReturnUnusedResourcesFromParent(host_impl);
1069 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck);
1071 class LayerTreeHostDelegatedTestFrameBeforeTakeResources
1072 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1073 public:
1074 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1076 void DidCommitAndDrawFrame() override {
1077 scoped_ptr<DelegatedFrameData> frame;
1078 ReturnedResourceArray resources;
1080 int next_source_frame_number = layer_tree_host()->source_frame_number();
1081 switch (next_source_frame_number) {
1082 case 1:
1083 // Generate a frame with some resources in it.
1084 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1085 AddTextureQuad(frame.get(), 999);
1086 AddTransferableResource(frame.get(), 999);
1087 AddTextureQuad(frame.get(), 555);
1088 AddTransferableResource(frame.get(), 555);
1089 AddTextureQuad(frame.get(), 444);
1090 AddTransferableResource(frame.get(), 444);
1091 SetFrameData(frame.Pass());
1092 break;
1093 case 2:
1094 // All of the resources are in use.
1095 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1096 EXPECT_EQ(0u, resources.size());
1097 EXPECT_FALSE(TestAndResetAvailable());
1099 // Keep using 999 but stop using 555 and 444.
1100 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1101 AddTextureQuad(frame.get(), 999);
1102 AddTransferableResource(frame.get(), 999);
1103 SetFrameData(frame.Pass());
1105 // Resource are not immediately released.
1106 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1107 EXPECT_EQ(0u, resources.size());
1108 EXPECT_FALSE(TestAndResetAvailable());
1110 // The parent compositor (this one) does a commit.
1111 break;
1112 case 3:
1113 // The child compositor sends a frame before taking resources back
1114 // from the previous commit. This frame makes use of the resources 555
1115 // and 444, which were just released during commit.
1116 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1117 AddTextureQuad(frame.get(), 999);
1118 AddTransferableResource(frame.get(), 999);
1119 AddTextureQuad(frame.get(), 555);
1120 AddTransferableResource(frame.get(), 555);
1121 AddTextureQuad(frame.get(), 444);
1122 AddTransferableResource(frame.get(), 444);
1123 SetFrameData(frame.Pass());
1125 // The resources are used by the new frame but are returned anyway since
1126 // we passed them again.
1127 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1129 unsigned expected[] = {444, 555};
1130 EXPECT_RESOURCES(expected, resources);
1131 EXPECT_TRUE(TestAndResetAvailable());
1133 break;
1134 case 4:
1135 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1136 EXPECT_EQ(0u, resources.size());
1137 EXPECT_FALSE(TestAndResetAvailable());
1138 EndTest();
1139 break;
1143 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1144 if (host_impl->active_tree()->source_frame_number() != 3)
1145 return;
1147 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1148 FakeDelegatedRendererLayerImpl* delegated_impl =
1149 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1151 const ResourceProvider::ResourceIdMap& map =
1152 host_impl->resource_provider()->GetChildToParentMap(
1153 delegated_impl->ChildId());
1155 // The third frame has all of the resources in it again, the delegated
1156 // renderer layer should continue to own the resources for it.
1157 EXPECT_EQ(3u, map.size());
1158 EXPECT_EQ(1u, map.count(999));
1159 EXPECT_EQ(1u, map.count(555));
1160 EXPECT_EQ(1u, map.count(444));
1162 EXPECT_EQ(3u, delegated_impl->Resources().size());
1163 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1164 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1165 EXPECT_EQ(1u, delegated_impl->Resources().count(444));
1167 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1168 EXPECT_EQ(3u, pass->quad_list.size());
1169 const TextureDrawQuad* quad1 =
1170 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1171 EXPECT_EQ(map.find(999)->second, quad1->resource_id());
1172 const TextureDrawQuad* quad2 =
1173 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1174 EXPECT_EQ(map.find(555)->second, quad2->resource_id());
1175 const TextureDrawQuad* quad3 =
1176 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(2));
1177 EXPECT_EQ(map.find(444)->second, quad3->resource_id());
1180 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1181 ReturnUnusedResourcesFromParent(host_impl);
1185 SINGLE_AND_MULTI_THREAD_TEST_F(
1186 LayerTreeHostDelegatedTestFrameBeforeTakeResources);
1188 class LayerTreeHostDelegatedTestBadFrame
1189 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1190 public:
1191 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1193 void DidCommitAndDrawFrame() override {
1194 scoped_ptr<DelegatedFrameData> frame;
1195 ReturnedResourceArray resources;
1197 int next_source_frame_number = layer_tree_host()->source_frame_number();
1198 switch (next_source_frame_number) {
1199 case 1:
1200 // Generate a frame with some resources in it.
1201 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1202 AddTextureQuad(frame.get(), 999);
1203 AddTransferableResource(frame.get(), 999);
1204 AddTextureQuad(frame.get(), 555);
1205 AddTransferableResource(frame.get(), 555);
1206 SetFrameData(frame.Pass());
1207 break;
1208 case 2:
1209 // All of the resources are in use.
1210 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1211 EXPECT_EQ(0u, resources.size());
1212 EXPECT_FALSE(TestAndResetAvailable());
1214 // Generate a bad frame with a resource the layer doesn't have. The
1215 // 885 and 775 resources are unknown, while ownership of the legit 444
1216 // resource is passed in here. The bad frame does not use any of the
1217 // previous resources, 999 or 555.
1218 // A bad quad is present both before and after the good quad.
1219 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1220 AddTextureQuad(frame.get(), 885);
1221 AddTextureQuad(frame.get(), 444);
1222 AddTransferableResource(frame.get(), 444);
1223 AddTextureQuad(frame.get(), 775);
1224 SetFrameData(frame.Pass());
1226 // The parent compositor (this one) does a commit.
1227 break;
1228 case 3:
1229 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1230 EXPECT_EQ(0u, resources.size());
1231 EXPECT_FALSE(TestAndResetAvailable());
1233 // Now send a good frame with 999 again.
1234 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1235 AddTextureQuad(frame.get(), 999);
1236 SetFrameData(frame.Pass());
1238 // The bad frame's resource is given back to the child compositor.
1239 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1241 unsigned expected[] = {444};
1242 EXPECT_RESOURCES(expected, resources);
1243 EXPECT_TRUE(TestAndResetAvailable());
1245 break;
1246 case 4:
1247 // The unused 555 from the last good frame is now released.
1248 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1250 unsigned expected[] = {555};
1251 EXPECT_RESOURCES(expected, resources);
1252 EXPECT_TRUE(TestAndResetAvailable());
1255 EndTest();
1256 break;
1260 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1261 if (host_impl->active_tree()->source_frame_number() < 1)
1262 return;
1264 ReturnUnusedResourcesFromParent(host_impl);
1266 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1267 FakeDelegatedRendererLayerImpl* delegated_impl =
1268 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1270 const ResourceProvider::ResourceIdMap& map =
1271 host_impl->resource_provider()->GetChildToParentMap(
1272 delegated_impl->ChildId());
1274 switch (host_impl->active_tree()->source_frame_number()) {
1275 case 1: {
1276 // We have the first good frame with just 999 and 555 in it.
1277 // layer.
1278 EXPECT_EQ(2u, map.size());
1279 EXPECT_EQ(1u, map.count(999));
1280 EXPECT_EQ(1u, map.count(555));
1282 EXPECT_EQ(2u, delegated_impl->Resources().size());
1283 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1284 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1286 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1287 EXPECT_EQ(2u, pass->quad_list.size());
1288 const TextureDrawQuad* quad1 =
1289 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1290 EXPECT_EQ(map.find(999)->second, quad1->resource_id());
1291 const TextureDrawQuad* quad2 =
1292 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1293 EXPECT_EQ(map.find(555)->second, quad2->resource_id());
1294 break;
1296 case 2: {
1297 // We only keep resources from the last valid frame.
1298 EXPECT_EQ(2u, map.size());
1299 EXPECT_EQ(1u, map.count(999));
1300 EXPECT_EQ(1u, map.count(555));
1302 EXPECT_EQ(2u, delegated_impl->Resources().size());
1303 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1304 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1306 // The bad frame is dropped though, we still have the frame with 999 and
1307 // 555 in it.
1308 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1309 EXPECT_EQ(2u, pass->quad_list.size());
1310 const TextureDrawQuad* quad1 =
1311 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
1312 EXPECT_EQ(map.find(999)->second, quad1->resource_id());
1313 const TextureDrawQuad* quad2 =
1314 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
1315 EXPECT_EQ(map.find(555)->second, quad2->resource_id());
1316 break;
1318 case 3: {
1319 // We have the new good frame with just 999 in it.
1320 EXPECT_EQ(1u, map.size());
1321 EXPECT_EQ(1u, map.count(999));
1323 EXPECT_EQ(1u, delegated_impl->Resources().size());
1324 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1326 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1327 EXPECT_EQ(1u, pass->quad_list.size());
1328 const TextureDrawQuad* quad1 =
1329 TextureDrawQuad::MaterialCast(pass->quad_list.front());
1330 EXPECT_EQ(map.find(999)->second, quad1->resource_id());
1331 break;
1337 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame);
1339 class LayerTreeHostDelegatedTestUnnamedResource
1340 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1341 public:
1342 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1344 void DidCommitAndDrawFrame() override {
1345 scoped_ptr<DelegatedFrameData> frame;
1346 ReturnedResourceArray resources;
1348 int next_source_frame_number = layer_tree_host()->source_frame_number();
1349 switch (next_source_frame_number) {
1350 case 1:
1351 // This frame includes two resources in it, but only uses one.
1352 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1353 AddTransferableResource(frame.get(), 999);
1354 AddTextureQuad(frame.get(), 555);
1355 AddTransferableResource(frame.get(), 555);
1356 SetFrameData(frame.Pass());
1357 break;
1358 case 2:
1359 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1360 EXPECT_EQ(0u, resources.size());
1361 EXPECT_FALSE(TestAndResetAvailable());
1363 // Now send an empty frame.
1364 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1365 SetFrameData(frame.Pass());
1367 // The unused resource should be returned.
1368 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1370 unsigned expected[] = {999};
1371 EXPECT_RESOURCES(expected, resources);
1372 EXPECT_TRUE(TestAndResetAvailable());
1375 EndTest();
1376 break;
1380 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1381 if (host_impl->active_tree()->source_frame_number() != 1)
1382 return;
1384 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1385 FakeDelegatedRendererLayerImpl* delegated_impl =
1386 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1388 const ResourceProvider::ResourceIdMap& map =
1389 host_impl->resource_provider()->GetChildToParentMap(
1390 delegated_impl->ChildId());
1392 // The layer only held on to the resource that was used.
1393 EXPECT_EQ(1u, map.size());
1394 EXPECT_EQ(1u, map.count(555));
1396 EXPECT_EQ(1u, delegated_impl->Resources().size());
1397 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1401 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestUnnamedResource);
1403 class LayerTreeHostDelegatedTestDontLeakResource
1404 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1405 public:
1406 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1408 void DidCommitAndDrawFrame() override {
1409 scoped_ptr<DelegatedFrameData> frame;
1410 ReturnedResourceArray resources;
1412 int next_source_frame_number = layer_tree_host()->source_frame_number();
1413 switch (next_source_frame_number) {
1414 case 1:
1415 // This frame includes two resources in it.
1416 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1417 AddTextureQuad(frame.get(), 999);
1418 AddTransferableResource(frame.get(), 999);
1419 AddTextureQuad(frame.get(), 555);
1420 AddTransferableResource(frame.get(), 555);
1421 SetFrameData(frame.Pass());
1423 // But then we immediately stop using 999.
1424 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1425 AddTextureQuad(frame.get(), 555);
1426 AddTransferableResource(frame.get(), 555);
1427 SetFrameData(frame.Pass());
1428 break;
1429 case 2:
1430 // The unused resources should be returned. 555 is still used, but it's
1431 // returned once to account for the first frame.
1432 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1434 unsigned expected[] = {555, 999};
1435 EXPECT_RESOURCES(expected, resources);
1436 EXPECT_TRUE(TestAndResetAvailable());
1438 // Send a frame with no resources in it.
1439 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1440 SetFrameData(frame.Pass());
1441 break;
1442 case 3:
1443 // The now unused resource 555 should be returned.
1444 resources.clear();
1445 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1447 unsigned expected[] = {555};
1448 EXPECT_RESOURCES(expected, resources);
1449 EXPECT_TRUE(TestAndResetAvailable());
1451 EndTest();
1452 break;
1456 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1457 if (host_impl->active_tree()->source_frame_number() != 1)
1458 return;
1460 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1461 FakeDelegatedRendererLayerImpl* delegated_impl =
1462 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1464 const ResourceProvider::ResourceIdMap& map =
1465 host_impl->resource_provider()->GetChildToParentMap(
1466 delegated_impl->ChildId());
1468 // The layer only held on to the resource that was used.
1469 EXPECT_EQ(1u, map.size());
1470 EXPECT_EQ(1u, map.count(555));
1472 EXPECT_EQ(1u, delegated_impl->Resources().size());
1473 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1476 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1477 ReturnUnusedResourcesFromParent(host_impl);
1481 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource);
1483 class LayerTreeHostDelegatedTestResourceSentToParent
1484 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1485 public:
1486 void DidCommitAndDrawFrame() override {
1487 scoped_ptr<DelegatedFrameData> frame;
1488 ReturnedResourceArray resources;
1490 int next_source_frame_number = layer_tree_host()->source_frame_number();
1491 switch (next_source_frame_number) {
1492 case 1:
1493 // This frame includes two resources in it.
1494 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1495 AddTextureQuad(frame.get(), 999);
1496 AddTransferableResource(frame.get(), 999);
1497 AddTextureQuad(frame.get(), 555);
1498 AddTransferableResource(frame.get(), 555);
1499 SetFrameData(frame.Pass());
1500 break;
1501 case 2:
1502 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1503 EXPECT_EQ(0u, resources.size());
1504 EXPECT_FALSE(TestAndResetAvailable());
1506 // 999 is in use in the grandparent compositor, generate a frame without
1507 // it present.
1508 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1509 AddTextureQuad(frame.get(), 555);
1510 AddTransferableResource(frame.get(), 555);
1511 SetFrameData(frame.Pass());
1512 break;
1513 case 3:
1514 // Since 999 is in the grandparent it is not returned.
1515 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1516 EXPECT_EQ(0u, resources.size());
1517 EXPECT_FALSE(TestAndResetAvailable());
1519 // The impl side will get back the resource at some point.
1520 ImplThreadTaskRunner()->PostTask(FROM_HERE,
1521 receive_resource_on_thread_);
1522 break;
1526 void ReceiveResourceOnThread(LayerTreeHostImpl* host_impl) {
1527 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1528 FakeDelegatedRendererLayerImpl* delegated_impl =
1529 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1531 const ResourceProvider::ResourceIdMap& map =
1532 host_impl->resource_provider()->GetChildToParentMap(
1533 delegated_impl->ChildId());
1535 // Receive 999 back from the grandparent.
1536 CompositorFrameAck ack;
1537 output_surface()->ReturnResource(map.find(999)->second, &ack);
1538 host_impl->ReclaimResources(&ack);
1541 void UnusedResourcesAreAvailable() override {
1542 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
1544 ReturnedResourceArray resources;
1546 // 999 was returned from the grandparent and could be released.
1547 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1549 unsigned expected[] = {999};
1550 EXPECT_RESOURCES(expected, resources);
1553 EndTest();
1556 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1557 if (host_impl->active_tree()->source_frame_number() < 1)
1558 return;
1560 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1561 FakeDelegatedRendererLayerImpl* delegated_impl =
1562 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1564 const ResourceProvider::ResourceIdMap& map =
1565 host_impl->resource_provider()->GetChildToParentMap(
1566 delegated_impl->ChildId());
1568 switch (host_impl->active_tree()->source_frame_number()) {
1569 case 1: {
1570 EXPECT_EQ(2u, map.size());
1571 EXPECT_EQ(1u, map.count(999));
1572 EXPECT_EQ(1u, map.count(555));
1574 EXPECT_EQ(2u, delegated_impl->Resources().size());
1575 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1576 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1578 // The 999 resource will be sent to a grandparent compositor.
1579 break;
1581 case 2: {
1582 EXPECT_EQ(2u, map.size());
1583 EXPECT_EQ(1u, map.count(999));
1584 EXPECT_EQ(1u, map.count(555));
1586 // 999 is in the parent, so not held by delegated renderer layer.
1587 EXPECT_EQ(1u, delegated_impl->Resources().size());
1588 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1590 receive_resource_on_thread_ =
1591 base::Bind(&LayerTreeHostDelegatedTestResourceSentToParent::
1592 ReceiveResourceOnThread,
1593 base::Unretained(this),
1594 host_impl);
1595 break;
1597 case 3:
1598 // 999 should be released.
1599 EXPECT_EQ(1u, map.size());
1600 EXPECT_EQ(1u, map.count(555));
1602 EXPECT_EQ(1u, delegated_impl->Resources().size());
1603 EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second));
1604 break;
1608 base::Closure receive_resource_on_thread_;
1611 SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(
1612 LayerTreeHostDelegatedTestResourceSentToParent);
1614 class LayerTreeHostDelegatedTestCommitWithoutTake
1615 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1616 public:
1617 void BeginTest() override {
1618 // Prevent drawing with resources that are sent to the grandparent.
1619 layer_tree_host()->SetViewportSize(gfx::Size());
1620 PostSetNeedsCommitToMainThread();
1623 void DidCommit() override {
1624 scoped_ptr<DelegatedFrameData> frame;
1625 ReturnedResourceArray resources;
1627 int next_source_frame_number = layer_tree_host()->source_frame_number();
1628 switch (next_source_frame_number) {
1629 case 1:
1630 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1631 AddTextureQuad(frame.get(), 999);
1632 AddTransferableResource(frame.get(), 999);
1633 AddTextureQuad(frame.get(), 555);
1634 AddTransferableResource(frame.get(), 555);
1635 AddTextureQuad(frame.get(), 444);
1636 AddTransferableResource(frame.get(), 444);
1637 SetFrameData(frame.Pass());
1638 break;
1639 case 2:
1640 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1641 EXPECT_EQ(0u, resources.size());
1642 EXPECT_FALSE(TestAndResetAvailable());
1644 // Stop using 999 and 444 in this frame and commit.
1645 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1646 AddTextureQuad(frame.get(), 555);
1647 AddTransferableResource(frame.get(), 555);
1648 SetFrameData(frame.Pass());
1649 // 999 and 444 will be returned for frame 1, but not 555 since it's in
1650 // the current frame.
1651 break;
1652 case 3:
1653 // Don't take resources here, but set a new frame that uses 999 again.
1654 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1655 AddTextureQuad(frame.get(), 999);
1656 AddTransferableResource(frame.get(), 999);
1657 AddTextureQuad(frame.get(), 555);
1658 AddTransferableResource(frame.get(), 555);
1659 SetFrameData(frame.Pass());
1660 break;
1661 case 4:
1662 // 555 from frame 1 and 2 isn't returned since it's still in use. 999
1663 // from frame 1 is returned though.
1664 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1666 unsigned expected[] = {444, 999};
1667 EXPECT_RESOURCES(expected, resources);
1668 EXPECT_TRUE(TestAndResetAvailable());
1671 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1672 SetFrameData(frame.Pass());
1673 // 555 will be returned 3 times for frames 1 2 and 3, and 999 will be
1674 // returned once for frame 3.
1675 break;
1676 case 5:
1677 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1679 unsigned expected[] = {555, 555, 555, 999};
1680 EXPECT_RESOURCES(expected, resources);
1681 EXPECT_TRUE(TestAndResetAvailable());
1684 EndTest();
1685 break;
1689 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1690 if (host_impl->active_tree()->source_frame_number() < 1)
1691 return;
1693 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1694 FakeDelegatedRendererLayerImpl* delegated_impl =
1695 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1697 const ResourceProvider::ResourceIdMap& map =
1698 host_impl->resource_provider()->GetChildToParentMap(
1699 delegated_impl->ChildId());
1701 switch (host_impl->active_tree()->source_frame_number()) {
1702 case 1:
1703 EXPECT_EQ(3u, map.size());
1704 EXPECT_EQ(1u, map.count(999));
1705 EXPECT_EQ(1u, map.count(555));
1706 EXPECT_EQ(1u, map.count(444));
1708 EXPECT_EQ(3u, delegated_impl->Resources().size());
1709 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1710 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1711 EXPECT_EQ(1u, delegated_impl->Resources().count(444));
1712 break;
1713 case 2:
1714 EXPECT_EQ(1u, map.size());
1715 EXPECT_EQ(1u, map.count(555));
1717 EXPECT_EQ(1u, delegated_impl->Resources().size());
1718 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1719 break;
1720 case 3:
1721 EXPECT_EQ(2u, map.size());
1722 EXPECT_EQ(1u, map.count(999));
1723 EXPECT_EQ(1u, map.count(555));
1725 EXPECT_EQ(2u, delegated_impl->Resources().size());
1726 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1727 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1732 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCommitWithoutTake);
1734 class DelegatedFrameIsActivatedDuringCommit
1735 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1736 protected:
1737 DelegatedFrameIsActivatedDuringCommit() : returned_resource_count_(0) {}
1739 void BeginTest() override {
1740 activate_count_ = 0;
1742 scoped_ptr<DelegatedFrameData> frame =
1743 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1744 AddTextureQuad(frame.get(), 999);
1745 AddTransferableResource(frame.get(), 999);
1746 SetFrameData(frame.Pass());
1748 PostSetNeedsCommitToMainThread();
1751 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1752 base::AutoLock lock(activate_count_lock_);
1753 ++activate_count_;
1756 void DidCommit() override {
1757 // The first frame doesn't cause anything to be returned so it does not
1758 // need to wait for activation.
1759 if (layer_tree_host()->source_frame_number() > 1) {
1760 base::AutoLock lock(activate_count_lock_);
1761 // The activate happened before commit is done on the main side.
1762 EXPECT_EQ(activate_count_, layer_tree_host()->source_frame_number());
1765 switch (layer_tree_host()->source_frame_number()) {
1766 case 1: {
1767 // The first frame has been committed and will activate. Set a new
1768 // frame, and expect the next commit to finish *after* it is activated.
1769 scoped_ptr<DelegatedFrameData> frame =
1770 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1771 AddTextureQuad(frame.get(), 555);
1772 AddTransferableResource(frame.get(), 555);
1773 SetFrameData(frame.Pass());
1774 break;
1776 case 2:
1777 // The second frame has been activated. Remove the layer from
1778 // the tree to cause another commit/activation. The commit should
1779 // finish *after* the layer is removed from the active tree.
1780 delegated_->RemoveFromParent();
1781 break;
1782 case 3:
1783 // Finish the test by releasing resources on the next frame.
1784 scoped_ptr<DelegatedFrameData> frame =
1785 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1786 SetFrameData(frame.Pass());
1787 break;
1791 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1792 // The activate didn't happen before commit is done on the impl side (but it
1793 // should happen before the main thread is done).
1794 EXPECT_EQ(activate_count_, host_impl->sync_tree()->source_frame_number());
1797 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1798 ReturnUnusedResourcesFromParent(host_impl);
1801 void UnusedResourcesAreAvailable() override {
1802 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::
1803 UnusedResourcesAreAvailable();
1804 ReturnedResourceArray resources;
1805 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1806 EXPECT_TRUE(TestAndResetAvailable());
1807 returned_resource_count_ += resources.size();
1808 if (returned_resource_count_ == 2)
1809 EndTest();
1812 base::Lock activate_count_lock_;
1813 int activate_count_;
1814 size_t returned_resource_count_;
1817 SINGLE_AND_MULTI_THREAD_TEST_F(
1818 DelegatedFrameIsActivatedDuringCommit);
1820 class LayerTreeHostDelegatedTestTwoImplLayers
1821 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1822 public:
1823 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1825 void DidCommitAndDrawFrame() override {
1826 scoped_ptr<DelegatedFrameData> frame;
1827 ReturnedResourceArray resources;
1829 int next_source_frame_number = layer_tree_host()->source_frame_number();
1830 switch (next_source_frame_number) {
1831 case 1:
1832 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1833 AddTextureQuad(frame.get(), 999);
1834 AddTransferableResource(frame.get(), 999);
1835 AddTextureQuad(frame.get(), 555);
1836 AddTransferableResource(frame.get(), 555);
1837 SetFrameData(frame.Pass());
1838 break;
1839 case 2:
1840 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1841 EXPECT_EQ(0u, resources.size());
1842 EXPECT_FALSE(TestAndResetAvailable());
1844 // Remove the delegated layer and replace it with a new one. Use the
1845 // same frame and resources for it.
1846 delegated_->RemoveFromParent();
1847 delegated_ = CreateDelegatedLayer(frame_provider_.get());
1848 break;
1849 case 3:
1850 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1851 EXPECT_EQ(0u, resources.size());
1852 EXPECT_FALSE(TestAndResetAvailable());
1854 // Use a frame with no resources in it.
1855 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1856 SetFrameData(frame.Pass());
1857 break;
1858 case 4:
1859 // We gave one frame to the frame provider, so we should get one
1860 // ref back for each resource.
1861 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1863 unsigned expected[] = {555, 999};
1864 EXPECT_RESOURCES(expected, resources);
1865 EXPECT_TRUE(TestAndResetAvailable());
1867 EndTest();
1868 break;
1872 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1873 ReturnUnusedResourcesFromParent(host_impl);
1877 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoImplLayers);
1879 class LayerTreeHostDelegatedTestTwoImplLayersTwoFrames
1880 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1881 public:
1882 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1884 void DidCommitAndDrawFrame() override {
1885 scoped_ptr<DelegatedFrameData> frame;
1886 ReturnedResourceArray resources;
1888 int next_source_frame_number = layer_tree_host()->source_frame_number();
1889 switch (next_source_frame_number) {
1890 case 1:
1891 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1892 AddTextureQuad(frame.get(), 999);
1893 AddTransferableResource(frame.get(), 999);
1894 AddTextureQuad(frame.get(), 555);
1895 AddTransferableResource(frame.get(), 555);
1896 SetFrameData(frame.Pass());
1897 break;
1898 case 2:
1899 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1900 EXPECT_EQ(0u, resources.size());
1901 EXPECT_FALSE(TestAndResetAvailable());
1903 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1904 AddTextureQuad(frame.get(), 999);
1905 AddTransferableResource(frame.get(), 999);
1906 AddTextureQuad(frame.get(), 555);
1907 AddTransferableResource(frame.get(), 555);
1909 // Remove the delegated layer and replace it with a new one. Make a new
1910 // frame but with the same resources for it.
1911 delegated_->RemoveFromParent();
1912 delegated_ = NULL;
1914 frame_provider_->SetFrameData(frame.Pass());
1915 delegated_ = CreateDelegatedLayer(frame_provider_.get());
1916 break;
1917 case 3:
1918 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1919 EXPECT_EQ(0u, resources.size());
1920 EXPECT_FALSE(TestAndResetAvailable());
1922 // Use a frame with no resources in it.
1923 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1924 SetFrameData(frame.Pass());
1925 break;
1926 case 4:
1927 // We gave two frames to the frame provider, so we should get two
1928 // refs back for each resource.
1929 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1931 unsigned expected[] = {555, 555, 999, 999};
1932 EXPECT_RESOURCES(expected, resources);
1933 EXPECT_TRUE(TestAndResetAvailable());
1935 EndTest();
1936 break;
1940 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1941 ReturnUnusedResourcesFromParent(host_impl);
1945 SINGLE_AND_MULTI_THREAD_TEST_F(
1946 LayerTreeHostDelegatedTestTwoImplLayersTwoFrames);
1948 class LayerTreeHostDelegatedTestTwoLayers
1949 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1950 public:
1951 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1953 void DidCommitAndDrawFrame() override {
1954 scoped_ptr<DelegatedFrameData> frame;
1955 ReturnedResourceArray resources;
1957 int next_source_frame_number = layer_tree_host()->source_frame_number();
1958 switch (next_source_frame_number) {
1959 case 1:
1960 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1961 AddTextureQuad(frame.get(), 999);
1962 AddTransferableResource(frame.get(), 999);
1963 AddTextureQuad(frame.get(), 555);
1964 AddTransferableResource(frame.get(), 555);
1966 // Create a DelegatedRendererLayer using the frame.
1967 SetFrameData(frame.Pass());
1968 break;
1969 case 2:
1970 // Create a second DelegatedRendererLayer using the same frame provider.
1971 delegated_thief_ = CreateDelegatedLayer(frame_provider_.get());
1972 root_->AddChild(delegated_thief_);
1974 // And drop our ref on the frame provider so only the layers keep it
1975 // alive.
1976 frame_provider_ = NULL;
1977 break;
1978 case 3:
1979 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1980 EXPECT_EQ(0u, resources.size());
1981 EXPECT_FALSE(TestAndResetAvailable());
1983 // Remove one delegated layer from the tree. No resources should be
1984 // returned yet.
1985 delegated_->RemoveFromParent();
1986 break;
1987 case 4:
1988 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1989 EXPECT_EQ(0u, resources.size());
1990 EXPECT_FALSE(TestAndResetAvailable());
1992 // Put the first layer back, and remove the other layer and destroy it.
1993 // No resources should be returned yet.
1994 root_->AddChild(delegated_);
1995 delegated_thief_->RemoveFromParent();
1996 delegated_thief_ = NULL;
1997 break;
1998 case 5:
1999 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2000 EXPECT_EQ(0u, resources.size());
2001 EXPECT_FALSE(TestAndResetAvailable());
2003 // Remove the first layer from the tree again. The resources are still
2004 // held by the main thread layer.
2005 delegated_->RemoveFromParent();
2006 break;
2007 case 6:
2008 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2009 EXPECT_EQ(0u, resources.size());
2010 EXPECT_FALSE(TestAndResetAvailable());
2012 // Destroy the layer and the resources should be returned immediately.
2013 delegated_ = NULL;
2015 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2017 unsigned expected[] = {555, 999};
2018 EXPECT_RESOURCES(expected, resources);
2019 EXPECT_TRUE(TestAndResetAvailable());
2021 EndTest();
2022 break;
2026 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2027 ReturnUnusedResourcesFromParent(host_impl);
2030 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2033 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoLayers);
2035 class LayerTreeHostDelegatedTestRemoveAndAddToTree
2036 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2037 public:
2038 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2040 void DidCommitAndDrawFrame() override {
2041 scoped_ptr<DelegatedFrameData> frame;
2042 ReturnedResourceArray resources;
2044 int next_source_frame_number = layer_tree_host()->source_frame_number();
2045 switch (next_source_frame_number) {
2046 case 1:
2047 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2048 AddTextureQuad(frame.get(), 999);
2049 AddTransferableResource(frame.get(), 999);
2050 AddTextureQuad(frame.get(), 555);
2051 AddTransferableResource(frame.get(), 555);
2053 // Create a DelegatedRendererLayer using the frame.
2054 SetFrameData(frame.Pass());
2055 break;
2056 case 2:
2057 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2058 EXPECT_EQ(0u, resources.size());
2059 EXPECT_FALSE(TestAndResetAvailable());
2061 // Remove the layer from the tree. The resources should not be returned
2062 // since they are still on the main thread layer.
2063 delegated_->RemoveFromParent();
2064 break;
2065 case 3:
2066 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2067 EXPECT_EQ(0u, resources.size());
2068 EXPECT_FALSE(TestAndResetAvailable());
2070 // Add the layer back to the tree.
2071 layer_tree_host()->root_layer()->AddChild(delegated_);
2072 break;
2073 case 4:
2074 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2075 EXPECT_EQ(0u, resources.size());
2076 EXPECT_FALSE(TestAndResetAvailable());
2078 // Set a new frame. Resources should be returned.
2079 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2080 AddTextureQuad(frame.get(), 888);
2081 AddTransferableResource(frame.get(), 888);
2082 AddTextureQuad(frame.get(), 777);
2083 AddTransferableResource(frame.get(), 777);
2084 SetFrameData(frame.Pass());
2085 break;
2086 case 5:
2087 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2089 unsigned expected[] = {555, 999};
2090 EXPECT_RESOURCES(expected, resources);
2091 EXPECT_TRUE(TestAndResetAvailable());
2094 // Destroy the layer.
2095 delegated_->RemoveFromParent();
2096 delegated_ = NULL;
2097 break;
2098 case 6:
2099 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2100 EXPECT_EQ(0u, resources.size());
2101 EXPECT_FALSE(TestAndResetAvailable());
2103 // Destroy the frame provider. Resources should be returned.
2104 frame_provider_ = NULL;
2106 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2108 unsigned expected[] = {777, 888};
2109 EXPECT_RESOURCES(expected, resources);
2110 EXPECT_TRUE(TestAndResetAvailable());
2112 EndTest();
2113 break;
2117 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2118 ReturnUnusedResourcesFromParent(host_impl);
2121 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2124 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemoveAndAddToTree);
2126 class LayerTreeHostDelegatedTestRemoveAndChangeResources
2127 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2128 public:
2129 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2131 void DidCommitAndDrawFrame() override {
2132 scoped_ptr<DelegatedFrameData> frame;
2133 ReturnedResourceArray resources;
2135 int next_source_frame_number = layer_tree_host()->source_frame_number();
2136 switch (next_source_frame_number) {
2137 case 1:
2138 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2139 AddTextureQuad(frame.get(), 999);
2140 AddTransferableResource(frame.get(), 999);
2141 AddTextureQuad(frame.get(), 555);
2142 AddTransferableResource(frame.get(), 555);
2144 // Create a DelegatedRendererLayer using the frame.
2145 SetFrameData(frame.Pass());
2146 break;
2147 case 2:
2148 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2149 EXPECT_EQ(0u, resources.size());
2150 EXPECT_FALSE(TestAndResetAvailable());
2152 // Remove the layer from the tree. The resources should not be returned
2153 // since they are still on the main thread layer.
2154 delegated_->RemoveFromParent();
2155 break;
2156 case 3:
2157 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2158 EXPECT_EQ(0u, resources.size());
2159 EXPECT_FALSE(TestAndResetAvailable());
2161 // Set a new frame. Resources should be returned immediately.
2162 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2163 AddTextureQuad(frame.get(), 888);
2164 AddTransferableResource(frame.get(), 888);
2165 AddTextureQuad(frame.get(), 777);
2166 AddTransferableResource(frame.get(), 777);
2167 SetFrameData(frame.Pass());
2169 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2171 unsigned expected[] = {555, 999};
2172 EXPECT_RESOURCES(expected, resources);
2173 EXPECT_TRUE(TestAndResetAvailable());
2174 resources.clear();
2177 // Destroy the frame provider.
2178 frame_provider_ = NULL;
2180 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2181 EXPECT_EQ(0u, resources.size());
2182 EXPECT_FALSE(TestAndResetAvailable());
2184 // Destroy the layer. Resources should be returned.
2185 delegated_ = NULL;
2187 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2189 unsigned expected[] = {777, 888};
2190 EXPECT_RESOURCES(expected, resources);
2191 EXPECT_TRUE(TestAndResetAvailable());
2193 EndTest();
2194 break;
2198 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2199 ReturnUnusedResourcesFromParent(host_impl);
2202 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2205 SINGLE_AND_MULTI_THREAD_TEST_F(
2206 LayerTreeHostDelegatedTestRemoveAndChangeResources);
2208 class LayerTreeHostDelegatedTestActiveFrameIsValid
2209 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2210 public:
2211 LayerTreeHostDelegatedTestActiveFrameIsValid()
2212 : drew_with_pending_tree_(false) {}
2214 void DidCommitAndDrawFrame() override {
2215 scoped_ptr<DelegatedFrameData> frame;
2216 switch (layer_tree_host()->source_frame_number()) {
2217 case 1:
2218 // This frame goes to the active tree.
2219 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2220 AddTextureQuad(frame.get(), 999);
2221 AddTransferableResource(frame.get(), 999);
2222 SetFrameData(frame.Pass());
2223 break;
2224 case 2:
2225 // This frame stops in the pending tree while we redraw the active tree.
2226 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2227 AddTextureQuad(frame.get(), 555);
2228 AddTransferableResource(frame.get(), 555);
2229 SetFrameData(frame.Pass());
2230 break;
2234 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2235 if (host_impl->active_tree()->source_frame_number() < 1)
2236 return;
2238 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
2239 FakeDelegatedRendererLayerImpl* delegated_impl =
2240 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
2241 const ResourceProvider::ResourceIdMap& map =
2242 host_impl->resource_provider()->GetChildToParentMap(
2243 delegated_impl->ChildId());
2245 switch (host_impl->active_tree()->source_frame_number()) {
2246 case 1:
2247 if (!host_impl->pending_tree()) {
2248 // Frame 2 is blocked from activating until another draw happens with
2249 // Frame 1. This ensures we draw a different active frame from
2250 // what's in the pending tree.
2251 host_impl->BlockNotifyReadyToActivateForTesting(true);
2252 host_impl->SetNeedsRedrawRect(gfx::Rect(1, 1));
2253 break;
2256 // The resources in the active tree should be valid.
2257 EXPECT_EQ(1u, map.count(999));
2259 host_impl->BlockNotifyReadyToActivateForTesting(false);
2260 drew_with_pending_tree_ = true;
2261 break;
2262 case 2:
2263 EXPECT_TRUE(drew_with_pending_tree_);
2265 // The resources in the active tree should be valid.
2266 EXPECT_EQ(1u, map.count(555));
2267 EndTest();
2268 break;
2272 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2273 // Return everything so that we can reliably delete resources that lose
2274 // their references. This would happen if the tab was backgrounded or
2275 // the parent decided to drop all resources for some reason.
2276 ReturnAllResourcesFromParent(host_impl);
2279 bool drew_with_pending_tree_;
2282 // This test blocks activation which is not supported for single thread mode.
2283 MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostDelegatedTestActiveFrameIsValid);
2285 } // namespace
2286 } // namespace cc