Changes to RenderFrameProxy:
[chromium-blink-merge.git] / cc / layers / delegated_frame_provider_unittest.cc
blob88936d719b89d45581cab4fbd429ec8479b61c6c
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"
14 namespace cc {
15 namespace {
17 class DelegatedFrameProviderTest
18 : public testing::Test,
19 public DelegatedFrameResourceCollectionClient {
20 protected:
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(RenderPass::Id(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();
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};
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);
65 virtual void SetUp() OVERRIDE {
66 resource_collection_ = new DelegatedFrameResourceCollection;
67 resource_collection_->SetClient(this);
70 virtual void TearDown() OVERRIDE { resource_collection_->SetClient(NULL); }
72 virtual void UnusedResourcesAreAvailable() OVERRIDE {
73 resources_available_ = true;
74 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources_);
77 bool ReturnAndResetResourcesAvailable() {
78 bool r = resources_available_;
79 resources_available_ = false;
80 return r;
83 void SetFrameProvider(scoped_ptr<DelegatedFrameData> frame_data) {
84 frame_provider_ =
85 new DelegatedFrameProvider(resource_collection_, frame_data.Pass());
88 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
89 scoped_refptr<DelegatedFrameProvider> frame_provider_;
90 bool resources_available_;
91 ReturnedResourceArray resources_;
94 TEST_F(DelegatedFrameProviderTest, SameResources) {
95 scoped_ptr<DelegatedFrameData> frame =
96 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
97 AddTextureQuad(frame.get(), 444);
98 AddTransferableResource(frame.get(), 444);
99 SetFrameProvider(frame.Pass());
101 frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
102 AddTextureQuad(frame.get(), 444);
103 AddTransferableResource(frame.get(), 444);
104 SetFrameProvider(frame.Pass());
106 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
107 EXPECT_EQ(0u, resources_.size());
109 frame_provider_ = NULL;
111 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
112 EXPECT_EQ(1u, resources_.size());
113 EXPECT_EQ(444u, resources_[0].id);
116 TEST_F(DelegatedFrameProviderTest, ReplaceResources) {
117 scoped_ptr<DelegatedFrameData> frame =
118 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
119 AddTextureQuad(frame.get(), 444);
120 AddTransferableResource(frame.get(), 444);
121 SetFrameProvider(frame.Pass());
123 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
125 frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
126 AddTextureQuad(frame.get(), 555);
127 AddTransferableResource(frame.get(), 555);
128 SetFrameProvider(frame.Pass());
130 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
131 EXPECT_EQ(1u, resources_.size());
132 EXPECT_EQ(444u, resources_[0].id);
133 resources_.clear();
135 frame_provider_ = NULL;
137 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
138 EXPECT_EQ(1u, resources_.size());
139 EXPECT_EQ(555u, resources_[0].id);
142 TEST_F(DelegatedFrameProviderTest, RefResources) {
143 scoped_ptr<DelegatedFrameData> frame =
144 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
145 AddTextureQuad(frame.get(), 444);
146 AddTransferableResource(frame.get(), 444);
148 TransferableResourceArray reffed = frame->resource_list;
149 ReturnedResourceArray returned;
150 TransferableResource::ReturnResources(reffed, &returned);
152 SetFrameProvider(frame.Pass());
154 scoped_refptr<DelegatedRendererLayer> observer1 =
155 DelegatedRendererLayer::Create(frame_provider_);
156 scoped_refptr<DelegatedRendererLayer> observer2 =
157 DelegatedRendererLayer::Create(frame_provider_);
159 gfx::RectF damage;
161 // Both observers get a full frame of damage on the first request.
162 frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
163 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
164 frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
165 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
167 // And both get no damage on the 2nd request. This adds a second ref to the
168 // resources.
169 frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
170 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
171 frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
172 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
174 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
176 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
177 AddTextureQuad(frame.get(), 555);
178 AddTransferableResource(frame.get(), 555);
179 frame_provider_->SetFrameData(frame.Pass());
181 // The resources from the first frame are still reffed by the observers.
182 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
184 // There are 4 refs taken.
185 frame_provider_->UnrefResourcesOnMainThread(returned);
186 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
187 frame_provider_->UnrefResourcesOnMainThread(returned);
188 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
189 frame_provider_->UnrefResourcesOnMainThread(returned);
190 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
192 // The 4th unref will release them.
193 frame_provider_->UnrefResourcesOnMainThread(returned);
195 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
196 EXPECT_EQ(1u, resources_.size());
197 EXPECT_EQ(444u, resources_[0].id);
200 TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProvider) {
201 scoped_ptr<DelegatedFrameData> frame =
202 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
203 AddTextureQuad(frame.get(), 444);
204 AddTransferableResource(frame.get(), 444);
206 TransferableResourceArray reffed = frame->resource_list;
207 ReturnedResourceArray returned;
208 TransferableResource::ReturnResources(reffed, &returned);
210 SetFrameProvider(frame.Pass());
212 scoped_refptr<DelegatedRendererLayer> observer1 =
213 DelegatedRendererLayer::Create(frame_provider_);
214 scoped_refptr<DelegatedRendererLayer> observer2 =
215 DelegatedRendererLayer::Create(frame_provider_);
217 gfx::RectF damage;
219 // Take a ref on each observer.
220 frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
221 frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
223 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
225 // Release both refs. But there's still a ref held in the frame
226 // provider itself.
227 frame_provider_->UnrefResourcesOnMainThread(returned);
228 frame_provider_->UnrefResourcesOnMainThread(returned);
229 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
231 // Setting a new frame will release it.
232 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
233 AddTextureQuad(frame.get(), 555);
234 AddTransferableResource(frame.get(), 555);
235 frame_provider_->SetFrameData(frame.Pass());
237 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
238 EXPECT_EQ(1u, resources_.size());
239 EXPECT_EQ(444u, resources_[0].id);
242 TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProviderUntilDestroy) {
243 scoped_ptr<DelegatedFrameData> frame =
244 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
245 AddTextureQuad(frame.get(), 444);
246 AddTransferableResource(frame.get(), 444);
248 TransferableResourceArray reffed = frame->resource_list;
249 ReturnedResourceArray returned;
250 TransferableResource::ReturnResources(reffed, &returned);
252 SetFrameProvider(frame.Pass());
254 scoped_refptr<DelegatedRendererLayer> observer1 =
255 DelegatedRendererLayer::Create(frame_provider_);
256 scoped_refptr<DelegatedRendererLayer> observer2 =
257 DelegatedRendererLayer::Create(frame_provider_);
259 gfx::RectF damage;
261 // Take a ref on each observer.
262 frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
263 frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
265 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
267 // Release both refs. But there's still a ref held in the frame
268 // provider itself.
269 frame_provider_->UnrefResourcesOnMainThread(returned);
270 frame_provider_->UnrefResourcesOnMainThread(returned);
271 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
273 // Releasing all references to the frame provider will release
274 // the frame.
275 observer1 = NULL;
276 observer2 = NULL;
277 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
279 frame_provider_ = NULL;
281 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
282 EXPECT_EQ(1u, resources_.size());
283 EXPECT_EQ(444u, resources_[0].id);
286 TEST_F(DelegatedFrameProviderTest, Damage) {
287 scoped_ptr<DelegatedFrameData> frame =
288 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
289 AddTextureQuad(frame.get(), 444);
290 AddTransferableResource(frame.get(), 444);
292 TransferableResourceArray reffed = frame->resource_list;
293 ReturnedResourceArray returned;
294 TransferableResource::ReturnResources(reffed, &returned);
296 SetFrameProvider(frame.Pass());
298 scoped_refptr<DelegatedRendererLayer> observer1 =
299 DelegatedRendererLayer::Create(frame_provider_);
300 scoped_refptr<DelegatedRendererLayer> observer2 =
301 DelegatedRendererLayer::Create(frame_provider_);
303 gfx::RectF damage;
305 // Both observers get a full frame of damage on the first request.
306 frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
307 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
308 frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
309 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
311 // And both get no damage on the 2nd request.
312 frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
313 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
314 frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
315 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
317 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
318 AddTextureQuad(frame.get(), 555);
319 AddTransferableResource(frame.get(), 555);
320 frame_provider_->SetFrameData(frame.Pass());
322 // Both observers get the damage for the new frame.
323 frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
324 EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString());
325 frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
326 EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString());
328 // And both get no damage on the 2nd request.
329 frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
330 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
331 frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
332 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
335 TEST_F(DelegatedFrameProviderTest, LostNothing) {
336 scoped_ptr<DelegatedFrameData> frame =
337 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
339 TransferableResourceArray reffed = frame->resource_list;
341 SetFrameProvider(frame.Pass());
343 // There is nothing to lose.
344 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
345 EXPECT_FALSE(resource_collection_->LoseAllResources());
346 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
347 EXPECT_EQ(0u, resources_.size());
350 TEST_F(DelegatedFrameProviderTest, LostSomething) {
351 scoped_ptr<DelegatedFrameData> frame =
352 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
353 AddTextureQuad(frame.get(), 444);
354 AddTransferableResource(frame.get(), 444);
356 SetFrameProvider(frame.Pass());
358 // Add a second reference on the resource.
359 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5));
360 AddTextureQuad(frame.get(), 444);
361 AddTransferableResource(frame.get(), 444);
363 SetFrameProvider(frame.Pass());
365 // There is something to lose.
366 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
367 EXPECT_TRUE(resource_collection_->LoseAllResources());
368 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
370 EXPECT_EQ(1u, resources_.size());
371 EXPECT_EQ(444u, resources_[0].id);
372 EXPECT_EQ(2, resources_[0].count);
375 TEST_F(DelegatedFrameProviderTest, NothingReturnedAfterLoss) {
376 scoped_ptr<DelegatedFrameData> frame =
377 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
378 AddTextureQuad(frame.get(), 444);
379 AddTransferableResource(frame.get(), 444);
380 SetFrameProvider(frame.Pass());
382 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
384 // Lose all the resources.
385 EXPECT_TRUE(resource_collection_->LoseAllResources());
386 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
387 resources_.clear();
389 frame_provider_ = NULL;
391 // Nothing is returned twice.
392 EXPECT_FALSE(ReturnAndResetResourcesAvailable());
393 EXPECT_EQ(0u, resources_.size());
396 } // namespace
397 } // namespace cc