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