delegated_frame_provider_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 14namespace cc { 15namespace { 16 17class 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(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(); 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 scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create(); 48 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); 49 float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; 50 quad->SetNew(sqs.get(), 51 gfx::Rect(0, 0, 10, 10), 52 gfx::Rect(0, 0, 10, 10), 53 resource_id, 54 false, 55 gfx::PointF(0.f, 0.f), 56 gfx::PointF(1.f, 1.f), 57 SK_ColorTRANSPARENT, 58 vertex_opacity, 59 false); 60 frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass()); 61 frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>()); 62 } 63 64 virtual void SetUp() OVERRIDE { 65 resource_collection_ = new DelegatedFrameResourceCollection; 66 resource_collection_->SetClient(this); 67 } 68 69 virtual void TearDown() OVERRIDE { resource_collection_->SetClient(NULL); } 70 71 virtual void UnusedResourcesAreAvailable() OVERRIDE { 72 resources_available_ = true; 73 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources_); 74 } 75 76 bool ReturnAndResetResourcesAvailable() { 77 bool r = resources_available_; 78 resources_available_ = false; 79 return r; 80 } 81 82 void SetFrameProvider(scoped_ptr<DelegatedFrameData> frame_data) { 83 frame_provider_ = 84 new DelegatedFrameProvider(resource_collection_, frame_data.Pass()); 85 } 86 87 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_; 88 scoped_refptr<DelegatedFrameProvider> frame_provider_; 89 bool resources_available_; 90 ReturnedResourceArray resources_; 91}; 92 93TEST_F(DelegatedFrameProviderTest, SameResources) { 94 scoped_ptr<DelegatedFrameData> frame = 95 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); 96 AddTextureQuad(frame.get(), 444); 97 AddTransferableResource(frame.get(), 444); 98 SetFrameProvider(frame.Pass()); 99 100 frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); 101 AddTextureQuad(frame.get(), 444); 102 AddTransferableResource(frame.get(), 444); 103 SetFrameProvider(frame.Pass()); 104 105 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 106 EXPECT_EQ(0u, resources_.size()); 107 108 frame_provider_ = NULL; 109 110 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); 111 EXPECT_EQ(1u, resources_.size()); 112 EXPECT_EQ(444u, resources_[0].id); 113} 114 115TEST_F(DelegatedFrameProviderTest, ReplaceResources) { 116 scoped_ptr<DelegatedFrameData> frame = 117 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); 118 AddTextureQuad(frame.get(), 444); 119 AddTransferableResource(frame.get(), 444); 120 SetFrameProvider(frame.Pass()); 121 122 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 123 124 frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); 125 AddTextureQuad(frame.get(), 555); 126 AddTransferableResource(frame.get(), 555); 127 SetFrameProvider(frame.Pass()); 128 129 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); 130 EXPECT_EQ(1u, resources_.size()); 131 EXPECT_EQ(444u, resources_[0].id); 132 resources_.clear(); 133 134 frame_provider_ = NULL; 135 136 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); 137 EXPECT_EQ(1u, resources_.size()); 138 EXPECT_EQ(555u, resources_[0].id); 139} 140 141TEST_F(DelegatedFrameProviderTest, RefResources) { 142 scoped_ptr<DelegatedFrameData> frame = 143 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); 144 AddTextureQuad(frame.get(), 444); 145 AddTransferableResource(frame.get(), 444); 146 147 TransferableResourceArray reffed = frame->resource_list; 148 ReturnedResourceArray returned; 149 TransferableResource::ReturnResources(reffed, &returned); 150 151 SetFrameProvider(frame.Pass()); 152 153 scoped_refptr<DelegatedRendererLayer> observer1 = 154 DelegatedRendererLayer::Create(frame_provider_); 155 scoped_refptr<DelegatedRendererLayer> observer2 = 156 DelegatedRendererLayer::Create(frame_provider_); 157 158 gfx::RectF damage; 159 160 // Both observers get a full frame of damage on the first request. 161 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); 162 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString()); 163 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); 164 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString()); 165 166 // And both get no damage on the 2nd request. This adds a second ref to the 167 // resources. 168 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); 169 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); 170 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); 171 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); 172 173 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 174 175 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); 176 AddTextureQuad(frame.get(), 555); 177 AddTransferableResource(frame.get(), 555); 178 frame_provider_->SetFrameData(frame.Pass()); 179 180 // The resources from the first frame are still reffed by the observers. 181 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 182 183 // There are 4 refs taken. 184 frame_provider_->UnrefResourcesOnMainThread(returned); 185 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 186 frame_provider_->UnrefResourcesOnMainThread(returned); 187 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 188 frame_provider_->UnrefResourcesOnMainThread(returned); 189 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 190 191 // The 4th unref will release them. 192 frame_provider_->UnrefResourcesOnMainThread(returned); 193 194 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); 195 EXPECT_EQ(1u, resources_.size()); 196 EXPECT_EQ(444u, resources_[0].id); 197} 198 199TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProvider) { 200 scoped_ptr<DelegatedFrameData> frame = 201 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); 202 AddTextureQuad(frame.get(), 444); 203 AddTransferableResource(frame.get(), 444); 204 205 TransferableResourceArray reffed = frame->resource_list; 206 ReturnedResourceArray returned; 207 TransferableResource::ReturnResources(reffed, &returned); 208 209 SetFrameProvider(frame.Pass()); 210 211 scoped_refptr<DelegatedRendererLayer> observer1 = 212 DelegatedRendererLayer::Create(frame_provider_); 213 scoped_refptr<DelegatedRendererLayer> observer2 = 214 DelegatedRendererLayer::Create(frame_provider_); 215 216 gfx::RectF damage; 217 218 // Take a ref on each observer. 219 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); 220 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); 221 222 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 223 224 // Release both refs. But there's still a ref held in the frame 225 // provider itself. 226 frame_provider_->UnrefResourcesOnMainThread(returned); 227 frame_provider_->UnrefResourcesOnMainThread(returned); 228 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 229 230 // Setting a new frame will release it. 231 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); 232 AddTextureQuad(frame.get(), 555); 233 AddTransferableResource(frame.get(), 555); 234 frame_provider_->SetFrameData(frame.Pass()); 235 236 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); 237 EXPECT_EQ(1u, resources_.size()); 238 EXPECT_EQ(444u, resources_[0].id); 239} 240 241TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProviderUntilDestroy) { 242 scoped_ptr<DelegatedFrameData> frame = 243 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); 244 AddTextureQuad(frame.get(), 444); 245 AddTransferableResource(frame.get(), 444); 246 247 TransferableResourceArray reffed = frame->resource_list; 248 ReturnedResourceArray returned; 249 TransferableResource::ReturnResources(reffed, &returned); 250 251 SetFrameProvider(frame.Pass()); 252 253 scoped_refptr<DelegatedRendererLayer> observer1 = 254 DelegatedRendererLayer::Create(frame_provider_); 255 scoped_refptr<DelegatedRendererLayer> observer2 = 256 DelegatedRendererLayer::Create(frame_provider_); 257 258 gfx::RectF damage; 259 260 // Take a ref on each observer. 261 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); 262 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); 263 264 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 265 266 // Release both refs. But there's still a ref held in the frame 267 // provider itself. 268 frame_provider_->UnrefResourcesOnMainThread(returned); 269 frame_provider_->UnrefResourcesOnMainThread(returned); 270 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 271 272 // Releasing all references to the frame provider will release 273 // the frame. 274 observer1 = NULL; 275 observer2 = NULL; 276 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 277 278 frame_provider_ = NULL; 279 280 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); 281 EXPECT_EQ(1u, resources_.size()); 282 EXPECT_EQ(444u, resources_[0].id); 283} 284 285TEST_F(DelegatedFrameProviderTest, Damage) { 286 scoped_ptr<DelegatedFrameData> frame = 287 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); 288 AddTextureQuad(frame.get(), 444); 289 AddTransferableResource(frame.get(), 444); 290 291 TransferableResourceArray reffed = frame->resource_list; 292 ReturnedResourceArray returned; 293 TransferableResource::ReturnResources(reffed, &returned); 294 295 SetFrameProvider(frame.Pass()); 296 297 scoped_refptr<DelegatedRendererLayer> observer1 = 298 DelegatedRendererLayer::Create(frame_provider_); 299 scoped_refptr<DelegatedRendererLayer> observer2 = 300 DelegatedRendererLayer::Create(frame_provider_); 301 302 gfx::RectF damage; 303 304 // Both observers get a full frame of damage on the first request. 305 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); 306 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString()); 307 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); 308 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString()); 309 310 // And both get no damage on the 2nd request. 311 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); 312 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); 313 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); 314 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); 315 316 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); 317 AddTextureQuad(frame.get(), 555); 318 AddTransferableResource(frame.get(), 555); 319 frame_provider_->SetFrameData(frame.Pass()); 320 321 // Both observers get the damage for the new frame. 322 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); 323 EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString()); 324 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); 325 EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString()); 326 327 // And both get no damage on the 2nd request. 328 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); 329 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); 330 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); 331 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); 332} 333 334TEST_F(DelegatedFrameProviderTest, LostNothing) { 335 scoped_ptr<DelegatedFrameData> frame = 336 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5)); 337 338 TransferableResourceArray reffed = frame->resource_list; 339 340 SetFrameProvider(frame.Pass()); 341 342 // There is nothing to lose. 343 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 344 EXPECT_FALSE(resource_collection_->LoseAllResources()); 345 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 346 EXPECT_EQ(0u, resources_.size()); 347} 348 349TEST_F(DelegatedFrameProviderTest, LostSomething) { 350 scoped_ptr<DelegatedFrameData> frame = 351 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5)); 352 AddTextureQuad(frame.get(), 444); 353 AddTransferableResource(frame.get(), 444); 354 355 SetFrameProvider(frame.Pass()); 356 357 // Add a second reference on the resource. 358 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(5, 5)); 359 AddTextureQuad(frame.get(), 444); 360 AddTransferableResource(frame.get(), 444); 361 362 SetFrameProvider(frame.Pass()); 363 364 // There is something to lose. 365 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 366 EXPECT_TRUE(resource_collection_->LoseAllResources()); 367 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); 368 369 EXPECT_EQ(1u, resources_.size()); 370 EXPECT_EQ(444u, resources_[0].id); 371 EXPECT_EQ(2, resources_[0].count); 372} 373 374TEST_F(DelegatedFrameProviderTest, NothingReturnedAfterLoss) { 375 scoped_ptr<DelegatedFrameData> frame = 376 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); 377 AddTextureQuad(frame.get(), 444); 378 AddTransferableResource(frame.get(), 444); 379 SetFrameProvider(frame.Pass()); 380 381 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 382 383 // Lose all the resources. 384 EXPECT_TRUE(resource_collection_->LoseAllResources()); 385 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); 386 resources_.clear(); 387 388 frame_provider_ = NULL; 389 390 // Nothing is returned twice. 391 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); 392 EXPECT_EQ(0u, resources_.size()); 393} 394 395} // namespace 396} // namespace cc 397