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