Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / cc / layers / delegated_frame_provider_unittest.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/layers/delegated_frame_provider.h"
6 #include "cc/layers/delegated_frame_resource_collection.h"
7 #include "cc/layers/delegated_renderer_layer.h"
8 #include "cc/output/delegated_frame_data.h"
9 #include "cc/quads/texture_draw_quad.h"
10 #include "cc/resources/returned_resource.h"
11 #include "cc/resources/transferable_resource.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace cc {
15 namespace {
16
17 class DelegatedFrameProviderTest
18     : public testing::Test,
19       public DelegatedFrameResourceCollectionClient {
20  protected:
21   DelegatedFrameProviderTest() : resources_available_(false) {}
22
23   scoped_ptr<DelegatedFrameData> CreateFrameData(
24           const gfx::Rect& root_output_rect,
25           const gfx::Rect& root_damage_rect) {
26     scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
27
28     scoped_ptr<RenderPass> root_pass(RenderPass::Create());
29     root_pass->SetNew(RenderPass::Id(1, 1),
30                       root_output_rect,
31                       root_damage_rect,
32                       gfx::Transform());
33     frame->render_pass_list.push_back(root_pass.Pass());
34     return frame.Pass();
35   }
36
37   void AddTransferableResource(DelegatedFrameData* frame,
38                                ResourceProvider::ResourceId resource_id) {
39     TransferableResource resource;
40     resource.id = resource_id;
41     resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
42     frame->resource_list.push_back(resource);
43   }
44
45   void AddTextureQuad(DelegatedFrameData* frame,
46                       ResourceProvider::ResourceId resource_id) {
47     SharedQuadState* sqs =
48         frame->render_pass_list[0]->CreateAndAppendSharedQuadState();
49     TextureDrawQuad* quad =
50         frame->render_pass_list[0]->CreateAndAppendDrawQuad<TextureDrawQuad>();
51     float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
52     quad->SetNew(sqs,
53                  gfx::Rect(0, 0, 10, 10),
54                  gfx::Rect(0, 0, 10, 10),
55                  gfx::Rect(0, 0, 10, 10),
56                  resource_id,
57                  false,
58                  gfx::PointF(0.f, 0.f),
59                  gfx::PointF(1.f, 1.f),
60                  SK_ColorTRANSPARENT,
61                  vertex_opacity,
62                  false);
63   }
64
65   virtual void SetUp() OVERRIDE {
66     resource_collection_ = new DelegatedFrameResourceCollection;
67     resource_collection_->SetClient(this);
68   }
69
70   virtual void TearDown() OVERRIDE { resource_collection_->SetClient(NULL); }
71
72   virtual void UnusedResourcesAreAvailable() OVERRIDE {
73     resources_available_ = true;
74     resource_collection_->TakeUnusedResourcesForChildCompositor(&resources_);
75   }
76
77   bool ReturnAndResetResourcesAvailable() {
78     bool r = resources_available_;
79     resources_available_ = false;
80     return r;
81   }
82
83   void SetFrameProvider(scoped_ptr<DelegatedFrameData> frame_data) {
84     frame_provider_ =
85         new DelegatedFrameProvider(resource_collection_, frame_data.Pass());
86   }
87
88   scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
89   scoped_refptr<DelegatedFrameProvider> frame_provider_;
90   bool resources_available_;
91   ReturnedResourceArray resources_;
92 };
93
94 TEST_F(DelegatedFrameProviderTest, SameResources) {
95   scoped_ptr<DelegatedFrameData> frame =
96       CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
97   AddTextureQuad(frame.get(), 444);
98   AddTransferableResource(frame.get(), 444);
99   SetFrameProvider(frame.Pass());
100
101   frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
102   AddTextureQuad(frame.get(), 444);
103   AddTransferableResource(frame.get(), 444);
104   SetFrameProvider(frame.Pass());
105
106   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
107   EXPECT_EQ(0u, resources_.size());
108
109   frame_provider_ = NULL;
110
111   EXPECT_TRUE(ReturnAndResetResourcesAvailable());
112   EXPECT_EQ(1u, resources_.size());
113   EXPECT_EQ(444u, resources_[0].id);
114 }
115
116 TEST_F(DelegatedFrameProviderTest, ReplaceResources) {
117   scoped_ptr<DelegatedFrameData> frame =
118       CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
119   AddTextureQuad(frame.get(), 444);
120   AddTransferableResource(frame.get(), 444);
121   SetFrameProvider(frame.Pass());
122
123   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
124
125   frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
126   AddTextureQuad(frame.get(), 555);
127   AddTransferableResource(frame.get(), 555);
128   SetFrameProvider(frame.Pass());
129
130   EXPECT_TRUE(ReturnAndResetResourcesAvailable());
131   EXPECT_EQ(1u, resources_.size());
132   EXPECT_EQ(444u, resources_[0].id);
133   resources_.clear();
134
135   frame_provider_ = NULL;
136
137   EXPECT_TRUE(ReturnAndResetResourcesAvailable());
138   EXPECT_EQ(1u, resources_.size());
139   EXPECT_EQ(555u, resources_[0].id);
140 }
141
142 TEST_F(DelegatedFrameProviderTest, RefResources) {
143   scoped_ptr<DelegatedFrameData> frame =
144       CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
145   AddTextureQuad(frame.get(), 444);
146   AddTransferableResource(frame.get(), 444);
147
148   TransferableResourceArray reffed = frame->resource_list;
149   ReturnedResourceArray returned;
150   TransferableResource::ReturnResources(reffed, &returned);
151
152   SetFrameProvider(frame.Pass());
153
154   scoped_refptr<DelegatedRendererLayer> observer1 =
155       DelegatedRendererLayer::Create(frame_provider_);
156   scoped_refptr<DelegatedRendererLayer> observer2 =
157       DelegatedRendererLayer::Create(frame_provider_);
158
159   gfx::RectF damage;
160
161   // Both observers get a full frame of damage on the first request.
162   frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
163   EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
164   frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
165   EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
166
167   // And both get no damage on the 2nd request. This adds a second ref to the
168   // resources.
169   frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
170   EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
171   frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
172   EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
173
174   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
175
176   frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
177   AddTextureQuad(frame.get(), 555);
178   AddTransferableResource(frame.get(), 555);
179   frame_provider_->SetFrameData(frame.Pass());
180
181   // The resources from the first frame are still reffed by the observers.
182   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
183
184   // There are 4 refs taken.
185   frame_provider_->UnrefResourcesOnMainThread(returned);
186   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
187   frame_provider_->UnrefResourcesOnMainThread(returned);
188   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
189   frame_provider_->UnrefResourcesOnMainThread(returned);
190   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
191
192   // The 4th unref will release them.
193   frame_provider_->UnrefResourcesOnMainThread(returned);
194
195   EXPECT_TRUE(ReturnAndResetResourcesAvailable());
196   EXPECT_EQ(1u, resources_.size());
197   EXPECT_EQ(444u, resources_[0].id);
198 }
199
200 TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProvider) {
201   scoped_ptr<DelegatedFrameData> frame =
202       CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
203   AddTextureQuad(frame.get(), 444);
204   AddTransferableResource(frame.get(), 444);
205
206   TransferableResourceArray reffed = frame->resource_list;
207   ReturnedResourceArray returned;
208   TransferableResource::ReturnResources(reffed, &returned);
209
210   SetFrameProvider(frame.Pass());
211
212   scoped_refptr<DelegatedRendererLayer> observer1 =
213       DelegatedRendererLayer::Create(frame_provider_);
214   scoped_refptr<DelegatedRendererLayer> observer2 =
215       DelegatedRendererLayer::Create(frame_provider_);
216
217   gfx::RectF damage;
218
219   // Take a ref on each observer.
220   frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
221   frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
222
223   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
224
225   // Release both refs. But there's still a ref held in the frame
226   // provider itself.
227   frame_provider_->UnrefResourcesOnMainThread(returned);
228   frame_provider_->UnrefResourcesOnMainThread(returned);
229   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
230
231   // Setting a new frame will release it.
232   frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
233   AddTextureQuad(frame.get(), 555);
234   AddTransferableResource(frame.get(), 555);
235   frame_provider_->SetFrameData(frame.Pass());
236
237   EXPECT_TRUE(ReturnAndResetResourcesAvailable());
238   EXPECT_EQ(1u, resources_.size());
239   EXPECT_EQ(444u, resources_[0].id);
240 }
241
242 TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProviderUntilDestroy) {
243   scoped_ptr<DelegatedFrameData> frame =
244       CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
245   AddTextureQuad(frame.get(), 444);
246   AddTransferableResource(frame.get(), 444);
247
248   TransferableResourceArray reffed = frame->resource_list;
249   ReturnedResourceArray returned;
250   TransferableResource::ReturnResources(reffed, &returned);
251
252   SetFrameProvider(frame.Pass());
253
254   scoped_refptr<DelegatedRendererLayer> observer1 =
255       DelegatedRendererLayer::Create(frame_provider_);
256   scoped_refptr<DelegatedRendererLayer> observer2 =
257       DelegatedRendererLayer::Create(frame_provider_);
258
259   gfx::RectF damage;
260
261   // Take a ref on each observer.
262   frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
263   frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
264
265   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
266
267   // Release both refs. But there's still a ref held in the frame
268   // provider itself.
269   frame_provider_->UnrefResourcesOnMainThread(returned);
270   frame_provider_->UnrefResourcesOnMainThread(returned);
271   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
272
273   // Releasing all references to the frame provider will release
274   // the frame.
275   observer1 = NULL;
276   observer2 = NULL;
277   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
278
279   frame_provider_ = NULL;
280
281   EXPECT_TRUE(ReturnAndResetResourcesAvailable());
282   EXPECT_EQ(1u, resources_.size());
283   EXPECT_EQ(444u, resources_[0].id);
284 }
285
286 TEST_F(DelegatedFrameProviderTest, Damage) {
287   scoped_ptr<DelegatedFrameData> frame =
288       CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
289   AddTextureQuad(frame.get(), 444);
290   AddTransferableResource(frame.get(), 444);
291
292   TransferableResourceArray reffed = frame->resource_list;
293   ReturnedResourceArray returned;
294   TransferableResource::ReturnResources(reffed, &returned);
295
296   SetFrameProvider(frame.Pass());
297
298   scoped_refptr<DelegatedRendererLayer> observer1 =
299       DelegatedRendererLayer::Create(frame_provider_);
300   scoped_refptr<DelegatedRendererLayer> observer2 =
301       DelegatedRendererLayer::Create(frame_provider_);
302
303   gfx::RectF damage;
304
305   // Both observers get a full frame of damage on the first request.
306   frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
307   EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
308   frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
309   EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
310
311   // And both get no damage on the 2nd request.
312   frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
313   EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
314   frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
315   EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
316
317   frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
318   AddTextureQuad(frame.get(), 555);
319   AddTransferableResource(frame.get(), 555);
320   frame_provider_->SetFrameData(frame.Pass());
321
322   // Both observers get the damage for the new frame.
323   frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
324   EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString());
325   frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
326   EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString());
327
328   // And both get no damage on the 2nd request.
329   frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
330   EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
331   frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
332   EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
333 }
334
335 TEST_F(DelegatedFrameProviderTest, LostNothing) {
336   scoped_ptr<DelegatedFrameData> frame =
337       CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
338
339   TransferableResourceArray reffed = frame->resource_list;
340
341   SetFrameProvider(frame.Pass());
342
343   // There is nothing to lose.
344   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
345   EXPECT_FALSE(resource_collection_->LoseAllResources());
346   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
347   EXPECT_EQ(0u, resources_.size());
348 }
349
350 TEST_F(DelegatedFrameProviderTest, LostSomething) {
351   scoped_ptr<DelegatedFrameData> frame =
352       CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
353   AddTextureQuad(frame.get(), 444);
354   AddTransferableResource(frame.get(), 444);
355
356   SetFrameProvider(frame.Pass());
357
358   // Add a second reference on the resource.
359   frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
360   AddTextureQuad(frame.get(), 444);
361   AddTransferableResource(frame.get(), 444);
362
363   SetFrameProvider(frame.Pass());
364
365   // There is something to lose.
366   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
367   EXPECT_TRUE(resource_collection_->LoseAllResources());
368   EXPECT_TRUE(ReturnAndResetResourcesAvailable());
369
370   EXPECT_EQ(1u, resources_.size());
371   EXPECT_EQ(444u, resources_[0].id);
372   EXPECT_EQ(2, resources_[0].count);
373 }
374
375 TEST_F(DelegatedFrameProviderTest, NothingReturnedAfterLoss) {
376   scoped_ptr<DelegatedFrameData> frame =
377       CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
378   AddTextureQuad(frame.get(), 444);
379   AddTransferableResource(frame.get(), 444);
380   SetFrameProvider(frame.Pass());
381
382   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
383
384   // Lose all the resources.
385   EXPECT_TRUE(resource_collection_->LoseAllResources());
386   EXPECT_TRUE(ReturnAndResetResourcesAvailable());
387   resources_.clear();
388
389   frame_provider_ = NULL;
390
391   // Nothing is returned twice.
392   EXPECT_FALSE(ReturnAndResetResourcesAvailable());
393   EXPECT_EQ(0u, resources_.size());
394 }
395
396 }  // namespace
397 }  // namespace cc