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