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 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),
55 gfx::PointF(0.f
, 0.f
),
56 gfx::PointF(1.f
, 1.f
),
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
>());
64 virtual void SetUp() OVERRIDE
{
65 resource_collection_
= new DelegatedFrameResourceCollection
;
66 resource_collection_
->SetClient(this);
69 virtual void TearDown() OVERRIDE
{ resource_collection_
->SetClient(NULL
); }
71 virtual void UnusedResourcesAreAvailable() OVERRIDE
{
72 resources_available_
= true;
73 resource_collection_
->TakeUnusedResourcesForChildCompositor(&resources_
);
76 bool ReturnAndResetResourcesAvailable() {
77 bool r
= resources_available_
;
78 resources_available_
= false;
82 void SetFrameProvider(scoped_ptr
<DelegatedFrameData
> frame_data
) {
84 new DelegatedFrameProvider(resource_collection_
, frame_data
.Pass());
87 scoped_refptr
<DelegatedFrameResourceCollection
> resource_collection_
;
88 scoped_refptr
<DelegatedFrameProvider
> frame_provider_
;
89 bool resources_available_
;
90 ReturnedResourceArray resources_
;
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());
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());
105 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
106 EXPECT_EQ(0u, resources_
.size());
108 frame_provider_
= NULL
;
110 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
111 EXPECT_EQ(1u, resources_
.size());
112 EXPECT_EQ(444u, resources_
[0].id
);
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());
122 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
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());
129 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
130 EXPECT_EQ(1u, resources_
.size());
131 EXPECT_EQ(444u, resources_
[0].id
);
134 frame_provider_
= NULL
;
136 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
137 EXPECT_EQ(1u, resources_
.size());
138 EXPECT_EQ(555u, resources_
[0].id
);
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);
147 TransferableResourceArray reffed
= frame
->resource_list
;
148 ReturnedResourceArray returned
;
149 TransferableResource::ReturnResources(reffed
, &returned
);
151 SetFrameProvider(frame
.Pass());
153 scoped_refptr
<DelegatedRendererLayer
> observer1
=
154 DelegatedRendererLayer::Create(frame_provider_
);
155 scoped_refptr
<DelegatedRendererLayer
> observer2
=
156 DelegatedRendererLayer::Create(frame_provider_
);
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());
166 // And both get no damage on the 2nd request. This adds a second ref to the
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());
173 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
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());
180 // The resources from the first frame are still reffed by the observers.
181 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
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());
191 // The 4th unref will release them.
192 frame_provider_
->UnrefResourcesOnMainThread(returned
);
194 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
195 EXPECT_EQ(1u, resources_
.size());
196 EXPECT_EQ(444u, resources_
[0].id
);
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);
205 TransferableResourceArray reffed
= frame
->resource_list
;
206 ReturnedResourceArray returned
;
207 TransferableResource::ReturnResources(reffed
, &returned
);
209 SetFrameProvider(frame
.Pass());
211 scoped_refptr
<DelegatedRendererLayer
> observer1
=
212 DelegatedRendererLayer::Create(frame_provider_
);
213 scoped_refptr
<DelegatedRendererLayer
> observer2
=
214 DelegatedRendererLayer::Create(frame_provider_
);
218 // Take a ref on each observer.
219 frame_provider_
->GetFrameDataAndRefResources(observer1
, &damage
);
220 frame_provider_
->GetFrameDataAndRefResources(observer2
, &damage
);
222 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
224 // Release both refs. But there's still a ref held in the frame
226 frame_provider_
->UnrefResourcesOnMainThread(returned
);
227 frame_provider_
->UnrefResourcesOnMainThread(returned
);
228 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
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());
236 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
237 EXPECT_EQ(1u, resources_
.size());
238 EXPECT_EQ(444u, resources_
[0].id
);
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);
247 TransferableResourceArray reffed
= frame
->resource_list
;
248 ReturnedResourceArray returned
;
249 TransferableResource::ReturnResources(reffed
, &returned
);
251 SetFrameProvider(frame
.Pass());
253 scoped_refptr
<DelegatedRendererLayer
> observer1
=
254 DelegatedRendererLayer::Create(frame_provider_
);
255 scoped_refptr
<DelegatedRendererLayer
> observer2
=
256 DelegatedRendererLayer::Create(frame_provider_
);
260 // Take a ref on each observer.
261 frame_provider_
->GetFrameDataAndRefResources(observer1
, &damage
);
262 frame_provider_
->GetFrameDataAndRefResources(observer2
, &damage
);
264 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
266 // Release both refs. But there's still a ref held in the frame
268 frame_provider_
->UnrefResourcesOnMainThread(returned
);
269 frame_provider_
->UnrefResourcesOnMainThread(returned
);
270 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
272 // Releasing all references to the frame provider will release
276 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
278 frame_provider_
= NULL
;
280 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
281 EXPECT_EQ(1u, resources_
.size());
282 EXPECT_EQ(444u, resources_
[0].id
);
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);
291 TransferableResourceArray reffed
= frame
->resource_list
;
292 ReturnedResourceArray returned
;
293 TransferableResource::ReturnResources(reffed
, &returned
);
295 SetFrameProvider(frame
.Pass());
297 scoped_refptr
<DelegatedRendererLayer
> observer1
=
298 DelegatedRendererLayer::Create(frame_provider_
);
299 scoped_refptr
<DelegatedRendererLayer
> observer2
=
300 DelegatedRendererLayer::Create(frame_provider_
);
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());
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());
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());
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());
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());
334 TEST_F(DelegatedFrameProviderTest
, LostNothing
) {
335 scoped_ptr
<DelegatedFrameData
> frame
=
336 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
338 TransferableResourceArray reffed
= frame
->resource_list
;
340 SetFrameProvider(frame
.Pass());
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());
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);
355 SetFrameProvider(frame
.Pass());
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);
362 SetFrameProvider(frame
.Pass());
364 // There is something to lose.
365 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
366 EXPECT_TRUE(resource_collection_
->LoseAllResources());
367 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
369 EXPECT_EQ(1u, resources_
.size());
370 EXPECT_EQ(444u, resources_
[0].id
);
371 EXPECT_EQ(2, resources_
[0].count
);
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());
381 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
383 // Lose all the resources.
384 EXPECT_TRUE(resource_collection_
->LoseAllResources());
385 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
388 frame_provider_
= NULL
;
390 // Nothing is returned twice.
391 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
392 EXPECT_EQ(0u, resources_
.size());