| 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/trees/layer_tree_host.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/location.h" | |
| 11 #include "base/synchronization/waitable_event.h" | |
| 12 #include "base/threading/thread.h" | |
| 13 #include "base/time/time.h" | |
| 14 #include "cc/layers/delegated_frame_provider.h" | |
| 15 #include "cc/layers/delegated_frame_resource_collection.h" | |
| 16 #include "cc/layers/delegated_renderer_layer.h" | |
| 17 #include "cc/layers/delegated_renderer_layer_impl.h" | |
| 18 #include "cc/output/compositor_frame.h" | |
| 19 #include "cc/output/compositor_frame_ack.h" | |
| 20 #include "cc/output/delegated_frame_data.h" | |
| 21 #include "cc/quads/render_pass_draw_quad.h" | |
| 22 #include "cc/quads/shared_quad_state.h" | |
| 23 #include "cc/quads/texture_draw_quad.h" | |
| 24 #include "cc/resources/returned_resource.h" | |
| 25 #include "cc/test/fake_delegated_renderer_layer.h" | |
| 26 #include "cc/test/fake_delegated_renderer_layer_impl.h" | |
| 27 #include "cc/test/fake_output_surface.h" | |
| 28 #include "cc/test/layer_tree_test.h" | |
| 29 #include "cc/trees/layer_tree_impl.h" | |
| 30 #include "gpu/GLES2/gl2extchromium.h" | |
| 31 | |
| 32 namespace cc { | |
| 33 namespace { | |
| 34 | |
| 35 bool ReturnedResourceLower(const ReturnedResource& a, | |
| 36 const ReturnedResource& b) { | |
| 37 return a.id < b.id; | |
| 38 } | |
| 39 | |
| 40 // Tests if the list of resources matches an expectation, modulo the order. | |
| 41 bool ResourcesMatch(ReturnedResourceArray actual, | |
| 42 unsigned* expected, | |
| 43 size_t expected_count) { | |
| 44 std::sort(actual.begin(), actual.end(), ReturnedResourceLower); | |
| 45 std::sort(expected, expected + expected_count); | |
| 46 size_t actual_index = 0; | |
| 47 | |
| 48 // for each element of the expected array, count off one of the actual array | |
| 49 // (after checking it matches). | |
| 50 for (size_t expected_index = 0; expected_index < expected_count; | |
| 51 ++expected_index) { | |
| 52 EXPECT_LT(actual_index, actual.size()); | |
| 53 if (actual_index >= actual.size()) | |
| 54 return false; | |
| 55 EXPECT_EQ(actual[actual_index].id, expected[expected_index]); | |
| 56 if (actual[actual_index].id != expected[expected_index]) | |
| 57 return false; | |
| 58 EXPECT_GT(actual[actual_index].count, 0); | |
| 59 if (actual[actual_index].count <= 0) { | |
| 60 return false; | |
| 61 } else { | |
| 62 --actual[actual_index].count; | |
| 63 if (actual[actual_index].count == 0) | |
| 64 ++actual_index; | |
| 65 } | |
| 66 } | |
| 67 EXPECT_EQ(actual_index, actual.size()); | |
| 68 return actual_index == actual.size(); | |
| 69 } | |
| 70 | |
| 71 #define EXPECT_RESOURCES(expected, actual) \ | |
| 72 EXPECT_TRUE(ResourcesMatch(actual, expected, arraysize(expected))); | |
| 73 | |
| 74 // These tests deal with delegated renderer layers. | |
| 75 class LayerTreeHostDelegatedTest : public LayerTreeTest { | |
| 76 protected: | |
| 77 scoped_ptr<DelegatedFrameData> CreateFrameData( | |
| 78 const gfx::Rect& root_output_rect, | |
| 79 const gfx::Rect& root_damage_rect) { | |
| 80 scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData); | |
| 81 | |
| 82 scoped_ptr<RenderPass> root_pass(RenderPass::Create()); | |
| 83 root_pass->SetNew(RenderPassId(1, 1), | |
| 84 root_output_rect, | |
| 85 root_damage_rect, | |
| 86 gfx::Transform()); | |
| 87 frame->render_pass_list.push_back(root_pass.Pass()); | |
| 88 return frame.Pass(); | |
| 89 } | |
| 90 | |
| 91 scoped_ptr<DelegatedFrameData> CreateInvalidFrameData( | |
| 92 const gfx::Rect& root_output_rect, | |
| 93 const gfx::Rect& root_damage_rect) { | |
| 94 scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData); | |
| 95 | |
| 96 scoped_ptr<RenderPass> root_pass(RenderPass::Create()); | |
| 97 root_pass->SetNew(RenderPassId(1, 1), | |
| 98 root_output_rect, | |
| 99 root_damage_rect, | |
| 100 gfx::Transform()); | |
| 101 | |
| 102 SharedQuadState* shared_quad_state = | |
| 103 root_pass->CreateAndAppendSharedQuadState(); | |
| 104 | |
| 105 gfx::Rect rect = root_output_rect; | |
| 106 gfx::Rect opaque_rect = root_output_rect; | |
| 107 gfx::Rect visible_rect = root_output_rect; | |
| 108 // An invalid resource id! The resource isn't part of the frame. | |
| 109 unsigned resource_id = 5; | |
| 110 bool premultiplied_alpha = false; | |
| 111 gfx::PointF uv_top_left = gfx::PointF(0.f, 0.f); | |
| 112 gfx::PointF uv_bottom_right = gfx::PointF(1.f, 1.f); | |
| 113 SkColor background_color = 0; | |
| 114 float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; | |
| 115 bool flipped = false; | |
| 116 bool nearest_neighbor = false; | |
| 117 | |
| 118 TextureDrawQuad* invalid_draw_quad = | |
| 119 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | |
| 120 invalid_draw_quad->SetNew(shared_quad_state, | |
| 121 rect, | |
| 122 opaque_rect, | |
| 123 visible_rect, | |
| 124 resource_id, | |
| 125 premultiplied_alpha, | |
| 126 uv_top_left, | |
| 127 uv_bottom_right, | |
| 128 background_color, | |
| 129 vertex_opacity, | |
| 130 flipped, | |
| 131 nearest_neighbor); | |
| 132 | |
| 133 frame->render_pass_list.push_back(root_pass.Pass()); | |
| 134 return frame.Pass(); | |
| 135 } | |
| 136 | |
| 137 void AddTransferableResource(DelegatedFrameData* frame, | |
| 138 ResourceProvider::ResourceId resource_id) { | |
| 139 TransferableResource resource; | |
| 140 resource.id = resource_id; | |
| 141 resource.mailbox_holder.texture_target = GL_TEXTURE_2D; | |
| 142 GLbyte arbitrary_mailbox[GL_MAILBOX_SIZE_CHROMIUM] = { | |
| 143 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, | |
| 144 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, | |
| 145 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4}; | |
| 146 resource.mailbox_holder.mailbox.SetName(arbitrary_mailbox); | |
| 147 frame->resource_list.push_back(resource); | |
| 148 } | |
| 149 | |
| 150 void AddTextureQuad(DelegatedFrameData* frame, | |
| 151 ResourceProvider::ResourceId resource_id) { | |
| 152 RenderPass* render_pass = frame->render_pass_list[0]; | |
| 153 SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); | |
| 154 TextureDrawQuad* quad = | |
| 155 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | |
| 156 float vertex_opacity[4] = { 1.f, 1.f, 1.f, 1.f }; | |
| 157 quad->SetNew(sqs, | |
| 158 gfx::Rect(0, 0, 10, 10), | |
| 159 gfx::Rect(0, 0, 10, 10), | |
| 160 gfx::Rect(0, 0, 10, 10), | |
| 161 resource_id, | |
| 162 false, | |
| 163 gfx::PointF(0.f, 0.f), | |
| 164 gfx::PointF(1.f, 1.f), | |
| 165 SK_ColorTRANSPARENT, | |
| 166 vertex_opacity, | |
| 167 false, | |
| 168 false); | |
| 169 } | |
| 170 | |
| 171 void AddRenderPass(DelegatedFrameData* frame, | |
| 172 RenderPassId id, | |
| 173 const gfx::Rect& output_rect, | |
| 174 const gfx::Rect& damage_rect, | |
| 175 const FilterOperations& filters, | |
| 176 const FilterOperations& background_filters) { | |
| 177 for (size_t i = 0; i < frame->render_pass_list.size(); ++i) | |
| 178 DCHECK(id != frame->render_pass_list[i]->id); | |
| 179 | |
| 180 scoped_ptr<RenderPass> pass(RenderPass::Create()); | |
| 181 pass->SetNew(id, | |
| 182 output_rect, | |
| 183 damage_rect, | |
| 184 gfx::Transform()); | |
| 185 frame->render_pass_list.push_back(pass.Pass()); | |
| 186 | |
| 187 RenderPass* render_pass = frame->render_pass_list[0]; | |
| 188 SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); | |
| 189 RenderPassDrawQuad* quad = | |
| 190 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
| 191 | |
| 192 quad->SetNew(sqs, | |
| 193 output_rect, | |
| 194 output_rect, | |
| 195 id, | |
| 196 0, | |
| 197 gfx::Vector2dF(), | |
| 198 gfx::Size(), | |
| 199 filters, | |
| 200 gfx::Vector2dF(), | |
| 201 background_filters); | |
| 202 } | |
| 203 | |
| 204 static ResourceProvider::ResourceId AppendResourceId( | |
| 205 std::vector<ResourceProvider::ResourceId>* resources_in_last_sent_frame, | |
| 206 ResourceProvider::ResourceId resource_id) { | |
| 207 resources_in_last_sent_frame->push_back(resource_id); | |
| 208 return resource_id; | |
| 209 } | |
| 210 | |
| 211 void ReturnUnusedResourcesFromParent(LayerTreeHostImpl* host_impl) { | |
| 212 DelegatedFrameData* delegated_frame_data = | |
| 213 output_surface()->last_sent_frame().delegated_frame_data.get(); | |
| 214 if (!delegated_frame_data) | |
| 215 return; | |
| 216 | |
| 217 std::vector<ResourceProvider::ResourceId> resources_in_last_sent_frame; | |
| 218 for (size_t i = 0; i < delegated_frame_data->resource_list.size(); ++i) { | |
| 219 resources_in_last_sent_frame.push_back( | |
| 220 delegated_frame_data->resource_list[i].id); | |
| 221 } | |
| 222 | |
| 223 std::vector<ResourceProvider::ResourceId> resources_to_return; | |
| 224 | |
| 225 const TransferableResourceArray& resources_held_by_parent = | |
| 226 output_surface()->resources_held_by_parent(); | |
| 227 for (size_t i = 0; i < resources_held_by_parent.size(); ++i) { | |
| 228 ResourceProvider::ResourceId resource_in_parent = | |
| 229 resources_held_by_parent[i].id; | |
| 230 bool resource_in_parent_is_not_part_of_frame = | |
| 231 std::find(resources_in_last_sent_frame.begin(), | |
| 232 resources_in_last_sent_frame.end(), | |
| 233 resource_in_parent) == resources_in_last_sent_frame.end(); | |
| 234 if (resource_in_parent_is_not_part_of_frame) | |
| 235 resources_to_return.push_back(resource_in_parent); | |
| 236 } | |
| 237 | |
| 238 if (resources_to_return.empty()) | |
| 239 return; | |
| 240 | |
| 241 CompositorFrameAck ack; | |
| 242 for (size_t i = 0; i < resources_to_return.size(); ++i) | |
| 243 output_surface()->ReturnResource(resources_to_return[i], &ack); | |
| 244 host_impl->ReclaimResources(&ack); | |
| 245 } | |
| 246 }; | |
| 247 | |
| 248 class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer | |
| 249 : public LayerTreeHostDelegatedTest, | |
| 250 public DelegatedFrameResourceCollectionClient { | |
| 251 public: | |
| 252 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer() | |
| 253 : resource_collection_(new DelegatedFrameResourceCollection), | |
| 254 available_(false) { | |
| 255 resource_collection_->SetClient(this); | |
| 256 } | |
| 257 | |
| 258 void SetupTree() override { | |
| 259 root_ = Layer::Create(); | |
| 260 root_->SetBounds(gfx::Size(15, 15)); | |
| 261 | |
| 262 layer_tree_host()->SetRootLayer(root_); | |
| 263 LayerTreeHostDelegatedTest::SetupTree(); | |
| 264 } | |
| 265 | |
| 266 void BeginTest() override { | |
| 267 resource_collection_->SetClient(this); | |
| 268 PostSetNeedsCommitToMainThread(); | |
| 269 } | |
| 270 | |
| 271 void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data) { | |
| 272 RenderPass* root_pass = frame_data->render_pass_list.back(); | |
| 273 gfx::Size frame_size = root_pass->output_rect.size(); | |
| 274 | |
| 275 if (frame_provider_.get() && frame_size == frame_provider_->frame_size()) { | |
| 276 frame_provider_->SetFrameData(frame_data.Pass()); | |
| 277 return; | |
| 278 } | |
| 279 | |
| 280 if (delegated_.get()) { | |
| 281 delegated_->RemoveFromParent(); | |
| 282 delegated_ = NULL; | |
| 283 frame_provider_ = NULL; | |
| 284 } | |
| 285 | |
| 286 frame_provider_ = new DelegatedFrameProvider(resource_collection_.get(), | |
| 287 frame_data.Pass()); | |
| 288 | |
| 289 delegated_ = CreateDelegatedLayer(frame_provider_.get()); | |
| 290 } | |
| 291 | |
| 292 scoped_refptr<DelegatedRendererLayer> CreateDelegatedLayer( | |
| 293 DelegatedFrameProvider* frame_provider) { | |
| 294 scoped_refptr<DelegatedRendererLayer> delegated = | |
| 295 FakeDelegatedRendererLayer::Create(frame_provider); | |
| 296 delegated->SetBounds(gfx::Size(10, 10)); | |
| 297 delegated->SetIsDrawable(true); | |
| 298 | |
| 299 root_->AddChild(delegated); | |
| 300 return delegated; | |
| 301 } | |
| 302 | |
| 303 void AfterTest() override { resource_collection_->SetClient(NULL); } | |
| 304 | |
| 305 // DelegatedFrameProviderClient implementation. | |
| 306 void UnusedResourcesAreAvailable() override { available_ = true; } | |
| 307 | |
| 308 bool TestAndResetAvailable() { | |
| 309 bool available = available_; | |
| 310 available_ = false; | |
| 311 return available; | |
| 312 } | |
| 313 | |
| 314 protected: | |
| 315 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_; | |
| 316 scoped_refptr<DelegatedFrameProvider> frame_provider_; | |
| 317 scoped_refptr<Layer> root_; | |
| 318 scoped_refptr<DelegatedRendererLayer> delegated_; | |
| 319 bool available_; | |
| 320 }; | |
| 321 | |
| 322 class LayerTreeHostDelegatedTestCreateChildId | |
| 323 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 324 public: | |
| 325 LayerTreeHostDelegatedTestCreateChildId() | |
| 326 : LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(), | |
| 327 num_activates_(0), | |
| 328 did_reset_child_id_(false) {} | |
| 329 | |
| 330 void DidCommit() override { | |
| 331 if (TestEnded()) | |
| 332 return; | |
| 333 SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1))); | |
| 334 } | |
| 335 | |
| 336 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 337 if (host_impl->active_tree()->source_frame_number() < 1) | |
| 338 return; | |
| 339 | |
| 340 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 341 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 342 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 343 | |
| 344 TestContextProvider* context_provider = static_cast<TestContextProvider*>( | |
| 345 host_impl->output_surface()->context_provider()); | |
| 346 | |
| 347 ++num_activates_; | |
| 348 switch (num_activates_) { | |
| 349 case 2: | |
| 350 EXPECT_TRUE(delegated_impl->ChildId()); | |
| 351 EXPECT_FALSE(did_reset_child_id_); | |
| 352 | |
| 353 context_provider->ContextGL()->LoseContextCHROMIUM( | |
| 354 GL_GUILTY_CONTEXT_RESET_ARB, | |
| 355 GL_INNOCENT_CONTEXT_RESET_ARB); | |
| 356 context_provider->ContextGL()->Flush(); | |
| 357 break; | |
| 358 case 3: | |
| 359 EXPECT_TRUE(delegated_impl->ChildId()); | |
| 360 EXPECT_TRUE(did_reset_child_id_); | |
| 361 EndTest(); | |
| 362 break; | |
| 363 } | |
| 364 } | |
| 365 | |
| 366 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, | |
| 367 bool success) override { | |
| 368 EXPECT_TRUE(success); | |
| 369 | |
| 370 if (num_activates_ < 2) | |
| 371 return; | |
| 372 | |
| 373 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 374 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 375 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 376 | |
| 377 EXPECT_EQ(2, num_activates_); | |
| 378 EXPECT_FALSE(delegated_impl->ChildId()); | |
| 379 did_reset_child_id_ = true; | |
| 380 } | |
| 381 | |
| 382 protected: | |
| 383 int num_activates_; | |
| 384 bool did_reset_child_id_; | |
| 385 }; | |
| 386 | |
| 387 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCreateChildId); | |
| 388 | |
| 389 // Test that we can gracefully handle invalid frames after the context was lost. | |
| 390 // For example, we might be trying to use the previous frame in that case and | |
| 391 // have to make sure we don't crash because our resource accounting goes wrong. | |
| 392 class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost | |
| 393 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 394 public: | |
| 395 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost() | |
| 396 : num_activates_(0), num_output_surfaces_initialized_(0) {} | |
| 397 | |
| 398 void DidCommit() override { | |
| 399 if (TestEnded()) | |
| 400 return; | |
| 401 scoped_ptr<DelegatedFrameData> frame1 = | |
| 402 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 403 AddTextureQuad(frame1.get(), 999); | |
| 404 AddTransferableResource(frame1.get(), 999); | |
| 405 SetFrameData(frame1.Pass()); | |
| 406 } | |
| 407 | |
| 408 void DidInitializeOutputSurface() override { | |
| 409 if (!num_output_surfaces_initialized_++) | |
| 410 return; | |
| 411 | |
| 412 scoped_refptr<DelegatedRendererLayer> old_delegated = delegated_; | |
| 413 SetFrameData( | |
| 414 CreateInvalidFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1))); | |
| 415 // Make sure we end up using the same layer, or we won't test the right | |
| 416 // thing, which is to make sure we can handle an invalid frame when using | |
| 417 // a stale layer from before the context was lost. | |
| 418 DCHECK(delegated_.get() == old_delegated.get()); | |
| 419 } | |
| 420 | |
| 421 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 422 if (host_impl->active_tree()->source_frame_number() < 1) | |
| 423 return; | |
| 424 | |
| 425 TestContextProvider* context_provider = static_cast<TestContextProvider*>( | |
| 426 host_impl->output_surface()->context_provider()); | |
| 427 | |
| 428 ++num_activates_; | |
| 429 switch (num_activates_) { | |
| 430 case 2: | |
| 431 context_provider->ContextGL()->LoseContextCHROMIUM( | |
| 432 GL_GUILTY_CONTEXT_RESET_ARB, | |
| 433 GL_INNOCENT_CONTEXT_RESET_ARB); | |
| 434 break; | |
| 435 case 3: | |
| 436 EndTest(); | |
| 437 break; | |
| 438 } | |
| 439 } | |
| 440 | |
| 441 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, | |
| 442 bool success) override { | |
| 443 EXPECT_TRUE(success); | |
| 444 | |
| 445 if (num_activates_ < 2) | |
| 446 return; | |
| 447 | |
| 448 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 449 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 450 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 451 | |
| 452 EXPECT_EQ(2, num_activates_); | |
| 453 // Resources should have gotten cleared after the context was lost. | |
| 454 EXPECT_EQ(0U, delegated_impl->Resources().size()); | |
| 455 } | |
| 456 | |
| 457 void AfterTest() override { | |
| 458 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::AfterTest(); | |
| 459 EXPECT_EQ(2, num_output_surfaces_initialized_); | |
| 460 } | |
| 461 | |
| 462 protected: | |
| 463 int num_activates_; | |
| 464 int num_output_surfaces_initialized_; | |
| 465 }; | |
| 466 | |
| 467 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 468 LayerTreeHostDelegatedTestInvalidFrameAfterContextLost); | |
| 469 | |
| 470 class LayerTreeHostDelegatedTestLayerUsesFrameDamage | |
| 471 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 472 public: | |
| 473 void DidCommit() override { | |
| 474 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 475 switch (next_source_frame_number) { | |
| 476 case 1: | |
| 477 // The first time the layer gets a frame the whole layer should be | |
| 478 // damaged. | |
| 479 SetFrameData( | |
| 480 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1))); | |
| 481 break; | |
| 482 case 2: | |
| 483 // A different frame size will damage the whole layer. | |
| 484 SetFrameData( | |
| 485 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(0, 0, 0, 0))); | |
| 486 break; | |
| 487 case 3: | |
| 488 // Should create a total amount of gfx::Rect(2, 2, 8, 6) damage: | |
| 489 // (2, 2, 10, 6) clamped to the root output rect. | |
| 490 SetFrameData( | |
| 491 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(2, 2, 5, 5))); | |
| 492 SetFrameData( | |
| 493 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(7, 2, 5, 6))); | |
| 494 break; | |
| 495 case 4: | |
| 496 // Should create zero damage. | |
| 497 layer_tree_host()->SetNeedsCommit(); | |
| 498 break; | |
| 499 case 5: | |
| 500 // Should damage the full viewport. | |
| 501 delegated_->SetBounds(gfx::Size(2, 2)); | |
| 502 break; | |
| 503 case 6: | |
| 504 // Should create zero damage. | |
| 505 layer_tree_host()->SetNeedsCommit(); | |
| 506 break; | |
| 507 case 7: | |
| 508 // Should damage the full layer, tho the frame size is not changing. | |
| 509 delegated_->SetBounds(gfx::Size(6, 6)); | |
| 510 SetFrameData( | |
| 511 CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(1, 1, 2, 2))); | |
| 512 break; | |
| 513 case 8: | |
| 514 // Should create zero damage. | |
| 515 layer_tree_host()->SetNeedsCommit(); | |
| 516 break; | |
| 517 case 9: | |
| 518 // Should create zero damage. | |
| 519 layer_tree_host()->SetNeedsCommit(); | |
| 520 break; | |
| 521 case 10: | |
| 522 // Changing the frame size damages the full layer. | |
| 523 SetFrameData( | |
| 524 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1))); | |
| 525 break; | |
| 526 case 11: | |
| 527 // An invalid frame isn't used, so it should not cause damage. | |
| 528 SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 5, 5), | |
| 529 gfx::Rect(4, 4, 1, 1))); | |
| 530 break; | |
| 531 case 12: | |
| 532 // Should create gfx::Rect(1, 1, 2, 2) of damage. | |
| 533 SetFrameData( | |
| 534 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2))); | |
| 535 break; | |
| 536 case 13: | |
| 537 // Should create zero damage. | |
| 538 layer_tree_host()->SetNeedsCommit(); | |
| 539 break; | |
| 540 case 14: | |
| 541 // Moving the layer out of the tree and back in will damage the whole | |
| 542 // impl layer. | |
| 543 delegated_->RemoveFromParent(); | |
| 544 layer_tree_host()->root_layer()->AddChild(delegated_); | |
| 545 break; | |
| 546 case 15: | |
| 547 // Make a larger frame with lots of damage. Then a frame smaller than | |
| 548 // the first frame's damage. The entire layer should be damaged, but | |
| 549 // nothing more. | |
| 550 SetFrameData( | |
| 551 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10))); | |
| 552 SetFrameData( | |
| 553 CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2))); | |
| 554 break; | |
| 555 case 16: | |
| 556 // Make a frame with lots of damage. Then replace it with a frame with | |
| 557 // no damage. The entire layer should be damaged, but nothing more. | |
| 558 SetFrameData( | |
| 559 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10))); | |
| 560 SetFrameData( | |
| 561 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 0, 0))); | |
| 562 break; | |
| 563 case 17: | |
| 564 // Make another layer that uses the same frame provider. The new layer | |
| 565 // should be damaged. | |
| 566 delegated_copy_ = CreateDelegatedLayer(frame_provider_.get()); | |
| 567 delegated_copy_->SetPosition(gfx::Point(5, 0)); | |
| 568 | |
| 569 // Also set a new frame. | |
| 570 SetFrameData( | |
| 571 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(4, 0, 1, 1))); | |
| 572 break; | |
| 573 case 18: | |
| 574 // Set another new frame, both layers should be damaged in the same | |
| 575 // ways. | |
| 576 SetFrameData( | |
| 577 CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(3, 3, 1, 1))); | |
| 578 break; | |
| 579 } | |
| 580 } | |
| 581 | |
| 582 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 583 LayerTreeHostImpl::FrameData* frame, | |
| 584 DrawResult draw_result) override { | |
| 585 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
| 586 | |
| 587 gfx::Rect damage_rect; | |
| 588 if (!frame->has_no_damage) { | |
| 589 damage_rect = frame->render_passes.back()->damage_rect; | |
| 590 } else { | |
| 591 // If there is no damage, then we have no render passes to send. | |
| 592 EXPECT_TRUE(frame->render_passes.empty()); | |
| 593 } | |
| 594 | |
| 595 switch (host_impl->active_tree()->source_frame_number()) { | |
| 596 case 0: | |
| 597 // First frame is damaged because of viewport resize. | |
| 598 EXPECT_EQ(gfx::Rect(15, 15).ToString(), damage_rect.ToString()); | |
| 599 break; | |
| 600 case 1: | |
| 601 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); | |
| 602 break; | |
| 603 case 2: | |
| 604 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); | |
| 605 break; | |
| 606 case 3: | |
| 607 EXPECT_EQ(gfx::Rect(2, 2, 8, 6).ToString(), damage_rect.ToString()); | |
| 608 break; | |
| 609 case 4: | |
| 610 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); | |
| 611 break; | |
| 612 case 5: | |
| 613 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); | |
| 614 break; | |
| 615 case 6: | |
| 616 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); | |
| 617 break; | |
| 618 case 7: | |
| 619 EXPECT_EQ(gfx::Rect(6, 6).ToString(), damage_rect.ToString()); | |
| 620 break; | |
| 621 case 8: | |
| 622 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); | |
| 623 break; | |
| 624 case 9: | |
| 625 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); | |
| 626 break; | |
| 627 case 10: | |
| 628 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); | |
| 629 break; | |
| 630 case 11: | |
| 631 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); | |
| 632 break; | |
| 633 case 12: | |
| 634 EXPECT_EQ(gfx::Rect(1, 1, 2, 2).ToString(), damage_rect.ToString()); | |
| 635 break; | |
| 636 case 13: | |
| 637 EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); | |
| 638 break; | |
| 639 case 14: | |
| 640 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); | |
| 641 break; | |
| 642 case 15: | |
| 643 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); | |
| 644 break; | |
| 645 case 16: | |
| 646 EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); | |
| 647 break; | |
| 648 case 17: | |
| 649 EXPECT_EQ(gfx::UnionRects(gfx::Rect(5, 0, 10, 10), | |
| 650 gfx::Rect(4, 0, 1, 1)).ToString(), | |
| 651 damage_rect.ToString()); | |
| 652 break; | |
| 653 case 18: | |
| 654 EXPECT_EQ(gfx::Rect(3, 3, 6, 1).ToString(), damage_rect.ToString()); | |
| 655 EndTest(); | |
| 656 break; | |
| 657 } | |
| 658 | |
| 659 return draw_result; | |
| 660 } | |
| 661 | |
| 662 protected: | |
| 663 scoped_refptr<DelegatedRendererLayer> delegated_copy_; | |
| 664 }; | |
| 665 | |
| 666 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestLayerUsesFrameDamage); | |
| 667 | |
| 668 class LayerTreeHostDelegatedTestMergeResources | |
| 669 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 670 public: | |
| 671 void BeginTest() override { | |
| 672 // Push two frames to the delegated renderer layer with no commit between. | |
| 673 | |
| 674 // The first frame has resource 999. | |
| 675 scoped_ptr<DelegatedFrameData> frame1 = | |
| 676 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 677 AddTextureQuad(frame1.get(), 999); | |
| 678 AddTransferableResource(frame1.get(), 999); | |
| 679 SetFrameData(frame1.Pass()); | |
| 680 | |
| 681 // The second frame uses resource 999 still, but also adds 555. | |
| 682 scoped_ptr<DelegatedFrameData> frame2 = | |
| 683 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 684 AddTextureQuad(frame2.get(), 999); | |
| 685 AddTransferableResource(frame2.get(), 999); | |
| 686 AddTextureQuad(frame2.get(), 555); | |
| 687 AddTransferableResource(frame2.get(), 555); | |
| 688 SetFrameData(frame2.Pass()); | |
| 689 | |
| 690 // The resource 999 from frame1 is returned since it is still on the main | |
| 691 // thread. | |
| 692 ReturnedResourceArray returned_resources; | |
| 693 resource_collection_->TakeUnusedResourcesForChildCompositor( | |
| 694 &returned_resources); | |
| 695 { | |
| 696 unsigned expected[] = {999}; | |
| 697 EXPECT_RESOURCES(expected, returned_resources); | |
| 698 EXPECT_TRUE(TestAndResetAvailable()); | |
| 699 } | |
| 700 | |
| 701 PostSetNeedsCommitToMainThread(); | |
| 702 } | |
| 703 | |
| 704 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 705 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 706 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 707 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 708 | |
| 709 const ResourceProvider::ResourceIdMap& map = | |
| 710 host_impl->resource_provider()->GetChildToParentMap( | |
| 711 delegated_impl->ChildId()); | |
| 712 | |
| 713 // Both frames' resources should be in the parent's resource provider. | |
| 714 EXPECT_EQ(2u, map.size()); | |
| 715 EXPECT_EQ(1u, map.count(999)); | |
| 716 EXPECT_EQ(1u, map.count(555)); | |
| 717 | |
| 718 EXPECT_EQ(2u, delegated_impl->Resources().size()); | |
| 719 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 720 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 721 | |
| 722 EndTest(); | |
| 723 } | |
| 724 }; | |
| 725 | |
| 726 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestMergeResources); | |
| 727 | |
| 728 class LayerTreeHostDelegatedTestRemapResourcesInQuads | |
| 729 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 730 public: | |
| 731 void BeginTest() override { | |
| 732 // Generate a frame with two resources in it. | |
| 733 scoped_ptr<DelegatedFrameData> frame = | |
| 734 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 735 AddTextureQuad(frame.get(), 999); | |
| 736 AddTransferableResource(frame.get(), 999); | |
| 737 AddTextureQuad(frame.get(), 555); | |
| 738 AddTransferableResource(frame.get(), 555); | |
| 739 SetFrameData(frame.Pass()); | |
| 740 | |
| 741 PostSetNeedsCommitToMainThread(); | |
| 742 } | |
| 743 | |
| 744 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 745 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 746 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 747 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 748 | |
| 749 const ResourceProvider::ResourceIdMap& map = | |
| 750 host_impl->resource_provider()->GetChildToParentMap( | |
| 751 delegated_impl->ChildId()); | |
| 752 | |
| 753 // The frame's resource should be in the parent's resource provider. | |
| 754 EXPECT_EQ(2u, map.size()); | |
| 755 EXPECT_EQ(1u, map.count(999)); | |
| 756 EXPECT_EQ(1u, map.count(555)); | |
| 757 | |
| 758 ResourceProvider::ResourceId parent_resource_id1 = map.find(999)->second; | |
| 759 EXPECT_NE(parent_resource_id1, 999u); | |
| 760 ResourceProvider::ResourceId parent_resource_id2 = map.find(555)->second; | |
| 761 EXPECT_NE(parent_resource_id2, 555u); | |
| 762 | |
| 763 // The resources in the quads should be remapped to the parent's namespace. | |
| 764 const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast( | |
| 765 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(0)); | |
| 766 EXPECT_EQ(parent_resource_id1, quad1->resource_id); | |
| 767 const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast( | |
| 768 delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(1)); | |
| 769 EXPECT_EQ(parent_resource_id2, quad2->resource_id); | |
| 770 | |
| 771 EndTest(); | |
| 772 } | |
| 773 }; | |
| 774 | |
| 775 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemapResourcesInQuads); | |
| 776 | |
| 777 class LayerTreeHostDelegatedTestReturnUnusedResources | |
| 778 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 779 public: | |
| 780 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 781 | |
| 782 void DidCommitAndDrawFrame() override { | |
| 783 scoped_ptr<DelegatedFrameData> frame; | |
| 784 ReturnedResourceArray resources; | |
| 785 | |
| 786 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 787 switch (next_source_frame_number) { | |
| 788 case 1: | |
| 789 // Generate a frame with two resources in it. | |
| 790 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 791 AddTextureQuad(frame.get(), 999); | |
| 792 AddTransferableResource(frame.get(), 999); | |
| 793 AddTextureQuad(frame.get(), 555); | |
| 794 AddTransferableResource(frame.get(), 555); | |
| 795 SetFrameData(frame.Pass()); | |
| 796 break; | |
| 797 case 2: | |
| 798 // All of the resources are in use. | |
| 799 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 800 EXPECT_EQ(0u, resources.size()); | |
| 801 EXPECT_FALSE(TestAndResetAvailable()); | |
| 802 | |
| 803 // Keep using 999 but stop using 555. | |
| 804 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 805 AddTextureQuad(frame.get(), 999); | |
| 806 AddTransferableResource(frame.get(), 999); | |
| 807 AddTextureQuad(frame.get(), 444); | |
| 808 AddTransferableResource(frame.get(), 444); | |
| 809 SetFrameData(frame.Pass()); | |
| 810 break; | |
| 811 case 3: | |
| 812 // 555 is no longer in use. | |
| 813 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 814 { | |
| 815 unsigned expected[] = {555}; | |
| 816 EXPECT_RESOURCES(expected, resources); | |
| 817 EXPECT_TRUE(TestAndResetAvailable()); | |
| 818 } | |
| 819 | |
| 820 // Stop using any resources. | |
| 821 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 822 SetFrameData(frame.Pass()); | |
| 823 break; | |
| 824 case 4: | |
| 825 // Postpone collecting resources for a frame. They should still be there | |
| 826 // the next frame. | |
| 827 layer_tree_host()->SetNeedsCommit(); | |
| 828 return; | |
| 829 case 5: | |
| 830 // 444 and 999 are no longer in use. We sent two refs to 999, so we | |
| 831 // should get two back. | |
| 832 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 833 { | |
| 834 unsigned expected[] = {444, 999, 999}; | |
| 835 EXPECT_RESOURCES(expected, resources); | |
| 836 EXPECT_TRUE(TestAndResetAvailable()); | |
| 837 } | |
| 838 EndTest(); | |
| 839 break; | |
| 840 } | |
| 841 | |
| 842 // Resources are never immediately released. | |
| 843 ReturnedResourceArray empty_resources; | |
| 844 resource_collection_->TakeUnusedResourcesForChildCompositor( | |
| 845 &empty_resources); | |
| 846 EXPECT_EQ(0u, empty_resources.size()); | |
| 847 EXPECT_FALSE(TestAndResetAvailable()); | |
| 848 } | |
| 849 | |
| 850 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 851 ReturnUnusedResourcesFromParent(host_impl); | |
| 852 } | |
| 853 }; | |
| 854 | |
| 855 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 856 LayerTreeHostDelegatedTestReturnUnusedResources); | |
| 857 | |
| 858 class LayerTreeHostDelegatedTestReusedResources | |
| 859 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 860 public: | |
| 861 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 862 | |
| 863 void DidCommitAndDrawFrame() override { | |
| 864 scoped_ptr<DelegatedFrameData> frame; | |
| 865 ReturnedResourceArray resources; | |
| 866 | |
| 867 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 868 switch (next_source_frame_number) { | |
| 869 case 1: | |
| 870 // Generate a frame with some resources in it. | |
| 871 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 872 AddTextureQuad(frame.get(), 999); | |
| 873 AddTransferableResource(frame.get(), 999); | |
| 874 AddTextureQuad(frame.get(), 555); | |
| 875 AddTransferableResource(frame.get(), 555); | |
| 876 AddTextureQuad(frame.get(), 444); | |
| 877 AddTransferableResource(frame.get(), 444); | |
| 878 SetFrameData(frame.Pass()); | |
| 879 break; | |
| 880 case 2: | |
| 881 // All of the resources are in use. | |
| 882 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 883 EXPECT_EQ(0u, resources.size()); | |
| 884 EXPECT_FALSE(TestAndResetAvailable()); | |
| 885 | |
| 886 // Keep using 999 but stop using 555 and 444. | |
| 887 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 888 AddTextureQuad(frame.get(), 999); | |
| 889 AddTransferableResource(frame.get(), 999); | |
| 890 SetFrameData(frame.Pass()); | |
| 891 | |
| 892 // Resource are not immediately released. | |
| 893 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 894 EXPECT_EQ(0u, resources.size()); | |
| 895 EXPECT_FALSE(TestAndResetAvailable()); | |
| 896 | |
| 897 // Now using 555 and 444 again, but not 999. | |
| 898 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 899 AddTextureQuad(frame.get(), 555); | |
| 900 AddTransferableResource(frame.get(), 555); | |
| 901 AddTextureQuad(frame.get(), 444); | |
| 902 AddTransferableResource(frame.get(), 444); | |
| 903 SetFrameData(frame.Pass()); | |
| 904 break; | |
| 905 case 3: | |
| 906 // The 999 resource is the only unused one. Two references were sent, so | |
| 907 // two should be returned. | |
| 908 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 909 { | |
| 910 unsigned expected[] = {999, 999}; | |
| 911 EXPECT_RESOURCES(expected, resources); | |
| 912 EXPECT_TRUE(TestAndResetAvailable()); | |
| 913 } | |
| 914 EndTest(); | |
| 915 break; | |
| 916 } | |
| 917 } | |
| 918 | |
| 919 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 920 ReturnUnusedResourcesFromParent(host_impl); | |
| 921 } | |
| 922 }; | |
| 923 | |
| 924 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources); | |
| 925 | |
| 926 class LayerTreeHostDelegatedTestFrameBeforeAck | |
| 927 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 928 public: | |
| 929 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 930 | |
| 931 void DidCommitAndDrawFrame() override { | |
| 932 scoped_ptr<DelegatedFrameData> frame; | |
| 933 ReturnedResourceArray resources; | |
| 934 | |
| 935 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 936 switch (next_source_frame_number) { | |
| 937 case 1: | |
| 938 // Generate a frame with some resources in it. | |
| 939 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 940 AddTextureQuad(frame.get(), 999); | |
| 941 AddTransferableResource(frame.get(), 999); | |
| 942 AddTextureQuad(frame.get(), 555); | |
| 943 AddTransferableResource(frame.get(), 555); | |
| 944 AddTextureQuad(frame.get(), 444); | |
| 945 AddTransferableResource(frame.get(), 444); | |
| 946 SetFrameData(frame.Pass()); | |
| 947 break; | |
| 948 case 2: | |
| 949 // All of the resources are in use. | |
| 950 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 951 EXPECT_EQ(0u, resources.size()); | |
| 952 EXPECT_FALSE(TestAndResetAvailable()); | |
| 953 | |
| 954 // Keep using 999 but stop using 555 and 444. | |
| 955 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 956 AddTextureQuad(frame.get(), 999); | |
| 957 AddTransferableResource(frame.get(), 999); | |
| 958 SetFrameData(frame.Pass()); | |
| 959 | |
| 960 // Resource are not immediately released. | |
| 961 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 962 EXPECT_EQ(0u, resources.size()); | |
| 963 EXPECT_FALSE(TestAndResetAvailable()); | |
| 964 | |
| 965 // The parent compositor (this one) does a commit. | |
| 966 break; | |
| 967 case 3: | |
| 968 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 969 { | |
| 970 unsigned expected[] = {444, 555}; | |
| 971 EXPECT_RESOURCES(expected, resources); | |
| 972 EXPECT_TRUE(TestAndResetAvailable()); | |
| 973 } | |
| 974 | |
| 975 // The child compositor sends a frame referring to resources not in the | |
| 976 // frame. | |
| 977 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 978 AddTextureQuad(frame.get(), 999); | |
| 979 AddTextureQuad(frame.get(), 555); | |
| 980 AddTextureQuad(frame.get(), 444); | |
| 981 SetFrameData(frame.Pass()); | |
| 982 break; | |
| 983 } | |
| 984 } | |
| 985 | |
| 986 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 987 if (host_impl->active_tree()->source_frame_number() != 3) | |
| 988 return; | |
| 989 | |
| 990 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 991 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 992 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 993 | |
| 994 const ResourceProvider::ResourceIdMap& map = | |
| 995 host_impl->resource_provider()->GetChildToParentMap( | |
| 996 delegated_impl->ChildId()); | |
| 997 | |
| 998 // The bad frame should be dropped. So we should only have one quad (the | |
| 999 // one with resource 999) on the impl tree. And only 999 will be present | |
| 1000 // in the parent's resource provider. | |
| 1001 EXPECT_EQ(1u, map.size()); | |
| 1002 EXPECT_EQ(1u, map.count(999)); | |
| 1003 | |
| 1004 EXPECT_EQ(1u, delegated_impl->Resources().size()); | |
| 1005 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 1006 | |
| 1007 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; | |
| 1008 EXPECT_EQ(1u, pass->quad_list.size()); | |
| 1009 const TextureDrawQuad* quad = | |
| 1010 TextureDrawQuad::MaterialCast(pass->quad_list.front()); | |
| 1011 EXPECT_EQ(map.find(999)->second, quad->resource_id); | |
| 1012 | |
| 1013 EndTest(); | |
| 1014 } | |
| 1015 | |
| 1016 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 1017 ReturnUnusedResourcesFromParent(host_impl); | |
| 1018 } | |
| 1019 }; | |
| 1020 | |
| 1021 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck); | |
| 1022 | |
| 1023 class LayerTreeHostDelegatedTestFrameBeforeTakeResources | |
| 1024 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1025 public: | |
| 1026 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1027 | |
| 1028 void DidCommitAndDrawFrame() override { | |
| 1029 scoped_ptr<DelegatedFrameData> frame; | |
| 1030 ReturnedResourceArray resources; | |
| 1031 | |
| 1032 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1033 switch (next_source_frame_number) { | |
| 1034 case 1: | |
| 1035 // Generate a frame with some resources in it. | |
| 1036 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1037 AddTextureQuad(frame.get(), 999); | |
| 1038 AddTransferableResource(frame.get(), 999); | |
| 1039 AddTextureQuad(frame.get(), 555); | |
| 1040 AddTransferableResource(frame.get(), 555); | |
| 1041 AddTextureQuad(frame.get(), 444); | |
| 1042 AddTransferableResource(frame.get(), 444); | |
| 1043 SetFrameData(frame.Pass()); | |
| 1044 break; | |
| 1045 case 2: | |
| 1046 // All of the resources are in use. | |
| 1047 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1048 EXPECT_EQ(0u, resources.size()); | |
| 1049 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1050 | |
| 1051 // Keep using 999 but stop using 555 and 444. | |
| 1052 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1053 AddTextureQuad(frame.get(), 999); | |
| 1054 AddTransferableResource(frame.get(), 999); | |
| 1055 SetFrameData(frame.Pass()); | |
| 1056 | |
| 1057 // Resource are not immediately released. | |
| 1058 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1059 EXPECT_EQ(0u, resources.size()); | |
| 1060 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1061 | |
| 1062 // The parent compositor (this one) does a commit. | |
| 1063 break; | |
| 1064 case 3: | |
| 1065 // The child compositor sends a frame before taking resources back | |
| 1066 // from the previous commit. This frame makes use of the resources 555 | |
| 1067 // and 444, which were just released during commit. | |
| 1068 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1069 AddTextureQuad(frame.get(), 999); | |
| 1070 AddTransferableResource(frame.get(), 999); | |
| 1071 AddTextureQuad(frame.get(), 555); | |
| 1072 AddTransferableResource(frame.get(), 555); | |
| 1073 AddTextureQuad(frame.get(), 444); | |
| 1074 AddTransferableResource(frame.get(), 444); | |
| 1075 SetFrameData(frame.Pass()); | |
| 1076 | |
| 1077 // The resources are used by the new frame but are returned anyway since | |
| 1078 // we passed them again. | |
| 1079 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1080 { | |
| 1081 unsigned expected[] = {444, 555}; | |
| 1082 EXPECT_RESOURCES(expected, resources); | |
| 1083 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1084 } | |
| 1085 break; | |
| 1086 case 4: | |
| 1087 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1088 EXPECT_EQ(0u, resources.size()); | |
| 1089 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1090 EndTest(); | |
| 1091 break; | |
| 1092 } | |
| 1093 } | |
| 1094 | |
| 1095 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1096 if (host_impl->active_tree()->source_frame_number() != 3) | |
| 1097 return; | |
| 1098 | |
| 1099 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 1100 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 1101 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 1102 | |
| 1103 const ResourceProvider::ResourceIdMap& map = | |
| 1104 host_impl->resource_provider()->GetChildToParentMap( | |
| 1105 delegated_impl->ChildId()); | |
| 1106 | |
| 1107 // The third frame has all of the resources in it again, the delegated | |
| 1108 // renderer layer should continue to own the resources for it. | |
| 1109 EXPECT_EQ(3u, map.size()); | |
| 1110 EXPECT_EQ(1u, map.count(999)); | |
| 1111 EXPECT_EQ(1u, map.count(555)); | |
| 1112 EXPECT_EQ(1u, map.count(444)); | |
| 1113 | |
| 1114 EXPECT_EQ(3u, delegated_impl->Resources().size()); | |
| 1115 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 1116 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1117 EXPECT_EQ(1u, delegated_impl->Resources().count(444)); | |
| 1118 | |
| 1119 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; | |
| 1120 EXPECT_EQ(3u, pass->quad_list.size()); | |
| 1121 const TextureDrawQuad* quad1 = | |
| 1122 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0)); | |
| 1123 EXPECT_EQ(map.find(999)->second, quad1->resource_id); | |
| 1124 const TextureDrawQuad* quad2 = | |
| 1125 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1)); | |
| 1126 EXPECT_EQ(map.find(555)->second, quad2->resource_id); | |
| 1127 const TextureDrawQuad* quad3 = | |
| 1128 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(2)); | |
| 1129 EXPECT_EQ(map.find(444)->second, quad3->resource_id); | |
| 1130 } | |
| 1131 | |
| 1132 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 1133 ReturnUnusedResourcesFromParent(host_impl); | |
| 1134 } | |
| 1135 }; | |
| 1136 | |
| 1137 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 1138 LayerTreeHostDelegatedTestFrameBeforeTakeResources); | |
| 1139 | |
| 1140 class LayerTreeHostDelegatedTestBadFrame | |
| 1141 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1142 public: | |
| 1143 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1144 | |
| 1145 void DidCommitAndDrawFrame() override { | |
| 1146 scoped_ptr<DelegatedFrameData> frame; | |
| 1147 ReturnedResourceArray resources; | |
| 1148 | |
| 1149 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1150 switch (next_source_frame_number) { | |
| 1151 case 1: | |
| 1152 // Generate a frame with some resources in it. | |
| 1153 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1154 AddTextureQuad(frame.get(), 999); | |
| 1155 AddTransferableResource(frame.get(), 999); | |
| 1156 AddTextureQuad(frame.get(), 555); | |
| 1157 AddTransferableResource(frame.get(), 555); | |
| 1158 SetFrameData(frame.Pass()); | |
| 1159 break; | |
| 1160 case 2: | |
| 1161 // All of the resources are in use. | |
| 1162 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1163 EXPECT_EQ(0u, resources.size()); | |
| 1164 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1165 | |
| 1166 // Generate a bad frame with a resource the layer doesn't have. The | |
| 1167 // 885 and 775 resources are unknown, while ownership of the legit 444 | |
| 1168 // resource is passed in here. The bad frame does not use any of the | |
| 1169 // previous resources, 999 or 555. | |
| 1170 // A bad quad is present both before and after the good quad. | |
| 1171 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1172 AddTextureQuad(frame.get(), 885); | |
| 1173 AddTextureQuad(frame.get(), 444); | |
| 1174 AddTransferableResource(frame.get(), 444); | |
| 1175 AddTextureQuad(frame.get(), 775); | |
| 1176 SetFrameData(frame.Pass()); | |
| 1177 | |
| 1178 // The parent compositor (this one) does a commit. | |
| 1179 break; | |
| 1180 case 3: | |
| 1181 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1182 EXPECT_EQ(0u, resources.size()); | |
| 1183 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1184 | |
| 1185 // Now send a good frame with 999 again. | |
| 1186 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1187 AddTextureQuad(frame.get(), 999); | |
| 1188 SetFrameData(frame.Pass()); | |
| 1189 | |
| 1190 // The bad frame's resource is given back to the child compositor. | |
| 1191 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1192 { | |
| 1193 unsigned expected[] = {444}; | |
| 1194 EXPECT_RESOURCES(expected, resources); | |
| 1195 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1196 } | |
| 1197 break; | |
| 1198 case 4: | |
| 1199 // The unused 555 from the last good frame is now released. | |
| 1200 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1201 { | |
| 1202 unsigned expected[] = {555}; | |
| 1203 EXPECT_RESOURCES(expected, resources); | |
| 1204 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1205 } | |
| 1206 | |
| 1207 EndTest(); | |
| 1208 break; | |
| 1209 } | |
| 1210 } | |
| 1211 | |
| 1212 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 1213 if (host_impl->active_tree()->source_frame_number() < 1) | |
| 1214 return; | |
| 1215 | |
| 1216 ReturnUnusedResourcesFromParent(host_impl); | |
| 1217 | |
| 1218 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 1219 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 1220 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 1221 | |
| 1222 const ResourceProvider::ResourceIdMap& map = | |
| 1223 host_impl->resource_provider()->GetChildToParentMap( | |
| 1224 delegated_impl->ChildId()); | |
| 1225 | |
| 1226 switch (host_impl->active_tree()->source_frame_number()) { | |
| 1227 case 1: { | |
| 1228 // We have the first good frame with just 990 and 555 in it. | |
| 1229 // layer. | |
| 1230 EXPECT_EQ(2u, map.size()); | |
| 1231 EXPECT_EQ(1u, map.count(999)); | |
| 1232 EXPECT_EQ(1u, map.count(555)); | |
| 1233 | |
| 1234 EXPECT_EQ(2u, delegated_impl->Resources().size()); | |
| 1235 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 1236 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1237 | |
| 1238 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; | |
| 1239 EXPECT_EQ(2u, pass->quad_list.size()); | |
| 1240 const TextureDrawQuad* quad1 = | |
| 1241 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0)); | |
| 1242 EXPECT_EQ(map.find(999)->second, quad1->resource_id); | |
| 1243 const TextureDrawQuad* quad2 = | |
| 1244 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1)); | |
| 1245 EXPECT_EQ(map.find(555)->second, quad2->resource_id); | |
| 1246 break; | |
| 1247 } | |
| 1248 case 2: { | |
| 1249 // We only keep resources from the last valid frame. | |
| 1250 EXPECT_EQ(2u, map.size()); | |
| 1251 EXPECT_EQ(1u, map.count(999)); | |
| 1252 EXPECT_EQ(1u, map.count(555)); | |
| 1253 | |
| 1254 EXPECT_EQ(2u, delegated_impl->Resources().size()); | |
| 1255 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 1256 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1257 | |
| 1258 // The bad frame is dropped though, we still have the frame with 999 and | |
| 1259 // 555 in it. | |
| 1260 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; | |
| 1261 EXPECT_EQ(2u, pass->quad_list.size()); | |
| 1262 const TextureDrawQuad* quad1 = | |
| 1263 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0)); | |
| 1264 EXPECT_EQ(map.find(999)->second, quad1->resource_id); | |
| 1265 const TextureDrawQuad* quad2 = | |
| 1266 TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1)); | |
| 1267 EXPECT_EQ(map.find(555)->second, quad2->resource_id); | |
| 1268 break; | |
| 1269 } | |
| 1270 case 3: { | |
| 1271 // We have the new good frame with just 999 in it. | |
| 1272 EXPECT_EQ(1u, map.size()); | |
| 1273 EXPECT_EQ(1u, map.count(999)); | |
| 1274 | |
| 1275 EXPECT_EQ(1u, delegated_impl->Resources().size()); | |
| 1276 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 1277 | |
| 1278 const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; | |
| 1279 EXPECT_EQ(1u, pass->quad_list.size()); | |
| 1280 const TextureDrawQuad* quad1 = | |
| 1281 TextureDrawQuad::MaterialCast(pass->quad_list.front()); | |
| 1282 EXPECT_EQ(map.find(999)->second, quad1->resource_id); | |
| 1283 break; | |
| 1284 } | |
| 1285 } | |
| 1286 } | |
| 1287 }; | |
| 1288 | |
| 1289 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame); | |
| 1290 | |
| 1291 class LayerTreeHostDelegatedTestUnnamedResource | |
| 1292 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1293 public: | |
| 1294 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1295 | |
| 1296 void DidCommit() override { | |
| 1297 scoped_ptr<DelegatedFrameData> frame; | |
| 1298 ReturnedResourceArray resources; | |
| 1299 | |
| 1300 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1301 switch (next_source_frame_number) { | |
| 1302 case 1: | |
| 1303 // This frame includes two resources in it, but only uses one. | |
| 1304 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1305 AddTransferableResource(frame.get(), 999); | |
| 1306 AddTextureQuad(frame.get(), 555); | |
| 1307 AddTransferableResource(frame.get(), 555); | |
| 1308 SetFrameData(frame.Pass()); | |
| 1309 break; | |
| 1310 case 2: | |
| 1311 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1312 EXPECT_EQ(0u, resources.size()); | |
| 1313 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1314 | |
| 1315 // Now send an empty frame. | |
| 1316 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1317 SetFrameData(frame.Pass()); | |
| 1318 | |
| 1319 // The unused resource should be returned. | |
| 1320 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1321 { | |
| 1322 unsigned expected[] = {999}; | |
| 1323 EXPECT_RESOURCES(expected, resources); | |
| 1324 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1325 } | |
| 1326 | |
| 1327 EndTest(); | |
| 1328 break; | |
| 1329 } | |
| 1330 } | |
| 1331 | |
| 1332 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1333 if (host_impl->active_tree()->source_frame_number() != 1) | |
| 1334 return; | |
| 1335 | |
| 1336 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 1337 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 1338 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 1339 | |
| 1340 const ResourceProvider::ResourceIdMap& map = | |
| 1341 host_impl->resource_provider()->GetChildToParentMap( | |
| 1342 delegated_impl->ChildId()); | |
| 1343 | |
| 1344 // The layer only held on to the resource that was used. | |
| 1345 EXPECT_EQ(1u, map.size()); | |
| 1346 EXPECT_EQ(1u, map.count(555)); | |
| 1347 | |
| 1348 EXPECT_EQ(1u, delegated_impl->Resources().size()); | |
| 1349 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1350 } | |
| 1351 }; | |
| 1352 | |
| 1353 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestUnnamedResource); | |
| 1354 | |
| 1355 class LayerTreeHostDelegatedTestDontLeakResource | |
| 1356 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1357 public: | |
| 1358 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1359 | |
| 1360 void DidCommitAndDrawFrame() override { | |
| 1361 scoped_ptr<DelegatedFrameData> frame; | |
| 1362 ReturnedResourceArray resources; | |
| 1363 | |
| 1364 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1365 switch (next_source_frame_number) { | |
| 1366 case 1: | |
| 1367 // This frame includes two resources in it. | |
| 1368 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1369 AddTextureQuad(frame.get(), 999); | |
| 1370 AddTransferableResource(frame.get(), 999); | |
| 1371 AddTextureQuad(frame.get(), 555); | |
| 1372 AddTransferableResource(frame.get(), 555); | |
| 1373 SetFrameData(frame.Pass()); | |
| 1374 | |
| 1375 // But then we immediately stop using 999. | |
| 1376 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1377 AddTextureQuad(frame.get(), 555); | |
| 1378 AddTransferableResource(frame.get(), 555); | |
| 1379 SetFrameData(frame.Pass()); | |
| 1380 break; | |
| 1381 case 2: | |
| 1382 // The unused resources should be returned. 555 is still used, but it's | |
| 1383 // returned once to account for the first frame. | |
| 1384 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1385 { | |
| 1386 unsigned expected[] = {555, 999}; | |
| 1387 EXPECT_RESOURCES(expected, resources); | |
| 1388 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1389 } | |
| 1390 // Send a frame with no resources in it. | |
| 1391 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1392 SetFrameData(frame.Pass()); | |
| 1393 break; | |
| 1394 case 3: | |
| 1395 // The now unused resource 555 should be returned. | |
| 1396 resources.clear(); | |
| 1397 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1398 { | |
| 1399 unsigned expected[] = {555}; | |
| 1400 EXPECT_RESOURCES(expected, resources); | |
| 1401 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1402 } | |
| 1403 EndTest(); | |
| 1404 break; | |
| 1405 } | |
| 1406 } | |
| 1407 | |
| 1408 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1409 if (host_impl->active_tree()->source_frame_number() != 1) | |
| 1410 return; | |
| 1411 | |
| 1412 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 1413 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 1414 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 1415 | |
| 1416 const ResourceProvider::ResourceIdMap& map = | |
| 1417 host_impl->resource_provider()->GetChildToParentMap( | |
| 1418 delegated_impl->ChildId()); | |
| 1419 | |
| 1420 // The layer only held on to the resource that was used. | |
| 1421 EXPECT_EQ(1u, map.size()); | |
| 1422 EXPECT_EQ(1u, map.count(555)); | |
| 1423 | |
| 1424 EXPECT_EQ(1u, delegated_impl->Resources().size()); | |
| 1425 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1426 } | |
| 1427 | |
| 1428 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 1429 ReturnUnusedResourcesFromParent(host_impl); | |
| 1430 } | |
| 1431 }; | |
| 1432 | |
| 1433 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource); | |
| 1434 | |
| 1435 class LayerTreeHostDelegatedTestResourceSentToParent | |
| 1436 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1437 public: | |
| 1438 void DidCommitAndDrawFrame() override { | |
| 1439 scoped_ptr<DelegatedFrameData> frame; | |
| 1440 ReturnedResourceArray resources; | |
| 1441 | |
| 1442 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1443 switch (next_source_frame_number) { | |
| 1444 case 1: | |
| 1445 // This frame includes two resources in it. | |
| 1446 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1447 AddTextureQuad(frame.get(), 999); | |
| 1448 AddTransferableResource(frame.get(), 999); | |
| 1449 AddTextureQuad(frame.get(), 555); | |
| 1450 AddTransferableResource(frame.get(), 555); | |
| 1451 SetFrameData(frame.Pass()); | |
| 1452 break; | |
| 1453 case 2: | |
| 1454 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1455 EXPECT_EQ(0u, resources.size()); | |
| 1456 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1457 | |
| 1458 // 999 is in use in the grandparent compositor, generate a frame without | |
| 1459 // it present. | |
| 1460 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1461 AddTextureQuad(frame.get(), 555); | |
| 1462 AddTransferableResource(frame.get(), 555); | |
| 1463 SetFrameData(frame.Pass()); | |
| 1464 break; | |
| 1465 case 3: | |
| 1466 // Since 999 is in the grandparent it is not returned. | |
| 1467 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1468 EXPECT_EQ(0u, resources.size()); | |
| 1469 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1470 | |
| 1471 // The impl side will get back the resource at some point. | |
| 1472 ImplThreadTaskRunner()->PostTask(FROM_HERE, | |
| 1473 receive_resource_on_thread_); | |
| 1474 break; | |
| 1475 } | |
| 1476 } | |
| 1477 | |
| 1478 void ReceiveResourceOnThread(LayerTreeHostImpl* host_impl) { | |
| 1479 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 1480 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 1481 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 1482 | |
| 1483 const ResourceProvider::ResourceIdMap& map = | |
| 1484 host_impl->resource_provider()->GetChildToParentMap( | |
| 1485 delegated_impl->ChildId()); | |
| 1486 | |
| 1487 // Receive 999 back from the grandparent. | |
| 1488 CompositorFrameAck ack; | |
| 1489 output_surface()->ReturnResource(map.find(999)->second, &ack); | |
| 1490 host_impl->ReclaimResources(&ack); | |
| 1491 } | |
| 1492 | |
| 1493 void UnusedResourcesAreAvailable() override { | |
| 1494 EXPECT_EQ(3, layer_tree_host()->source_frame_number()); | |
| 1495 | |
| 1496 ReturnedResourceArray resources; | |
| 1497 | |
| 1498 // 999 was returned from the grandparent and could be released. | |
| 1499 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1500 { | |
| 1501 unsigned expected[] = {999}; | |
| 1502 EXPECT_RESOURCES(expected, resources); | |
| 1503 } | |
| 1504 | |
| 1505 EndTest(); | |
| 1506 } | |
| 1507 | |
| 1508 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1509 if (host_impl->active_tree()->source_frame_number() < 1) | |
| 1510 return; | |
| 1511 | |
| 1512 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 1513 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 1514 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 1515 | |
| 1516 const ResourceProvider::ResourceIdMap& map = | |
| 1517 host_impl->resource_provider()->GetChildToParentMap( | |
| 1518 delegated_impl->ChildId()); | |
| 1519 | |
| 1520 switch (host_impl->active_tree()->source_frame_number()) { | |
| 1521 case 1: { | |
| 1522 EXPECT_EQ(2u, map.size()); | |
| 1523 EXPECT_EQ(1u, map.count(999)); | |
| 1524 EXPECT_EQ(1u, map.count(555)); | |
| 1525 | |
| 1526 EXPECT_EQ(2u, delegated_impl->Resources().size()); | |
| 1527 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 1528 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1529 | |
| 1530 // The 999 resource will be sent to a grandparent compositor. | |
| 1531 break; | |
| 1532 } | |
| 1533 case 2: { | |
| 1534 EXPECT_EQ(2u, map.size()); | |
| 1535 EXPECT_EQ(1u, map.count(999)); | |
| 1536 EXPECT_EQ(1u, map.count(555)); | |
| 1537 | |
| 1538 // 999 is in the parent, so not held by delegated renderer layer. | |
| 1539 EXPECT_EQ(1u, delegated_impl->Resources().size()); | |
| 1540 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1541 | |
| 1542 receive_resource_on_thread_ = | |
| 1543 base::Bind(&LayerTreeHostDelegatedTestResourceSentToParent:: | |
| 1544 ReceiveResourceOnThread, | |
| 1545 base::Unretained(this), | |
| 1546 host_impl); | |
| 1547 break; | |
| 1548 } | |
| 1549 case 3: | |
| 1550 // 999 should be released. | |
| 1551 EXPECT_EQ(1u, map.size()); | |
| 1552 EXPECT_EQ(1u, map.count(555)); | |
| 1553 | |
| 1554 EXPECT_EQ(1u, delegated_impl->Resources().size()); | |
| 1555 EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second)); | |
| 1556 break; | |
| 1557 } | |
| 1558 } | |
| 1559 | |
| 1560 base::Closure receive_resource_on_thread_; | |
| 1561 }; | |
| 1562 | |
| 1563 SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F( | |
| 1564 LayerTreeHostDelegatedTestResourceSentToParent); | |
| 1565 | |
| 1566 class LayerTreeHostDelegatedTestCommitWithoutTake | |
| 1567 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1568 public: | |
| 1569 void BeginTest() override { | |
| 1570 // Prevent drawing with resources that are sent to the grandparent. | |
| 1571 layer_tree_host()->SetViewportSize(gfx::Size()); | |
| 1572 PostSetNeedsCommitToMainThread(); | |
| 1573 } | |
| 1574 | |
| 1575 void DidCommit() override { | |
| 1576 scoped_ptr<DelegatedFrameData> frame; | |
| 1577 ReturnedResourceArray resources; | |
| 1578 | |
| 1579 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1580 switch (next_source_frame_number) { | |
| 1581 case 1: | |
| 1582 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1583 AddTextureQuad(frame.get(), 999); | |
| 1584 AddTransferableResource(frame.get(), 999); | |
| 1585 AddTextureQuad(frame.get(), 555); | |
| 1586 AddTransferableResource(frame.get(), 555); | |
| 1587 AddTextureQuad(frame.get(), 444); | |
| 1588 AddTransferableResource(frame.get(), 444); | |
| 1589 SetFrameData(frame.Pass()); | |
| 1590 break; | |
| 1591 case 2: | |
| 1592 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1593 EXPECT_EQ(0u, resources.size()); | |
| 1594 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1595 | |
| 1596 // Stop using 999 and 444 in this frame and commit. | |
| 1597 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1598 AddTextureQuad(frame.get(), 555); | |
| 1599 AddTransferableResource(frame.get(), 555); | |
| 1600 SetFrameData(frame.Pass()); | |
| 1601 // 999 and 444 will be returned for frame 1, but not 555 since it's in | |
| 1602 // the current frame. | |
| 1603 break; | |
| 1604 case 3: | |
| 1605 // Don't take resources here, but set a new frame that uses 999 again. | |
| 1606 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1607 AddTextureQuad(frame.get(), 999); | |
| 1608 AddTransferableResource(frame.get(), 999); | |
| 1609 AddTextureQuad(frame.get(), 555); | |
| 1610 AddTransferableResource(frame.get(), 555); | |
| 1611 SetFrameData(frame.Pass()); | |
| 1612 break; | |
| 1613 case 4: | |
| 1614 // 555 from frame 1 and 2 isn't returned since it's still in use. 999 | |
| 1615 // from frame 1 is returned though. | |
| 1616 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1617 { | |
| 1618 unsigned expected[] = {444, 999}; | |
| 1619 EXPECT_RESOURCES(expected, resources); | |
| 1620 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1621 } | |
| 1622 | |
| 1623 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1624 SetFrameData(frame.Pass()); | |
| 1625 // 555 will be returned 3 times for frames 1 2 and 3, and 999 will be | |
| 1626 // returned once for frame 3. | |
| 1627 break; | |
| 1628 case 5: | |
| 1629 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1630 { | |
| 1631 unsigned expected[] = {555, 555, 555, 999}; | |
| 1632 EXPECT_RESOURCES(expected, resources); | |
| 1633 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1634 } | |
| 1635 | |
| 1636 EndTest(); | |
| 1637 break; | |
| 1638 } | |
| 1639 } | |
| 1640 | |
| 1641 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1642 if (host_impl->active_tree()->source_frame_number() < 1) | |
| 1643 return; | |
| 1644 | |
| 1645 LayerImpl* root_impl = host_impl->active_tree()->root_layer(); | |
| 1646 FakeDelegatedRendererLayerImpl* delegated_impl = | |
| 1647 static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); | |
| 1648 | |
| 1649 const ResourceProvider::ResourceIdMap& map = | |
| 1650 host_impl->resource_provider()->GetChildToParentMap( | |
| 1651 delegated_impl->ChildId()); | |
| 1652 | |
| 1653 switch (host_impl->active_tree()->source_frame_number()) { | |
| 1654 case 1: | |
| 1655 EXPECT_EQ(3u, map.size()); | |
| 1656 EXPECT_EQ(1u, map.count(999)); | |
| 1657 EXPECT_EQ(1u, map.count(555)); | |
| 1658 EXPECT_EQ(1u, map.count(444)); | |
| 1659 | |
| 1660 EXPECT_EQ(3u, delegated_impl->Resources().size()); | |
| 1661 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 1662 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1663 EXPECT_EQ(1u, delegated_impl->Resources().count(444)); | |
| 1664 break; | |
| 1665 case 2: | |
| 1666 EXPECT_EQ(1u, map.size()); | |
| 1667 EXPECT_EQ(1u, map.count(555)); | |
| 1668 | |
| 1669 EXPECT_EQ(1u, delegated_impl->Resources().size()); | |
| 1670 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1671 break; | |
| 1672 case 3: | |
| 1673 EXPECT_EQ(2u, map.size()); | |
| 1674 EXPECT_EQ(1u, map.count(999)); | |
| 1675 EXPECT_EQ(1u, map.count(555)); | |
| 1676 | |
| 1677 EXPECT_EQ(2u, delegated_impl->Resources().size()); | |
| 1678 EXPECT_EQ(1u, delegated_impl->Resources().count(999)); | |
| 1679 EXPECT_EQ(1u, delegated_impl->Resources().count(555)); | |
| 1680 } | |
| 1681 } | |
| 1682 }; | |
| 1683 | |
| 1684 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCommitWithoutTake); | |
| 1685 | |
| 1686 class DelegatedFrameIsActivatedDuringCommit | |
| 1687 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1688 protected: | |
| 1689 DelegatedFrameIsActivatedDuringCommit() : returned_resource_count_(0) {} | |
| 1690 | |
| 1691 void BeginTest() override { | |
| 1692 activate_count_ = 0; | |
| 1693 | |
| 1694 scoped_ptr<DelegatedFrameData> frame = | |
| 1695 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1696 AddTextureQuad(frame.get(), 999); | |
| 1697 AddTransferableResource(frame.get(), 999); | |
| 1698 SetFrameData(frame.Pass()); | |
| 1699 | |
| 1700 PostSetNeedsCommitToMainThread(); | |
| 1701 } | |
| 1702 | |
| 1703 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
| 1704 ++activate_count_; | |
| 1705 } | |
| 1706 | |
| 1707 void DidCommit() override { | |
| 1708 switch (layer_tree_host()->source_frame_number()) { | |
| 1709 case 1: { | |
| 1710 // The first frame has been activated. Set a new frame, and | |
| 1711 // expect the next commit to finish *after* it is activated. | |
| 1712 scoped_ptr<DelegatedFrameData> frame = | |
| 1713 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1714 AddTextureQuad(frame.get(), 555); | |
| 1715 AddTransferableResource(frame.get(), 555); | |
| 1716 SetFrameData(frame.Pass()); | |
| 1717 break; | |
| 1718 } | |
| 1719 case 2: | |
| 1720 // The second frame has been activated. Remove the layer from | |
| 1721 // the tree to cause another commit/activation. The commit should | |
| 1722 // finish *after* the layer is removed from the active tree. | |
| 1723 delegated_->RemoveFromParent(); | |
| 1724 break; | |
| 1725 case 3: | |
| 1726 // Finish the test by releasing resources on the next frame. | |
| 1727 scoped_ptr<DelegatedFrameData> frame = | |
| 1728 CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1729 SetFrameData(frame.Pass()); | |
| 1730 break; | |
| 1731 } | |
| 1732 } | |
| 1733 | |
| 1734 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1735 switch (host_impl->active_tree()->source_frame_number()) { | |
| 1736 case 0: { | |
| 1737 // The activate for the 1st frame should have happened before now. | |
| 1738 EXPECT_EQ(1, activate_count_); | |
| 1739 break; | |
| 1740 } | |
| 1741 case 1: { | |
| 1742 // The activate for the 2nd frame should have happened before now. | |
| 1743 EXPECT_EQ(2, activate_count_); | |
| 1744 break; | |
| 1745 } | |
| 1746 case 2: { | |
| 1747 // The activate to remove the layer should have happened before now. | |
| 1748 EXPECT_EQ(3, activate_count_); | |
| 1749 break; | |
| 1750 } | |
| 1751 case 3: { | |
| 1752 NOTREACHED(); | |
| 1753 break; | |
| 1754 } | |
| 1755 } | |
| 1756 } | |
| 1757 | |
| 1758 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 1759 ReturnUnusedResourcesFromParent(host_impl); | |
| 1760 } | |
| 1761 | |
| 1762 void UnusedResourcesAreAvailable() override { | |
| 1763 LayerTreeHostDelegatedTestCaseSingleDelegatedLayer:: | |
| 1764 UnusedResourcesAreAvailable(); | |
| 1765 ReturnedResourceArray resources; | |
| 1766 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1767 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1768 returned_resource_count_ += resources.size(); | |
| 1769 if (returned_resource_count_ == 2) | |
| 1770 EndTest(); | |
| 1771 } | |
| 1772 | |
| 1773 int activate_count_; | |
| 1774 size_t returned_resource_count_; | |
| 1775 }; | |
| 1776 | |
| 1777 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 1778 DelegatedFrameIsActivatedDuringCommit); | |
| 1779 | |
| 1780 class LayerTreeHostDelegatedTestTwoImplLayers | |
| 1781 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1782 public: | |
| 1783 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1784 | |
| 1785 void DidCommitAndDrawFrame() override { | |
| 1786 scoped_ptr<DelegatedFrameData> frame; | |
| 1787 ReturnedResourceArray resources; | |
| 1788 | |
| 1789 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1790 switch (next_source_frame_number) { | |
| 1791 case 1: | |
| 1792 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1793 AddTextureQuad(frame.get(), 999); | |
| 1794 AddTransferableResource(frame.get(), 999); | |
| 1795 AddTextureQuad(frame.get(), 555); | |
| 1796 AddTransferableResource(frame.get(), 555); | |
| 1797 SetFrameData(frame.Pass()); | |
| 1798 break; | |
| 1799 case 2: | |
| 1800 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1801 EXPECT_EQ(0u, resources.size()); | |
| 1802 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1803 | |
| 1804 // Remove the delegated layer and replace it with a new one. Use the | |
| 1805 // same frame and resources for it. | |
| 1806 delegated_->RemoveFromParent(); | |
| 1807 delegated_ = CreateDelegatedLayer(frame_provider_.get()); | |
| 1808 break; | |
| 1809 case 3: | |
| 1810 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1811 EXPECT_EQ(0u, resources.size()); | |
| 1812 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1813 | |
| 1814 // Use a frame with no resources in it. | |
| 1815 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1816 SetFrameData(frame.Pass()); | |
| 1817 break; | |
| 1818 case 4: | |
| 1819 // We gave one frame to the frame provider, so we should get one | |
| 1820 // ref back for each resource. | |
| 1821 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1822 { | |
| 1823 unsigned expected[] = {555, 999}; | |
| 1824 EXPECT_RESOURCES(expected, resources); | |
| 1825 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1826 } | |
| 1827 EndTest(); | |
| 1828 break; | |
| 1829 } | |
| 1830 } | |
| 1831 | |
| 1832 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 1833 ReturnUnusedResourcesFromParent(host_impl); | |
| 1834 } | |
| 1835 }; | |
| 1836 | |
| 1837 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoImplLayers); | |
| 1838 | |
| 1839 class LayerTreeHostDelegatedTestTwoImplLayersTwoFrames | |
| 1840 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1841 public: | |
| 1842 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1843 | |
| 1844 void DidCommitAndDrawFrame() override { | |
| 1845 scoped_ptr<DelegatedFrameData> frame; | |
| 1846 ReturnedResourceArray resources; | |
| 1847 | |
| 1848 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1849 switch (next_source_frame_number) { | |
| 1850 case 1: | |
| 1851 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1852 AddTextureQuad(frame.get(), 999); | |
| 1853 AddTransferableResource(frame.get(), 999); | |
| 1854 AddTextureQuad(frame.get(), 555); | |
| 1855 AddTransferableResource(frame.get(), 555); | |
| 1856 SetFrameData(frame.Pass()); | |
| 1857 break; | |
| 1858 case 2: | |
| 1859 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1860 EXPECT_EQ(0u, resources.size()); | |
| 1861 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1862 | |
| 1863 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1864 AddTextureQuad(frame.get(), 999); | |
| 1865 AddTransferableResource(frame.get(), 999); | |
| 1866 AddTextureQuad(frame.get(), 555); | |
| 1867 AddTransferableResource(frame.get(), 555); | |
| 1868 | |
| 1869 // Remove the delegated layer and replace it with a new one. Make a new | |
| 1870 // frame but with the same resources for it. | |
| 1871 delegated_->RemoveFromParent(); | |
| 1872 delegated_ = NULL; | |
| 1873 | |
| 1874 frame_provider_->SetFrameData(frame.Pass()); | |
| 1875 delegated_ = CreateDelegatedLayer(frame_provider_.get()); | |
| 1876 break; | |
| 1877 case 3: | |
| 1878 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1879 EXPECT_EQ(0u, resources.size()); | |
| 1880 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1881 | |
| 1882 // Use a frame with no resources in it. | |
| 1883 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1884 SetFrameData(frame.Pass()); | |
| 1885 break; | |
| 1886 case 4: | |
| 1887 // We gave two frames to the frame provider, so we should get two | |
| 1888 // refs back for each resource. | |
| 1889 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1890 { | |
| 1891 unsigned expected[] = {555, 555, 999, 999}; | |
| 1892 EXPECT_RESOURCES(expected, resources); | |
| 1893 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1894 } | |
| 1895 EndTest(); | |
| 1896 break; | |
| 1897 } | |
| 1898 } | |
| 1899 | |
| 1900 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 1901 ReturnUnusedResourcesFromParent(host_impl); | |
| 1902 } | |
| 1903 }; | |
| 1904 | |
| 1905 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 1906 LayerTreeHostDelegatedTestTwoImplLayersTwoFrames); | |
| 1907 | |
| 1908 class LayerTreeHostDelegatedTestTwoLayers | |
| 1909 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1910 public: | |
| 1911 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1912 | |
| 1913 void DidCommitAndDrawFrame() override { | |
| 1914 scoped_ptr<DelegatedFrameData> frame; | |
| 1915 ReturnedResourceArray resources; | |
| 1916 | |
| 1917 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 1918 switch (next_source_frame_number) { | |
| 1919 case 1: | |
| 1920 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 1921 AddTextureQuad(frame.get(), 999); | |
| 1922 AddTransferableResource(frame.get(), 999); | |
| 1923 AddTextureQuad(frame.get(), 555); | |
| 1924 AddTransferableResource(frame.get(), 555); | |
| 1925 | |
| 1926 // Create a DelegatedRendererLayer using the frame. | |
| 1927 SetFrameData(frame.Pass()); | |
| 1928 break; | |
| 1929 case 2: | |
| 1930 // Create a second DelegatedRendererLayer using the same frame provider. | |
| 1931 delegated_thief_ = CreateDelegatedLayer(frame_provider_.get()); | |
| 1932 root_->AddChild(delegated_thief_); | |
| 1933 | |
| 1934 // And drop our ref on the frame provider so only the layers keep it | |
| 1935 // alive. | |
| 1936 frame_provider_ = NULL; | |
| 1937 break; | |
| 1938 case 3: | |
| 1939 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1940 EXPECT_EQ(0u, resources.size()); | |
| 1941 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1942 | |
| 1943 // Remove one delegated layer from the tree. No resources should be | |
| 1944 // returned yet. | |
| 1945 delegated_->RemoveFromParent(); | |
| 1946 break; | |
| 1947 case 4: | |
| 1948 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1949 EXPECT_EQ(0u, resources.size()); | |
| 1950 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1951 | |
| 1952 // Put the first layer back, and remove the other layer and destroy it. | |
| 1953 // No resources should be returned yet. | |
| 1954 root_->AddChild(delegated_); | |
| 1955 delegated_thief_->RemoveFromParent(); | |
| 1956 delegated_thief_ = NULL; | |
| 1957 break; | |
| 1958 case 5: | |
| 1959 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1960 EXPECT_EQ(0u, resources.size()); | |
| 1961 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1962 | |
| 1963 // Remove the first layer from the tree again. The resources are still | |
| 1964 // held by the main thread layer. | |
| 1965 delegated_->RemoveFromParent(); | |
| 1966 break; | |
| 1967 case 6: | |
| 1968 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1969 EXPECT_EQ(0u, resources.size()); | |
| 1970 EXPECT_FALSE(TestAndResetAvailable()); | |
| 1971 | |
| 1972 // Destroy the layer and the resources should be returned immediately. | |
| 1973 delegated_ = NULL; | |
| 1974 | |
| 1975 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 1976 { | |
| 1977 unsigned expected[] = {555, 999}; | |
| 1978 EXPECT_RESOURCES(expected, resources); | |
| 1979 EXPECT_TRUE(TestAndResetAvailable()); | |
| 1980 } | |
| 1981 EndTest(); | |
| 1982 break; | |
| 1983 } | |
| 1984 } | |
| 1985 | |
| 1986 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 1987 ReturnUnusedResourcesFromParent(host_impl); | |
| 1988 } | |
| 1989 | |
| 1990 scoped_refptr<DelegatedRendererLayer> delegated_thief_; | |
| 1991 }; | |
| 1992 | |
| 1993 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoLayers); | |
| 1994 | |
| 1995 class LayerTreeHostDelegatedTestRemoveAndAddToTree | |
| 1996 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 1997 public: | |
| 1998 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1999 | |
| 2000 void DidCommitAndDrawFrame() override { | |
| 2001 scoped_ptr<DelegatedFrameData> frame; | |
| 2002 ReturnedResourceArray resources; | |
| 2003 | |
| 2004 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 2005 switch (next_source_frame_number) { | |
| 2006 case 1: | |
| 2007 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 2008 AddTextureQuad(frame.get(), 999); | |
| 2009 AddTransferableResource(frame.get(), 999); | |
| 2010 AddTextureQuad(frame.get(), 555); | |
| 2011 AddTransferableResource(frame.get(), 555); | |
| 2012 | |
| 2013 // Create a DelegatedRendererLayer using the frame. | |
| 2014 SetFrameData(frame.Pass()); | |
| 2015 break; | |
| 2016 case 2: | |
| 2017 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2018 EXPECT_EQ(0u, resources.size()); | |
| 2019 EXPECT_FALSE(TestAndResetAvailable()); | |
| 2020 | |
| 2021 // Remove the layer from the tree. The resources should not be returned | |
| 2022 // since they are still on the main thread layer. | |
| 2023 delegated_->RemoveFromParent(); | |
| 2024 break; | |
| 2025 case 3: | |
| 2026 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2027 EXPECT_EQ(0u, resources.size()); | |
| 2028 EXPECT_FALSE(TestAndResetAvailable()); | |
| 2029 | |
| 2030 // Add the layer back to the tree. | |
| 2031 layer_tree_host()->root_layer()->AddChild(delegated_); | |
| 2032 break; | |
| 2033 case 4: | |
| 2034 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2035 EXPECT_EQ(0u, resources.size()); | |
| 2036 EXPECT_FALSE(TestAndResetAvailable()); | |
| 2037 | |
| 2038 // Set a new frame. Resources should be returned. | |
| 2039 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 2040 AddTextureQuad(frame.get(), 888); | |
| 2041 AddTransferableResource(frame.get(), 888); | |
| 2042 AddTextureQuad(frame.get(), 777); | |
| 2043 AddTransferableResource(frame.get(), 777); | |
| 2044 SetFrameData(frame.Pass()); | |
| 2045 break; | |
| 2046 case 5: | |
| 2047 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2048 { | |
| 2049 unsigned expected[] = {555, 999}; | |
| 2050 EXPECT_RESOURCES(expected, resources); | |
| 2051 EXPECT_TRUE(TestAndResetAvailable()); | |
| 2052 } | |
| 2053 | |
| 2054 // Destroy the layer. | |
| 2055 delegated_->RemoveFromParent(); | |
| 2056 delegated_ = NULL; | |
| 2057 break; | |
| 2058 case 6: | |
| 2059 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2060 EXPECT_EQ(0u, resources.size()); | |
| 2061 EXPECT_FALSE(TestAndResetAvailable()); | |
| 2062 | |
| 2063 // Destroy the frame provider. Resources should be returned. | |
| 2064 frame_provider_ = NULL; | |
| 2065 | |
| 2066 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2067 { | |
| 2068 unsigned expected[] = {777, 888}; | |
| 2069 EXPECT_RESOURCES(expected, resources); | |
| 2070 EXPECT_TRUE(TestAndResetAvailable()); | |
| 2071 } | |
| 2072 EndTest(); | |
| 2073 break; | |
| 2074 } | |
| 2075 } | |
| 2076 | |
| 2077 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 2078 ReturnUnusedResourcesFromParent(host_impl); | |
| 2079 } | |
| 2080 | |
| 2081 scoped_refptr<DelegatedRendererLayer> delegated_thief_; | |
| 2082 }; | |
| 2083 | |
| 2084 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemoveAndAddToTree); | |
| 2085 | |
| 2086 class LayerTreeHostDelegatedTestRemoveAndChangeResources | |
| 2087 : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { | |
| 2088 public: | |
| 2089 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 2090 | |
| 2091 void DidCommitAndDrawFrame() override { | |
| 2092 scoped_ptr<DelegatedFrameData> frame; | |
| 2093 ReturnedResourceArray resources; | |
| 2094 | |
| 2095 int next_source_frame_number = layer_tree_host()->source_frame_number(); | |
| 2096 switch (next_source_frame_number) { | |
| 2097 case 1: | |
| 2098 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 2099 AddTextureQuad(frame.get(), 999); | |
| 2100 AddTransferableResource(frame.get(), 999); | |
| 2101 AddTextureQuad(frame.get(), 555); | |
| 2102 AddTransferableResource(frame.get(), 555); | |
| 2103 | |
| 2104 // Create a DelegatedRendererLayer using the frame. | |
| 2105 SetFrameData(frame.Pass()); | |
| 2106 break; | |
| 2107 case 2: | |
| 2108 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2109 EXPECT_EQ(0u, resources.size()); | |
| 2110 EXPECT_FALSE(TestAndResetAvailable()); | |
| 2111 | |
| 2112 // Remove the layer from the tree. The resources should not be returned | |
| 2113 // since they are still on the main thread layer. | |
| 2114 delegated_->RemoveFromParent(); | |
| 2115 break; | |
| 2116 case 3: | |
| 2117 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2118 EXPECT_EQ(0u, resources.size()); | |
| 2119 EXPECT_FALSE(TestAndResetAvailable()); | |
| 2120 | |
| 2121 // Set a new frame. Resources should be returned immediately. | |
| 2122 frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); | |
| 2123 AddTextureQuad(frame.get(), 888); | |
| 2124 AddTransferableResource(frame.get(), 888); | |
| 2125 AddTextureQuad(frame.get(), 777); | |
| 2126 AddTransferableResource(frame.get(), 777); | |
| 2127 SetFrameData(frame.Pass()); | |
| 2128 | |
| 2129 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2130 { | |
| 2131 unsigned expected[] = {555, 999}; | |
| 2132 EXPECT_RESOURCES(expected, resources); | |
| 2133 EXPECT_TRUE(TestAndResetAvailable()); | |
| 2134 resources.clear(); | |
| 2135 } | |
| 2136 | |
| 2137 // Destroy the frame provider. | |
| 2138 frame_provider_ = NULL; | |
| 2139 | |
| 2140 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2141 EXPECT_EQ(0u, resources.size()); | |
| 2142 EXPECT_FALSE(TestAndResetAvailable()); | |
| 2143 | |
| 2144 // Destroy the layer. Resources should be returned. | |
| 2145 delegated_ = NULL; | |
| 2146 | |
| 2147 resource_collection_->TakeUnusedResourcesForChildCompositor(&resources); | |
| 2148 { | |
| 2149 unsigned expected[] = {777, 888}; | |
| 2150 EXPECT_RESOURCES(expected, resources); | |
| 2151 EXPECT_TRUE(TestAndResetAvailable()); | |
| 2152 } | |
| 2153 EndTest(); | |
| 2154 break; | |
| 2155 } | |
| 2156 } | |
| 2157 | |
| 2158 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 2159 ReturnUnusedResourcesFromParent(host_impl); | |
| 2160 } | |
| 2161 | |
| 2162 scoped_refptr<DelegatedRendererLayer> delegated_thief_; | |
| 2163 }; | |
| 2164 | |
| 2165 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 2166 LayerTreeHostDelegatedTestRemoveAndChangeResources); | |
| 2167 | |
| 2168 } // namespace | |
| 2169 } // namespace cc | |
| OLD | NEW |