Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_delegated.cc
bloba6562ae0bb3b041368fa4adad12d0f77c5b0f6aa
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(RenderPass::Id(1, 1),
84 root_output_rect,
85 root_damage_rect,
86 gfx::Transform());
87 frame->render_pass_list.push_back(root_pass.Pass());
88 return frame.Pass();
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(RenderPass::Id(1, 1),
98 root_output_rect,
99 root_damage_rect,
100 gfx::Transform());
102 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
104 gfx::Rect rect = root_output_rect;
105 gfx::Rect opaque_rect = root_output_rect;
106 gfx::Rect visible_rect = root_output_rect;
107 // An invalid resource id! The resource isn't part of the frame.
108 unsigned resource_id = 5;
109 bool premultiplied_alpha = false;
110 gfx::PointF uv_top_left = gfx::PointF(0.f, 0.f);
111 gfx::PointF uv_bottom_right = gfx::PointF(1.f, 1.f);
112 SkColor background_color = 0;
113 float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
114 bool flipped = false;
116 scoped_ptr<TextureDrawQuad> invalid_draw_quad = TextureDrawQuad::Create();
117 invalid_draw_quad->SetNew(shared_quad_state.get(),
118 rect,
119 opaque_rect,
120 visible_rect,
121 resource_id,
122 premultiplied_alpha,
123 uv_top_left,
124 uv_bottom_right,
125 background_color,
126 vertex_opacity,
127 flipped);
128 root_pass->quad_list.push_back(invalid_draw_quad.PassAs<DrawQuad>());
130 root_pass->shared_quad_state_list.push_back(shared_quad_state.Pass());
132 frame->render_pass_list.push_back(root_pass.Pass());
133 return frame.Pass();
136 void AddTransferableResource(DelegatedFrameData* frame,
137 ResourceProvider::ResourceId resource_id) {
138 TransferableResource resource;
139 resource.id = resource_id;
140 resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
141 GLbyte arbitrary_mailbox[GL_MAILBOX_SIZE_CHROMIUM] = {
142 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
143 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
144 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4};
145 resource.mailbox_holder.mailbox.SetName(arbitrary_mailbox);
146 frame->resource_list.push_back(resource);
149 void AddTextureQuad(DelegatedFrameData* frame,
150 ResourceProvider::ResourceId resource_id) {
151 scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create();
152 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
153 float vertex_opacity[4] = { 1.f, 1.f, 1.f, 1.f };
154 quad->SetNew(sqs.get(),
155 gfx::Rect(0, 0, 10, 10),
156 gfx::Rect(0, 0, 10, 10),
157 gfx::Rect(0, 0, 10, 10),
158 resource_id,
159 false,
160 gfx::PointF(0.f, 0.f),
161 gfx::PointF(1.f, 1.f),
162 SK_ColorTRANSPARENT,
163 vertex_opacity,
164 false);
165 frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass());
166 frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>());
169 void AddRenderPass(DelegatedFrameData* frame,
170 RenderPass::Id id,
171 const gfx::Rect& output_rect,
172 const gfx::Rect& damage_rect,
173 const FilterOperations& filters,
174 const FilterOperations& background_filters) {
175 for (size_t i = 0; i < frame->render_pass_list.size(); ++i)
176 DCHECK(id != frame->render_pass_list[i]->id);
178 scoped_ptr<RenderPass> pass(RenderPass::Create());
179 pass->SetNew(id,
180 output_rect,
181 damage_rect,
182 gfx::Transform());
183 frame->render_pass_list.push_back(pass.Pass());
185 scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create();
186 scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create();
188 quad->SetNew(sqs.get(),
189 output_rect,
190 output_rect,
192 false, // is_replica
193 0, // mask_resource_id
194 damage_rect,
195 gfx::Rect(0, 0, 1, 1), // mask_uv_rect
196 filters,
197 background_filters);
198 frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass());
199 frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>());
202 static ResourceProvider::ResourceId AppendResourceId(
203 std::vector<ResourceProvider::ResourceId>* resources_in_last_sent_frame,
204 ResourceProvider::ResourceId resource_id) {
205 resources_in_last_sent_frame->push_back(resource_id);
206 return resource_id;
209 void ReturnUnusedResourcesFromParent(LayerTreeHostImpl* host_impl) {
210 DelegatedFrameData* delegated_frame_data =
211 output_surface()->last_sent_frame().delegated_frame_data.get();
212 if (!delegated_frame_data)
213 return;
215 std::vector<ResourceProvider::ResourceId> resources_in_last_sent_frame;
216 for (size_t i = 0; i < delegated_frame_data->resource_list.size(); ++i) {
217 resources_in_last_sent_frame.push_back(
218 delegated_frame_data->resource_list[i].id);
221 std::vector<ResourceProvider::ResourceId> resources_to_return;
223 const TransferableResourceArray& resources_held_by_parent =
224 output_surface()->resources_held_by_parent();
225 for (size_t i = 0; i < resources_held_by_parent.size(); ++i) {
226 ResourceProvider::ResourceId resource_in_parent =
227 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);
246 class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
247 : public LayerTreeHostDelegatedTest,
248 public DelegatedFrameResourceCollectionClient {
249 public:
250 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer()
251 : resource_collection_(new DelegatedFrameResourceCollection),
252 available_(false) {
253 resource_collection_->SetClient(this);
256 virtual void SetupTree() OVERRIDE {
257 root_ = Layer::Create();
258 root_->SetAnchorPoint(gfx::PointF());
259 root_->SetBounds(gfx::Size(15, 15));
261 layer_tree_host()->SetRootLayer(root_);
262 LayerTreeHostDelegatedTest::SetupTree();
265 virtual void BeginTest() OVERRIDE {
266 resource_collection_->SetClient(this);
267 PostSetNeedsCommitToMainThread();
270 void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data) {
271 RenderPass* root_pass = frame_data->render_pass_list.back();
272 gfx::Size frame_size = root_pass->output_rect.size();
274 if (frame_provider_.get() && frame_size == frame_provider_->frame_size()) {
275 frame_provider_->SetFrameData(frame_data.Pass());
276 return;
279 if (delegated_.get()) {
280 delegated_->RemoveFromParent();
281 delegated_ = NULL;
282 frame_provider_ = NULL;
285 frame_provider_ = new DelegatedFrameProvider(resource_collection_.get(),
286 frame_data.Pass());
288 delegated_ = CreateDelegatedLayer(frame_provider_.get());
291 scoped_refptr<DelegatedRendererLayer> CreateDelegatedLayer(
292 DelegatedFrameProvider* frame_provider) {
293 scoped_refptr<DelegatedRendererLayer> delegated =
294 FakeDelegatedRendererLayer::Create(frame_provider);
295 delegated->SetAnchorPoint(gfx::PointF());
296 delegated->SetBounds(gfx::Size(10, 10));
297 delegated->SetIsDrawable(true);
299 root_->AddChild(delegated);
300 return delegated;
303 virtual void AfterTest() OVERRIDE { resource_collection_->SetClient(NULL); }
305 // DelegatedFrameProviderClient implementation.
306 virtual void UnusedResourcesAreAvailable() OVERRIDE { available_ = true; }
308 bool TestAndResetAvailable() {
309 bool available = available_;
310 available_ = false;
311 return available;
314 protected:
315 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
316 scoped_refptr<DelegatedFrameProvider> frame_provider_;
317 scoped_refptr<Layer> root_;
318 scoped_refptr<DelegatedRendererLayer> delegated_;
319 bool available_;
322 class LayerTreeHostDelegatedTestCreateChildId
323 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
324 public:
325 LayerTreeHostDelegatedTestCreateChildId()
326 : LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(),
327 num_activates_(0),
328 did_reset_child_id_(false) {}
330 virtual void DidCommit() OVERRIDE {
331 if (TestEnded())
332 return;
333 SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
336 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
337 if (host_impl->active_tree()->source_frame_number() < 1)
338 return;
340 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
341 FakeDelegatedRendererLayerImpl* delegated_impl =
342 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
344 TestContextProvider* context_provider = static_cast<TestContextProvider*>(
345 host_impl->output_surface()->context_provider().get());
347 ++num_activates_;
348 switch (num_activates_) {
349 case 2:
350 EXPECT_TRUE(delegated_impl->ChildId());
351 EXPECT_FALSE(did_reset_child_id_);
353 context_provider->ContextGL()->LoseContextCHROMIUM(
354 GL_GUILTY_CONTEXT_RESET_ARB,
355 GL_INNOCENT_CONTEXT_RESET_ARB);
356 context_provider->ContextGL()->Flush();
357 break;
358 case 3:
359 EXPECT_TRUE(delegated_impl->ChildId());
360 EXPECT_TRUE(did_reset_child_id_);
361 EndTest();
362 break;
366 virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
367 bool success) OVERRIDE {
368 EXPECT_TRUE(success);
370 if (num_activates_ < 2)
371 return;
373 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
374 FakeDelegatedRendererLayerImpl* delegated_impl =
375 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
377 EXPECT_EQ(2, num_activates_);
378 EXPECT_FALSE(delegated_impl->ChildId());
379 did_reset_child_id_ = true;
382 protected:
383 int num_activates_;
384 bool did_reset_child_id_;
387 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCreateChildId);
389 // Test that we can gracefully handle invalid frames after the context was lost.
390 // For example, we might be trying to use the previous frame in that case and
391 // have to make sure we don't crash because our resource accounting goes wrong.
392 class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost
393 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
394 public:
395 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost()
396 : num_activates_(0), num_output_surfaces_initialized_(0) {}
398 virtual void DidCommit() OVERRIDE {
399 if (TestEnded())
400 return;
401 scoped_ptr<DelegatedFrameData> frame1 =
402 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
403 AddTextureQuad(frame1.get(), 999);
404 AddTransferableResource(frame1.get(), 999);
405 SetFrameData(frame1.Pass());
408 virtual void DidInitializeOutputSurface() OVERRIDE {
409 if (!num_output_surfaces_initialized_++)
410 return;
412 scoped_refptr<DelegatedRendererLayer> old_delegated = delegated_;
413 SetFrameData(
414 CreateInvalidFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
415 // Make sure we end up using the same layer, or we won't test the right
416 // thing, which is to make sure we can handle an invalid frame when using
417 // a stale layer from before the context was lost.
418 DCHECK(delegated_.get() == old_delegated.get());
421 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
422 if (host_impl->active_tree()->source_frame_number() < 1)
423 return;
425 TestContextProvider* context_provider = static_cast<TestContextProvider*>(
426 host_impl->output_surface()->context_provider().get());
428 ++num_activates_;
429 switch (num_activates_) {
430 case 2:
431 context_provider->ContextGL()->LoseContextCHROMIUM(
432 GL_GUILTY_CONTEXT_RESET_ARB,
433 GL_INNOCENT_CONTEXT_RESET_ARB);
434 break;
435 case 3:
436 EndTest();
437 break;
441 virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
442 bool success) OVERRIDE {
443 EXPECT_TRUE(success);
445 if (num_activates_ < 2)
446 return;
448 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
449 FakeDelegatedRendererLayerImpl* delegated_impl =
450 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
452 EXPECT_EQ(2, num_activates_);
453 // Resources should have gotten cleared after the context was lost.
454 EXPECT_EQ(0U, delegated_impl->Resources().size());
457 virtual void AfterTest() OVERRIDE {
458 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::AfterTest();
459 EXPECT_EQ(2, num_output_surfaces_initialized_);
462 protected:
463 int num_activates_;
464 int num_output_surfaces_initialized_;
467 SINGLE_AND_MULTI_THREAD_TEST_F(
468 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost);
470 class LayerTreeHostDelegatedTestLayerUsesFrameDamage
471 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
472 public:
473 LayerTreeHostDelegatedTestLayerUsesFrameDamage()
474 : LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(),
475 first_draw_for_source_frame_(true) {}
477 virtual void DidCommit() OVERRIDE {
478 int next_source_frame_number = layer_tree_host()->source_frame_number();
479 switch (next_source_frame_number) {
480 case 1:
481 // The first time the layer gets a frame the whole layer should be
482 // damaged.
483 SetFrameData(
484 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
485 break;
486 case 2:
487 // A different frame size will damage the whole layer.
488 SetFrameData(
489 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(0, 0, 0, 0)));
490 break;
491 case 3:
492 // Should create a total amount of gfx::Rect(2, 2, 10, 6) damage.
493 // The frame size is 20x20 while the layer is 10x10, so this should
494 // produce a gfx::Rect(1, 1, 5, 3) damage rect.
495 SetFrameData(
496 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(2, 2, 5, 5)));
497 SetFrameData(
498 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(7, 2, 5, 6)));
499 break;
500 case 4:
501 // Should create zero damage.
502 layer_tree_host()->SetNeedsCommit();
503 break;
504 case 5:
505 // Should damage the full viewport.
506 delegated_->SetBounds(gfx::Size(2, 2));
507 break;
508 case 6:
509 // Should create zero damage.
510 layer_tree_host()->SetNeedsCommit();
511 break;
512 case 7:
513 // Should damage the full layer, tho the frame size is not changing.
514 delegated_->SetBounds(gfx::Size(6, 6));
515 SetFrameData(
516 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(1, 1, 2, 2)));
517 break;
518 case 8:
519 // Should create zero damage.
520 layer_tree_host()->SetNeedsCommit();
521 break;
522 case 9:
523 // Should damage the full layer.
524 delegated_->SetDisplaySize(gfx::Size(10, 10));
525 break;
526 case 10:
527 // Should create zero damage.
528 layer_tree_host()->SetNeedsCommit();
529 break;
530 case 11:
531 // Changing the frame size damages the full layer.
532 SetFrameData(
533 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1)));
534 break;
535 case 12:
536 // An invalid frame isn't used, so it should not cause damage.
537 SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 5, 5),
538 gfx::Rect(4, 4, 1, 1)));
539 break;
540 case 13:
541 // Should create gfx::Rect(1, 1, 2, 2) of damage. The frame size is
542 // 5x5 and the display size is now set to 10x10, so this should result
543 // in a gfx::Rect(2, 2, 4, 4) damage rect.
544 SetFrameData(
545 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
546 break;
547 case 14:
548 // Should create zero damage.
549 layer_tree_host()->SetNeedsCommit();
550 break;
551 case 15:
552 // Moving the layer out of the tree and back in will damage the whole
553 // impl layer.
554 delegated_->RemoveFromParent();
555 layer_tree_host()->root_layer()->AddChild(delegated_);
556 break;
557 case 16:
558 // Make a larger frame with lots of damage. Then a frame smaller than
559 // the first frame's damage. The entire layer should be damaged, but
560 // nothing more.
561 SetFrameData(
562 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
563 SetFrameData(
564 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
565 break;
566 case 17:
567 // Make a frame with lots of damage. Then replace it with a frame with
568 // no damage. The entire layer should be damaged, but nothing more.
569 SetFrameData(
570 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
571 SetFrameData(
572 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 0, 0)));
573 break;
574 case 18:
575 // Make another layer that uses the same frame provider. The new layer
576 // should be damaged.
577 delegated_copy_ = CreateDelegatedLayer(frame_provider_);
578 delegated_copy_->SetPosition(gfx::Point(5, 0));
580 // Also set a new frame.
581 SetFrameData(
582 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(4, 0, 1, 1)));
583 break;
584 case 19:
585 // Set another new frame, both layers should be damaged in the same
586 // ways.
587 SetFrameData(
588 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(3, 3, 1, 1)));
590 first_draw_for_source_frame_ = true;
593 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
594 LayerTreeHostImpl* host_impl,
595 LayerTreeHostImpl::FrameData* frame,
596 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
597 EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
599 if (!first_draw_for_source_frame_)
600 return draw_result;
602 gfx::Rect damage_rect;
603 if (!frame->has_no_damage) {
604 damage_rect = frame->render_passes.back()->damage_rect;
605 } else {
606 // If there is no damage, then we have no render passes to send.
607 EXPECT_TRUE(frame->render_passes.empty());
610 switch (host_impl->active_tree()->source_frame_number()) {
611 case 0:
612 // First frame is damaged because of viewport resize.
613 EXPECT_EQ(gfx::Rect(15, 15).ToString(), damage_rect.ToString());
614 break;
615 case 1:
616 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
617 break;
618 case 2:
619 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
620 break;
621 case 3:
622 EXPECT_EQ(gfx::Rect(1, 1, 5, 3).ToString(), damage_rect.ToString());
623 break;
624 case 4:
625 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
626 break;
627 case 5:
628 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
629 break;
630 case 6:
631 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
632 break;
633 case 7:
634 EXPECT_EQ(gfx::Rect(6, 6).ToString(), damage_rect.ToString());
635 break;
636 case 8:
637 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
638 break;
639 case 9:
640 EXPECT_EQ(gfx::Rect(6, 6).ToString(), damage_rect.ToString());
641 break;
642 case 10:
643 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
644 break;
645 case 11:
646 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
647 break;
648 case 12:
649 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
650 break;
651 case 13:
652 EXPECT_EQ(gfx::Rect(2, 2, 4, 4).ToString(), damage_rect.ToString());
653 break;
654 case 14:
655 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString());
656 break;
657 case 15:
658 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
659 break;
660 case 16:
661 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
662 break;
663 case 17:
664 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString());
665 break;
666 case 18:
667 EXPECT_EQ(gfx::UnionRects(gfx::Rect(5, 0, 10, 10),
668 gfx::Rect(4, 0, 1, 1)).ToString(),
669 damage_rect.ToString());
670 break;
671 case 19:
672 EXPECT_EQ(gfx::Rect(3, 3, 6, 1).ToString(), damage_rect.ToString());
673 EndTest();
674 break;
677 return draw_result;
680 protected:
681 scoped_refptr<DelegatedRendererLayer> delegated_copy_;
682 bool first_draw_for_source_frame_;
685 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestLayerUsesFrameDamage);
687 class LayerTreeHostDelegatedTestMergeResources
688 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
689 public:
690 virtual void BeginTest() OVERRIDE {
691 // Push two frames to the delegated renderer layer with no commit between.
693 // The first frame has resource 999.
694 scoped_ptr<DelegatedFrameData> frame1 =
695 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
696 AddTextureQuad(frame1.get(), 999);
697 AddTransferableResource(frame1.get(), 999);
698 SetFrameData(frame1.Pass());
700 // The second frame uses resource 999 still, but also adds 555.
701 scoped_ptr<DelegatedFrameData> frame2 =
702 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
703 AddTextureQuad(frame2.get(), 999);
704 AddTransferableResource(frame2.get(), 999);
705 AddTextureQuad(frame2.get(), 555);
706 AddTransferableResource(frame2.get(), 555);
707 SetFrameData(frame2.Pass());
709 // The resource 999 from frame1 is returned since it is still on the main
710 // thread.
711 ReturnedResourceArray returned_resources;
712 resource_collection_->TakeUnusedResourcesForChildCompositor(
713 &returned_resources);
715 unsigned expected[] = {999};
716 EXPECT_RESOURCES(expected, returned_resources);
717 EXPECT_TRUE(TestAndResetAvailable());
720 PostSetNeedsCommitToMainThread();
723 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
724 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
725 FakeDelegatedRendererLayerImpl* delegated_impl =
726 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
728 const ResourceProvider::ResourceIdMap& map =
729 host_impl->resource_provider()->GetChildToParentMap(
730 delegated_impl->ChildId());
732 // Both frames' resources should be in the parent's resource provider.
733 EXPECT_EQ(2u, map.size());
734 EXPECT_EQ(1u, map.count(999));
735 EXPECT_EQ(1u, map.count(555));
737 EXPECT_EQ(2u, delegated_impl->Resources().size());
738 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
739 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
741 EndTest();
745 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestMergeResources);
747 class LayerTreeHostDelegatedTestRemapResourcesInQuads
748 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
749 public:
750 virtual void BeginTest() OVERRIDE {
751 // Generate a frame with two resources in it.
752 scoped_ptr<DelegatedFrameData> frame =
753 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
754 AddTextureQuad(frame.get(), 999);
755 AddTransferableResource(frame.get(), 999);
756 AddTextureQuad(frame.get(), 555);
757 AddTransferableResource(frame.get(), 555);
758 SetFrameData(frame.Pass());
760 PostSetNeedsCommitToMainThread();
763 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
764 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
765 FakeDelegatedRendererLayerImpl* delegated_impl =
766 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
768 const ResourceProvider::ResourceIdMap& map =
769 host_impl->resource_provider()->GetChildToParentMap(
770 delegated_impl->ChildId());
772 // The frame's resource should be in the parent's resource provider.
773 EXPECT_EQ(2u, map.size());
774 EXPECT_EQ(1u, map.count(999));
775 EXPECT_EQ(1u, map.count(555));
777 ResourceProvider::ResourceId parent_resource_id1 = map.find(999)->second;
778 EXPECT_NE(parent_resource_id1, 999u);
779 ResourceProvider::ResourceId parent_resource_id2 = map.find(555)->second;
780 EXPECT_NE(parent_resource_id2, 555u);
782 // The resources in the quads should be remapped to the parent's namespace.
783 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
784 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list[0]);
785 EXPECT_EQ(parent_resource_id1, quad1->resource_id);
786 const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
787 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list[1]);
788 EXPECT_EQ(parent_resource_id2, quad2->resource_id);
790 EndTest();
794 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemapResourcesInQuads);
796 class LayerTreeHostDelegatedTestReturnUnusedResources
797 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
798 public:
799 virtual void BeginTest() OVERRIDE {
800 PostSetNeedsCommitToMainThread();
803 virtual void DidCommitAndDrawFrame() OVERRIDE {
804 scoped_ptr<DelegatedFrameData> frame;
805 ReturnedResourceArray resources;
807 int next_source_frame_number = layer_tree_host()->source_frame_number();
808 switch (next_source_frame_number) {
809 case 1:
810 // Generate a frame with two resources in it.
811 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
812 AddTextureQuad(frame.get(), 999);
813 AddTransferableResource(frame.get(), 999);
814 AddTextureQuad(frame.get(), 555);
815 AddTransferableResource(frame.get(), 555);
816 SetFrameData(frame.Pass());
817 break;
818 case 2:
819 // All of the resources are in use.
820 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
821 EXPECT_EQ(0u, resources.size());
822 EXPECT_FALSE(TestAndResetAvailable());
824 // Keep using 999 but stop using 555.
825 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
826 AddTextureQuad(frame.get(), 999);
827 AddTransferableResource(frame.get(), 999);
828 AddTextureQuad(frame.get(), 444);
829 AddTransferableResource(frame.get(), 444);
830 SetFrameData(frame.Pass());
831 break;
832 case 3:
833 // 555 is no longer in use.
834 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
836 unsigned expected[] = {555};
837 EXPECT_RESOURCES(expected, resources);
838 EXPECT_TRUE(TestAndResetAvailable());
841 // Stop using any resources.
842 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
843 SetFrameData(frame.Pass());
844 break;
845 case 4:
846 // Postpone collecting resources for a frame. They should still be there
847 // the next frame.
848 layer_tree_host()->SetNeedsCommit();
849 return;
850 case 5:
851 // 444 and 999 are no longer in use. We sent two refs to 999, so we
852 // should get two back.
853 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
855 unsigned expected[] = {444, 999, 999};
856 EXPECT_RESOURCES(expected, resources);
857 EXPECT_TRUE(TestAndResetAvailable());
859 EndTest();
860 break;
863 // Resources are never immediately released.
864 ReturnedResourceArray empty_resources;
865 resource_collection_->TakeUnusedResourcesForChildCompositor(
866 &empty_resources);
867 EXPECT_EQ(0u, empty_resources.size());
868 EXPECT_FALSE(TestAndResetAvailable());
871 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
872 bool result) OVERRIDE {
873 ReturnUnusedResourcesFromParent(host_impl);
877 SINGLE_AND_MULTI_THREAD_TEST_F(
878 LayerTreeHostDelegatedTestReturnUnusedResources);
880 class LayerTreeHostDelegatedTestReusedResources
881 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
882 public:
883 virtual void BeginTest() OVERRIDE {
884 PostSetNeedsCommitToMainThread();
887 virtual void DidCommitAndDrawFrame() OVERRIDE {
888 scoped_ptr<DelegatedFrameData> frame;
889 ReturnedResourceArray resources;
891 int next_source_frame_number = layer_tree_host()->source_frame_number();
892 switch (next_source_frame_number) {
893 case 1:
894 // Generate a frame with some resources in it.
895 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
896 AddTextureQuad(frame.get(), 999);
897 AddTransferableResource(frame.get(), 999);
898 AddTextureQuad(frame.get(), 555);
899 AddTransferableResource(frame.get(), 555);
900 AddTextureQuad(frame.get(), 444);
901 AddTransferableResource(frame.get(), 444);
902 SetFrameData(frame.Pass());
903 break;
904 case 2:
905 // All of the resources are in use.
906 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
907 EXPECT_EQ(0u, resources.size());
908 EXPECT_FALSE(TestAndResetAvailable());
910 // Keep using 999 but stop using 555 and 444.
911 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
912 AddTextureQuad(frame.get(), 999);
913 AddTransferableResource(frame.get(), 999);
914 SetFrameData(frame.Pass());
916 // Resource are not immediately released.
917 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
918 EXPECT_EQ(0u, resources.size());
919 EXPECT_FALSE(TestAndResetAvailable());
921 // Now using 555 and 444 again, but not 999.
922 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
923 AddTextureQuad(frame.get(), 555);
924 AddTransferableResource(frame.get(), 555);
925 AddTextureQuad(frame.get(), 444);
926 AddTransferableResource(frame.get(), 444);
927 SetFrameData(frame.Pass());
928 break;
929 case 3:
930 // The 999 resource is the only unused one. Two references were sent, so
931 // two should be returned.
932 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
934 unsigned expected[] = {999, 999};
935 EXPECT_RESOURCES(expected, resources);
936 EXPECT_TRUE(TestAndResetAvailable());
938 EndTest();
939 break;
943 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
944 bool result) OVERRIDE {
945 ReturnUnusedResourcesFromParent(host_impl);
949 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources);
951 class LayerTreeHostDelegatedTestFrameBeforeAck
952 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
953 public:
954 virtual void BeginTest() OVERRIDE {
955 PostSetNeedsCommitToMainThread();
958 virtual void DidCommitAndDrawFrame() OVERRIDE {
959 scoped_ptr<DelegatedFrameData> frame;
960 ReturnedResourceArray resources;
962 int next_source_frame_number = layer_tree_host()->source_frame_number();
963 switch (next_source_frame_number) {
964 case 1:
965 // Generate a frame with some resources in it.
966 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
967 AddTextureQuad(frame.get(), 999);
968 AddTransferableResource(frame.get(), 999);
969 AddTextureQuad(frame.get(), 555);
970 AddTransferableResource(frame.get(), 555);
971 AddTextureQuad(frame.get(), 444);
972 AddTransferableResource(frame.get(), 444);
973 SetFrameData(frame.Pass());
974 break;
975 case 2:
976 // All of the resources are in use.
977 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
978 EXPECT_EQ(0u, resources.size());
979 EXPECT_FALSE(TestAndResetAvailable());
981 // Keep using 999 but stop using 555 and 444.
982 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
983 AddTextureQuad(frame.get(), 999);
984 AddTransferableResource(frame.get(), 999);
985 SetFrameData(frame.Pass());
987 // Resource are not immediately released.
988 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
989 EXPECT_EQ(0u, resources.size());
990 EXPECT_FALSE(TestAndResetAvailable());
992 // The parent compositor (this one) does a commit.
993 break;
994 case 3:
995 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
997 unsigned expected[] = {444, 555};
998 EXPECT_RESOURCES(expected, resources);
999 EXPECT_TRUE(TestAndResetAvailable());
1002 // The child compositor sends a frame referring to resources not in the
1003 // frame.
1004 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1005 AddTextureQuad(frame.get(), 999);
1006 AddTextureQuad(frame.get(), 555);
1007 AddTextureQuad(frame.get(), 444);
1008 SetFrameData(frame.Pass());
1009 break;
1013 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1014 if (host_impl->active_tree()->source_frame_number() != 3)
1015 return;
1017 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1018 FakeDelegatedRendererLayerImpl* delegated_impl =
1019 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1021 const ResourceProvider::ResourceIdMap& map =
1022 host_impl->resource_provider()->GetChildToParentMap(
1023 delegated_impl->ChildId());
1025 // The bad frame should be dropped. So we should only have one quad (the
1026 // one with resource 999) on the impl tree. And only 999 will be present
1027 // in the parent's resource provider.
1028 EXPECT_EQ(1u, map.size());
1029 EXPECT_EQ(1u, map.count(999));
1031 EXPECT_EQ(1u, delegated_impl->Resources().size());
1032 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1034 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1035 EXPECT_EQ(1u, pass->quad_list.size());
1036 const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast(
1037 pass->quad_list[0]);
1038 EXPECT_EQ(map.find(999)->second, quad->resource_id);
1040 EndTest();
1043 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1044 bool result) OVERRIDE {
1045 ReturnUnusedResourcesFromParent(host_impl);
1049 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck);
1051 class LayerTreeHostDelegatedTestFrameBeforeTakeResources
1052 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1053 public:
1054 virtual void BeginTest() OVERRIDE {
1055 PostSetNeedsCommitToMainThread();
1058 virtual void DidCommitAndDrawFrame() OVERRIDE {
1059 scoped_ptr<DelegatedFrameData> frame;
1060 ReturnedResourceArray resources;
1062 int next_source_frame_number = layer_tree_host()->source_frame_number();
1063 switch (next_source_frame_number) {
1064 case 1:
1065 // Generate a frame with some resources in it.
1066 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1067 AddTextureQuad(frame.get(), 999);
1068 AddTransferableResource(frame.get(), 999);
1069 AddTextureQuad(frame.get(), 555);
1070 AddTransferableResource(frame.get(), 555);
1071 AddTextureQuad(frame.get(), 444);
1072 AddTransferableResource(frame.get(), 444);
1073 SetFrameData(frame.Pass());
1074 break;
1075 case 2:
1076 // All of the resources are in use.
1077 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1078 EXPECT_EQ(0u, resources.size());
1079 EXPECT_FALSE(TestAndResetAvailable());
1081 // Keep using 999 but stop using 555 and 444.
1082 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1083 AddTextureQuad(frame.get(), 999);
1084 AddTransferableResource(frame.get(), 999);
1085 SetFrameData(frame.Pass());
1087 // Resource are not immediately released.
1088 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1089 EXPECT_EQ(0u, resources.size());
1090 EXPECT_FALSE(TestAndResetAvailable());
1092 // The parent compositor (this one) does a commit.
1093 break;
1094 case 3:
1095 // The child compositor sends a frame before taking resources back
1096 // from the previous commit. This frame makes use of the resources 555
1097 // and 444, which were just released during commit.
1098 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1099 AddTextureQuad(frame.get(), 999);
1100 AddTransferableResource(frame.get(), 999);
1101 AddTextureQuad(frame.get(), 555);
1102 AddTransferableResource(frame.get(), 555);
1103 AddTextureQuad(frame.get(), 444);
1104 AddTransferableResource(frame.get(), 444);
1105 SetFrameData(frame.Pass());
1107 // The resources are used by the new frame but are returned anyway since
1108 // we passed them again.
1109 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1111 unsigned expected[] = {444, 555};
1112 EXPECT_RESOURCES(expected, resources);
1113 EXPECT_TRUE(TestAndResetAvailable());
1115 break;
1116 case 4:
1117 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1118 EXPECT_EQ(0u, resources.size());
1119 EXPECT_FALSE(TestAndResetAvailable());
1120 EndTest();
1121 break;
1125 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1126 if (host_impl->active_tree()->source_frame_number() != 3)
1127 return;
1129 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1130 FakeDelegatedRendererLayerImpl* delegated_impl =
1131 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1133 const ResourceProvider::ResourceIdMap& map =
1134 host_impl->resource_provider()->GetChildToParentMap(
1135 delegated_impl->ChildId());
1137 // The third frame has all of the resources in it again, the delegated
1138 // renderer layer should continue to own the resources for it.
1139 EXPECT_EQ(3u, map.size());
1140 EXPECT_EQ(1u, map.count(999));
1141 EXPECT_EQ(1u, map.count(555));
1142 EXPECT_EQ(1u, map.count(444));
1144 EXPECT_EQ(3u, delegated_impl->Resources().size());
1145 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1146 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1147 EXPECT_EQ(1u, delegated_impl->Resources().count(444));
1149 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1150 EXPECT_EQ(3u, pass->quad_list.size());
1151 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
1152 pass->quad_list[0]);
1153 EXPECT_EQ(map.find(999)->second, quad1->resource_id);
1154 const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
1155 pass->quad_list[1]);
1156 EXPECT_EQ(map.find(555)->second, quad2->resource_id);
1157 const TextureDrawQuad* quad3 = TextureDrawQuad::MaterialCast(
1158 pass->quad_list[2]);
1159 EXPECT_EQ(map.find(444)->second, quad3->resource_id);
1162 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1163 bool result) OVERRIDE {
1164 ReturnUnusedResourcesFromParent(host_impl);
1168 SINGLE_AND_MULTI_THREAD_TEST_F(
1169 LayerTreeHostDelegatedTestFrameBeforeTakeResources);
1171 class LayerTreeHostDelegatedTestBadFrame
1172 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1173 public:
1174 virtual void BeginTest() OVERRIDE {
1175 PostSetNeedsCommitToMainThread();
1178 virtual void DidCommitAndDrawFrame() OVERRIDE {
1179 scoped_ptr<DelegatedFrameData> frame;
1180 ReturnedResourceArray resources;
1182 int next_source_frame_number = layer_tree_host()->source_frame_number();
1183 switch (next_source_frame_number) {
1184 case 1:
1185 // Generate a frame with some resources in it.
1186 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1187 AddTextureQuad(frame.get(), 999);
1188 AddTransferableResource(frame.get(), 999);
1189 AddTextureQuad(frame.get(), 555);
1190 AddTransferableResource(frame.get(), 555);
1191 SetFrameData(frame.Pass());
1192 break;
1193 case 2:
1194 // All of the resources are in use.
1195 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1196 EXPECT_EQ(0u, resources.size());
1197 EXPECT_FALSE(TestAndResetAvailable());
1199 // Generate a bad frame with a resource the layer doesn't have. The
1200 // 885 and 775 resources are unknown, while ownership of the legit 444
1201 // resource is passed in here. The bad frame does not use any of the
1202 // previous resources, 999 or 555.
1203 // A bad quad is present both before and after the good quad.
1204 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1205 AddTextureQuad(frame.get(), 885);
1206 AddTextureQuad(frame.get(), 444);
1207 AddTransferableResource(frame.get(), 444);
1208 AddTextureQuad(frame.get(), 775);
1209 SetFrameData(frame.Pass());
1211 // The parent compositor (this one) does a commit.
1212 break;
1213 case 3:
1214 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1215 EXPECT_EQ(0u, resources.size());
1216 EXPECT_FALSE(TestAndResetAvailable());
1218 // Now send a good frame with 999 again.
1219 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1220 AddTextureQuad(frame.get(), 999);
1221 SetFrameData(frame.Pass());
1223 // The bad frame's resource is given back to the child compositor.
1224 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1226 unsigned expected[] = {444};
1227 EXPECT_RESOURCES(expected, resources);
1228 EXPECT_TRUE(TestAndResetAvailable());
1230 break;
1231 case 4:
1232 // The unused 555 from the last good frame is now released.
1233 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1235 unsigned expected[] = {555};
1236 EXPECT_RESOURCES(expected, resources);
1237 EXPECT_TRUE(TestAndResetAvailable());
1240 EndTest();
1241 break;
1245 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1246 bool result) OVERRIDE {
1247 if (host_impl->active_tree()->source_frame_number() < 1)
1248 return;
1250 ReturnUnusedResourcesFromParent(host_impl);
1252 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1253 FakeDelegatedRendererLayerImpl* delegated_impl =
1254 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1256 const ResourceProvider::ResourceIdMap& map =
1257 host_impl->resource_provider()->GetChildToParentMap(
1258 delegated_impl->ChildId());
1260 switch (host_impl->active_tree()->source_frame_number()) {
1261 case 1: {
1262 // We have the first good frame with just 990 and 555 in it.
1263 // layer.
1264 EXPECT_EQ(2u, map.size());
1265 EXPECT_EQ(1u, map.count(999));
1266 EXPECT_EQ(1u, map.count(555));
1268 EXPECT_EQ(2u, delegated_impl->Resources().size());
1269 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1270 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1272 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1273 EXPECT_EQ(2u, pass->quad_list.size());
1274 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
1275 pass->quad_list[0]);
1276 EXPECT_EQ(map.find(999)->second, quad1->resource_id);
1277 const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
1278 pass->quad_list[1]);
1279 EXPECT_EQ(map.find(555)->second, quad2->resource_id);
1280 break;
1282 case 2: {
1283 // We only keep resources from the last valid frame.
1284 EXPECT_EQ(2u, map.size());
1285 EXPECT_EQ(1u, map.count(999));
1286 EXPECT_EQ(1u, map.count(555));
1288 EXPECT_EQ(2u, delegated_impl->Resources().size());
1289 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1290 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1292 // The bad frame is dropped though, we still have the frame with 999 and
1293 // 555 in it.
1294 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1295 EXPECT_EQ(2u, pass->quad_list.size());
1296 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
1297 pass->quad_list[0]);
1298 EXPECT_EQ(map.find(999)->second, quad1->resource_id);
1299 const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
1300 pass->quad_list[1]);
1301 EXPECT_EQ(map.find(555)->second, quad2->resource_id);
1302 break;
1304 case 3: {
1305 // We have the new good frame with just 999 in it.
1306 EXPECT_EQ(1u, map.size());
1307 EXPECT_EQ(1u, map.count(999));
1309 EXPECT_EQ(1u, delegated_impl->Resources().size());
1310 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1312 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
1313 EXPECT_EQ(1u, pass->quad_list.size());
1314 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
1315 pass->quad_list[0]);
1316 EXPECT_EQ(map.find(999)->second, quad1->resource_id);
1317 break;
1323 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame);
1325 class LayerTreeHostDelegatedTestUnnamedResource
1326 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1327 public:
1328 virtual void BeginTest() OVERRIDE {
1329 PostSetNeedsCommitToMainThread();
1332 virtual void DidCommit() OVERRIDE {
1333 scoped_ptr<DelegatedFrameData> frame;
1334 ReturnedResourceArray resources;
1336 int next_source_frame_number = layer_tree_host()->source_frame_number();
1337 switch (next_source_frame_number) {
1338 case 1:
1339 // This frame includes two resources in it, but only uses one.
1340 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1341 AddTransferableResource(frame.get(), 999);
1342 AddTextureQuad(frame.get(), 555);
1343 AddTransferableResource(frame.get(), 555);
1344 SetFrameData(frame.Pass());
1345 break;
1346 case 2:
1347 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1348 EXPECT_EQ(0u, resources.size());
1349 EXPECT_FALSE(TestAndResetAvailable());
1351 // Now send an empty frame.
1352 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1353 SetFrameData(frame.Pass());
1355 // The unused resource should be returned.
1356 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1358 unsigned expected[] = {999};
1359 EXPECT_RESOURCES(expected, resources);
1360 EXPECT_TRUE(TestAndResetAvailable());
1363 EndTest();
1364 break;
1368 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1369 if (host_impl->active_tree()->source_frame_number() != 1)
1370 return;
1372 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1373 FakeDelegatedRendererLayerImpl* delegated_impl =
1374 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1376 const ResourceProvider::ResourceIdMap& map =
1377 host_impl->resource_provider()->GetChildToParentMap(
1378 delegated_impl->ChildId());
1380 // The layer only held on to the resource that was used.
1381 EXPECT_EQ(1u, map.size());
1382 EXPECT_EQ(1u, map.count(555));
1384 EXPECT_EQ(1u, delegated_impl->Resources().size());
1385 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1389 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestUnnamedResource);
1391 class LayerTreeHostDelegatedTestDontLeakResource
1392 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1393 public:
1394 virtual void BeginTest() OVERRIDE {
1395 PostSetNeedsCommitToMainThread();
1398 virtual void DidCommitAndDrawFrame() OVERRIDE {
1399 scoped_ptr<DelegatedFrameData> frame;
1400 ReturnedResourceArray resources;
1402 int next_source_frame_number = layer_tree_host()->source_frame_number();
1403 switch (next_source_frame_number) {
1404 case 1:
1405 // This frame includes two resources in it.
1406 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1407 AddTextureQuad(frame.get(), 999);
1408 AddTransferableResource(frame.get(), 999);
1409 AddTextureQuad(frame.get(), 555);
1410 AddTransferableResource(frame.get(), 555);
1411 SetFrameData(frame.Pass());
1413 // But then we immediately stop using 999.
1414 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1415 AddTextureQuad(frame.get(), 555);
1416 AddTransferableResource(frame.get(), 555);
1417 SetFrameData(frame.Pass());
1418 break;
1419 case 2:
1420 // The unused resources should be returned. 555 is still used, but it's
1421 // returned once to account for the first frame.
1422 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1424 unsigned expected[] = {555, 999};
1425 EXPECT_RESOURCES(expected, resources);
1426 EXPECT_TRUE(TestAndResetAvailable());
1428 // Send a frame with no resources in it.
1429 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1430 SetFrameData(frame.Pass());
1431 break;
1432 case 3:
1433 // The now unused resource 555 should be returned.
1434 resources.clear();
1435 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1437 unsigned expected[] = {555};
1438 EXPECT_RESOURCES(expected, resources);
1439 EXPECT_TRUE(TestAndResetAvailable());
1441 EndTest();
1442 break;
1446 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1447 if (host_impl->active_tree()->source_frame_number() != 1)
1448 return;
1450 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1451 FakeDelegatedRendererLayerImpl* delegated_impl =
1452 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1454 const ResourceProvider::ResourceIdMap& map =
1455 host_impl->resource_provider()->GetChildToParentMap(
1456 delegated_impl->ChildId());
1458 // The layer only held on to the resource that was used.
1459 EXPECT_EQ(1u, map.size());
1460 EXPECT_EQ(1u, map.count(555));
1462 EXPECT_EQ(1u, delegated_impl->Resources().size());
1463 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1466 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1467 bool result) OVERRIDE {
1468 ReturnUnusedResourcesFromParent(host_impl);
1472 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource);
1474 class LayerTreeHostDelegatedTestResourceSentToParent
1475 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1476 public:
1477 virtual void DidCommitAndDrawFrame() OVERRIDE {
1478 scoped_ptr<DelegatedFrameData> frame;
1479 ReturnedResourceArray resources;
1481 int next_source_frame_number = layer_tree_host()->source_frame_number();
1482 switch (next_source_frame_number) {
1483 case 1:
1484 // This frame includes two resources in it.
1485 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1486 AddTextureQuad(frame.get(), 999);
1487 AddTransferableResource(frame.get(), 999);
1488 AddTextureQuad(frame.get(), 555);
1489 AddTransferableResource(frame.get(), 555);
1490 SetFrameData(frame.Pass());
1491 break;
1492 case 2:
1493 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1494 EXPECT_EQ(0u, resources.size());
1495 EXPECT_FALSE(TestAndResetAvailable());
1497 // 999 is in use in the grandparent compositor, generate a frame without
1498 // it present.
1499 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1500 AddTextureQuad(frame.get(), 555);
1501 AddTransferableResource(frame.get(), 555);
1502 SetFrameData(frame.Pass());
1503 break;
1504 case 3:
1505 // Since 999 is in the grandparent it is not returned.
1506 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1507 EXPECT_EQ(0u, resources.size());
1508 EXPECT_FALSE(TestAndResetAvailable());
1510 // The impl side will get back the resource at some point.
1511 ImplThreadTaskRunner()->PostTask(FROM_HERE,
1512 receive_resource_on_thread_);
1513 break;
1517 void ReceiveResourceOnThread(LayerTreeHostImpl* host_impl) {
1518 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1519 FakeDelegatedRendererLayerImpl* delegated_impl =
1520 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1522 const ResourceProvider::ResourceIdMap& map =
1523 host_impl->resource_provider()->GetChildToParentMap(
1524 delegated_impl->ChildId());
1526 // Receive 999 back from the grandparent.
1527 CompositorFrameAck ack;
1528 output_surface()->ReturnResource(map.find(999)->second, &ack);
1529 host_impl->ReclaimResources(&ack);
1532 virtual void UnusedResourcesAreAvailable() OVERRIDE {
1533 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
1535 ReturnedResourceArray resources;
1537 // 999 was returned from the grandparent and could be released.
1538 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1540 unsigned expected[] = {999};
1541 EXPECT_RESOURCES(expected, resources);
1544 EndTest();
1547 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1548 if (host_impl->active_tree()->source_frame_number() < 1)
1549 return;
1551 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1552 FakeDelegatedRendererLayerImpl* delegated_impl =
1553 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1555 const ResourceProvider::ResourceIdMap& map =
1556 host_impl->resource_provider()->GetChildToParentMap(
1557 delegated_impl->ChildId());
1559 switch (host_impl->active_tree()->source_frame_number()) {
1560 case 1: {
1561 EXPECT_EQ(2u, map.size());
1562 EXPECT_EQ(1u, map.count(999));
1563 EXPECT_EQ(1u, map.count(555));
1565 EXPECT_EQ(2u, delegated_impl->Resources().size());
1566 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1567 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1569 // The 999 resource will be sent to a grandparent compositor.
1570 break;
1572 case 2: {
1573 EXPECT_EQ(2u, map.size());
1574 EXPECT_EQ(1u, map.count(999));
1575 EXPECT_EQ(1u, map.count(555));
1577 // 999 is in the parent, so not held by delegated renderer layer.
1578 EXPECT_EQ(1u, delegated_impl->Resources().size());
1579 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1581 receive_resource_on_thread_ =
1582 base::Bind(&LayerTreeHostDelegatedTestResourceSentToParent::
1583 ReceiveResourceOnThread,
1584 base::Unretained(this),
1585 host_impl);
1586 break;
1588 case 3:
1589 // 999 should be released.
1590 EXPECT_EQ(1u, map.size());
1591 EXPECT_EQ(1u, map.count(555));
1593 EXPECT_EQ(1u, delegated_impl->Resources().size());
1594 EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second));
1595 break;
1599 base::Closure receive_resource_on_thread_;
1602 SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(
1603 LayerTreeHostDelegatedTestResourceSentToParent);
1605 class LayerTreeHostDelegatedTestCommitWithoutTake
1606 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1607 public:
1608 virtual void BeginTest() OVERRIDE {
1609 // Prevent drawing with resources that are sent to the grandparent.
1610 layer_tree_host()->SetViewportSize(gfx::Size());
1611 PostSetNeedsCommitToMainThread();
1614 virtual void DidCommit() OVERRIDE {
1615 scoped_ptr<DelegatedFrameData> frame;
1616 ReturnedResourceArray resources;
1618 int next_source_frame_number = layer_tree_host()->source_frame_number();
1619 switch (next_source_frame_number) {
1620 case 1:
1621 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1622 AddTextureQuad(frame.get(), 999);
1623 AddTransferableResource(frame.get(), 999);
1624 AddTextureQuad(frame.get(), 555);
1625 AddTransferableResource(frame.get(), 555);
1626 AddTextureQuad(frame.get(), 444);
1627 AddTransferableResource(frame.get(), 444);
1628 SetFrameData(frame.Pass());
1629 break;
1630 case 2:
1631 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1632 EXPECT_EQ(0u, resources.size());
1633 EXPECT_FALSE(TestAndResetAvailable());
1635 // Stop using 999 and 444 in this frame and commit.
1636 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1637 AddTextureQuad(frame.get(), 555);
1638 AddTransferableResource(frame.get(), 555);
1639 SetFrameData(frame.Pass());
1640 // 999 and 444 will be returned for frame 1, but not 555 since it's in
1641 // the current frame.
1642 break;
1643 case 3:
1644 // Don't take resources here, but set a new frame that uses 999 again.
1645 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1646 AddTextureQuad(frame.get(), 999);
1647 AddTransferableResource(frame.get(), 999);
1648 AddTextureQuad(frame.get(), 555);
1649 AddTransferableResource(frame.get(), 555);
1650 SetFrameData(frame.Pass());
1651 break;
1652 case 4:
1653 // 555 from frame 1 and 2 isn't returned since it's still in use. 999
1654 // from frame 1 is returned though.
1655 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1657 unsigned expected[] = {444, 999};
1658 EXPECT_RESOURCES(expected, resources);
1659 EXPECT_TRUE(TestAndResetAvailable());
1662 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1663 SetFrameData(frame.Pass());
1664 // 555 will be returned 3 times for frames 1 2 and 3, and 999 will be
1665 // returned once for frame 3.
1666 break;
1667 case 5:
1668 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1670 unsigned expected[] = {555, 555, 555, 999};
1671 EXPECT_RESOURCES(expected, resources);
1672 EXPECT_TRUE(TestAndResetAvailable());
1675 EndTest();
1676 break;
1680 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1681 if (host_impl->active_tree()->source_frame_number() < 1)
1682 return;
1684 LayerImpl* root_impl = host_impl->active_tree()->root_layer();
1685 FakeDelegatedRendererLayerImpl* delegated_impl =
1686 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
1688 const ResourceProvider::ResourceIdMap& map =
1689 host_impl->resource_provider()->GetChildToParentMap(
1690 delegated_impl->ChildId());
1692 switch (host_impl->active_tree()->source_frame_number()) {
1693 case 1:
1694 EXPECT_EQ(3u, map.size());
1695 EXPECT_EQ(1u, map.count(999));
1696 EXPECT_EQ(1u, map.count(555));
1697 EXPECT_EQ(1u, map.count(444));
1699 EXPECT_EQ(3u, delegated_impl->Resources().size());
1700 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1701 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1702 EXPECT_EQ(1u, delegated_impl->Resources().count(444));
1703 break;
1704 case 2:
1705 EXPECT_EQ(1u, map.size());
1706 EXPECT_EQ(1u, map.count(555));
1708 EXPECT_EQ(1u, delegated_impl->Resources().size());
1709 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1710 break;
1711 case 3:
1712 EXPECT_EQ(2u, map.size());
1713 EXPECT_EQ(1u, map.count(999));
1714 EXPECT_EQ(1u, map.count(555));
1716 EXPECT_EQ(2u, delegated_impl->Resources().size());
1717 EXPECT_EQ(1u, delegated_impl->Resources().count(999));
1718 EXPECT_EQ(1u, delegated_impl->Resources().count(555));
1723 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCommitWithoutTake);
1725 class DelegatedFrameIsActivatedDuringCommit
1726 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1727 protected:
1728 DelegatedFrameIsActivatedDuringCommit() : returned_resource_count_(0) {}
1730 virtual void BeginTest() OVERRIDE {
1731 activate_count_ = 0;
1733 scoped_ptr<DelegatedFrameData> frame =
1734 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1735 AddTextureQuad(frame.get(), 999);
1736 AddTransferableResource(frame.get(), 999);
1737 SetFrameData(frame.Pass());
1739 PostSetNeedsCommitToMainThread();
1742 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1743 ++activate_count_;
1746 virtual void DidCommit() OVERRIDE {
1747 switch (layer_tree_host()->source_frame_number()) {
1748 case 1: {
1749 // The first frame has been activated. Set a new frame, and
1750 // expect the next commit to finish *after* it is activated.
1751 scoped_ptr<DelegatedFrameData> frame =
1752 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1753 AddTextureQuad(frame.get(), 555);
1754 AddTransferableResource(frame.get(), 555);
1755 SetFrameData(frame.Pass());
1756 break;
1758 case 2:
1759 // The second frame has been activated. Remove the layer from
1760 // the tree to cause another commit/activation. The commit should
1761 // finish *after* the layer is removed from the active tree.
1762 delegated_->RemoveFromParent();
1763 break;
1764 case 3:
1765 // Finish the test by releasing resources on the next frame.
1766 scoped_ptr<DelegatedFrameData> frame =
1767 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1768 SetFrameData(frame.Pass());
1769 break;
1773 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1774 switch (host_impl->active_tree()->source_frame_number()) {
1775 case 2: {
1776 // The activate for the 2nd frame should have happened before now.
1777 EXPECT_EQ(2, activate_count_);
1778 break;
1780 case 3: {
1781 // The activate to remove the layer should have happened before now.
1782 EXPECT_EQ(3, activate_count_);
1783 break;
1788 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1789 bool result) OVERRIDE {
1790 ReturnUnusedResourcesFromParent(host_impl);
1793 virtual void UnusedResourcesAreAvailable() OVERRIDE {
1794 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::
1795 UnusedResourcesAreAvailable();
1796 ReturnedResourceArray resources;
1797 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1798 EXPECT_TRUE(TestAndResetAvailable());
1799 returned_resource_count_ += resources.size();
1800 if (returned_resource_count_ == 2)
1801 EndTest();
1804 int activate_count_;
1805 size_t returned_resource_count_;
1808 SINGLE_AND_MULTI_THREAD_TEST_F(
1809 DelegatedFrameIsActivatedDuringCommit);
1811 class LayerTreeHostDelegatedTestTwoImplLayers
1812 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1813 public:
1814 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1816 virtual void DidCommitAndDrawFrame() OVERRIDE {
1817 scoped_ptr<DelegatedFrameData> frame;
1818 ReturnedResourceArray resources;
1820 int next_source_frame_number = layer_tree_host()->source_frame_number();
1821 switch (next_source_frame_number) {
1822 case 1:
1823 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1824 AddTextureQuad(frame.get(), 999);
1825 AddTransferableResource(frame.get(), 999);
1826 AddTextureQuad(frame.get(), 555);
1827 AddTransferableResource(frame.get(), 555);
1828 SetFrameData(frame.Pass());
1829 break;
1830 case 2:
1831 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1832 EXPECT_EQ(0u, resources.size());
1833 EXPECT_FALSE(TestAndResetAvailable());
1835 // Remove the delegated layer and replace it with a new one. Use the
1836 // same frame and resources for it.
1837 delegated_->RemoveFromParent();
1838 delegated_ = CreateDelegatedLayer(frame_provider_.get());
1839 break;
1840 case 3:
1841 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1842 EXPECT_EQ(0u, resources.size());
1843 EXPECT_FALSE(TestAndResetAvailable());
1845 // Use a frame with no resources in it.
1846 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1847 SetFrameData(frame.Pass());
1848 break;
1849 case 4:
1850 // We gave one frame to the frame provider, so we should get one
1851 // ref back for each resource.
1852 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1854 unsigned expected[] = {555, 999};
1855 EXPECT_RESOURCES(expected, resources);
1856 EXPECT_TRUE(TestAndResetAvailable());
1858 EndTest();
1859 break;
1863 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1864 bool result) OVERRIDE {
1865 ReturnUnusedResourcesFromParent(host_impl);
1869 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoImplLayers);
1871 class LayerTreeHostDelegatedTestTwoImplLayersTwoFrames
1872 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1873 public:
1874 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1876 virtual void DidCommitAndDrawFrame() OVERRIDE {
1877 scoped_ptr<DelegatedFrameData> frame;
1878 ReturnedResourceArray resources;
1880 int next_source_frame_number = layer_tree_host()->source_frame_number();
1881 switch (next_source_frame_number) {
1882 case 1:
1883 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1884 AddTextureQuad(frame.get(), 999);
1885 AddTransferableResource(frame.get(), 999);
1886 AddTextureQuad(frame.get(), 555);
1887 AddTransferableResource(frame.get(), 555);
1888 SetFrameData(frame.Pass());
1889 break;
1890 case 2:
1891 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1892 EXPECT_EQ(0u, resources.size());
1893 EXPECT_FALSE(TestAndResetAvailable());
1895 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1896 AddTextureQuad(frame.get(), 999);
1897 AddTransferableResource(frame.get(), 999);
1898 AddTextureQuad(frame.get(), 555);
1899 AddTransferableResource(frame.get(), 555);
1901 // Remove the delegated layer and replace it with a new one. Make a new
1902 // frame but with the same resources for it.
1903 delegated_->RemoveFromParent();
1904 delegated_ = NULL;
1906 frame_provider_->SetFrameData(frame.Pass());
1907 delegated_ = CreateDelegatedLayer(frame_provider_.get());
1908 break;
1909 case 3:
1910 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1911 EXPECT_EQ(0u, resources.size());
1912 EXPECT_FALSE(TestAndResetAvailable());
1914 // Use a frame with no resources in it.
1915 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1916 SetFrameData(frame.Pass());
1917 break;
1918 case 4:
1919 // We gave two frames to the frame provider, so we should get two
1920 // refs back for each resource.
1921 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1923 unsigned expected[] = {555, 555, 999, 999};
1924 EXPECT_RESOURCES(expected, resources);
1925 EXPECT_TRUE(TestAndResetAvailable());
1927 EndTest();
1928 break;
1932 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1933 bool result) OVERRIDE {
1934 ReturnUnusedResourcesFromParent(host_impl);
1938 SINGLE_AND_MULTI_THREAD_TEST_F(
1939 LayerTreeHostDelegatedTestTwoImplLayersTwoFrames);
1941 class LayerTreeHostDelegatedTestTwoLayers
1942 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
1943 public:
1944 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1946 virtual void DidCommitAndDrawFrame() OVERRIDE {
1947 scoped_ptr<DelegatedFrameData> frame;
1948 ReturnedResourceArray resources;
1950 int next_source_frame_number = layer_tree_host()->source_frame_number();
1951 switch (next_source_frame_number) {
1952 case 1:
1953 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
1954 AddTextureQuad(frame.get(), 999);
1955 AddTransferableResource(frame.get(), 999);
1956 AddTextureQuad(frame.get(), 555);
1957 AddTransferableResource(frame.get(), 555);
1959 // Create a DelegatedRendererLayer using the frame.
1960 SetFrameData(frame.Pass());
1961 break;
1962 case 2:
1963 // Create a second DelegatedRendererLayer using the same frame provider.
1964 delegated_thief_ = CreateDelegatedLayer(frame_provider_.get());
1965 root_->AddChild(delegated_thief_);
1967 // And drop our ref on the frame provider so only the layers keep it
1968 // alive.
1969 frame_provider_ = NULL;
1970 break;
1971 case 3:
1972 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1973 EXPECT_EQ(0u, resources.size());
1974 EXPECT_FALSE(TestAndResetAvailable());
1976 // Remove one delegated layer from the tree. No resources should be
1977 // returned yet.
1978 delegated_->RemoveFromParent();
1979 break;
1980 case 4:
1981 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1982 EXPECT_EQ(0u, resources.size());
1983 EXPECT_FALSE(TestAndResetAvailable());
1985 // Put the first layer back, and remove the other layer and destroy it.
1986 // No resources should be returned yet.
1987 root_->AddChild(delegated_);
1988 delegated_thief_->RemoveFromParent();
1989 delegated_thief_ = NULL;
1990 break;
1991 case 5:
1992 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
1993 EXPECT_EQ(0u, resources.size());
1994 EXPECT_FALSE(TestAndResetAvailable());
1996 // Remove the first layer from the tree again. The resources are still
1997 // held by the main thread layer.
1998 delegated_->RemoveFromParent();
1999 break;
2000 case 6:
2001 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2002 EXPECT_EQ(0u, resources.size());
2003 EXPECT_FALSE(TestAndResetAvailable());
2005 // Destroy the layer and the resources should be returned immediately.
2006 delegated_ = NULL;
2008 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2010 unsigned expected[] = {555, 999};
2011 EXPECT_RESOURCES(expected, resources);
2012 EXPECT_TRUE(TestAndResetAvailable());
2014 EndTest();
2015 break;
2019 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
2020 bool result) OVERRIDE {
2021 ReturnUnusedResourcesFromParent(host_impl);
2024 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2027 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoLayers);
2029 class LayerTreeHostDelegatedTestRemoveAndAddToTree
2030 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2031 public:
2032 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2034 virtual void DidCommitAndDrawFrame() OVERRIDE {
2035 scoped_ptr<DelegatedFrameData> frame;
2036 ReturnedResourceArray resources;
2038 int next_source_frame_number = layer_tree_host()->source_frame_number();
2039 switch (next_source_frame_number) {
2040 case 1:
2041 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2042 AddTextureQuad(frame.get(), 999);
2043 AddTransferableResource(frame.get(), 999);
2044 AddTextureQuad(frame.get(), 555);
2045 AddTransferableResource(frame.get(), 555);
2047 // Create a DelegatedRendererLayer using the frame.
2048 SetFrameData(frame.Pass());
2049 break;
2050 case 2:
2051 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2052 EXPECT_EQ(0u, resources.size());
2053 EXPECT_FALSE(TestAndResetAvailable());
2055 // Remove the layer from the tree. The resources should not be returned
2056 // since they are still on the main thread layer.
2057 delegated_->RemoveFromParent();
2058 break;
2059 case 3:
2060 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2061 EXPECT_EQ(0u, resources.size());
2062 EXPECT_FALSE(TestAndResetAvailable());
2064 // Add the layer back to the tree.
2065 layer_tree_host()->root_layer()->AddChild(delegated_);
2066 break;
2067 case 4:
2068 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2069 EXPECT_EQ(0u, resources.size());
2070 EXPECT_FALSE(TestAndResetAvailable());
2072 // Set a new frame. Resources should be returned.
2073 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2074 AddTextureQuad(frame.get(), 888);
2075 AddTransferableResource(frame.get(), 888);
2076 AddTextureQuad(frame.get(), 777);
2077 AddTransferableResource(frame.get(), 777);
2078 SetFrameData(frame.Pass());
2079 break;
2080 case 5:
2081 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2083 unsigned expected[] = {555, 999};
2084 EXPECT_RESOURCES(expected, resources);
2085 EXPECT_TRUE(TestAndResetAvailable());
2088 // Destroy the layer.
2089 delegated_->RemoveFromParent();
2090 delegated_ = NULL;
2091 break;
2092 case 6:
2093 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2094 EXPECT_EQ(0u, resources.size());
2095 EXPECT_FALSE(TestAndResetAvailable());
2097 // Destroy the frame provider. Resources should be returned.
2098 frame_provider_ = NULL;
2100 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2102 unsigned expected[] = {777, 888};
2103 EXPECT_RESOURCES(expected, resources);
2104 EXPECT_TRUE(TestAndResetAvailable());
2106 EndTest();
2107 break;
2111 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
2112 bool result) OVERRIDE {
2113 ReturnUnusedResourcesFromParent(host_impl);
2116 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2119 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemoveAndAddToTree);
2121 class LayerTreeHostDelegatedTestRemoveAndChangeResources
2122 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
2123 public:
2124 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2126 virtual void DidCommitAndDrawFrame() OVERRIDE {
2127 scoped_ptr<DelegatedFrameData> frame;
2128 ReturnedResourceArray resources;
2130 int next_source_frame_number = layer_tree_host()->source_frame_number();
2131 switch (next_source_frame_number) {
2132 case 1:
2133 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2134 AddTextureQuad(frame.get(), 999);
2135 AddTransferableResource(frame.get(), 999);
2136 AddTextureQuad(frame.get(), 555);
2137 AddTransferableResource(frame.get(), 555);
2139 // Create a DelegatedRendererLayer using the frame.
2140 SetFrameData(frame.Pass());
2141 break;
2142 case 2:
2143 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2144 EXPECT_EQ(0u, resources.size());
2145 EXPECT_FALSE(TestAndResetAvailable());
2147 // Remove the layer from the tree. The resources should not be returned
2148 // since they are still on the main thread layer.
2149 delegated_->RemoveFromParent();
2150 break;
2151 case 3:
2152 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2153 EXPECT_EQ(0u, resources.size());
2154 EXPECT_FALSE(TestAndResetAvailable());
2156 // Set a new frame. Resources should be returned immediately.
2157 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
2158 AddTextureQuad(frame.get(), 888);
2159 AddTransferableResource(frame.get(), 888);
2160 AddTextureQuad(frame.get(), 777);
2161 AddTransferableResource(frame.get(), 777);
2162 SetFrameData(frame.Pass());
2164 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2166 unsigned expected[] = {555, 999};
2167 EXPECT_RESOURCES(expected, resources);
2168 EXPECT_TRUE(TestAndResetAvailable());
2169 resources.clear();
2172 // Destroy the frame provider.
2173 frame_provider_ = NULL;
2175 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2176 EXPECT_EQ(0u, resources.size());
2177 EXPECT_FALSE(TestAndResetAvailable());
2179 // Destroy the layer. Resources should be returned.
2180 delegated_ = NULL;
2182 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
2184 unsigned expected[] = {777, 888};
2185 EXPECT_RESOURCES(expected, resources);
2186 EXPECT_TRUE(TestAndResetAvailable());
2188 EndTest();
2189 break;
2193 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
2194 bool result) OVERRIDE {
2195 ReturnUnusedResourcesFromParent(host_impl);
2198 scoped_refptr<DelegatedRendererLayer> delegated_thief_;
2201 SINGLE_AND_MULTI_THREAD_TEST_F(
2202 LayerTreeHostDelegatedTestRemoveAndChangeResources);
2204 } // namespace
2205 } // namespace cc