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 "cc/trees/layer_tree_settings.h"
13 #include "testing/gtest/include/gtest/gtest.h"
18 class DelegatedFrameProviderTest
19 : public testing::Test
,
20 public DelegatedFrameResourceCollectionClient
{
22 DelegatedFrameProviderTest() : resources_available_(false) {}
24 scoped_ptr
<DelegatedFrameData
> CreateFrameData(
25 const gfx::Rect
& root_output_rect
,
26 const gfx::Rect
& root_damage_rect
) {
27 scoped_ptr
<DelegatedFrameData
> frame(new DelegatedFrameData
);
29 scoped_ptr
<RenderPass
> root_pass(RenderPass::Create());
30 root_pass
->SetNew(RenderPassId(1, 1),
34 frame
->render_pass_list
.push_back(root_pass
.Pass());
38 void AddTransferableResource(DelegatedFrameData
* frame
,
39 ResourceId resource_id
) {
40 TransferableResource resource
;
41 resource
.id
= resource_id
;
42 resource
.mailbox_holder
.texture_target
= GL_TEXTURE_2D
;
43 frame
->resource_list
.push_back(resource
);
46 void AddTextureQuad(DelegatedFrameData
* frame
, 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_
;
93 LayerSettings layer_settings_
;
96 TEST_F(DelegatedFrameProviderTest
, SameResources
) {
97 scoped_ptr
<DelegatedFrameData
> frame
=
98 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
99 AddTextureQuad(frame
.get(), 444);
100 AddTransferableResource(frame
.get(), 444);
101 SetFrameProvider(frame
.Pass());
103 frame
= CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
104 AddTextureQuad(frame
.get(), 444);
105 AddTransferableResource(frame
.get(), 444);
106 SetFrameProvider(frame
.Pass());
108 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
109 EXPECT_EQ(0u, resources_
.size());
111 frame_provider_
= nullptr;
113 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
114 EXPECT_EQ(1u, resources_
.size());
115 EXPECT_EQ(444u, resources_
[0].id
);
118 TEST_F(DelegatedFrameProviderTest
, ReplaceResources
) {
119 scoped_ptr
<DelegatedFrameData
> frame
=
120 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
121 AddTextureQuad(frame
.get(), 444);
122 AddTransferableResource(frame
.get(), 444);
123 SetFrameProvider(frame
.Pass());
125 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
127 frame
= CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
128 AddTextureQuad(frame
.get(), 555);
129 AddTransferableResource(frame
.get(), 555);
130 SetFrameProvider(frame
.Pass());
132 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
133 EXPECT_EQ(1u, resources_
.size());
134 EXPECT_EQ(444u, resources_
[0].id
);
137 frame_provider_
= nullptr;
139 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
140 EXPECT_EQ(1u, resources_
.size());
141 EXPECT_EQ(555u, resources_
[0].id
);
144 TEST_F(DelegatedFrameProviderTest
, RefResources
) {
145 scoped_ptr
<DelegatedFrameData
> frame
=
146 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
147 AddTextureQuad(frame
.get(), 444);
148 AddTransferableResource(frame
.get(), 444);
150 TransferableResourceArray reffed
= frame
->resource_list
;
151 ReturnedResourceArray returned
;
152 TransferableResource::ReturnResources(reffed
, &returned
);
154 SetFrameProvider(frame
.Pass());
156 scoped_refptr
<DelegatedRendererLayer
> observer1
=
157 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
158 scoped_refptr
<DelegatedRendererLayer
> observer2
=
159 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
163 // Both observers get a full frame of damage on the first request.
164 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
165 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
166 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
167 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
169 // And both get no damage on the 2nd request. This adds a second ref to the
171 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
172 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
173 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
174 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
176 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
178 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
179 AddTextureQuad(frame
.get(), 555);
180 AddTransferableResource(frame
.get(), 555);
181 frame_provider_
->SetFrameData(frame
.Pass());
183 // The resources from the first frame are still reffed by the observers.
184 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
186 // There are 4 refs taken.
187 frame_provider_
->UnrefResourcesOnMainThread(returned
);
188 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
189 frame_provider_
->UnrefResourcesOnMainThread(returned
);
190 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
191 frame_provider_
->UnrefResourcesOnMainThread(returned
);
192 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
194 // The 4th unref will release them.
195 frame_provider_
->UnrefResourcesOnMainThread(returned
);
197 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
198 EXPECT_EQ(1u, resources_
.size());
199 EXPECT_EQ(444u, resources_
[0].id
);
202 TEST_F(DelegatedFrameProviderTest
, RefResourcesInFrameProvider
) {
203 scoped_ptr
<DelegatedFrameData
> frame
=
204 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
205 AddTextureQuad(frame
.get(), 444);
206 AddTransferableResource(frame
.get(), 444);
208 TransferableResourceArray reffed
= frame
->resource_list
;
209 ReturnedResourceArray returned
;
210 TransferableResource::ReturnResources(reffed
, &returned
);
212 SetFrameProvider(frame
.Pass());
214 scoped_refptr
<DelegatedRendererLayer
> observer1
=
215 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
216 scoped_refptr
<DelegatedRendererLayer
> observer2
=
217 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
221 // Take a ref on each observer.
222 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
223 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
225 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
227 // Release both refs. But there's still a ref held in the frame
229 frame_provider_
->UnrefResourcesOnMainThread(returned
);
230 frame_provider_
->UnrefResourcesOnMainThread(returned
);
231 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
233 // Setting a new frame will release it.
234 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
235 AddTextureQuad(frame
.get(), 555);
236 AddTransferableResource(frame
.get(), 555);
237 frame_provider_
->SetFrameData(frame
.Pass());
239 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
240 EXPECT_EQ(1u, resources_
.size());
241 EXPECT_EQ(444u, resources_
[0].id
);
244 TEST_F(DelegatedFrameProviderTest
, RefResourcesInFrameProviderUntilDestroy
) {
245 scoped_ptr
<DelegatedFrameData
> frame
=
246 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
247 AddTextureQuad(frame
.get(), 444);
248 AddTransferableResource(frame
.get(), 444);
250 TransferableResourceArray reffed
= frame
->resource_list
;
251 ReturnedResourceArray returned
;
252 TransferableResource::ReturnResources(reffed
, &returned
);
254 SetFrameProvider(frame
.Pass());
256 scoped_refptr
<DelegatedRendererLayer
> observer1
=
257 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
258 scoped_refptr
<DelegatedRendererLayer
> observer2
=
259 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
263 // Take a ref on each observer.
264 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
265 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
267 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
269 // Release both refs. But there's still a ref held in the frame
271 frame_provider_
->UnrefResourcesOnMainThread(returned
);
272 frame_provider_
->UnrefResourcesOnMainThread(returned
);
273 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
275 // Releasing all references to the frame provider will release
279 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
281 frame_provider_
= nullptr;
283 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
284 EXPECT_EQ(1u, resources_
.size());
285 EXPECT_EQ(444u, resources_
[0].id
);
288 TEST_F(DelegatedFrameProviderTest
, Damage
) {
289 scoped_ptr
<DelegatedFrameData
> frame
=
290 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
291 AddTextureQuad(frame
.get(), 444);
292 AddTransferableResource(frame
.get(), 444);
294 TransferableResourceArray reffed
= frame
->resource_list
;
295 ReturnedResourceArray returned
;
296 TransferableResource::ReturnResources(reffed
, &returned
);
298 SetFrameProvider(frame
.Pass());
300 scoped_refptr
<DelegatedRendererLayer
> observer1
=
301 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
302 scoped_refptr
<DelegatedRendererLayer
> observer2
=
303 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
307 // Both observers get a full frame of damage on the first request.
308 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
309 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
310 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
311 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
313 // And both get no damage on the 2nd request.
314 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
315 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
316 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
317 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
319 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
320 AddTextureQuad(frame
.get(), 555);
321 AddTransferableResource(frame
.get(), 555);
322 frame_provider_
->SetFrameData(frame
.Pass());
324 // Both observers get the damage for the new frame.
325 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
326 EXPECT_EQ(gfx::RectF(2.f
, 2.f
).ToString(), damage
.ToString());
327 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
328 EXPECT_EQ(gfx::RectF(2.f
, 2.f
).ToString(), damage
.ToString());
330 // And both get no damage on the 2nd request.
331 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
332 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
333 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
334 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
337 TEST_F(DelegatedFrameProviderTest
, LostNothing
) {
338 scoped_ptr
<DelegatedFrameData
> frame
=
339 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
341 TransferableResourceArray reffed
= frame
->resource_list
;
343 SetFrameProvider(frame
.Pass());
345 // There is nothing to lose.
346 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
347 EXPECT_FALSE(resource_collection_
->LoseAllResources());
348 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
349 EXPECT_EQ(0u, resources_
.size());
352 TEST_F(DelegatedFrameProviderTest
, LostSomething
) {
353 scoped_ptr
<DelegatedFrameData
> frame
=
354 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
355 AddTextureQuad(frame
.get(), 444);
356 AddTransferableResource(frame
.get(), 444);
358 SetFrameProvider(frame
.Pass());
360 // Add a second reference on the resource.
361 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
362 AddTextureQuad(frame
.get(), 444);
363 AddTransferableResource(frame
.get(), 444);
365 SetFrameProvider(frame
.Pass());
367 // There is something to lose.
368 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
369 EXPECT_TRUE(resource_collection_
->LoseAllResources());
370 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
372 EXPECT_EQ(1u, resources_
.size());
373 EXPECT_EQ(444u, resources_
[0].id
);
374 EXPECT_EQ(2, resources_
[0].count
);
377 TEST_F(DelegatedFrameProviderTest
, NothingReturnedAfterLoss
) {
378 scoped_ptr
<DelegatedFrameData
> frame
=
379 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
380 AddTextureQuad(frame
.get(), 444);
381 AddTransferableResource(frame
.get(), 444);
382 SetFrameProvider(frame
.Pass());
384 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
386 // Lose all the resources.
387 EXPECT_TRUE(resource_collection_
->LoseAllResources());
388 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
391 frame_provider_
= nullptr;
393 // Nothing is returned twice.
394 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
395 EXPECT_EQ(0u, resources_
.size());