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