1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/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"
17 class DelegatedFrameProviderTest
18 : public testing::Test
,
19 public DelegatedFrameResourceCollectionClient
{
21 DelegatedFrameProviderTest() : resources_available_(false) {}
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
);
28 scoped_ptr
<RenderPass
> root_pass(RenderPass::Create());
29 root_pass
->SetNew(RenderPass::Id(1, 1),
33 frame
->render_pass_list
.push_back(root_pass
.Pass());
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
);
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
};
53 gfx::Rect(0, 0, 10, 10),
54 gfx::Rect(0, 0, 10, 10),
55 gfx::Rect(0, 0, 10, 10),
58 gfx::PointF(0.f
, 0.f
),
59 gfx::PointF(1.f
, 1.f
),
65 virtual void SetUp() OVERRIDE
{
66 resource_collection_
= new DelegatedFrameResourceCollection
;
67 resource_collection_
->SetClient(this);
70 virtual void TearDown() OVERRIDE
{ resource_collection_
->SetClient(NULL
); }
72 virtual void UnusedResourcesAreAvailable() OVERRIDE
{
73 resources_available_
= true;
74 resource_collection_
->TakeUnusedResourcesForChildCompositor(&resources_
);
77 bool ReturnAndResetResourcesAvailable() {
78 bool r
= resources_available_
;
79 resources_available_
= false;
83 void SetFrameProvider(scoped_ptr
<DelegatedFrameData
> frame_data
) {
85 new DelegatedFrameProvider(resource_collection_
, frame_data
.Pass());
88 scoped_refptr
<DelegatedFrameResourceCollection
> resource_collection_
;
89 scoped_refptr
<DelegatedFrameProvider
> frame_provider_
;
90 bool resources_available_
;
91 ReturnedResourceArray resources_
;
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());
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());
106 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
107 EXPECT_EQ(0u, resources_
.size());
109 frame_provider_
= NULL
;
111 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
112 EXPECT_EQ(1u, resources_
.size());
113 EXPECT_EQ(444u, resources_
[0].id
);
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());
123 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
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());
130 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
131 EXPECT_EQ(1u, resources_
.size());
132 EXPECT_EQ(444u, resources_
[0].id
);
135 frame_provider_
= NULL
;
137 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
138 EXPECT_EQ(1u, resources_
.size());
139 EXPECT_EQ(555u, resources_
[0].id
);
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);
148 TransferableResourceArray reffed
= frame
->resource_list
;
149 ReturnedResourceArray returned
;
150 TransferableResource::ReturnResources(reffed
, &returned
);
152 SetFrameProvider(frame
.Pass());
154 scoped_refptr
<DelegatedRendererLayer
> observer1
=
155 DelegatedRendererLayer::Create(frame_provider_
);
156 scoped_refptr
<DelegatedRendererLayer
> observer2
=
157 DelegatedRendererLayer::Create(frame_provider_
);
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());
167 // And both get no damage on the 2nd request. This adds a second ref to the
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());
174 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
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());
181 // The resources from the first frame are still reffed by the observers.
182 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
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());
192 // The 4th unref will release them.
193 frame_provider_
->UnrefResourcesOnMainThread(returned
);
195 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
196 EXPECT_EQ(1u, resources_
.size());
197 EXPECT_EQ(444u, resources_
[0].id
);
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);
206 TransferableResourceArray reffed
= frame
->resource_list
;
207 ReturnedResourceArray returned
;
208 TransferableResource::ReturnResources(reffed
, &returned
);
210 SetFrameProvider(frame
.Pass());
212 scoped_refptr
<DelegatedRendererLayer
> observer1
=
213 DelegatedRendererLayer::Create(frame_provider_
);
214 scoped_refptr
<DelegatedRendererLayer
> observer2
=
215 DelegatedRendererLayer::Create(frame_provider_
);
219 // Take a ref on each observer.
220 frame_provider_
->GetFrameDataAndRefResources(observer1
, &damage
);
221 frame_provider_
->GetFrameDataAndRefResources(observer2
, &damage
);
223 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
225 // Release both refs. But there's still a ref held in the frame
227 frame_provider_
->UnrefResourcesOnMainThread(returned
);
228 frame_provider_
->UnrefResourcesOnMainThread(returned
);
229 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
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());
237 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
238 EXPECT_EQ(1u, resources_
.size());
239 EXPECT_EQ(444u, resources_
[0].id
);
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);
248 TransferableResourceArray reffed
= frame
->resource_list
;
249 ReturnedResourceArray returned
;
250 TransferableResource::ReturnResources(reffed
, &returned
);
252 SetFrameProvider(frame
.Pass());
254 scoped_refptr
<DelegatedRendererLayer
> observer1
=
255 DelegatedRendererLayer::Create(frame_provider_
);
256 scoped_refptr
<DelegatedRendererLayer
> observer2
=
257 DelegatedRendererLayer::Create(frame_provider_
);
261 // Take a ref on each observer.
262 frame_provider_
->GetFrameDataAndRefResources(observer1
, &damage
);
263 frame_provider_
->GetFrameDataAndRefResources(observer2
, &damage
);
265 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
267 // Release both refs. But there's still a ref held in the frame
269 frame_provider_
->UnrefResourcesOnMainThread(returned
);
270 frame_provider_
->UnrefResourcesOnMainThread(returned
);
271 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
273 // Releasing all references to the frame provider will release
277 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
279 frame_provider_
= NULL
;
281 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
282 EXPECT_EQ(1u, resources_
.size());
283 EXPECT_EQ(444u, resources_
[0].id
);
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);
292 TransferableResourceArray reffed
= frame
->resource_list
;
293 ReturnedResourceArray returned
;
294 TransferableResource::ReturnResources(reffed
, &returned
);
296 SetFrameProvider(frame
.Pass());
298 scoped_refptr
<DelegatedRendererLayer
> observer1
=
299 DelegatedRendererLayer::Create(frame_provider_
);
300 scoped_refptr
<DelegatedRendererLayer
> observer2
=
301 DelegatedRendererLayer::Create(frame_provider_
);
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());
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());
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());
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());
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());
335 TEST_F(DelegatedFrameProviderTest
, LostNothing
) {
336 scoped_ptr
<DelegatedFrameData
> frame
=
337 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
339 TransferableResourceArray reffed
= frame
->resource_list
;
341 SetFrameProvider(frame
.Pass());
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());
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);
356 SetFrameProvider(frame
.Pass());
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);
363 SetFrameProvider(frame
.Pass());
365 // There is something to lose.
366 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
367 EXPECT_TRUE(resource_collection_
->LoseAllResources());
368 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
370 EXPECT_EQ(1u, resources_
.size());
371 EXPECT_EQ(444u, resources_
[0].id
);
372 EXPECT_EQ(2, resources_
[0].count
);
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());
382 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
384 // Lose all the resources.
385 EXPECT_TRUE(resource_collection_
->LoseAllResources());
386 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
389 frame_provider_
= NULL
;
391 // Nothing is returned twice.
392 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
393 EXPECT_EQ(0u, resources_
.size());