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/resource_provider.h"
11 #include "cc/resources/returned_resource.h"
12 #include "cc/resources/transferable_resource.h"
13 #include "cc/trees/layer_tree_settings.h"
14 #include "testing/gtest/include/gtest/gtest.h"
19 class DelegatedFrameProviderTest
20 : public testing::Test
,
21 public DelegatedFrameResourceCollectionClient
{
23 DelegatedFrameProviderTest() : resources_available_(false) {}
25 scoped_ptr
<DelegatedFrameData
> CreateFrameData(
26 const gfx::Rect
& root_output_rect
,
27 const gfx::Rect
& root_damage_rect
) {
28 scoped_ptr
<DelegatedFrameData
> frame(new DelegatedFrameData
);
30 scoped_ptr
<RenderPass
> root_pass(RenderPass::Create());
31 root_pass
->SetNew(RenderPassId(1, 1),
35 frame
->render_pass_list
.push_back(root_pass
.Pass());
39 void AddTransferableResource(DelegatedFrameData
* frame
,
40 ResourceId resource_id
) {
41 TransferableResource resource
;
42 resource
.id
= resource_id
;
43 resource
.mailbox_holder
.texture_target
= GL_TEXTURE_2D
;
44 frame
->resource_list
.push_back(resource
);
47 void AddTextureQuad(DelegatedFrameData
* frame
, ResourceId resource_id
) {
48 SharedQuadState
* sqs
=
49 frame
->render_pass_list
[0]->CreateAndAppendSharedQuadState();
50 TextureDrawQuad
* quad
=
51 frame
->render_pass_list
[0]->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
52 float vertex_opacity
[4] = {1.f
, 1.f
, 1.f
, 1.f
};
54 gfx::Rect(0, 0, 10, 10),
55 gfx::Rect(0, 0, 10, 10),
56 gfx::Rect(0, 0, 10, 10),
59 gfx::PointF(0.f
, 0.f
),
60 gfx::PointF(1.f
, 1.f
),
67 void SetUp() override
{
68 resource_collection_
= new DelegatedFrameResourceCollection
;
69 resource_collection_
->SetClient(this);
72 void TearDown() override
{ resource_collection_
->SetClient(nullptr); }
74 void UnusedResourcesAreAvailable() override
{
75 resources_available_
= true;
76 resource_collection_
->TakeUnusedResourcesForChildCompositor(&resources_
);
79 bool ReturnAndResetResourcesAvailable() {
80 bool r
= resources_available_
;
81 resources_available_
= false;
85 void SetFrameProvider(scoped_ptr
<DelegatedFrameData
> frame_data
) {
87 new DelegatedFrameProvider(resource_collection_
, frame_data
.Pass());
90 scoped_refptr
<DelegatedFrameResourceCollection
> resource_collection_
;
91 scoped_refptr
<DelegatedFrameProvider
> frame_provider_
;
92 bool resources_available_
;
93 ReturnedResourceArray resources_
;
94 LayerSettings layer_settings_
;
97 TEST_F(DelegatedFrameProviderTest
, SameResources
) {
98 scoped_ptr
<DelegatedFrameData
> frame
=
99 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
100 AddTextureQuad(frame
.get(), 444);
101 AddTransferableResource(frame
.get(), 444);
102 SetFrameProvider(frame
.Pass());
104 frame
= CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
105 AddTextureQuad(frame
.get(), 444);
106 AddTransferableResource(frame
.get(), 444);
107 SetFrameProvider(frame
.Pass());
109 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
110 EXPECT_EQ(0u, resources_
.size());
112 frame_provider_
= nullptr;
114 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
115 EXPECT_EQ(1u, resources_
.size());
116 EXPECT_EQ(444u, resources_
[0].id
);
119 TEST_F(DelegatedFrameProviderTest
, ReplaceResources
) {
120 scoped_ptr
<DelegatedFrameData
> frame
=
121 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
122 AddTextureQuad(frame
.get(), 444);
123 AddTransferableResource(frame
.get(), 444);
124 SetFrameProvider(frame
.Pass());
126 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
128 frame
= CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
129 AddTextureQuad(frame
.get(), 555);
130 AddTransferableResource(frame
.get(), 555);
131 SetFrameProvider(frame
.Pass());
133 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
134 EXPECT_EQ(1u, resources_
.size());
135 EXPECT_EQ(444u, resources_
[0].id
);
138 frame_provider_
= nullptr;
140 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
141 EXPECT_EQ(1u, resources_
.size());
142 EXPECT_EQ(555u, resources_
[0].id
);
145 TEST_F(DelegatedFrameProviderTest
, RefResources
) {
146 scoped_ptr
<DelegatedFrameData
> frame
=
147 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
148 AddTextureQuad(frame
.get(), 444);
149 AddTransferableResource(frame
.get(), 444);
151 TransferableResourceArray reffed
= frame
->resource_list
;
152 ReturnedResourceArray returned
;
153 TransferableResource::ReturnResources(reffed
, &returned
);
155 SetFrameProvider(frame
.Pass());
157 scoped_refptr
<DelegatedRendererLayer
> observer1
=
158 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
159 scoped_refptr
<DelegatedRendererLayer
> observer2
=
160 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
164 // Both observers get a full frame of damage on the first request.
165 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
166 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
167 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
168 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
170 // And both get no damage on the 2nd request. This adds a second ref to the
172 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
173 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
174 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
175 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
177 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
179 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
180 AddTextureQuad(frame
.get(), 555);
181 AddTransferableResource(frame
.get(), 555);
182 frame_provider_
->SetFrameData(frame
.Pass());
184 // The resources from the first frame are still reffed by the observers.
185 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
187 // There are 4 refs taken.
188 frame_provider_
->UnrefResourcesOnMainThread(returned
);
189 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
190 frame_provider_
->UnrefResourcesOnMainThread(returned
);
191 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
192 frame_provider_
->UnrefResourcesOnMainThread(returned
);
193 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
195 // The 4th unref will release them.
196 frame_provider_
->UnrefResourcesOnMainThread(returned
);
198 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
199 EXPECT_EQ(1u, resources_
.size());
200 EXPECT_EQ(444u, resources_
[0].id
);
203 TEST_F(DelegatedFrameProviderTest
, RefResourcesInFrameProvider
) {
204 scoped_ptr
<DelegatedFrameData
> frame
=
205 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
206 AddTextureQuad(frame
.get(), 444);
207 AddTransferableResource(frame
.get(), 444);
209 TransferableResourceArray reffed
= frame
->resource_list
;
210 ReturnedResourceArray returned
;
211 TransferableResource::ReturnResources(reffed
, &returned
);
213 SetFrameProvider(frame
.Pass());
215 scoped_refptr
<DelegatedRendererLayer
> observer1
=
216 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
217 scoped_refptr
<DelegatedRendererLayer
> observer2
=
218 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
222 // Take a ref on each observer.
223 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
224 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
226 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
228 // Release both refs. But there's still a ref held in the frame
230 frame_provider_
->UnrefResourcesOnMainThread(returned
);
231 frame_provider_
->UnrefResourcesOnMainThread(returned
);
232 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
234 // Setting a new frame will release it.
235 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
236 AddTextureQuad(frame
.get(), 555);
237 AddTransferableResource(frame
.get(), 555);
238 frame_provider_
->SetFrameData(frame
.Pass());
240 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
241 EXPECT_EQ(1u, resources_
.size());
242 EXPECT_EQ(444u, resources_
[0].id
);
245 TEST_F(DelegatedFrameProviderTest
, RefResourcesInFrameProviderUntilDestroy
) {
246 scoped_ptr
<DelegatedFrameData
> frame
=
247 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
248 AddTextureQuad(frame
.get(), 444);
249 AddTransferableResource(frame
.get(), 444);
251 TransferableResourceArray reffed
= frame
->resource_list
;
252 ReturnedResourceArray returned
;
253 TransferableResource::ReturnResources(reffed
, &returned
);
255 SetFrameProvider(frame
.Pass());
257 scoped_refptr
<DelegatedRendererLayer
> observer1
=
258 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
259 scoped_refptr
<DelegatedRendererLayer
> observer2
=
260 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
264 // Take a ref on each observer.
265 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
266 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
268 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
270 // Release both refs. But there's still a ref held in the frame
272 frame_provider_
->UnrefResourcesOnMainThread(returned
);
273 frame_provider_
->UnrefResourcesOnMainThread(returned
);
274 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
276 // Releasing all references to the frame provider will release
280 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
282 frame_provider_
= nullptr;
284 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
285 EXPECT_EQ(1u, resources_
.size());
286 EXPECT_EQ(444u, resources_
[0].id
);
289 TEST_F(DelegatedFrameProviderTest
, Damage
) {
290 scoped_ptr
<DelegatedFrameData
> frame
=
291 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
292 AddTextureQuad(frame
.get(), 444);
293 AddTransferableResource(frame
.get(), 444);
295 TransferableResourceArray reffed
= frame
->resource_list
;
296 ReturnedResourceArray returned
;
297 TransferableResource::ReturnResources(reffed
, &returned
);
299 SetFrameProvider(frame
.Pass());
301 scoped_refptr
<DelegatedRendererLayer
> observer1
=
302 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
303 scoped_refptr
<DelegatedRendererLayer
> observer2
=
304 DelegatedRendererLayer::Create(layer_settings_
, frame_provider_
);
308 // Both observers get a full frame of damage on the first request.
309 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
310 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
311 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
312 EXPECT_EQ(gfx::RectF(5.f
, 5.f
).ToString(), damage
.ToString());
314 // And both get no damage on the 2nd request.
315 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
316 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
317 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
318 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
320 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
321 AddTextureQuad(frame
.get(), 555);
322 AddTransferableResource(frame
.get(), 555);
323 frame_provider_
->SetFrameData(frame
.Pass());
325 // Both observers get the damage for the new frame.
326 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
327 EXPECT_EQ(gfx::RectF(2.f
, 2.f
).ToString(), damage
.ToString());
328 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
329 EXPECT_EQ(gfx::RectF(2.f
, 2.f
).ToString(), damage
.ToString());
331 // And both get no damage on the 2nd request.
332 frame_provider_
->GetFrameDataAndRefResources(observer1
.get(), &damage
);
333 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
334 frame_provider_
->GetFrameDataAndRefResources(observer2
.get(), &damage
);
335 EXPECT_EQ(gfx::RectF().ToString(), damage
.ToString());
338 TEST_F(DelegatedFrameProviderTest
, LostNothing
) {
339 scoped_ptr
<DelegatedFrameData
> frame
=
340 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
342 TransferableResourceArray reffed
= frame
->resource_list
;
344 SetFrameProvider(frame
.Pass());
346 // There is nothing to lose.
347 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
348 EXPECT_FALSE(resource_collection_
->LoseAllResources());
349 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
350 EXPECT_EQ(0u, resources_
.size());
353 TEST_F(DelegatedFrameProviderTest
, LostSomething
) {
354 scoped_ptr
<DelegatedFrameData
> frame
=
355 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
356 AddTextureQuad(frame
.get(), 444);
357 AddTransferableResource(frame
.get(), 444);
359 SetFrameProvider(frame
.Pass());
361 // Add a second reference on the resource.
362 frame
= CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
363 AddTextureQuad(frame
.get(), 444);
364 AddTransferableResource(frame
.get(), 444);
366 SetFrameProvider(frame
.Pass());
368 // There is something to lose.
369 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
370 EXPECT_TRUE(resource_collection_
->LoseAllResources());
371 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
373 EXPECT_EQ(1u, resources_
.size());
374 EXPECT_EQ(444u, resources_
[0].id
);
375 EXPECT_EQ(2, resources_
[0].count
);
378 TEST_F(DelegatedFrameProviderTest
, NothingReturnedAfterLoss
) {
379 scoped_ptr
<DelegatedFrameData
> frame
=
380 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
381 AddTextureQuad(frame
.get(), 444);
382 AddTransferableResource(frame
.get(), 444);
383 SetFrameProvider(frame
.Pass());
385 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
387 // Lose all the resources.
388 EXPECT_TRUE(resource_collection_
->LoseAllResources());
389 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
392 frame_provider_
= nullptr;
394 // Nothing is returned twice.
395 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
396 EXPECT_EQ(0u, resources_
.size());