| 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(gfx::Rect root_output_rect, |
| 24 gfx::Rect root_damage_rect) { |
| 25 scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData); |
| 26 |
| 27 scoped_ptr<RenderPass> root_pass(RenderPass::Create()); |
| 28 root_pass->SetNew(RenderPass::Id(1, 1), |
| 29 root_output_rect, |
| 30 root_damage_rect, |
| 31 gfx::Transform()); |
| 32 frame->render_pass_list.push_back(root_pass.Pass()); |
| 33 return frame.Pass(); |
| 34 } |
| 35 |
| 36 void AddTransferableResource(DelegatedFrameData* frame, |
| 37 ResourceProvider::ResourceId resource_id) { |
| 38 TransferableResource resource; |
| 39 resource.id = resource_id; |
| 40 resource.target = GL_TEXTURE_2D; |
| 41 frame->resource_list.push_back(resource); |
| 42 } |
| 43 |
| 44 void AddTextureQuad(DelegatedFrameData* frame, |
| 45 ResourceProvider::ResourceId resource_id) { |
| 46 scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create(); |
| 47 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); |
| 48 float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; |
| 49 quad->SetNew(sqs.get(), |
| 50 gfx::Rect(0, 0, 10, 10), |
| 51 gfx::Rect(0, 0, 10, 10), |
| 52 resource_id, |
| 53 false, |
| 54 gfx::PointF(0.f, 0.f), |
| 55 gfx::PointF(1.f, 1.f), |
| 56 SK_ColorTRANSPARENT, |
| 57 vertex_opacity, |
| 58 false); |
| 59 frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass()); |
| 60 frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>()); |
| 61 } |
| 62 |
| 63 virtual void SetUp() OVERRIDE { |
| 64 resource_collection_ = new DelegatedFrameResourceCollection; |
| 65 resource_collection_->SetClient(this); |
| 66 } |
| 67 |
| 68 virtual void TearDown() OVERRIDE { resource_collection_->SetClient(NULL); } |
| 69 |
| 70 virtual void UnusedResourcesAreAvailable() OVERRIDE { |
| 71 resources_available_ = true; |
| 72 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources_); |
| 73 } |
| 74 |
| 75 bool ReturnAndResetResourcesAvailable() { |
| 76 bool r = resources_available_; |
| 77 resources_available_ = false; |
| 78 return r; |
| 79 } |
| 80 |
| 81 void SetFrameProvider(scoped_ptr<DelegatedFrameData> frame_data) { |
| 82 frame_provider_ = |
| 83 new DelegatedFrameProvider(resource_collection_, frame_data.Pass()); |
| 84 } |
| 85 |
| 86 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_; |
| 87 scoped_refptr<DelegatedFrameProvider> frame_provider_; |
| 88 bool resources_available_; |
| 89 ReturnedResourceArray resources_; |
| 90 }; |
| 91 |
| 92 TEST_F(DelegatedFrameProviderTest, SameResources) { |
| 93 scoped_ptr<DelegatedFrameData> frame = |
| 94 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); |
| 95 AddTextureQuad(frame.get(), 444); |
| 96 AddTransferableResource(frame.get(), 444); |
| 97 SetFrameProvider(frame.Pass()); |
| 98 |
| 99 frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); |
| 100 AddTextureQuad(frame.get(), 444); |
| 101 AddTransferableResource(frame.get(), 444); |
| 102 SetFrameProvider(frame.Pass()); |
| 103 |
| 104 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 105 EXPECT_EQ(0u, resources_.size()); |
| 106 |
| 107 frame_provider_ = NULL; |
| 108 |
| 109 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); |
| 110 EXPECT_EQ(1u, resources_.size()); |
| 111 EXPECT_EQ(444u, resources_[0].id); |
| 112 } |
| 113 |
| 114 TEST_F(DelegatedFrameProviderTest, ReplaceResources) { |
| 115 scoped_ptr<DelegatedFrameData> frame = |
| 116 CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); |
| 117 AddTextureQuad(frame.get(), 444); |
| 118 AddTransferableResource(frame.get(), 444); |
| 119 SetFrameProvider(frame.Pass()); |
| 120 |
| 121 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 122 |
| 123 frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1)); |
| 124 AddTextureQuad(frame.get(), 555); |
| 125 AddTransferableResource(frame.get(), 555); |
| 126 SetFrameProvider(frame.Pass()); |
| 127 |
| 128 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); |
| 129 EXPECT_EQ(1u, resources_.size()); |
| 130 EXPECT_EQ(444u, resources_[0].id); |
| 131 resources_.clear(); |
| 132 |
| 133 frame_provider_ = NULL; |
| 134 |
| 135 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); |
| 136 EXPECT_EQ(1u, resources_.size()); |
| 137 EXPECT_EQ(555u, resources_[0].id); |
| 138 } |
| 139 |
| 140 TEST_F(DelegatedFrameProviderTest, RefResources) { |
| 141 scoped_ptr<DelegatedFrameData> frame = |
| 142 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); |
| 143 AddTextureQuad(frame.get(), 444); |
| 144 AddTransferableResource(frame.get(), 444); |
| 145 |
| 146 TransferableResourceArray reffed = frame->resource_list; |
| 147 ReturnedResourceArray returned; |
| 148 TransferableResource::ReturnResources(reffed, &returned); |
| 149 |
| 150 SetFrameProvider(frame.Pass()); |
| 151 |
| 152 scoped_refptr<DelegatedRendererLayer> observer1 = |
| 153 DelegatedRendererLayer::Create(NULL, frame_provider_.get()); |
| 154 scoped_refptr<DelegatedRendererLayer> observer2 = |
| 155 DelegatedRendererLayer::Create(NULL, frame_provider_.get()); |
| 156 |
| 157 gfx::RectF damage; |
| 158 |
| 159 // Both observers get a full frame of damage on the first request. |
| 160 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); |
| 161 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString()); |
| 162 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); |
| 163 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString()); |
| 164 |
| 165 // And both get no damage on the 2nd request. This adds a second ref to the |
| 166 // resources. |
| 167 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); |
| 168 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); |
| 169 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); |
| 170 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); |
| 171 |
| 172 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 173 |
| 174 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); |
| 175 AddTextureQuad(frame.get(), 555); |
| 176 AddTransferableResource(frame.get(), 555); |
| 177 frame_provider_->SetFrameData(frame.Pass()); |
| 178 |
| 179 // The resources from the first frame are still reffed by the observers. |
| 180 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 181 |
| 182 // There are 4 refs taken. |
| 183 frame_provider_->UnrefResourcesOnMainThread(returned); |
| 184 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 185 frame_provider_->UnrefResourcesOnMainThread(returned); |
| 186 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 187 frame_provider_->UnrefResourcesOnMainThread(returned); |
| 188 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 189 |
| 190 // The 4th unref will release them. |
| 191 frame_provider_->UnrefResourcesOnMainThread(returned); |
| 192 |
| 193 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); |
| 194 EXPECT_EQ(1u, resources_.size()); |
| 195 EXPECT_EQ(444u, resources_[0].id); |
| 196 } |
| 197 |
| 198 TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProvider) { |
| 199 scoped_ptr<DelegatedFrameData> frame = |
| 200 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); |
| 201 AddTextureQuad(frame.get(), 444); |
| 202 AddTransferableResource(frame.get(), 444); |
| 203 |
| 204 TransferableResourceArray reffed = frame->resource_list; |
| 205 ReturnedResourceArray returned; |
| 206 TransferableResource::ReturnResources(reffed, &returned); |
| 207 |
| 208 SetFrameProvider(frame.Pass()); |
| 209 |
| 210 scoped_refptr<DelegatedRendererLayer> observer1 = |
| 211 DelegatedRendererLayer::Create(NULL, frame_provider_.get()); |
| 212 scoped_refptr<DelegatedRendererLayer> observer2 = |
| 213 DelegatedRendererLayer::Create(NULL, frame_provider_.get()); |
| 214 |
| 215 gfx::RectF damage; |
| 216 |
| 217 // Take a ref on each observer. |
| 218 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); |
| 219 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); |
| 220 |
| 221 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 222 |
| 223 // Release both refs. But there's still a ref held in the frame |
| 224 // provider itself. |
| 225 frame_provider_->UnrefResourcesOnMainThread(returned); |
| 226 frame_provider_->UnrefResourcesOnMainThread(returned); |
| 227 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 228 |
| 229 // Setting a new frame will release it. |
| 230 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); |
| 231 AddTextureQuad(frame.get(), 555); |
| 232 AddTransferableResource(frame.get(), 555); |
| 233 frame_provider_->SetFrameData(frame.Pass()); |
| 234 |
| 235 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); |
| 236 EXPECT_EQ(1u, resources_.size()); |
| 237 EXPECT_EQ(444u, resources_[0].id); |
| 238 } |
| 239 |
| 240 TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProviderUntilDestroy) { |
| 241 scoped_ptr<DelegatedFrameData> frame = |
| 242 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); |
| 243 AddTextureQuad(frame.get(), 444); |
| 244 AddTransferableResource(frame.get(), 444); |
| 245 |
| 246 TransferableResourceArray reffed = frame->resource_list; |
| 247 ReturnedResourceArray returned; |
| 248 TransferableResource::ReturnResources(reffed, &returned); |
| 249 |
| 250 SetFrameProvider(frame.Pass()); |
| 251 |
| 252 scoped_refptr<DelegatedRendererLayer> observer1 = |
| 253 DelegatedRendererLayer::Create(NULL, frame_provider_.get()); |
| 254 scoped_refptr<DelegatedRendererLayer> observer2 = |
| 255 DelegatedRendererLayer::Create(NULL, frame_provider_.get()); |
| 256 |
| 257 gfx::RectF damage; |
| 258 |
| 259 // Take a ref on each observer. |
| 260 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); |
| 261 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); |
| 262 |
| 263 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 264 |
| 265 // Release both refs. But there's still a ref held in the frame |
| 266 // provider itself. |
| 267 frame_provider_->UnrefResourcesOnMainThread(returned); |
| 268 frame_provider_->UnrefResourcesOnMainThread(returned); |
| 269 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 270 |
| 271 // Releasing all references to the frame provider will release |
| 272 // the frame. |
| 273 observer1 = NULL; |
| 274 observer2 = NULL; |
| 275 EXPECT_FALSE(ReturnAndResetResourcesAvailable()); |
| 276 |
| 277 frame_provider_ = NULL; |
| 278 |
| 279 EXPECT_TRUE(ReturnAndResetResourcesAvailable()); |
| 280 EXPECT_EQ(1u, resources_.size()); |
| 281 EXPECT_EQ(444u, resources_[0].id); |
| 282 } |
| 283 |
| 284 TEST_F(DelegatedFrameProviderTest, Damage) { |
| 285 scoped_ptr<DelegatedFrameData> frame = |
| 286 CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); |
| 287 AddTextureQuad(frame.get(), 444); |
| 288 AddTransferableResource(frame.get(), 444); |
| 289 |
| 290 TransferableResourceArray reffed = frame->resource_list; |
| 291 ReturnedResourceArray returned; |
| 292 TransferableResource::ReturnResources(reffed, &returned); |
| 293 |
| 294 SetFrameProvider(frame.Pass()); |
| 295 |
| 296 scoped_refptr<DelegatedRendererLayer> observer1 = |
| 297 DelegatedRendererLayer::Create(NULL, frame_provider_.get()); |
| 298 scoped_refptr<DelegatedRendererLayer> observer2 = |
| 299 DelegatedRendererLayer::Create(NULL, frame_provider_.get()); |
| 300 |
| 301 gfx::RectF damage; |
| 302 |
| 303 // Both observers get a full frame of damage on the first request. |
| 304 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); |
| 305 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString()); |
| 306 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); |
| 307 EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString()); |
| 308 |
| 309 // And both get no damage on the 2nd request. |
| 310 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); |
| 311 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); |
| 312 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); |
| 313 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); |
| 314 |
| 315 frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2)); |
| 316 AddTextureQuad(frame.get(), 555); |
| 317 AddTransferableResource(frame.get(), 555); |
| 318 frame_provider_->SetFrameData(frame.Pass()); |
| 319 |
| 320 // Both observers get the damage for the new frame. |
| 321 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); |
| 322 EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString()); |
| 323 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); |
| 324 EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString()); |
| 325 |
| 326 // And both get no damage on the 2nd request. |
| 327 frame_provider_->GetFrameDataAndRefResources(observer1, &damage); |
| 328 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); |
| 329 frame_provider_->GetFrameDataAndRefResources(observer2, &damage); |
| 330 EXPECT_EQ(gfx::RectF().ToString(), damage.ToString()); |
| 331 } |
| 332 |
| 333 } // namespace |
| 334 } // namespace cc |
| OLD | NEW |