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