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(RenderPassId(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
),
66 void SetUp() override
{
67 resource_collection_
= new DelegatedFrameResourceCollection
;
68 resource_collection_
->SetClient(this);
71 void TearDown() override
{ resource_collection_
->SetClient(nullptr); }
73 void UnusedResourcesAreAvailable() override
{
74 resources_available_
= true;
75 resource_collection_
->TakeUnusedResourcesForChildCompositor(&resources_
);
78 bool ReturnAndResetResourcesAvailable() {
79 bool r
= resources_available_
;
80 resources_available_
= false;
84 void SetFrameProvider(scoped_ptr
<DelegatedFrameData
> frame_data
) {
86 new DelegatedFrameProvider(resource_collection_
, frame_data
.Pass());
89 scoped_refptr
<DelegatedFrameResourceCollection
> resource_collection_
;
90 scoped_refptr
<DelegatedFrameProvider
> frame_provider_
;
91 bool resources_available_
;
92 ReturnedResourceArray resources_
;
95 TEST_F(DelegatedFrameProviderTest
, SameResources
) {
96 scoped_ptr
<DelegatedFrameData
> frame
=
97 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
98 AddTextureQuad(frame
.get(), 444);
99 AddTransferableResource(frame
.get(), 444);
100 SetFrameProvider(frame
.Pass());
102 frame
= CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
103 AddTextureQuad(frame
.get(), 444);
104 AddTransferableResource(frame
.get(), 444);
105 SetFrameProvider(frame
.Pass());
107 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
108 EXPECT_EQ(0u, resources_
.size());
110 frame_provider_
= nullptr;
112 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
113 EXPECT_EQ(1u, resources_
.size());
114 EXPECT_EQ(444u, resources_
[0].id
);
117 TEST_F(DelegatedFrameProviderTest
, ReplaceResources
) {
118 scoped_ptr
<DelegatedFrameData
> frame
=
119 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
120 AddTextureQuad(frame
.get(), 444);
121 AddTransferableResource(frame
.get(), 444);
122 SetFrameProvider(frame
.Pass());
124 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
126 frame
= CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
127 AddTextureQuad(frame
.get(), 555);
128 AddTransferableResource(frame
.get(), 555);
129 SetFrameProvider(frame
.Pass());
131 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
132 EXPECT_EQ(1u, resources_
.size());
133 EXPECT_EQ(444u, resources_
[0].id
);
136 frame_provider_
= nullptr;
138 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
139 EXPECT_EQ(1u, resources_
.size());
140 EXPECT_EQ(555u, resources_
[0].id
);
143 TEST_F(DelegatedFrameProviderTest
, RefResources
) {
144 scoped_ptr
<DelegatedFrameData
> frame
=
145 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
146 AddTextureQuad(frame
.get(), 444);
147 AddTransferableResource(frame
.get(), 444);
149 TransferableResourceArray reffed
= frame
->resource_list
;
150 ReturnedResourceArray returned
;
151 TransferableResource::ReturnResources(reffed
, &returned
);
153 SetFrameProvider(frame
.Pass());
155 scoped_refptr
<DelegatedRendererLayer
> observer1
=
156 DelegatedRendererLayer::Create(frame_provider_
);
157 scoped_refptr
<DelegatedRendererLayer
> observer2
=
158 DelegatedRendererLayer::Create(frame_provider_
);
162 // Both observers get a full frame of damage on the first request.
163 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
164 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
165 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
166 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
168 // And both get no damage on the 2nd request. This adds a second ref to the
170 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
171 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
172 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
173 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
175 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
177 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
178 AddTextureQuad(frame
.get(), 555);
179 AddTransferableResource(frame
.get(), 555);
180 frame_provider_
->SetFrameData(frame
.Pass());
182 // The resources from the first frame are still reffed by the observers.
183 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
185 // There are 4 refs taken.
186 frame_provider_
->UnrefResourcesOnMainThread(returned
);
187 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
188 frame_provider_
->UnrefResourcesOnMainThread(returned
);
189 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
190 frame_provider_
->UnrefResourcesOnMainThread(returned
);
191 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
193 // The 4th unref will release them.
194 frame_provider_
->UnrefResourcesOnMainThread(returned
);
196 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
197 EXPECT_EQ(1u, resources_
.size());
198 EXPECT_EQ(444u, resources_
[0].id
);
201 TEST_F(DelegatedFrameProviderTest
, RefResourcesInFrameProvider
) {
202 scoped_ptr
<DelegatedFrameData
> frame
=
203 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
204 AddTextureQuad(frame
.get(), 444);
205 AddTransferableResource(frame
.get(), 444);
207 TransferableResourceArray reffed
= frame
->resource_list
;
208 ReturnedResourceArray returned
;
209 TransferableResource::ReturnResources(reffed
, &returned
);
211 SetFrameProvider(frame
.Pass());
213 scoped_refptr
<DelegatedRendererLayer
> observer1
=
214 DelegatedRendererLayer::Create(frame_provider_
);
215 scoped_refptr
<DelegatedRendererLayer
> observer2
=
216 DelegatedRendererLayer::Create(frame_provider_
);
220 // Take a ref on each observer.
221 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
222 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
224 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
226 // Release both refs. But there's still a ref held in the frame
228 frame_provider_
->UnrefResourcesOnMainThread(returned
);
229 frame_provider_
->UnrefResourcesOnMainThread(returned
);
230 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
232 // Setting a new frame will release it.
233 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
234 AddTextureQuad(frame
.get(), 555);
235 AddTransferableResource(frame
.get(), 555);
236 frame_provider_
->SetFrameData(frame
.Pass());
238 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
239 EXPECT_EQ(1u, resources_
.size());
240 EXPECT_EQ(444u, resources_
[0].id
);
243 TEST_F(DelegatedFrameProviderTest
, RefResourcesInFrameProviderUntilDestroy
) {
244 scoped_ptr
<DelegatedFrameData
> frame
=
245 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
246 AddTextureQuad(frame
.get(), 444);
247 AddTransferableResource(frame
.get(), 444);
249 TransferableResourceArray reffed
= frame
->resource_list
;
250 ReturnedResourceArray returned
;
251 TransferableResource::ReturnResources(reffed
, &returned
);
253 SetFrameProvider(frame
.Pass());
255 scoped_refptr
<DelegatedRendererLayer
> observer1
=
256 DelegatedRendererLayer::Create(frame_provider_
);
257 scoped_refptr
<DelegatedRendererLayer
> observer2
=
258 DelegatedRendererLayer::Create(frame_provider_
);
262 // Take a ref on each observer.
263 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
264 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
266 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
268 // Release both refs. But there's still a ref held in the frame
270 frame_provider_
->UnrefResourcesOnMainThread(returned
);
271 frame_provider_
->UnrefResourcesOnMainThread(returned
);
272 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
274 // Releasing all references to the frame provider will release
278 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
280 frame_provider_
= nullptr;
282 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
283 EXPECT_EQ(1u, resources_
.size());
284 EXPECT_EQ(444u, resources_
[0].id
);
287 TEST_F(DelegatedFrameProviderTest
, Damage
) {
288 scoped_ptr
<DelegatedFrameData
> frame
=
289 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
290 AddTextureQuad(frame
.get(), 444);
291 AddTransferableResource(frame
.get(), 444);
293 TransferableResourceArray reffed
= frame
->resource_list
;
294 ReturnedResourceArray returned
;
295 TransferableResource::ReturnResources(reffed
, &returned
);
297 SetFrameProvider(frame
.Pass());
299 scoped_refptr
<DelegatedRendererLayer
> observer1
=
300 DelegatedRendererLayer::Create(frame_provider_
);
301 scoped_refptr
<DelegatedRendererLayer
> observer2
=
302 DelegatedRendererLayer::Create(frame_provider_
);
306 // Both observers get a full frame of damage on the first request.
307 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
308 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
309 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
310 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
312 // And both get no damage on the 2nd request.
313 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
314 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
315 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
316 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
318 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
319 AddTextureQuad(frame
.get(), 555);
320 AddTransferableResource(frame
.get(), 555);
321 frame_provider_
->SetFrameData(frame
.Pass());
323 // Both observers get the damage for the new frame.
324 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
325 EXPECT_EQ(gfx::RectF(2.f
, 2.f
).ToString(), damage
.ToString());
326 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
327 EXPECT_EQ(gfx::RectF(2.f
, 2.f
).ToString(), damage
.ToString());
329 // And both get no damage on the 2nd request.
330 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
331 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
332 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
333 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
336 TEST_F(DelegatedFrameProviderTest
, LostNothing
) {
337 scoped_ptr
<DelegatedFrameData
> frame
=
338 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
340 TransferableResourceArray reffed
= frame
->resource_list
;
342 SetFrameProvider(frame
.Pass());
344 // There is nothing to lose.
345 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
346 EXPECT_FALSE(resource_collection_
->LoseAllResources());
347 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
348 EXPECT_EQ(0u, resources_
.size());
351 TEST_F(DelegatedFrameProviderTest
, LostSomething
) {
352 scoped_ptr
<DelegatedFrameData
> frame
=
353 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
354 AddTextureQuad(frame
.get(), 444);
355 AddTransferableResource(frame
.get(), 444);
357 SetFrameProvider(frame
.Pass());
359 // Add a second reference on the resource.
360 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
361 AddTextureQuad(frame
.get(), 444);
362 AddTransferableResource(frame
.get(), 444);
364 SetFrameProvider(frame
.Pass());
366 // There is something to lose.
367 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
368 EXPECT_TRUE(resource_collection_
->LoseAllResources());
369 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
371 EXPECT_EQ(1u, resources_
.size());
372 EXPECT_EQ(444u, resources_
[0].id
);
373 EXPECT_EQ(2, resources_
[0].count
);
376 TEST_F(DelegatedFrameProviderTest
, NothingReturnedAfterLoss
) {
377 scoped_ptr
<DelegatedFrameData
> frame
=
378 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
379 AddTextureQuad(frame
.get(), 444);
380 AddTransferableResource(frame
.get(), 444);
381 SetFrameProvider(frame
.Pass());
383 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
385 // Lose all the resources.
386 EXPECT_TRUE(resource_collection_
->LoseAllResources());
387 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
390 frame_provider_
= nullptr;
392 // Nothing is returned twice.
393 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
394 EXPECT_EQ(0u, resources_
.size());