1 // Copyright 2012 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 "cc/layers/layer.h" 8 #include "cc/output/copy_output_request.h" 9 #include "cc/output/copy_output_result.h" 10 #include "cc/test/layer_tree_test.h" 11 #include "cc/test/test_occlusion_tracker.h" 12 13 namespace cc { 14 namespace { 15 16 class TestLayer : public Layer { 17 public: 18 static scoped_refptr<TestLayer> Create() { 19 return make_scoped_refptr(new TestLayer()); 20 } 21 22 virtual bool Update(ResourceUpdateQueue* update_queue, 23 const OcclusionTracker<Layer>* occlusion) OVERRIDE { 24 if (!occlusion) 25 return false; 26 27 // Gain access to internals of the OcclusionTracker. 28 const TestOcclusionTracker<Layer>* test_occlusion = 29 static_cast<const TestOcclusionTracker<Layer>*>(occlusion); 30 occlusion_ = UnionRegions( 31 test_occlusion->occlusion_from_inside_target(), 32 test_occlusion->occlusion_from_outside_target()); 33 return false; 34 } 35 36 const Region& occlusion() const { return occlusion_; } 37 const Region& expected_occlusion() const { return expected_occlusion_; } 38 void set_expected_occlusion(const Region& occlusion) { 39 expected_occlusion_ = occlusion; 40 } 41 42 private: 43 TestLayer() : Layer() { 44 SetIsDrawable(true); 45 } 46 virtual ~TestLayer() {} 47 48 Region occlusion_; 49 Region expected_occlusion_; 50 }; 51 52 class LayerTreeHostOcclusionTest : public LayerTreeTest { 53 public: 54 LayerTreeHostOcclusionTest() 55 : root_(TestLayer::Create()), 56 child_(TestLayer::Create()), 57 child2_(TestLayer::Create()), 58 grand_child_(TestLayer::Create()), 59 mask_(TestLayer::Create()) { 60 } 61 62 virtual void BeginTest() OVERRIDE { 63 PostSetNeedsCommitToMainThread(); 64 } 65 66 virtual void DidCommit() OVERRIDE { 67 TestLayer* root = static_cast<TestLayer*>(layer_tree_host()->root_layer()); 68 VerifyOcclusion(root); 69 70 EndTest(); 71 } 72 73 virtual void AfterTest() OVERRIDE {} 74 75 void VerifyOcclusion(TestLayer* layer) const { 76 EXPECT_EQ(layer->expected_occlusion().ToString(), 77 layer->occlusion().ToString()); 78 79 for (size_t i = 0; i < layer->children().size(); ++i) { 80 TestLayer* child = static_cast<TestLayer*>(layer->children()[i].get()); 81 VerifyOcclusion(child); 82 } 83 } 84 85 void SetLayerPropertiesForTesting(TestLayer* layer, 86 TestLayer* parent, 87 const gfx::Transform& transform, 88 const gfx::PointF& position, 89 const gfx::Size& bounds, 90 bool opaque) const { 91 layer->RemoveAllChildren(); 92 if (parent) 93 parent->AddChild(layer); 94 layer->SetTransform(transform); 95 layer->SetPosition(position); 96 layer->SetBounds(bounds); 97 layer->SetContentsOpaque(opaque); 98 } 99 100 protected: 101 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 102 settings->minimum_occlusion_tracking_size = gfx::Size(); 103 } 104 105 scoped_refptr<TestLayer> root_; 106 scoped_refptr<TestLayer> child_; 107 scoped_refptr<TestLayer> child2_; 108 scoped_refptr<TestLayer> grand_child_; 109 scoped_refptr<TestLayer> mask_; 110 111 gfx::Transform identity_matrix_; 112 }; 113 114 115 class LayerTreeHostOcclusionTestOcclusionSurfaceClipping 116 : public LayerTreeHostOcclusionTest { 117 public: 118 virtual void SetupTree() OVERRIDE { 119 // The child layer is a surface and the grand_child is opaque, but clipped 120 // to the child and root 121 SetLayerPropertiesForTesting( 122 root_.get(), NULL, identity_matrix_, 123 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 124 SetLayerPropertiesForTesting( 125 child_.get(), root_.get(), identity_matrix_, 126 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false); 127 SetLayerPropertiesForTesting( 128 grand_child_.get(), child_.get(), identity_matrix_, 129 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 130 131 child_->SetMasksToBounds(true); 132 child_->SetForceRenderSurface(true); 133 134 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190)); 135 root_->set_expected_occlusion(gfx::Rect(10, 10, 10, 190)); 136 137 layer_tree_host()->SetRootLayer(root_); 138 LayerTreeTest::SetupTree(); 139 } 140 }; 141 142 SINGLE_AND_MULTI_THREAD_TEST_F( 143 LayerTreeHostOcclusionTestOcclusionSurfaceClipping); 144 145 class LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque 146 : public LayerTreeHostOcclusionTest { 147 public: 148 virtual void SetupTree() OVERRIDE { 149 // If the child layer is opaque, then it adds to the occlusion seen by the 150 // root_. 151 SetLayerPropertiesForTesting( 152 root_.get(), NULL, identity_matrix_, 153 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 154 SetLayerPropertiesForTesting( 155 child_.get(), root_.get(), identity_matrix_, 156 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 157 SetLayerPropertiesForTesting( 158 grand_child_.get(), child_.get(), identity_matrix_, 159 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 160 161 child_->SetMasksToBounds(true); 162 child_->SetForceRenderSurface(true); 163 164 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190)); 165 root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190)); 166 167 layer_tree_host()->SetRootLayer(root_); 168 LayerTreeTest::SetupTree(); 169 } 170 }; 171 172 SINGLE_AND_MULTI_THREAD_TEST_F( 173 LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque); 174 175 class LayerTreeHostOcclusionTestOcclusionTwoChildren 176 : public LayerTreeHostOcclusionTest { 177 public: 178 virtual void SetupTree() OVERRIDE { 179 // Add a second child to the root layer and the regions should merge 180 SetLayerPropertiesForTesting( 181 root_.get(), NULL, identity_matrix_, 182 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 183 SetLayerPropertiesForTesting( 184 child_.get(), root_.get(), identity_matrix_, 185 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false); 186 SetLayerPropertiesForTesting( 187 grand_child_.get(), child_.get(), identity_matrix_, 188 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 189 SetLayerPropertiesForTesting( 190 child2_.get(), root_.get(), identity_matrix_, 191 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true); 192 193 child_->SetMasksToBounds(true); 194 child_->SetForceRenderSurface(true); 195 196 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190)); 197 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190)); 198 root_->set_expected_occlusion(gfx::Rect(10, 10, 20, 190)); 199 200 layer_tree_host()->SetRootLayer(root_); 201 LayerTreeTest::SetupTree(); 202 } 203 }; 204 205 SINGLE_AND_MULTI_THREAD_TEST_F( 206 LayerTreeHostOcclusionTestOcclusionTwoChildren); 207 208 class LayerTreeHostOcclusionTestOcclusionMask 209 : public LayerTreeHostOcclusionTest { 210 public: 211 virtual void SetupTree() OVERRIDE { 212 // If the child layer has a mask on it, then it shouldn't contribute to 213 // occlusion on stuff below it. 214 SetLayerPropertiesForTesting( 215 root_.get(), NULL, identity_matrix_, 216 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 217 SetLayerPropertiesForTesting( 218 child2_.get(), root_.get(), identity_matrix_, 219 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 220 SetLayerPropertiesForTesting( 221 child_.get(), root_.get(), identity_matrix_, 222 gfx::PointF(20.f, 20.f), gfx::Size(500, 500), true); 223 SetLayerPropertiesForTesting( 224 grand_child_.get(), child_.get(), identity_matrix_, 225 gfx::PointF(-10.f, -10.f), gfx::Size(500, 500), true); 226 227 child_->SetMasksToBounds(true); 228 child_->SetForceRenderSurface(true); 229 child_->SetMaskLayer(mask_.get()); 230 231 child_->set_expected_occlusion(gfx::Rect(0, 0, 180, 180)); 232 root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190)); 233 234 layer_tree_host()->SetRootLayer(root_); 235 LayerTreeTest::SetupTree(); 236 } 237 }; 238 239 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionMask); 240 241 class LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion 242 : public LayerTreeHostOcclusionTest { 243 public: 244 virtual void SetupTree() OVERRIDE { 245 // If the child layer with a mask is below child2, then child2 should 246 // contribute to occlusion on everything, and child shouldn't contribute 247 // to the root_. 248 SetLayerPropertiesForTesting( 249 root_.get(), NULL, identity_matrix_, 250 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 251 SetLayerPropertiesForTesting( 252 child_.get(), root_.get(), identity_matrix_, 253 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 254 SetLayerPropertiesForTesting( 255 grand_child_.get(), child_.get(), identity_matrix_, 256 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 257 SetLayerPropertiesForTesting( 258 child2_.get(), root_.get(), identity_matrix_, 259 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true); 260 261 child_->SetMasksToBounds(true); 262 child_->SetForceRenderSurface(true); 263 child_->SetMaskLayer(mask_.get()); 264 265 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190)); 266 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190)); 267 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190)); 268 269 layer_tree_host()->SetRootLayer(root_); 270 LayerTreeTest::SetupTree(); 271 } 272 }; 273 274 SINGLE_AND_MULTI_THREAD_TEST_F( 275 LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion); 276 277 class LayerTreeHostOcclusionTestOcclusionOpacity 278 : public LayerTreeHostOcclusionTest { 279 public: 280 virtual void SetupTree() OVERRIDE { 281 // If the child layer has a non-opaque opacity, then it shouldn't 282 // contribute to occlusion on stuff below it 283 SetLayerPropertiesForTesting( 284 root_.get(), NULL, identity_matrix_, 285 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 286 SetLayerPropertiesForTesting( 287 child2_.get(), root_.get(), identity_matrix_, 288 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true); 289 SetLayerPropertiesForTesting( 290 child_.get(), root_.get(), identity_matrix_, 291 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 292 SetLayerPropertiesForTesting( 293 grand_child_.get(), child_.get(), identity_matrix_, 294 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 295 296 child_->SetMasksToBounds(true); 297 child_->SetForceRenderSurface(true); 298 child_->SetOpacity(0.5f); 299 300 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190)); 301 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190)); 302 303 layer_tree_host()->SetRootLayer(root_); 304 LayerTreeTest::SetupTree(); 305 } 306 }; 307 308 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionOpacity); 309 310 class LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion 311 : public LayerTreeHostOcclusionTest { 312 public: 313 virtual void SetupTree() OVERRIDE { 314 // If the child layer with non-opaque opacity is below child2, then 315 // child2 should contribute to occlusion on everything, and child shouldn't 316 // contribute to the root_. 317 SetLayerPropertiesForTesting( 318 root_.get(), NULL, identity_matrix_, 319 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 320 SetLayerPropertiesForTesting( 321 child_.get(), root_.get(), identity_matrix_, 322 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 323 SetLayerPropertiesForTesting( 324 grand_child_.get(), child_.get(), identity_matrix_, 325 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 326 SetLayerPropertiesForTesting( 327 child2_.get(), root_.get(), identity_matrix_, 328 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true); 329 330 child_->SetMasksToBounds(true); 331 child_->SetForceRenderSurface(true); 332 child_->SetOpacity(0.5f); 333 334 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190)); 335 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190)); 336 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190)); 337 338 layer_tree_host()->SetRootLayer(root_); 339 LayerTreeTest::SetupTree(); 340 } 341 }; 342 343 SINGLE_AND_MULTI_THREAD_TEST_F( 344 LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion); 345 346 class LayerTreeHostOcclusionTestOcclusionBlending 347 : public LayerTreeHostOcclusionTest { 348 public: 349 virtual void SetupTree() OVERRIDE { 350 // If the child layer has a blend mode, then it shouldn't 351 // contribute to occlusion on stuff below it 352 SetLayerPropertiesForTesting( 353 root_.get(), NULL, identity_matrix_, 354 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 355 SetLayerPropertiesForTesting( 356 child2_.get(), root_.get(), identity_matrix_, 357 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true); 358 SetLayerPropertiesForTesting( 359 child_.get(), root_.get(), identity_matrix_, 360 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 361 SetLayerPropertiesForTesting( 362 grand_child_.get(), child_.get(), identity_matrix_, 363 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 364 365 child_->SetMasksToBounds(true); 366 child_->SetBlendMode(SkXfermode::kMultiply_Mode); 367 child_->SetForceRenderSurface(true); 368 369 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190)); 370 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190)); 371 372 layer_tree_host()->SetRootLayer(root_); 373 LayerTreeTest::SetupTree(); 374 } 375 }; 376 377 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionBlending); 378 379 class LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion 380 : public LayerTreeHostOcclusionTest { 381 public: 382 virtual void SetupTree() OVERRIDE { 383 // If the child layer with a blend mode is below child2, then 384 // child2 should contribute to occlusion on everything, and child shouldn't 385 // contribute to the root_. 386 SetLayerPropertiesForTesting( 387 root_.get(), NULL, identity_matrix_, 388 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 389 SetLayerPropertiesForTesting( 390 child_.get(), root_.get(), identity_matrix_, 391 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 392 SetLayerPropertiesForTesting( 393 grand_child_.get(), child_.get(), identity_matrix_, 394 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 395 SetLayerPropertiesForTesting( 396 child2_.get(), root_.get(), identity_matrix_, 397 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true); 398 399 child_->SetMasksToBounds(true); 400 child_->SetBlendMode(SkXfermode::kMultiply_Mode); 401 402 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190)); 403 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190)); 404 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190)); 405 406 layer_tree_host()->SetRootLayer(root_); 407 LayerTreeTest::SetupTree(); 408 } 409 }; 410 411 SINGLE_AND_MULTI_THREAD_TEST_F( 412 LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion); 413 414 class LayerTreeHostOcclusionTestOcclusionOpacityFilter 415 : public LayerTreeHostOcclusionTest { 416 public: 417 virtual void SetupTree() OVERRIDE { 418 gfx::Transform child_transform; 419 child_transform.Translate(250.0, 250.0); 420 child_transform.Rotate(90.0); 421 child_transform.Translate(-250.0, -250.0); 422 423 FilterOperations filters; 424 filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); 425 426 // If the child layer has a filter that changes alpha values, and is below 427 // child2, then child2 should contribute to occlusion on everything, 428 // and child shouldn't contribute to the root 429 SetLayerPropertiesForTesting( 430 root_.get(), NULL, identity_matrix_, 431 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 432 SetLayerPropertiesForTesting( 433 child_.get(), root_.get(), child_transform, 434 gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); 435 SetLayerPropertiesForTesting( 436 grand_child_.get(), child_.get(), identity_matrix_, 437 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 438 SetLayerPropertiesForTesting( 439 child2_.get(), root_.get(), identity_matrix_, 440 gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true); 441 442 child_->SetMasksToBounds(true); 443 child_->SetFilters(filters); 444 445 grand_child_->set_expected_occlusion(gfx::Rect(40, 330, 130, 190)); 446 child_->set_expected_occlusion(UnionRegions( 447 gfx::Rect(10, 330, 160, 170), gfx::Rect(40, 500, 130, 20))); 448 root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130)); 449 450 layer_tree_host()->SetRootLayer(root_); 451 LayerTreeTest::SetupTree(); 452 } 453 }; 454 455 SINGLE_AND_MULTI_THREAD_TEST_F( 456 LayerTreeHostOcclusionTestOcclusionOpacityFilter); 457 458 class LayerTreeHostOcclusionTestOcclusionBlurFilter 459 : public LayerTreeHostOcclusionTest { 460 public: 461 virtual void SetupTree() OVERRIDE { 462 gfx::Transform child_transform; 463 child_transform.Translate(250.0, 250.0); 464 child_transform.Rotate(90.0); 465 child_transform.Translate(-250.0, -250.0); 466 467 FilterOperations filters; 468 filters.Append(FilterOperation::CreateBlurFilter(10.f)); 469 470 // If the child layer has a filter that moves pixels/changes alpha, and is 471 // below child2, then child should not inherit occlusion from outside its 472 // subtree, and should not contribute to the root 473 SetLayerPropertiesForTesting( 474 root_.get(), NULL, identity_matrix_, 475 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 476 SetLayerPropertiesForTesting( 477 child_.get(), root_.get(), child_transform, 478 gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); 479 SetLayerPropertiesForTesting( 480 grand_child_.get(), child_.get(), identity_matrix_, 481 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 482 SetLayerPropertiesForTesting( 483 child2_.get(), root_.get(), identity_matrix_, 484 gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true); 485 486 child_->SetMasksToBounds(true); 487 child_->SetFilters(filters); 488 489 child_->set_expected_occlusion(gfx::Rect(10, 330, 160, 170)); 490 root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130)); 491 492 layer_tree_host()->SetRootLayer(root_); 493 LayerTreeTest::SetupTree(); 494 } 495 }; 496 497 SINGLE_AND_MULTI_THREAD_TEST_F( 498 LayerTreeHostOcclusionTestOcclusionBlurFilter); 499 500 class LayerTreeHostOcclusionTestOcclusionCopyRequest 501 : public LayerTreeHostOcclusionTest { 502 public: 503 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} 504 505 virtual void SetupTree() OVERRIDE { 506 // If the child layer has copy request, and is below child2, 507 // then child should not inherit occlusion from outside its subtree. 508 // The child layer will still receive occlusion from inside, and 509 // the root layer will recive occlusion from child. 510 SetLayerPropertiesForTesting( 511 root_.get(), NULL, identity_matrix_, 512 gfx::PointF(), gfx::Size(100, 100), true); 513 SetLayerPropertiesForTesting( 514 child_.get(), root_.get(), identity_matrix_, 515 gfx::PointF(), gfx::Size(75, 75), true); 516 SetLayerPropertiesForTesting( 517 grand_child_.get(), child_.get(), identity_matrix_, 518 gfx::PointF(), gfx::Size(75, 50), true); 519 SetLayerPropertiesForTesting( 520 child2_.get(), root_.get(), identity_matrix_, 521 gfx::PointF(0.f, 25.f), gfx::Size(75, 75), true); 522 523 child_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( 524 base::Bind(&CopyOutputCallback))); 525 EXPECT_TRUE(child_->HasCopyRequest()); 526 527 child_->set_expected_occlusion(gfx::Rect(0, 0, 75, 50)); 528 root_->set_expected_occlusion(gfx::Rect(0, 0, 75, 100)); 529 530 layer_tree_host()->SetRootLayer(root_); 531 LayerTreeTest::SetupTree(); 532 } 533 }; 534 535 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionCopyRequest); 536 537 class LayerTreeHostOcclusionTestOcclusionReplica 538 : public LayerTreeHostOcclusionTest { 539 public: 540 virtual void SetupTree() OVERRIDE { 541 // If the child layer has copy request, and is below child2, 542 // then child should not inherit occlusion from outside its subtree. 543 // The child layer will still receive occlusion from inside, and 544 // the root layer will recive occlusion from child. 545 SetLayerPropertiesForTesting( 546 root_.get(), NULL, identity_matrix_, 547 gfx::PointF(), gfx::Size(100, 100), true); 548 SetLayerPropertiesForTesting( 549 child_.get(), root_.get(), identity_matrix_, 550 gfx::PointF(), gfx::Size(75, 75), true); 551 SetLayerPropertiesForTesting( 552 grand_child_.get(), child_.get(), identity_matrix_, 553 gfx::PointF(), gfx::Size(75, 50), true); 554 SetLayerPropertiesForTesting( 555 child2_.get(), root_.get(), identity_matrix_, 556 gfx::PointF(0.f, 25.f), gfx::Size(75, 75), true); 557 558 scoped_refptr<Layer> replica_layer(Layer::Create()); 559 child_->SetReplicaLayer(replica_layer.get()); 560 EXPECT_TRUE(child_->has_replica()); 561 562 child_->set_expected_occlusion(gfx::Rect(0, 0, 75, 50)); 563 root_->set_expected_occlusion(gfx::Rect(0, 0, 75, 100)); 564 565 layer_tree_host()->SetRootLayer(root_); 566 LayerTreeTest::SetupTree(); 567 } 568 }; 569 570 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionReplica); 571 572 class LayerTreeHostOcclusionTestManySurfaces 573 : public LayerTreeHostOcclusionTest { 574 public: 575 virtual void SetupTree() OVERRIDE { 576 // We create enough RenderSurfaces that it will trigger Vector reallocation 577 // while computing occlusion. 578 std::vector<scoped_refptr<TestLayer> > layers; 579 int num_surfaces = 200; 580 int root_width = 400; 581 int root_height = 400; 582 583 for (int i = 0; i < num_surfaces; ++i) { 584 layers.push_back(TestLayer::Create()); 585 if (i == 0) { 586 SetLayerPropertiesForTesting( 587 layers.back().get(), NULL, identity_matrix_, 588 gfx::PointF(0.f, 0.f), 589 gfx::Size(root_width, root_height), true); 590 } else { 591 SetLayerPropertiesForTesting( 592 layers.back().get(), layers[layers.size() - 2].get(), 593 identity_matrix_, 594 gfx::PointF(1.f, 1.f), 595 gfx::Size(root_width-i, root_height-i), true); 596 layers.back()->SetForceRenderSurface(true); 597 } 598 } 599 600 for (int i = 1; i < num_surfaces; ++i) { 601 scoped_refptr<TestLayer> child = TestLayer::Create(); 602 SetLayerPropertiesForTesting( 603 child.get(), layers[i].get(), identity_matrix_, 604 gfx::PointF(0.f, 0.f), gfx::Size(root_width, root_height), false); 605 } 606 607 for (int i = 0; i < num_surfaces-1; ++i) { 608 gfx::Rect expected_occlusion(1, 1, root_width-i-1, root_height-i-1); 609 layers[i]->set_expected_occlusion(expected_occlusion); 610 } 611 612 layer_tree_host()->SetRootLayer(layers[0]); 613 LayerTreeTest::SetupTree(); 614 } 615 }; 616 617 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestManySurfaces); 618 619 } // namespace 620 } // namespace cc 621