OLD | NEW |
| (Empty) |
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. | |
4 | |
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" | |
13 | |
14 namespace cc { | |
15 namespace { | |
16 | |
17 class DelegatedFrameProviderTest | |
18 : public testing::Test, | |
19 public DelegatedFrameResourceCollectionClient { | |
20 protected: | |
21 DelegatedFrameProviderTest() : resources_available_(false) {} | |
22 | |
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); | |
27 | |
28 scoped_ptr<RenderPass> root_pass(RenderPass::Create()); | |
29 root_pass->SetNew(RenderPassId(1, 1), | |
30 root_output_rect, | |
31 root_damage_rect, | |
32 gfx::Transform()); | |
33 frame->render_pass_list.push_back(root_pass.Pass()); | |
34 return frame.Pass(); | |
35 } | |
36 | |
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); | |
43 } | |
44 | |
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}; | |
52 quad->SetNew(sqs, | |
53 gfx::Rect(0, 0, 10, 10), | |
54 gfx::Rect(0, 0, 10, 10), | |
55 gfx::Rect(0, 0, 10, 10), | |
56 resource_id, | |
57 false, | |
58 gfx::PointF(0.f, 0.f), | |
59 gfx::PointF(1.f, 1.f), | |
60 SK_ColorTRANSPARENT, | |
61 vertex_opacity, | |
62 false, | |
63 false); | |
64 } | |
65 | |
66 void SetUp() override { | |
67 resource_collection_ = new DelegatedFrameResourceCollection; | |
68 resource_collection_->SetClient(this); | |
69 } | |
70 | |
71 void TearDown() override { resource_collection_->SetClient(nullptr); } | |
72 | |
73 void UnusedResourcesAreAvailable() override { | |
74 resources_available_ = true; | |
75 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources_); | |
76 } | |
77 | |
78 bool ReturnAndResetResourcesAvailable() { | |
79 bool r = resources_available_; | |
80 resources_available_ = false; | |
81 return r; | |
82 } | |
83 | |
84 void SetFrameProvider(scoped_ptr<DelegatedFrameData> frame_data) { | |
85 frame_provider_ = | |
86 new DelegatedFrameProvider(resource_collection_, frame_data.Pass()); | |
87 } | |
88 | |
89 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_; | |
90 scoped_refptr<DelegatedFrameProvider> frame_provider_; | |
91 bool resources_available_; | |
92 ReturnedResourceArray resources_; | |
93 }; | |
94 | |
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()); | |
101 | |
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()); | |
106 | |
107 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
108 EXPECT_EQ(0u, resources_.size()); | |
109 | |
110 frame_provider_ = nullptr; | |
111 | |
112 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); | |
113 EXPECT_EQ(1u, resources_.size()); | |
114 EXPECT_EQ(444u, resources_[0].id); | |
115 } | |
116 | |
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()); | |
123 | |
124 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
125 | |
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()); | |
130 | |
131 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); | |
132 EXPECT_EQ(1u, resources_.size()); | |
133 EXPECT_EQ(444u, resources_[0].id); | |
134 resources_.clear(); | |
135 | |
136 frame_provider_ = nullptr; | |
137 | |
138 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); | |
139 EXPECT_EQ(1u, resources_.size()); | |
140 EXPECT_EQ(555u, resources_[0].id); | |
141 } | |
142 | |
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); | |
148 | |
149 TransferableResourceArray reffed = frame->resource_list; | |
150 ReturnedResourceArray returned; | |
151 TransferableResource::ReturnResources(reffed, &returned); | |
152 | |
153 SetFrameProvider(frame.Pass()); | |
154 | |
155 scoped_refptr<DelegatedRendererLayer> observer1 = | |
156 DelegatedRendererLayer::Create(frame_provider_); | |
157 scoped_refptr<DelegatedRendererLayer> observer2 = | |
158 DelegatedRendererLayer::Create(frame_provider_); | |
159 | |
160 gfx::RectF damage; | |
161 | |
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()); | |
167 | |
168 // And both get no damage on the 2nd request. This adds a second ref to the | |
169 // resources. | |
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()); | |
174 | |
175 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
176 | |
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()); | |
181 | |
182 // The resources from the first frame are still reffed by the observers. | |
183 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
184 | |
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()); | |
192 | |
193 // The 4th unref will release them. | |
194 frame_provider_->UnrefResourcesOnMainThread(returned); | |
195 | |
196 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); | |
197 EXPECT_EQ(1u, resources_.size()); | |
198 EXPECT_EQ(444u, resources_[0].id); | |
199 } | |
200 | |
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); | |
206 | |
207 TransferableResourceArray reffed = frame->resource_list; | |
208 ReturnedResourceArray returned; | |
209 TransferableResource::ReturnResources(reffed, &returned); | |
210 | |
211 SetFrameProvider(frame.Pass()); | |
212 | |
213 scoped_refptr<DelegatedRendererLayer> observer1 = | |
214 DelegatedRendererLayer::Create(frame_provider_); | |
215 scoped_refptr<DelegatedRendererLayer> observer2 = | |
216 DelegatedRendererLayer::Create(frame_provider_); | |
217 | |
218 gfx::RectF damage; | |
219 | |
220 // Take a ref on each observer. | |
221 frame_provider_->GetFrameDataAndRefResources(observer1.get(), &damage); | |
222 frame_provider_->GetFrameDataAndRefResources(observer2.get(), &damage); | |
223 | |
224 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
225 | |
226 // Release both refs. But there's still a ref held in the frame | |
227 // provider itself. | |
228 frame_provider_->UnrefResourcesOnMainThread(returned); | |
229 frame_provider_->UnrefResourcesOnMainThread(returned); | |
230 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
231 | |
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()); | |
237 | |
238 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); | |
239 EXPECT_EQ(1u, resources_.size()); | |
240 EXPECT_EQ(444u, resources_[0].id); | |
241 } | |
242 | |
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); | |
248 | |
249 TransferableResourceArray reffed = frame->resource_list; | |
250 ReturnedResourceArray returned; | |
251 TransferableResource::ReturnResources(reffed, &returned); | |
252 | |
253 SetFrameProvider(frame.Pass()); | |
254 | |
255 scoped_refptr<DelegatedRendererLayer> observer1 = | |
256 DelegatedRendererLayer::Create(frame_provider_); | |
257 scoped_refptr<DelegatedRendererLayer> observer2 = | |
258 DelegatedRendererLayer::Create(frame_provider_); | |
259 | |
260 gfx::RectF damage; | |
261 | |
262 // Take a ref on each observer. | |
263 frame_provider_->GetFrameDataAndRefResources(observer1.get(), &damage); | |
264 frame_provider_->GetFrameDataAndRefResources(observer2.get(), &damage); | |
265 | |
266 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
267 | |
268 // Release both refs. But there's still a ref held in the frame | |
269 // provider itself. | |
270 frame_provider_->UnrefResourcesOnMainThread(returned); | |
271 frame_provider_->UnrefResourcesOnMainThread(returned); | |
272 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
273 | |
274 // Releasing all references to the frame provider will release | |
275 // the frame. | |
276 observer1 = nullptr; | |
277 observer2 = nullptr; | |
278 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
279 | |
280 frame_provider_ = nullptr; | |
281 | |
282 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); | |
283 EXPECT_EQ(1u, resources_.size()); | |
284 EXPECT_EQ(444u, resources_[0].id); | |
285 } | |
286 | |
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); | |
292 | |
293 TransferableResourceArray reffed = frame->resource_list; | |
294 ReturnedResourceArray returned; | |
295 TransferableResource::ReturnResources(reffed, &returned); | |
296 | |
297 SetFrameProvider(frame.Pass()); | |
298 | |
299 scoped_refptr<DelegatedRendererLayer> observer1 = | |
300 DelegatedRendererLayer::Create(frame_provider_); | |
301 scoped_refptr<DelegatedRendererLayer> observer2 = | |
302 DelegatedRendererLayer::Create(frame_provider_); | |
303 | |
304 gfx::RectF damage; | |
305 | |
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()); | |
311 | |
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()); | |
317 | |
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()); | |
322 | |
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()); | |
328 | |
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()); | |
334 } | |
335 | |
336 TEST_F(DelegatedFrameProviderTest, LostNothing) { | |
337 scoped_ptr<DelegatedFrameData> frame = | |
338 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5)); | |
339 | |
340 TransferableResourceArray reffed = frame->resource_list; | |
341 | |
342 SetFrameProvider(frame.Pass()); | |
343 | |
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()); | |
349 } | |
350 | |
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); | |
356 | |
357 SetFrameProvider(frame.Pass()); | |
358 | |
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); | |
363 | |
364 SetFrameProvider(frame.Pass()); | |
365 | |
366 // There is something to lose. | |
367 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
368 EXPECT_TRUE(resource_collection_->LoseAllResources()); | |
369 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); | |
370 | |
371 EXPECT_EQ(1u, resources_.size()); | |
372 EXPECT_EQ(444u, resources_[0].id); | |
373 EXPECT_EQ(2, resources_[0].count); | |
374 } | |
375 | |
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()); | |
382 | |
383 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
384 | |
385 // Lose all the resources. | |
386 EXPECT_TRUE(resource_collection_->LoseAllResources()); | |
387 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); | |
388 resources_.clear(); | |
389 | |
390 frame_provider_ = nullptr; | |
391 | |
392 // Nothing is returned twice. | |
393 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); | |
394 EXPECT_EQ(0u, resources_.size()); | |
395 } | |
396 | |
397 } // namespace | |
398 } // namespace cc | |
OLD | NEW |