cc: Make a FakeResourceProvider and use it in tests to construct.
[chromium-blink-merge.git] / cc / layers / delegated_frame_provider_unittest.cc
blobaab9436256fe2fe888948dbade49eb0935aafd56
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"
15 namespace cc {
16 namespace {
18 class DelegatedFrameProviderTest
19 : public testing::Test,
20 public DelegatedFrameResourceCollectionClient {
21 protected:
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),
31 root_output_rect,
32 root_damage_rect,
33 gfx::Transform());
34 frame->render_pass_list.push_back(root_pass.Pass());
35 return frame.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};
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);
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;
81 return r;
84 void SetFrameProvider(scoped_ptr<DelegatedFrameData> frame_data) {
85 frame_provider_ =
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);
135 resources_.clear();
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_);
161 gfx::RectF damage;
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
170 // resources.
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_);
219 gfx::RectF damage;
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
228 // provider itself.
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_);
261 gfx::RectF damage;
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
270 // provider itself.
271 frame_provider_->UnrefResourcesOnMainThread(returned);
272 frame_provider_->UnrefResourcesOnMainThread(returned);
273 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
275 // Releasing all references to the frame provider will release
276 // the frame.
277 observer1 = nullptr;
278 observer2 = nullptr;
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_);
305 gfx::RectF damage;
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());
389 resources_.clear();
391 frame_provider_ = nullptr;
393 // Nothing is returned twice.
394 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
395 EXPECT_EQ(0u, resources_.size());
398 } // namespace
399 } // namespace cc