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/occlusion_tracker.h" 6 7 #include "cc/animation/layer_animation_controller.h" 8 #include "cc/base/math_util.h" 9 #include "cc/layers/layer.h" 10 #include "cc/layers/layer_impl.h" 11 #include "cc/output/copy_output_request.h" 12 #include "cc/output/copy_output_result.h" 13 #include "cc/output/filter_operation.h" 14 #include "cc/output/filter_operations.h" 15 #include "cc/test/animation_test_common.h" 16 #include "cc/test/fake_impl_proxy.h" 17 #include "cc/test/fake_layer_tree_host.h" 18 #include "cc/test/fake_layer_tree_host_impl.h" 19 #include "cc/test/geometry_test_utils.h" 20 #include "cc/test/test_occlusion_tracker.h" 21 #include "cc/trees/layer_tree_host_common.h" 22 #include "cc/trees/single_thread_proxy.h" 23 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gtest/include/gtest/gtest.h" 25 #include "ui/gfx/transform.h" 26 27 namespace cc { 28 namespace { 29 30 class TestContentLayer : public Layer { 31 public: 32 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) { 33 SetIsDrawable(true); 34 } 35 36 virtual SimpleEnclosedRegion VisibleContentOpaqueRegion() const OVERRIDE { 37 if (override_opaque_contents_rect_) { 38 return SimpleEnclosedRegion( 39 gfx::IntersectRects(opaque_contents_rect_, visible_content_rect())); 40 } 41 return Layer::VisibleContentOpaqueRegion(); 42 } 43 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) { 44 override_opaque_contents_rect_ = true; 45 opaque_contents_rect_ = opaque_contents_rect; 46 } 47 48 private: 49 virtual ~TestContentLayer() {} 50 51 bool override_opaque_contents_rect_; 52 gfx::Rect opaque_contents_rect_; 53 }; 54 55 class TestContentLayerImpl : public LayerImpl { 56 public: 57 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id) 58 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) { 59 SetDrawsContent(true); 60 } 61 62 virtual SimpleEnclosedRegion VisibleContentOpaqueRegion() const OVERRIDE { 63 if (override_opaque_contents_rect_) { 64 return SimpleEnclosedRegion( 65 gfx::IntersectRects(opaque_contents_rect_, visible_content_rect())); 66 } 67 return LayerImpl::VisibleContentOpaqueRegion(); 68 } 69 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) { 70 override_opaque_contents_rect_ = true; 71 opaque_contents_rect_ = opaque_contents_rect; 72 } 73 74 private: 75 bool override_opaque_contents_rect_; 76 gfx::Rect opaque_contents_rect_; 77 }; 78 79 template <typename LayerType> 80 class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> { 81 public: 82 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect) 83 : TestOcclusionTracker<LayerType>(viewport_rect) {} 84 85 bool OccludedLayer(const LayerType* layer, 86 const gfx::Rect& content_rect) const { 87 DCHECK(layer->visible_content_rect().Contains(content_rect)); 88 return this->GetCurrentOcclusionForLayer(layer->draw_transform()) 89 .IsOccluded(content_rect); 90 } 91 92 // Gives an unoccluded sub-rect of |content_rect| in the content space of the 93 // layer. Simple wrapper around GetUnoccludedContentRect. 94 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer, 95 const gfx::Rect& content_rect) const { 96 DCHECK(layer->visible_content_rect().Contains(content_rect)); 97 return this->GetCurrentOcclusionForLayer(layer->draw_transform()) 98 .GetUnoccludedContentRect(content_rect); 99 } 100 101 gfx::Rect UnoccludedSurfaceContentRect(const LayerType* layer, 102 const gfx::Rect& content_rect) const { 103 typename LayerType::RenderSurfaceType* surface = layer->render_surface(); 104 return this->UnoccludedContributingSurfaceContentRect( 105 content_rect, surface->draw_transform()); 106 } 107 }; 108 109 struct OcclusionTrackerTestMainThreadTypes { 110 typedef Layer LayerType; 111 typedef FakeLayerTreeHost HostType; 112 typedef RenderSurface RenderSurfaceType; 113 typedef TestContentLayer ContentLayerType; 114 typedef scoped_refptr<Layer> LayerPtrType; 115 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType; 116 typedef LayerIterator<Layer> TestLayerIterator; 117 typedef OcclusionTracker<Layer> OcclusionTrackerType; 118 119 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); } 120 static ContentLayerPtrType CreateContentLayer(HostType* host) { 121 return make_scoped_refptr(new ContentLayerType()); 122 } 123 124 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) { 125 LayerPtrType ref(*layer); 126 *layer = NULL; 127 return ref; 128 } 129 130 static LayerPtrType PassLayerPtr(LayerPtrType* layer) { 131 LayerPtrType ref(*layer); 132 *layer = NULL; 133 return ref; 134 } 135 136 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; } 137 138 static void RecursiveUpdateNumChildren(LayerType* layerType) {} 139 }; 140 141 struct OcclusionTrackerTestImplThreadTypes { 142 typedef LayerImpl LayerType; 143 typedef LayerTreeImpl HostType; 144 typedef RenderSurfaceImpl RenderSurfaceType; 145 typedef TestContentLayerImpl ContentLayerType; 146 typedef scoped_ptr<LayerImpl> LayerPtrType; 147 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType; 148 typedef LayerIterator<LayerImpl> TestLayerIterator; 149 typedef OcclusionTracker<LayerImpl> OcclusionTrackerType; 150 151 static LayerPtrType CreateLayer(HostType* host) { 152 return LayerImpl::Create(host, next_layer_impl_id++); 153 } 154 static ContentLayerPtrType CreateContentLayer(HostType* host) { 155 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++)); 156 } 157 static int next_layer_impl_id; 158 159 static LayerPtrType PassLayerPtr(LayerPtrType* layer) { 160 return layer->Pass(); 161 } 162 163 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) { 164 return layer->PassAs<LayerType>(); 165 } 166 167 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); } 168 169 static void RecursiveUpdateNumChildren(LayerType* layer) { 170 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer); 171 } 172 }; 173 174 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1; 175 176 template <typename Types> class OcclusionTrackerTest : public testing::Test { 177 protected: 178 explicit OcclusionTrackerTest(bool opaque_layers) 179 : opaque_layers_(opaque_layers), 180 client_(FakeLayerTreeHostClient::DIRECT_3D), 181 host_(FakeLayerTreeHost::Create(&client_)) {} 182 183 virtual void RunMyTest() = 0; 184 185 virtual void TearDown() { DestroyLayers(); } 186 187 typename Types::HostType* GetHost(); 188 189 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform, 190 const gfx::PointF& position, 191 const gfx::Size& bounds) { 192 typename Types::ContentLayerPtrType layer( 193 Types::CreateContentLayer(GetHost())); 194 typename Types::ContentLayerType* layer_ptr = layer.get(); 195 SetProperties(layer_ptr, transform, position, bounds); 196 197 DCHECK(!root_.get()); 198 root_ = Types::PassLayerPtr(&layer); 199 200 SetRootLayerOnMainThread(layer_ptr); 201 202 return layer_ptr; 203 } 204 205 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent, 206 const gfx::Transform& transform, 207 const gfx::PointF& position, 208 const gfx::Size& bounds) { 209 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost())); 210 typename Types::LayerType* layer_ptr = layer.get(); 211 SetProperties(layer_ptr, transform, position, bounds); 212 parent->AddChild(Types::PassLayerPtr(&layer)); 213 return layer_ptr; 214 } 215 216 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent, 217 const gfx::Transform& transform, 218 const gfx::PointF& position, 219 const gfx::Size& bounds) { 220 typename Types::LayerType* layer = 221 CreateLayer(parent, transform, position, bounds); 222 layer->SetForceRenderSurface(true); 223 return layer; 224 } 225 226 typename Types::ContentLayerType* CreateDrawingLayer( 227 typename Types::LayerType* parent, 228 const gfx::Transform& transform, 229 const gfx::PointF& position, 230 const gfx::Size& bounds, 231 bool opaque) { 232 typename Types::ContentLayerPtrType layer( 233 Types::CreateContentLayer(GetHost())); 234 typename Types::ContentLayerType* layer_ptr = layer.get(); 235 SetProperties(layer_ptr, transform, position, bounds); 236 237 if (opaque_layers_) { 238 layer_ptr->SetContentsOpaque(opaque); 239 } else { 240 layer_ptr->SetContentsOpaque(false); 241 if (opaque) 242 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds)); 243 else 244 layer_ptr->SetOpaqueContentsRect(gfx::Rect()); 245 } 246 247 parent->AddChild(Types::PassLayerPtr(&layer)); 248 return layer_ptr; 249 } 250 251 typename Types::LayerType* CreateReplicaLayer( 252 typename Types::LayerType* owning_layer, 253 const gfx::Transform& transform, 254 const gfx::PointF& position, 255 const gfx::Size& bounds) { 256 typename Types::ContentLayerPtrType layer( 257 Types::CreateContentLayer(GetHost())); 258 typename Types::ContentLayerType* layer_ptr = layer.get(); 259 SetProperties(layer_ptr, transform, position, bounds); 260 SetReplica(owning_layer, Types::PassLayerPtr(&layer)); 261 return layer_ptr; 262 } 263 264 typename Types::LayerType* CreateMaskLayer( 265 typename Types::LayerType* owning_layer, 266 const gfx::Size& bounds) { 267 typename Types::ContentLayerPtrType layer( 268 Types::CreateContentLayer(GetHost())); 269 typename Types::ContentLayerType* layer_ptr = layer.get(); 270 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds); 271 SetMask(owning_layer, Types::PassLayerPtr(&layer)); 272 return layer_ptr; 273 } 274 275 typename Types::ContentLayerType* CreateDrawingSurface( 276 typename Types::LayerType* parent, 277 const gfx::Transform& transform, 278 const gfx::PointF& position, 279 const gfx::Size& bounds, 280 bool opaque) { 281 typename Types::ContentLayerType* layer = 282 CreateDrawingLayer(parent, transform, position, bounds, opaque); 283 layer->SetForceRenderSurface(true); 284 return layer; 285 } 286 287 void DestroyLayers() { 288 Types::DestroyLayer(&root_); 289 render_surface_layer_list_.reset(); 290 render_surface_layer_list_impl_.clear(); 291 replica_layers_.clear(); 292 mask_layers_.clear(); 293 ResetLayerIterator(); 294 } 295 296 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} 297 298 void AddCopyRequest(Layer* layer) { 299 layer->RequestCopyOfOutput( 300 CopyOutputRequest::CreateBitmapRequest(base::Bind( 301 &OcclusionTrackerTest<Types>::CopyOutputCallback, 302 base::Unretained(this)))); 303 } 304 305 void AddCopyRequest(LayerImpl* layer) { 306 ScopedPtrVector<CopyOutputRequest> requests; 307 requests.push_back( 308 CopyOutputRequest::CreateBitmapRequest(base::Bind( 309 &OcclusionTrackerTest<Types>::CopyOutputCallback, 310 base::Unretained(this)))); 311 layer->PassCopyRequests(&requests); 312 } 313 314 void CalcDrawEtc(TestContentLayerImpl* root) { 315 DCHECK(root == root_.get()); 316 DCHECK(!root->render_surface()); 317 318 Types::RecursiveUpdateNumChildren(root); 319 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 320 root, root->bounds(), &render_surface_layer_list_impl_); 321 inputs.can_adjust_raster_scales = true; 322 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 323 324 layer_iterator_ = layer_iterator_begin_ = 325 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_); 326 } 327 328 void CalcDrawEtc(TestContentLayer* root) { 329 DCHECK(root == root_.get()); 330 DCHECK(!root->render_surface()); 331 332 render_surface_layer_list_.reset(new RenderSurfaceLayerList); 333 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 334 root, root->bounds(), render_surface_layer_list_.get()); 335 inputs.can_adjust_raster_scales = true; 336 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 337 338 layer_iterator_ = layer_iterator_begin_ = 339 Types::TestLayerIterator::Begin(render_surface_layer_list_.get()); 340 } 341 342 void EnterLayer(typename Types::LayerType* layer, 343 typename Types::OcclusionTrackerType* occlusion) { 344 ASSERT_EQ(*layer_iterator_, layer); 345 ASSERT_TRUE(layer_iterator_.represents_itself()); 346 occlusion->EnterLayer(layer_iterator_); 347 } 348 349 void LeaveLayer(typename Types::LayerType* layer, 350 typename Types::OcclusionTrackerType* occlusion) { 351 ASSERT_EQ(*layer_iterator_, layer); 352 ASSERT_TRUE(layer_iterator_.represents_itself()); 353 occlusion->LeaveLayer(layer_iterator_); 354 ++layer_iterator_; 355 } 356 357 void VisitLayer(typename Types::LayerType* layer, 358 typename Types::OcclusionTrackerType* occlusion) { 359 EnterLayer(layer, occlusion); 360 LeaveLayer(layer, occlusion); 361 } 362 363 void EnterContributingSurface( 364 typename Types::LayerType* layer, 365 typename Types::OcclusionTrackerType* occlusion) { 366 ASSERT_EQ(*layer_iterator_, layer); 367 ASSERT_TRUE(layer_iterator_.represents_target_render_surface()); 368 occlusion->EnterLayer(layer_iterator_); 369 occlusion->LeaveLayer(layer_iterator_); 370 ++layer_iterator_; 371 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface()); 372 occlusion->EnterLayer(layer_iterator_); 373 } 374 375 void LeaveContributingSurface( 376 typename Types::LayerType* layer, 377 typename Types::OcclusionTrackerType* occlusion) { 378 ASSERT_EQ(*layer_iterator_, layer); 379 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface()); 380 occlusion->LeaveLayer(layer_iterator_); 381 ++layer_iterator_; 382 } 383 384 void VisitContributingSurface( 385 typename Types::LayerType* layer, 386 typename Types::OcclusionTrackerType* occlusion) { 387 EnterContributingSurface(layer, occlusion); 388 LeaveContributingSurface(layer, occlusion); 389 } 390 391 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; } 392 393 const gfx::Transform identity_matrix; 394 395 private: 396 void SetRootLayerOnMainThread(Layer* root) { 397 host_->SetRootLayer(scoped_refptr<Layer>(root)); 398 } 399 400 void SetRootLayerOnMainThread(LayerImpl* root) {} 401 402 void SetBaseProperties(typename Types::LayerType* layer, 403 const gfx::Transform& transform, 404 const gfx::PointF& position, 405 const gfx::Size& bounds) { 406 layer->SetTransform(transform); 407 layer->SetPosition(position); 408 layer->SetBounds(bounds); 409 } 410 411 void SetProperties(Layer* layer, 412 const gfx::Transform& transform, 413 const gfx::PointF& position, 414 const gfx::Size& bounds) { 415 SetBaseProperties(layer, transform, position, bounds); 416 } 417 418 void SetProperties(LayerImpl* layer, 419 const gfx::Transform& transform, 420 const gfx::PointF& position, 421 const gfx::Size& bounds) { 422 SetBaseProperties(layer, transform, position, bounds); 423 424 layer->SetContentBounds(layer->bounds()); 425 } 426 427 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) { 428 owning_layer->SetReplicaLayer(layer.get()); 429 replica_layers_.push_back(layer); 430 } 431 432 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) { 433 owning_layer->SetReplicaLayer(layer.Pass()); 434 } 435 436 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) { 437 owning_layer->SetMaskLayer(layer.get()); 438 mask_layers_.push_back(layer); 439 } 440 441 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) { 442 owning_layer->SetMaskLayer(layer.Pass()); 443 } 444 445 bool opaque_layers_; 446 FakeLayerTreeHostClient client_; 447 scoped_ptr<FakeLayerTreeHost> host_; 448 // These hold ownership of the layers for the duration of the test. 449 typename Types::LayerPtrType root_; 450 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_; 451 LayerImplList render_surface_layer_list_impl_; 452 typename Types::TestLayerIterator layer_iterator_begin_; 453 typename Types::TestLayerIterator layer_iterator_; 454 typename Types::LayerType* last_layer_visited_; 455 LayerList replica_layers_; 456 LayerList mask_layers_; 457 }; 458 459 template <> 460 FakeLayerTreeHost* 461 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() { 462 return host_.get(); 463 } 464 465 template <> 466 LayerTreeImpl* 467 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() { 468 return host_->host_impl()->active_tree(); 469 } 470 471 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ 472 class ClassName##MainThreadOpaqueLayers \ 473 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \ 474 public: /* NOLINT(whitespace/indent) */ \ 475 ClassName##MainThreadOpaqueLayers() \ 476 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \ 477 }; \ 478 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); } 479 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \ 480 class ClassName##MainThreadOpaquePaints \ 481 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \ 482 public: /* NOLINT(whitespace/indent) */ \ 483 ClassName##MainThreadOpaquePaints() \ 484 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \ 485 }; \ 486 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); } 487 488 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \ 489 class ClassName##ImplThreadOpaqueLayers \ 490 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \ 491 public: /* NOLINT(whitespace/indent) */ \ 492 ClassName##ImplThreadOpaqueLayers() \ 493 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \ 494 }; \ 495 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); } 496 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \ 497 class ClassName##ImplThreadOpaquePaints \ 498 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \ 499 public: /* NOLINT(whitespace/indent) */ \ 500 ClassName##ImplThreadOpaquePaints() \ 501 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \ 502 }; \ 503 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); } 504 505 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \ 506 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ 507 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \ 508 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \ 509 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) 510 511 #define MAIN_THREAD_TEST(ClassName) \ 512 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) 513 514 #define IMPL_THREAD_TEST(ClassName) \ 515 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) 516 517 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \ 518 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ 519 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) 520 521 template <class Types> 522 class OcclusionTrackerTestIdentityTransforms 523 : public OcclusionTrackerTest<Types> { 524 protected: 525 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers) 526 : OcclusionTrackerTest<Types>(opaque_layers) {} 527 528 void RunMyTest() { 529 typename Types::ContentLayerType* root = this->CreateRoot( 530 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 531 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 532 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 533 typename Types::ContentLayerType* layer = 534 this->CreateDrawingLayer(parent, 535 this->identity_matrix, 536 gfx::PointF(30.f, 30.f), 537 gfx::Size(500, 500), 538 true); 539 parent->SetMasksToBounds(true); 540 this->CalcDrawEtc(root); 541 542 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 543 gfx::Rect(0, 0, 1000, 1000)); 544 545 this->VisitLayer(layer, &occlusion); 546 this->EnterLayer(parent, &occlusion); 547 548 EXPECT_EQ(gfx::Rect().ToString(), 549 occlusion.occlusion_from_outside_target().ToString()); 550 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), 551 occlusion.occlusion_from_inside_target().ToString()); 552 } 553 }; 554 555 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms); 556 557 template <class Types> 558 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> { 559 protected: 560 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers) 561 : OcclusionTrackerTest<Types>(opaque_layers) {} 562 void RunMyTest() { 563 gfx::Transform layer_transform; 564 layer_transform.Translate(250.0, 250.0); 565 layer_transform.Rotate(90.0); 566 layer_transform.Translate(-250.0, -250.0); 567 568 typename Types::ContentLayerType* root = this->CreateRoot( 569 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200)); 570 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 571 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 572 typename Types::ContentLayerType* layer = 573 this->CreateDrawingLayer(parent, 574 layer_transform, 575 gfx::PointF(30.f, 30.f), 576 gfx::Size(500, 500), 577 true); 578 parent->SetMasksToBounds(true); 579 this->CalcDrawEtc(root); 580 581 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 582 gfx::Rect(0, 0, 1000, 1000)); 583 584 this->VisitLayer(layer, &occlusion); 585 this->EnterLayer(parent, &occlusion); 586 587 EXPECT_EQ(gfx::Rect().ToString(), 588 occlusion.occlusion_from_outside_target().ToString()); 589 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), 590 occlusion.occlusion_from_inside_target().ToString()); 591 } 592 }; 593 594 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild); 595 596 template <class Types> 597 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> { 598 protected: 599 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers) 600 : OcclusionTrackerTest<Types>(opaque_layers) {} 601 void RunMyTest() { 602 gfx::Transform layer_transform; 603 layer_transform.Translate(20.0, 20.0); 604 605 typename Types::ContentLayerType* root = this->CreateRoot( 606 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 607 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 608 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 609 typename Types::ContentLayerType* layer = 610 this->CreateDrawingLayer(parent, 611 layer_transform, 612 gfx::PointF(30.f, 30.f), 613 gfx::Size(500, 500), 614 true); 615 parent->SetMasksToBounds(true); 616 this->CalcDrawEtc(root); 617 618 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 619 gfx::Rect(0, 0, 1000, 1000)); 620 621 this->VisitLayer(layer, &occlusion); 622 this->EnterLayer(parent, &occlusion); 623 624 EXPECT_EQ(gfx::Rect().ToString(), 625 occlusion.occlusion_from_outside_target().ToString()); 626 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), 627 occlusion.occlusion_from_inside_target().ToString()); 628 } 629 }; 630 631 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild); 632 633 template <class Types> 634 class OcclusionTrackerTestChildInRotatedChild 635 : public OcclusionTrackerTest<Types> { 636 protected: 637 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers) 638 : OcclusionTrackerTest<Types>(opaque_layers) {} 639 void RunMyTest() { 640 gfx::Transform child_transform; 641 child_transform.Translate(250.0, 250.0); 642 child_transform.Rotate(90.0); 643 child_transform.Translate(-250.0, -250.0); 644 645 typename Types::ContentLayerType* parent = this->CreateRoot( 646 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 647 parent->SetMasksToBounds(true); 648 typename Types::LayerType* child = this->CreateSurface( 649 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); 650 child->SetMasksToBounds(true); 651 typename Types::ContentLayerType* layer = 652 this->CreateDrawingLayer(child, 653 this->identity_matrix, 654 gfx::PointF(10.f, 10.f), 655 gfx::Size(500, 500), 656 true); 657 this->CalcDrawEtc(parent); 658 659 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 660 gfx::Rect(0, 0, 1000, 1000)); 661 662 this->VisitLayer(layer, &occlusion); 663 this->EnterContributingSurface(child, &occlusion); 664 665 EXPECT_EQ(gfx::Rect().ToString(), 666 occlusion.occlusion_from_outside_target().ToString()); 667 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), 668 occlusion.occlusion_from_inside_target().ToString()); 669 670 this->LeaveContributingSurface(child, &occlusion); 671 this->EnterLayer(parent, &occlusion); 672 673 EXPECT_EQ(gfx::Rect().ToString(), 674 occlusion.occlusion_from_outside_target().ToString()); 675 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), 676 occlusion.occlusion_from_inside_target().ToString()); 677 678 /* Justification for the above occlusion from |layer|: 679 100 680 +---------------------+ 681 | | 682 | 30 | rotate(90) 683 | 30 + ---------------------------------+ 684 100 | | 10 | | ==> 685 | |10+---------------------------------+ 686 | | | | | | 687 | | | | | | 688 | | | | | | 689 +----|--|-------------+ | | 690 | | | | 691 | | | | 692 | | | |500 693 | | | | 694 | | | | 695 | | | | 696 | | | | 697 +--|-------------------------------+ | 698 | | 699 +---------------------------------+ 700 500 701 702 +---------------------+ 703 | |30 Visible region of |layer|: ///// 704 | | 705 | +---------------------------------+ 706 100| | |10 | 707 | +---------------------------------+ | 708 | | |///////////////| 420 | | 709 | | |///////////////|60 | | 710 | | |///////////////| | | 711 +--|--|---------------+ | | 712 20|10| 70 | | 713 | | | | 714 | | | | 715 | | | | 716 | | | | 717 | | | | 718 | | |10| 719 | +------------------------------|--+ 720 | 490 | 721 +---------------------------------+ 722 500 723 724 */ 725 } 726 }; 727 728 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild); 729 730 template <class Types> 731 class OcclusionTrackerTestScaledRenderSurface 732 : public OcclusionTrackerTest<Types> { 733 protected: 734 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers) 735 : OcclusionTrackerTest<Types>(opaque_layers) {} 736 737 void RunMyTest() { 738 typename Types::ContentLayerType* parent = this->CreateRoot( 739 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 740 741 gfx::Transform layer1_matrix; 742 layer1_matrix.Scale(2.0, 2.0); 743 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer( 744 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true); 745 layer1->SetForceRenderSurface(true); 746 747 gfx::Transform layer2_matrix; 748 layer2_matrix.Translate(25.0, 25.0); 749 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer( 750 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true); 751 typename Types::ContentLayerType* occluder = 752 this->CreateDrawingLayer(parent, 753 this->identity_matrix, 754 gfx::PointF(100.f, 100.f), 755 gfx::Size(500, 500), 756 true); 757 this->CalcDrawEtc(parent); 758 759 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 760 gfx::Rect(0, 0, 1000, 1000)); 761 762 this->VisitLayer(occluder, &occlusion); 763 this->EnterLayer(layer2, &occlusion); 764 765 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), 766 occlusion.occlusion_from_outside_target().ToString()); 767 EXPECT_EQ(gfx::Rect().ToString(), 768 occlusion.occlusion_from_inside_target().ToString()); 769 } 770 }; 771 772 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface); 773 774 template <class Types> 775 class OcclusionTrackerTestVisitTargetTwoTimes 776 : public OcclusionTrackerTest<Types> { 777 protected: 778 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers) 779 : OcclusionTrackerTest<Types>(opaque_layers) {} 780 void RunMyTest() { 781 typename Types::ContentLayerType* root = this->CreateRoot( 782 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 783 typename Types::LayerType* surface = this->CreateSurface( 784 root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size()); 785 typename Types::ContentLayerType* surface_child = 786 this->CreateDrawingLayer(surface, 787 this->identity_matrix, 788 gfx::PointF(10.f, 10.f), 789 gfx::Size(50, 50), 790 true); 791 // |top_layer| makes |root|'s surface get considered by OcclusionTracker 792 // first, instead of |surface|'s. This exercises different code in 793 // LeaveToRenderTarget, as the target surface has already been seen when 794 // leaving |surface| later. 795 typename Types::ContentLayerType* top_layer = 796 this->CreateDrawingLayer(root, 797 this->identity_matrix, 798 gfx::PointF(40.f, 90.f), 799 gfx::Size(50, 20), 800 true); 801 this->CalcDrawEtc(root); 802 803 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 804 gfx::Rect(0, 0, 1000, 1000)); 805 806 this->VisitLayer(top_layer, &occlusion); 807 808 EXPECT_EQ(gfx::Rect().ToString(), 809 occlusion.occlusion_from_outside_target().ToString()); 810 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(), 811 occlusion.occlusion_from_inside_target().ToString()); 812 813 this->VisitLayer(surface_child, &occlusion); 814 815 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), 816 occlusion.occlusion_from_outside_target().ToString()); 817 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), 818 occlusion.occlusion_from_inside_target().ToString()); 819 820 this->EnterContributingSurface(surface, &occlusion); 821 822 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), 823 occlusion.occlusion_from_outside_target().ToString()); 824 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), 825 occlusion.occlusion_from_inside_target().ToString()); 826 827 // Occlusion from |top_layer| already in the root target should get merged 828 // with the occlusion from the |surface| we are leaving now. 829 this->LeaveContributingSurface(surface, &occlusion); 830 this->EnterLayer(root, &occlusion); 831 832 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 833 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(), 834 occlusion.occlusion_from_inside_target().ToString()); 835 } 836 }; 837 838 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes); 839 840 template <class Types> 841 class OcclusionTrackerTestSurfaceRotatedOffAxis 842 : public OcclusionTrackerTest<Types> { 843 protected: 844 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers) 845 : OcclusionTrackerTest<Types>(opaque_layers) {} 846 void RunMyTest() { 847 gfx::Transform child_transform; 848 child_transform.Translate(250.0, 250.0); 849 child_transform.Rotate(95.0); 850 child_transform.Translate(-250.0, -250.0); 851 852 gfx::Transform layer_transform; 853 layer_transform.Translate(10.0, 10.0); 854 855 typename Types::ContentLayerType* root = this->CreateRoot( 856 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); 857 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 858 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 859 typename Types::LayerType* child = this->CreateLayer( 860 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); 861 child->SetMasksToBounds(true); 862 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( 863 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true); 864 this->CalcDrawEtc(root); 865 866 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 867 gfx::Rect(0, 0, 1000, 1000)); 868 869 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect( 870 layer_transform, layer->visible_content_rect()); 871 872 this->VisitLayer(layer, &occlusion); 873 this->EnterContributingSurface(child, &occlusion); 874 875 EXPECT_EQ(gfx::Rect().ToString(), 876 occlusion.occlusion_from_outside_target().ToString()); 877 EXPECT_EQ(clipped_layer_in_child.ToString(), 878 occlusion.occlusion_from_inside_target().ToString()); 879 880 this->LeaveContributingSurface(child, &occlusion); 881 this->EnterLayer(parent, &occlusion); 882 883 EXPECT_EQ(gfx::Rect().ToString(), 884 occlusion.occlusion_from_outside_target().ToString()); 885 EXPECT_EQ(gfx::Rect().ToString(), 886 occlusion.occlusion_from_inside_target().ToString()); 887 } 888 }; 889 890 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis); 891 892 template <class Types> 893 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren 894 : public OcclusionTrackerTest<Types> { 895 protected: 896 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers) 897 : OcclusionTrackerTest<Types>(opaque_layers) {} 898 void RunMyTest() { 899 gfx::Transform child_transform; 900 child_transform.Translate(250.0, 250.0); 901 child_transform.Rotate(90.0); 902 child_transform.Translate(-250.0, -250.0); 903 904 typename Types::ContentLayerType* root = this->CreateRoot( 905 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); 906 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 907 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 908 parent->SetMasksToBounds(true); 909 typename Types::ContentLayerType* child = 910 this->CreateDrawingSurface(parent, 911 child_transform, 912 gfx::PointF(30.f, 30.f), 913 gfx::Size(500, 500), 914 false); 915 child->SetMasksToBounds(true); 916 typename Types::ContentLayerType* layer1 = 917 this->CreateDrawingLayer(child, 918 this->identity_matrix, 919 gfx::PointF(10.f, 10.f), 920 gfx::Size(500, 500), 921 true); 922 typename Types::ContentLayerType* layer2 = 923 this->CreateDrawingLayer(child, 924 this->identity_matrix, 925 gfx::PointF(10.f, 450.f), 926 gfx::Size(500, 60), 927 true); 928 this->CalcDrawEtc(root); 929 930 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 931 gfx::Rect(0, 0, 1000, 1000)); 932 933 this->VisitLayer(layer2, &occlusion); 934 this->VisitLayer(layer1, &occlusion); 935 this->VisitLayer(child, &occlusion); 936 this->EnterContributingSurface(child, &occlusion); 937 938 EXPECT_EQ(gfx::Rect().ToString(), 939 occlusion.occlusion_from_outside_target().ToString()); 940 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), 941 occlusion.occlusion_from_inside_target().ToString()); 942 943 this->LeaveContributingSurface(child, &occlusion); 944 this->EnterLayer(parent, &occlusion); 945 946 EXPECT_EQ(gfx::Rect().ToString(), 947 occlusion.occlusion_from_outside_target().ToString()); 948 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), 949 occlusion.occlusion_from_inside_target().ToString()); 950 951 /* Justification for the above occlusion from |layer1| and |layer2|: 952 953 +---------------------+ 954 | |30 Visible region of |layer1|: ///// 955 | | Visible region of |layer2|: \\\\\ 956 | +---------------------------------+ 957 | | |10 | 958 | +---------------+-----------------+ | 959 | | |\\\\\\\\\\\\|//| 420 | | 960 | | |\\\\\\\\\\\\|//|60 | | 961 | | |\\\\\\\\\\\\|//| | | 962 +--|--|------------|--+ | | 963 20|10| 70 | | | 964 | | | | | 965 | | | | | 966 | | | | | 967 | | | | | 968 | | | | | 969 | | | |10| 970 | +------------|-----------------|--+ 971 | | 490 | 972 +---------------+-----------------+ 973 60 440 974 */ 975 } 976 }; 977 978 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren); 979 980 template <class Types> 981 class OcclusionTrackerTestOverlappingSurfaceSiblings 982 : public OcclusionTrackerTest<Types> { 983 protected: 984 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers) 985 : OcclusionTrackerTest<Types>(opaque_layers) {} 986 void RunMyTest() { 987 typename Types::ContentLayerType* parent = this->CreateRoot( 988 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 989 parent->SetMasksToBounds(true); 990 typename Types::LayerType* child1 = this->CreateSurface( 991 parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size()); 992 typename Types::LayerType* child2 = this->CreateSurface( 993 parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size()); 994 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer( 995 child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true); 996 typename Types::ContentLayerType* layer2 = 997 this->CreateDrawingLayer(child2, 998 this->identity_matrix, 999 gfx::PointF(10.f, 0.f), 1000 gfx::Size(40, 50), 1001 true); 1002 this->CalcDrawEtc(parent); 1003 1004 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1005 gfx::Rect(0, 0, 1000, 1000)); 1006 1007 this->VisitLayer(layer2, &occlusion); 1008 this->EnterContributingSurface(child2, &occlusion); 1009 1010 // layer2's occlusion. 1011 EXPECT_EQ(gfx::Rect().ToString(), 1012 occlusion.occlusion_from_outside_target().ToString()); 1013 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(), 1014 occlusion.occlusion_from_inside_target().ToString()); 1015 1016 this->LeaveContributingSurface(child2, &occlusion); 1017 this->VisitLayer(layer1, &occlusion); 1018 this->EnterContributingSurface(child1, &occlusion); 1019 1020 // layer2's occlusion in the target space of layer1. 1021 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(), 1022 occlusion.occlusion_from_outside_target().ToString()); 1023 // layer1's occlusion. 1024 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(), 1025 occlusion.occlusion_from_inside_target().ToString()); 1026 1027 this->LeaveContributingSurface(child1, &occlusion); 1028 this->EnterLayer(parent, &occlusion); 1029 1030 // The occlusion from from layer1 and layer2 is merged. 1031 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1032 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(), 1033 occlusion.occlusion_from_inside_target().ToString()); 1034 } 1035 }; 1036 1037 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings); 1038 1039 template <class Types> 1040 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms 1041 : public OcclusionTrackerTest<Types> { 1042 protected: 1043 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms( 1044 bool opaque_layers) 1045 : OcclusionTrackerTest<Types>(opaque_layers) {} 1046 void RunMyTest() { 1047 gfx::Transform child1_transform; 1048 child1_transform.Translate(250.0, 250.0); 1049 child1_transform.Rotate(-90.0); 1050 child1_transform.Translate(-250.0, -250.0); 1051 1052 gfx::Transform child2_transform; 1053 child2_transform.Translate(250.0, 250.0); 1054 child2_transform.Rotate(90.0); 1055 child2_transform.Translate(-250.0, -250.0); 1056 1057 typename Types::ContentLayerType* parent = this->CreateRoot( 1058 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 1059 parent->SetMasksToBounds(true); 1060 typename Types::LayerType* child1 = this->CreateSurface( 1061 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10)); 1062 typename Types::LayerType* child2 = 1063 this->CreateDrawingSurface(parent, 1064 child2_transform, 1065 gfx::PointF(20.f, 40.f), 1066 gfx::Size(10, 10), 1067 false); 1068 typename Types::ContentLayerType* layer1 = 1069 this->CreateDrawingLayer(child1, 1070 this->identity_matrix, 1071 gfx::PointF(-10.f, -20.f), 1072 gfx::Size(510, 510), 1073 true); 1074 typename Types::ContentLayerType* layer2 = 1075 this->CreateDrawingLayer(child2, 1076 this->identity_matrix, 1077 gfx::PointF(-10.f, -10.f), 1078 gfx::Size(510, 510), 1079 true); 1080 this->CalcDrawEtc(parent); 1081 1082 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1083 gfx::Rect(0, 0, 1000, 1000)); 1084 1085 this->VisitLayer(layer2, &occlusion); 1086 this->EnterLayer(child2, &occlusion); 1087 1088 EXPECT_EQ(gfx::Rect().ToString(), 1089 occlusion.occlusion_from_outside_target().ToString()); 1090 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), 1091 occlusion.occlusion_from_inside_target().ToString()); 1092 1093 this->LeaveLayer(child2, &occlusion); 1094 this->EnterContributingSurface(child2, &occlusion); 1095 1096 EXPECT_EQ(gfx::Rect().ToString(), 1097 occlusion.occlusion_from_outside_target().ToString()); 1098 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), 1099 occlusion.occlusion_from_inside_target().ToString()); 1100 1101 this->LeaveContributingSurface(child2, &occlusion); 1102 this->VisitLayer(layer1, &occlusion); 1103 this->EnterContributingSurface(child1, &occlusion); 1104 1105 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(), 1106 occlusion.occlusion_from_outside_target().ToString()); 1107 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), 1108 occlusion.occlusion_from_inside_target().ToString()); 1109 1110 this->LeaveContributingSurface(child1, &occlusion); 1111 this->EnterLayer(parent, &occlusion); 1112 1113 EXPECT_EQ(gfx::Rect().ToString(), 1114 occlusion.occlusion_from_outside_target().ToString()); 1115 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), 1116 occlusion.occlusion_from_inside_target().ToString()); 1117 1118 /* Justification for the above occlusion: 1119 100 1120 +---------------------+ 1121 |20 | layer1 1122 10+----------------------------------+ 1123 100 || 30 | layer2 | 1124 |20+----------------------------------+ 1125 || | | | | 1126 || | | | | 1127 || | | | | 1128 +|-|------------------+ | | 1129 | | | | 510 1130 | | 510 | | 1131 | | | | 1132 | | | | 1133 | | | | 1134 | | | | 1135 | | 520 | | 1136 +----------------------------------+ | 1137 | | 1138 +----------------------------------+ 1139 510 1140 */ 1141 } 1142 }; 1143 1144 ALL_OCCLUSIONTRACKER_TEST( 1145 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms); 1146 1147 template <class Types> 1148 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> { 1149 protected: 1150 explicit OcclusionTrackerTestFilters(bool opaque_layers) 1151 : OcclusionTrackerTest<Types>(opaque_layers) {} 1152 void RunMyTest() { 1153 gfx::Transform layer_transform; 1154 layer_transform.Translate(250.0, 250.0); 1155 layer_transform.Rotate(90.0); 1156 layer_transform.Translate(-250.0, -250.0); 1157 1158 typename Types::ContentLayerType* parent = this->CreateRoot( 1159 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 1160 parent->SetMasksToBounds(true); 1161 typename Types::ContentLayerType* blur_layer = 1162 this->CreateDrawingLayer(parent, 1163 layer_transform, 1164 gfx::PointF(30.f, 30.f), 1165 gfx::Size(500, 500), 1166 true); 1167 typename Types::ContentLayerType* opaque_layer = 1168 this->CreateDrawingLayer(parent, 1169 layer_transform, 1170 gfx::PointF(30.f, 30.f), 1171 gfx::Size(500, 500), 1172 true); 1173 typename Types::ContentLayerType* opacity_layer = 1174 this->CreateDrawingLayer(parent, 1175 layer_transform, 1176 gfx::PointF(30.f, 30.f), 1177 gfx::Size(500, 500), 1178 true); 1179 1180 FilterOperations filters; 1181 filters.Append(FilterOperation::CreateBlurFilter(10.f)); 1182 blur_layer->SetFilters(filters); 1183 1184 filters.Clear(); 1185 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); 1186 opaque_layer->SetFilters(filters); 1187 1188 filters.Clear(); 1189 filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); 1190 opacity_layer->SetFilters(filters); 1191 1192 this->CalcDrawEtc(parent); 1193 1194 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1195 gfx::Rect(0, 0, 1000, 1000)); 1196 1197 // Opacity layer won't contribute to occlusion. 1198 this->VisitLayer(opacity_layer, &occlusion); 1199 this->EnterContributingSurface(opacity_layer, &occlusion); 1200 1201 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1202 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1203 1204 // And has nothing to contribute to its parent surface. 1205 this->LeaveContributingSurface(opacity_layer, &occlusion); 1206 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1207 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1208 1209 // Opaque layer will contribute to occlusion. 1210 this->VisitLayer(opaque_layer, &occlusion); 1211 this->EnterContributingSurface(opaque_layer, &occlusion); 1212 1213 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1214 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), 1215 occlusion.occlusion_from_inside_target().ToString()); 1216 1217 // And it gets translated to the parent surface. 1218 this->LeaveContributingSurface(opaque_layer, &occlusion); 1219 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1220 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), 1221 occlusion.occlusion_from_inside_target().ToString()); 1222 1223 // The blur layer needs to throw away any occlusion from outside its 1224 // subtree. 1225 this->EnterLayer(blur_layer, &occlusion); 1226 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1227 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1228 1229 // And it won't contribute to occlusion. 1230 this->LeaveLayer(blur_layer, &occlusion); 1231 this->EnterContributingSurface(blur_layer, &occlusion); 1232 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1233 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1234 1235 // But the opaque layer's occlusion is preserved on the parent. 1236 this->LeaveContributingSurface(blur_layer, &occlusion); 1237 this->EnterLayer(parent, &occlusion); 1238 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1239 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), 1240 occlusion.occlusion_from_inside_target().ToString()); 1241 } 1242 }; 1243 1244 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters); 1245 1246 template <class Types> 1247 class OcclusionTrackerTestReplicaDoesOcclude 1248 : public OcclusionTrackerTest<Types> { 1249 protected: 1250 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers) 1251 : OcclusionTrackerTest<Types>(opaque_layers) {} 1252 void RunMyTest() { 1253 typename Types::ContentLayerType* parent = this->CreateRoot( 1254 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 1255 typename Types::LayerType* surface = this->CreateDrawingSurface( 1256 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true); 1257 this->CreateReplicaLayer( 1258 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size()); 1259 this->CalcDrawEtc(parent); 1260 1261 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1262 gfx::Rect(0, 0, 1000, 1000)); 1263 1264 this->VisitLayer(surface, &occlusion); 1265 1266 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 1267 occlusion.occlusion_from_inside_target().ToString()); 1268 1269 this->VisitContributingSurface(surface, &occlusion); 1270 this->EnterLayer(parent, &occlusion); 1271 1272 // The surface and replica should both be occluding the parent. 1273 EXPECT_EQ(gfx::Rect(50, 100).ToString(), 1274 occlusion.occlusion_from_inside_target().ToString()); 1275 } 1276 }; 1277 1278 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude); 1279 1280 template <class Types> 1281 class OcclusionTrackerTestReplicaWithClipping 1282 : public OcclusionTrackerTest<Types> { 1283 protected: 1284 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers) 1285 : OcclusionTrackerTest<Types>(opaque_layers) {} 1286 void RunMyTest() { 1287 typename Types::ContentLayerType* parent = this->CreateRoot( 1288 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170)); 1289 parent->SetMasksToBounds(true); 1290 typename Types::LayerType* surface = 1291 this->CreateDrawingSurface(parent, 1292 this->identity_matrix, 1293 gfx::PointF(0.f, 100.f), 1294 gfx::Size(50, 50), 1295 true); 1296 this->CreateReplicaLayer( 1297 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size()); 1298 this->CalcDrawEtc(parent); 1299 1300 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1301 gfx::Rect(0, 0, 1000, 1000)); 1302 1303 this->VisitLayer(surface, &occlusion); 1304 1305 // The surface layer's occlusion in its own space. 1306 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 1307 occlusion.occlusion_from_inside_target().ToString()); 1308 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1309 1310 this->VisitContributingSurface(surface, &occlusion); 1311 this->EnterLayer(parent, &occlusion); 1312 1313 // The surface and replica should both be occluding the parent, the 1314 // replica's occlusion is clipped by the parent. 1315 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(), 1316 occlusion.occlusion_from_inside_target().ToString()); 1317 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1318 } 1319 }; 1320 1321 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping); 1322 1323 template <class Types> 1324 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> { 1325 protected: 1326 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers) 1327 : OcclusionTrackerTest<Types>(opaque_layers) {} 1328 void RunMyTest() { 1329 typename Types::ContentLayerType* parent = this->CreateRoot( 1330 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 1331 typename Types::LayerType* surface = 1332 this->CreateDrawingSurface(parent, 1333 this->identity_matrix, 1334 gfx::PointF(0.f, 100.f), 1335 gfx::Size(50, 50), 1336 true); 1337 typename Types::LayerType* replica = this->CreateReplicaLayer( 1338 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size()); 1339 this->CreateMaskLayer(replica, gfx::Size(10, 10)); 1340 this->CalcDrawEtc(parent); 1341 1342 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1343 gfx::Rect(0, 0, 1000, 1000)); 1344 1345 this->VisitLayer(surface, &occlusion); 1346 1347 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 1348 occlusion.occlusion_from_inside_target().ToString()); 1349 1350 this->VisitContributingSurface(surface, &occlusion); 1351 this->EnterLayer(parent, &occlusion); 1352 1353 // The replica should not be occluding the parent, since it has a mask 1354 // applied to it. 1355 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), 1356 occlusion.occlusion_from_inside_target().ToString()); 1357 } 1358 }; 1359 1360 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask); 1361 1362 template <class Types> 1363 class OcclusionTrackerTestOpaqueContentsRegionEmpty 1364 : public OcclusionTrackerTest<Types> { 1365 protected: 1366 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers) 1367 : OcclusionTrackerTest<Types>(opaque_layers) {} 1368 void RunMyTest() { 1369 typename Types::ContentLayerType* parent = this->CreateRoot( 1370 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1371 typename Types::ContentLayerType* layer = 1372 this->CreateDrawingSurface(parent, 1373 this->identity_matrix, 1374 gfx::PointF(), 1375 gfx::Size(200, 200), 1376 false); 1377 this->CalcDrawEtc(parent); 1378 1379 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1380 gfx::Rect(0, 0, 1000, 1000)); 1381 this->EnterLayer(layer, &occlusion); 1382 1383 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1384 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1385 1386 this->LeaveLayer(layer, &occlusion); 1387 this->VisitContributingSurface(layer, &occlusion); 1388 this->EnterLayer(parent, &occlusion); 1389 1390 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1391 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1392 } 1393 }; 1394 1395 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty); 1396 1397 template <class Types> 1398 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty 1399 : public OcclusionTrackerTest<Types> { 1400 protected: 1401 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers) 1402 : OcclusionTrackerTest<Types>(opaque_layers) {} 1403 void RunMyTest() { 1404 typename Types::ContentLayerType* parent = this->CreateRoot( 1405 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1406 typename Types::ContentLayerType* layer = 1407 this->CreateDrawingLayer(parent, 1408 this->identity_matrix, 1409 gfx::PointF(100.f, 100.f), 1410 gfx::Size(200, 200), 1411 false); 1412 this->CalcDrawEtc(parent); 1413 { 1414 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1415 gfx::Rect(0, 0, 1000, 1000)); 1416 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100)); 1417 1418 this->ResetLayerIterator(); 1419 this->VisitLayer(layer, &occlusion); 1420 this->EnterLayer(parent, &occlusion); 1421 1422 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), 1423 occlusion.occlusion_from_inside_target().ToString()); 1424 } 1425 { 1426 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1427 gfx::Rect(0, 0, 1000, 1000)); 1428 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180)); 1429 1430 this->ResetLayerIterator(); 1431 this->VisitLayer(layer, &occlusion); 1432 this->EnterLayer(parent, &occlusion); 1433 1434 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), 1435 occlusion.occlusion_from_inside_target().ToString()); 1436 } 1437 { 1438 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1439 gfx::Rect(0, 0, 1000, 1000)); 1440 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100)); 1441 1442 this->ResetLayerIterator(); 1443 this->VisitLayer(layer, &occlusion); 1444 this->EnterLayer(parent, &occlusion); 1445 1446 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), 1447 occlusion.occlusion_from_inside_target().ToString()); 1448 } 1449 } 1450 }; 1451 1452 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty); 1453 1454 template <class Types> 1455 class OcclusionTrackerTestUnsorted3dLayers 1456 : public OcclusionTrackerTest<Types> { 1457 protected: 1458 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers) 1459 : OcclusionTrackerTest<Types>(opaque_layers) {} 1460 void RunMyTest() { 1461 // Currently, The main thread layer iterator does not iterate over 3d items 1462 // in sorted order, because layer sorting is not performed on the main 1463 // thread. Because of this, the occlusion tracker cannot assume that a 3d 1464 // layer occludes other layers that have not yet been iterated over. For 1465 // now, the expected behavior is that a 3d layer simply does not add any 1466 // occlusion to the occlusion tracker. 1467 1468 gfx::Transform translation_to_front; 1469 translation_to_front.Translate3d(0.0, 0.0, -10.0); 1470 gfx::Transform translation_to_back; 1471 translation_to_front.Translate3d(0.0, 0.0, -100.0); 1472 1473 typename Types::ContentLayerType* parent = this->CreateRoot( 1474 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1475 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer( 1476 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true); 1477 typename Types::ContentLayerType* child2 = 1478 this->CreateDrawingLayer(parent, 1479 translation_to_front, 1480 gfx::PointF(50.f, 50.f), 1481 gfx::Size(100, 100), 1482 true); 1483 parent->SetShouldFlattenTransform(false); 1484 parent->Set3dSortingContextId(1); 1485 child1->Set3dSortingContextId(1); 1486 child2->Set3dSortingContextId(1); 1487 1488 this->CalcDrawEtc(parent); 1489 1490 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1491 gfx::Rect(0, 0, 1000, 1000)); 1492 this->VisitLayer(child2, &occlusion); 1493 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1494 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1495 1496 this->VisitLayer(child1, &occlusion); 1497 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1498 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1499 } 1500 }; 1501 1502 // This test will have different layer ordering on the impl thread; the test 1503 // will only work on the main thread. 1504 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers); 1505 1506 template <class Types> 1507 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude 1508 : public OcclusionTrackerTest<Types> { 1509 protected: 1510 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude( 1511 bool opaque_layers) 1512 : OcclusionTrackerTest<Types>(opaque_layers) {} 1513 void RunMyTest() { 1514 gfx::Transform transform; 1515 transform.Translate(50.0, 50.0); 1516 transform.ApplyPerspectiveDepth(100.0); 1517 transform.Translate3d(0.0, 0.0, 110.0); 1518 transform.Translate(-50.0, -50.0); 1519 1520 typename Types::ContentLayerType* parent = this->CreateRoot( 1521 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 1522 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( 1523 parent, transform, gfx::PointF(), gfx::Size(100, 100), true); 1524 parent->SetShouldFlattenTransform(false); 1525 parent->Set3dSortingContextId(1); 1526 layer->SetShouldFlattenTransform(false); 1527 layer->Set3dSortingContextId(1); 1528 this->CalcDrawEtc(parent); 1529 1530 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1531 gfx::Rect(0, 0, 1000, 1000)); 1532 1533 // The |layer| is entirely behind the camera and should not occlude. 1534 this->VisitLayer(layer, &occlusion); 1535 this->EnterLayer(parent, &occlusion); 1536 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1537 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1538 } 1539 }; 1540 1541 // This test requires accumulating occlusion of 3d layers, which are skipped by 1542 // the occlusion tracker on the main thread. So this test should run on the impl 1543 // thread. 1544 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude); 1545 1546 template <class Types> 1547 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect 1548 : public OcclusionTrackerTest<Types> { 1549 protected: 1550 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect( 1551 bool opaque_layers) 1552 : OcclusionTrackerTest<Types>(opaque_layers) {} 1553 void RunMyTest() { 1554 gfx::Transform transform; 1555 transform.Translate(50.0, 50.0); 1556 transform.ApplyPerspectiveDepth(100.0); 1557 transform.Translate3d(0.0, 0.0, 99.0); 1558 transform.Translate(-50.0, -50.0); 1559 1560 typename Types::ContentLayerType* parent = this->CreateRoot( 1561 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 1562 parent->SetMasksToBounds(true); 1563 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( 1564 parent, transform, gfx::PointF(), gfx::Size(100, 100), true); 1565 parent->SetShouldFlattenTransform(false); 1566 parent->Set3dSortingContextId(1); 1567 layer->SetShouldFlattenTransform(false); 1568 layer->Set3dSortingContextId(1); 1569 this->CalcDrawEtc(parent); 1570 1571 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1572 gfx::Rect(0, 0, 1000, 1000)); 1573 1574 // This is very close to the camera, so pixels in its visible_content_rect() 1575 // will actually go outside of the layer's clip rect. Ensure that those 1576 // pixels don't occlude things outside the clip rect. 1577 this->VisitLayer(layer, &occlusion); 1578 this->EnterLayer(parent, &occlusion); 1579 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 1580 occlusion.occlusion_from_inside_target().ToString()); 1581 EXPECT_EQ(gfx::Rect().ToString(), 1582 occlusion.occlusion_from_outside_target().ToString()); 1583 } 1584 }; 1585 1586 // This test requires accumulating occlusion of 3d layers, which are skipped by 1587 // the occlusion tracker on the main thread. So this test should run on the impl 1588 // thread. 1589 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect); 1590 1591 template <class Types> 1592 class OcclusionTrackerTestAnimationOpacity1OnMainThread 1593 : public OcclusionTrackerTest<Types> { 1594 protected: 1595 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers) 1596 : OcclusionTrackerTest<Types>(opaque_layers) {} 1597 void RunMyTest() { 1598 // parent 1599 // +--layer 1600 // +--surface 1601 // | +--surface_child 1602 // | +--surface_child2 1603 // +--parent2 1604 // +--topmost 1605 1606 typename Types::ContentLayerType* parent = this->CreateRoot( 1607 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1608 typename Types::ContentLayerType* layer = 1609 this->CreateDrawingLayer(parent, 1610 this->identity_matrix, 1611 gfx::PointF(), 1612 gfx::Size(300, 300), 1613 true); 1614 typename Types::ContentLayerType* surface = 1615 this->CreateDrawingSurface(parent, 1616 this->identity_matrix, 1617 gfx::PointF(), 1618 gfx::Size(300, 300), 1619 true); 1620 typename Types::ContentLayerType* surface_child = 1621 this->CreateDrawingLayer(surface, 1622 this->identity_matrix, 1623 gfx::PointF(), 1624 gfx::Size(200, 300), 1625 true); 1626 typename Types::ContentLayerType* surface_child2 = 1627 this->CreateDrawingLayer(surface, 1628 this->identity_matrix, 1629 gfx::PointF(), 1630 gfx::Size(100, 300), 1631 true); 1632 typename Types::ContentLayerType* parent2 = 1633 this->CreateDrawingLayer(parent, 1634 this->identity_matrix, 1635 gfx::PointF(), 1636 gfx::Size(300, 300), 1637 false); 1638 typename Types::ContentLayerType* topmost = 1639 this->CreateDrawingLayer(parent, 1640 this->identity_matrix, 1641 gfx::PointF(250.f, 0.f), 1642 gfx::Size(50, 300), 1643 true); 1644 1645 AddOpacityTransitionToController( 1646 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false); 1647 AddOpacityTransitionToController( 1648 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false); 1649 this->CalcDrawEtc(parent); 1650 1651 EXPECT_TRUE(layer->draw_opacity_is_animating()); 1652 EXPECT_FALSE(surface->draw_opacity_is_animating()); 1653 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating()); 1654 1655 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1656 gfx::Rect(0, 0, 1000, 1000)); 1657 1658 this->VisitLayer(topmost, &occlusion); 1659 this->EnterLayer(parent2, &occlusion); 1660 1661 // This occlusion will affect all surfaces. 1662 EXPECT_EQ(gfx::Rect().ToString(), 1663 occlusion.occlusion_from_outside_target().ToString()); 1664 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1665 occlusion.occlusion_from_inside_target().ToString()); 1666 1667 this->LeaveLayer(parent2, &occlusion); 1668 this->VisitLayer(surface_child2, &occlusion); 1669 this->EnterLayer(surface_child, &occlusion); 1670 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1671 occlusion.occlusion_from_outside_target().ToString()); 1672 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 1673 occlusion.occlusion_from_inside_target().ToString()); 1674 1675 this->LeaveLayer(surface_child, &occlusion); 1676 this->EnterLayer(surface, &occlusion); 1677 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1678 occlusion.occlusion_from_outside_target().ToString()); 1679 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), 1680 occlusion.occlusion_from_inside_target().ToString()); 1681 1682 this->LeaveLayer(surface, &occlusion); 1683 this->EnterContributingSurface(surface, &occlusion); 1684 // Occlusion within the surface is lost when leaving the animating surface. 1685 EXPECT_EQ(gfx::Rect().ToString(), 1686 occlusion.occlusion_from_outside_target().ToString()); 1687 EXPECT_EQ(gfx::Rect().ToString(), 1688 occlusion.occlusion_from_inside_target().ToString()); 1689 1690 this->LeaveContributingSurface(surface, &occlusion); 1691 // Occlusion from outside the animating surface still exists. 1692 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1693 occlusion.occlusion_from_inside_target().ToString()); 1694 EXPECT_EQ(gfx::Rect().ToString(), 1695 occlusion.occlusion_from_outside_target().ToString()); 1696 1697 this->VisitLayer(layer, &occlusion); 1698 this->EnterLayer(parent, &occlusion); 1699 1700 // Occlusion is not added for the animating |layer|. 1701 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1702 occlusion.occlusion_from_inside_target().ToString()); 1703 EXPECT_EQ(gfx::Rect().ToString(), 1704 occlusion.occlusion_from_outside_target().ToString()); 1705 } 1706 }; 1707 1708 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread); 1709 1710 template <class Types> 1711 class OcclusionTrackerTestAnimationOpacity0OnMainThread 1712 : public OcclusionTrackerTest<Types> { 1713 protected: 1714 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers) 1715 : OcclusionTrackerTest<Types>(opaque_layers) {} 1716 void RunMyTest() { 1717 typename Types::ContentLayerType* parent = this->CreateRoot( 1718 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1719 typename Types::ContentLayerType* layer = 1720 this->CreateDrawingLayer(parent, 1721 this->identity_matrix, 1722 gfx::PointF(), 1723 gfx::Size(300, 300), 1724 true); 1725 typename Types::ContentLayerType* surface = 1726 this->CreateDrawingSurface(parent, 1727 this->identity_matrix, 1728 gfx::PointF(), 1729 gfx::Size(300, 300), 1730 true); 1731 typename Types::ContentLayerType* surface_child = 1732 this->CreateDrawingLayer(surface, 1733 this->identity_matrix, 1734 gfx::PointF(), 1735 gfx::Size(200, 300), 1736 true); 1737 typename Types::ContentLayerType* surface_child2 = 1738 this->CreateDrawingLayer(surface, 1739 this->identity_matrix, 1740 gfx::PointF(), 1741 gfx::Size(100, 300), 1742 true); 1743 typename Types::ContentLayerType* parent2 = 1744 this->CreateDrawingLayer(parent, 1745 this->identity_matrix, 1746 gfx::PointF(), 1747 gfx::Size(300, 300), 1748 false); 1749 typename Types::ContentLayerType* topmost = 1750 this->CreateDrawingLayer(parent, 1751 this->identity_matrix, 1752 gfx::PointF(250.f, 0.f), 1753 gfx::Size(50, 300), 1754 true); 1755 1756 AddOpacityTransitionToController( 1757 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false); 1758 AddOpacityTransitionToController( 1759 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false); 1760 this->CalcDrawEtc(parent); 1761 1762 EXPECT_TRUE(layer->draw_opacity_is_animating()); 1763 EXPECT_FALSE(surface->draw_opacity_is_animating()); 1764 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating()); 1765 1766 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1767 gfx::Rect(0, 0, 1000, 1000)); 1768 1769 this->VisitLayer(topmost, &occlusion); 1770 this->EnterLayer(parent2, &occlusion); 1771 // This occlusion will affect all surfaces. 1772 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1773 occlusion.occlusion_from_inside_target().ToString()); 1774 EXPECT_EQ(gfx::Rect().ToString(), 1775 occlusion.occlusion_from_outside_target().ToString()); 1776 1777 this->LeaveLayer(parent2, &occlusion); 1778 this->VisitLayer(surface_child2, &occlusion); 1779 this->EnterLayer(surface_child, &occlusion); 1780 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 1781 occlusion.occlusion_from_inside_target().ToString()); 1782 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1783 occlusion.occlusion_from_outside_target().ToString()); 1784 1785 this->LeaveLayer(surface_child, &occlusion); 1786 this->EnterLayer(surface, &occlusion); 1787 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), 1788 occlusion.occlusion_from_inside_target().ToString()); 1789 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1790 occlusion.occlusion_from_outside_target().ToString()); 1791 1792 this->LeaveLayer(surface, &occlusion); 1793 this->EnterContributingSurface(surface, &occlusion); 1794 // Occlusion within the surface is lost when leaving the animating surface. 1795 EXPECT_EQ(gfx::Rect().ToString(), 1796 occlusion.occlusion_from_inside_target().ToString()); 1797 EXPECT_EQ(gfx::Rect().ToString(), 1798 occlusion.occlusion_from_outside_target().ToString()); 1799 1800 this->LeaveContributingSurface(surface, &occlusion); 1801 // Occlusion from outside the animating surface still exists. 1802 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1803 occlusion.occlusion_from_inside_target().ToString()); 1804 EXPECT_EQ(gfx::Rect().ToString(), 1805 occlusion.occlusion_from_outside_target().ToString()); 1806 1807 this->VisitLayer(layer, &occlusion); 1808 this->EnterLayer(parent, &occlusion); 1809 1810 // Occlusion is not added for the animating |layer|. 1811 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 1812 occlusion.occlusion_from_inside_target().ToString()); 1813 EXPECT_EQ(gfx::Rect().ToString(), 1814 occlusion.occlusion_from_outside_target().ToString()); 1815 } 1816 }; 1817 1818 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread); 1819 1820 template <class Types> 1821 class OcclusionTrackerTestAnimationTranslateOnMainThread 1822 : public OcclusionTrackerTest<Types> { 1823 protected: 1824 explicit OcclusionTrackerTestAnimationTranslateOnMainThread( 1825 bool opaque_layers) 1826 : OcclusionTrackerTest<Types>(opaque_layers) {} 1827 void RunMyTest() { 1828 typename Types::ContentLayerType* parent = this->CreateRoot( 1829 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1830 typename Types::ContentLayerType* layer = 1831 this->CreateDrawingLayer(parent, 1832 this->identity_matrix, 1833 gfx::PointF(), 1834 gfx::Size(300, 300), 1835 true); 1836 typename Types::ContentLayerType* surface = 1837 this->CreateDrawingSurface(parent, 1838 this->identity_matrix, 1839 gfx::PointF(), 1840 gfx::Size(300, 300), 1841 true); 1842 typename Types::ContentLayerType* surface_child = 1843 this->CreateDrawingLayer(surface, 1844 this->identity_matrix, 1845 gfx::PointF(), 1846 gfx::Size(200, 300), 1847 true); 1848 typename Types::ContentLayerType* surface_child2 = 1849 this->CreateDrawingLayer(surface, 1850 this->identity_matrix, 1851 gfx::PointF(), 1852 gfx::Size(100, 300), 1853 true); 1854 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface( 1855 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true); 1856 1857 AddAnimatedTransformToController( 1858 layer->layer_animation_controller(), 10.0, 30, 0); 1859 AddAnimatedTransformToController( 1860 surface->layer_animation_controller(), 10.0, 30, 0); 1861 AddAnimatedTransformToController( 1862 surface_child->layer_animation_controller(), 10.0, 30, 0); 1863 this->CalcDrawEtc(parent); 1864 1865 EXPECT_TRUE(layer->draw_transform_is_animating()); 1866 EXPECT_TRUE(layer->screen_space_transform_is_animating()); 1867 EXPECT_TRUE( 1868 surface->render_surface()->target_surface_transforms_are_animating()); 1869 EXPECT_TRUE( 1870 surface->render_surface()->screen_space_transforms_are_animating()); 1871 // The surface owning layer doesn't animate against its own surface. 1872 EXPECT_FALSE(surface->draw_transform_is_animating()); 1873 EXPECT_TRUE(surface->screen_space_transform_is_animating()); 1874 EXPECT_TRUE(surface_child->draw_transform_is_animating()); 1875 EXPECT_TRUE(surface_child->screen_space_transform_is_animating()); 1876 1877 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1878 gfx::Rect(0, 0, 1000, 1000)); 1879 1880 this->VisitLayer(surface2, &occlusion); 1881 this->EnterContributingSurface(surface2, &occlusion); 1882 1883 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), 1884 occlusion.occlusion_from_inside_target().ToString()); 1885 1886 this->LeaveContributingSurface(surface2, &occlusion); 1887 this->EnterLayer(surface_child2, &occlusion); 1888 // surface_child2 is moving in screen space but not relative to its target, 1889 // so occlusion should happen in its target space only. It also means that 1890 // things occluding from outside the target (e.g. surface2) cannot occlude 1891 // this layer. 1892 EXPECT_EQ(gfx::Rect().ToString(), 1893 occlusion.occlusion_from_outside_target().ToString()); 1894 EXPECT_EQ(gfx::Rect().ToString(), 1895 occlusion.occlusion_from_inside_target().ToString()); 1896 1897 this->LeaveLayer(surface_child2, &occlusion); 1898 this->EnterLayer(surface_child, &occlusion); 1899 // surface_child2 added to the occlusion since it is not moving relative 1900 // to its target. 1901 EXPECT_EQ(gfx::Rect().ToString(), 1902 occlusion.occlusion_from_outside_target().ToString()); 1903 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 1904 occlusion.occlusion_from_inside_target().ToString()); 1905 1906 this->LeaveLayer(surface_child, &occlusion); 1907 // surface_child is moving relative to its target, so it does not add 1908 // occlusion. 1909 EXPECT_EQ(gfx::Rect().ToString(), 1910 occlusion.occlusion_from_outside_target().ToString()); 1911 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 1912 occlusion.occlusion_from_inside_target().ToString()); 1913 1914 this->EnterLayer(surface, &occlusion); 1915 EXPECT_EQ(gfx::Rect().ToString(), 1916 occlusion.occlusion_from_outside_target().ToString()); 1917 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 1918 occlusion.occlusion_from_inside_target().ToString()); 1919 1920 this->LeaveLayer(surface, &occlusion); 1921 // The surface's owning layer is moving in screen space but not relative to 1922 // its target, so it adds to the occlusion. 1923 EXPECT_EQ(gfx::Rect().ToString(), 1924 occlusion.occlusion_from_outside_target().ToString()); 1925 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), 1926 occlusion.occlusion_from_inside_target().ToString()); 1927 1928 this->EnterContributingSurface(surface, &occlusion); 1929 this->LeaveContributingSurface(surface, &occlusion); 1930 // The |surface| is moving in the screen and in its target, so all occlusion 1931 // within the surface is lost when leaving it. Only the |surface2| occlusion 1932 // is left. 1933 EXPECT_EQ(gfx::Rect().ToString(), 1934 occlusion.occlusion_from_outside_target().ToString()); 1935 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), 1936 occlusion.occlusion_from_inside_target().ToString()); 1937 1938 this->VisitLayer(layer, &occlusion); 1939 // The |layer| is animating in the screen and in its target, so no occlusion 1940 // is added. 1941 EXPECT_EQ(gfx::Rect().ToString(), 1942 occlusion.occlusion_from_outside_target().ToString()); 1943 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), 1944 occlusion.occlusion_from_inside_target().ToString()); 1945 } 1946 }; 1947 1948 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread); 1949 1950 template <class Types> 1951 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent 1952 : public OcclusionTrackerTest<Types> { 1953 protected: 1954 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent( 1955 bool opaque_layers) 1956 : OcclusionTrackerTest<Types>(opaque_layers) {} 1957 void RunMyTest() { 1958 gfx::Transform surface_transform; 1959 surface_transform.Translate(300.0, 300.0); 1960 surface_transform.Scale(2.0, 2.0); 1961 surface_transform.Translate(-150.0, -150.0); 1962 1963 typename Types::ContentLayerType* parent = this->CreateRoot( 1964 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500)); 1965 typename Types::ContentLayerType* surface = this->CreateDrawingSurface( 1966 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false); 1967 typename Types::ContentLayerType* surface2 = 1968 this->CreateDrawingSurface(parent, 1969 this->identity_matrix, 1970 gfx::PointF(50.f, 50.f), 1971 gfx::Size(300, 300), 1972 false); 1973 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); 1974 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); 1975 this->CalcDrawEtc(parent); 1976 1977 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 1978 gfx::Rect(0, 0, 1000, 1000)); 1979 1980 this->VisitLayer(surface2, &occlusion); 1981 this->VisitContributingSurface(surface2, &occlusion); 1982 1983 EXPECT_EQ(gfx::Rect().ToString(), 1984 occlusion.occlusion_from_outside_target().ToString()); 1985 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), 1986 occlusion.occlusion_from_inside_target().ToString()); 1987 1988 // Clear any stored occlusion. 1989 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); 1990 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); 1991 1992 this->VisitLayer(surface, &occlusion); 1993 this->VisitContributingSurface(surface, &occlusion); 1994 1995 EXPECT_EQ(gfx::Rect().ToString(), 1996 occlusion.occlusion_from_outside_target().ToString()); 1997 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), 1998 occlusion.occlusion_from_inside_target().ToString()); 1999 } 2000 }; 2001 2002 MAIN_AND_IMPL_THREAD_TEST( 2003 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent); 2004 2005 template <class Types> 2006 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping 2007 : public OcclusionTrackerTest<Types> { 2008 protected: 2009 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping( 2010 bool opaque_layers) 2011 : OcclusionTrackerTest<Types>(opaque_layers) {} 2012 void RunMyTest() { 2013 typename Types::ContentLayerType* parent = this->CreateRoot( 2014 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2015 parent->SetMasksToBounds(true); 2016 typename Types::ContentLayerType* surface = 2017 this->CreateDrawingSurface(parent, 2018 this->identity_matrix, 2019 gfx::PointF(), 2020 gfx::Size(500, 300), 2021 false); 2022 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200)); 2023 this->CalcDrawEtc(parent); 2024 2025 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2026 gfx::Rect(0, 0, 1000, 1000)); 2027 2028 this->VisitLayer(surface, &occlusion); 2029 this->VisitContributingSurface(surface, &occlusion); 2030 2031 EXPECT_EQ(gfx::Rect().ToString(), 2032 occlusion.occlusion_from_outside_target().ToString()); 2033 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), 2034 occlusion.occlusion_from_inside_target().ToString()); 2035 } 2036 }; 2037 2038 MAIN_AND_IMPL_THREAD_TEST( 2039 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping); 2040 2041 template <class Types> 2042 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded 2043 : public OcclusionTrackerTest<Types> { 2044 protected: 2045 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers) 2046 : OcclusionTrackerTest<Types>(opaque_layers) {} 2047 void RunMyTest() { 2048 typename Types::ContentLayerType* parent = this->CreateRoot( 2049 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 2050 typename Types::LayerType* surface = 2051 this->CreateDrawingSurface(parent, 2052 this->identity_matrix, 2053 gfx::PointF(), 2054 gfx::Size(100, 100), 2055 true); 2056 this->CreateReplicaLayer(surface, 2057 this->identity_matrix, 2058 gfx::PointF(0.f, 100.f), 2059 gfx::Size(100, 100)); 2060 typename Types::LayerType* topmost = 2061 this->CreateDrawingLayer(parent, 2062 this->identity_matrix, 2063 gfx::PointF(), 2064 gfx::Size(100, 110), 2065 true); 2066 this->CalcDrawEtc(parent); 2067 2068 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2069 gfx::Rect(0, 0, 1000, 1000)); 2070 2071 // |topmost| occludes the surface, but not the entire surface's replica. 2072 this->VisitLayer(topmost, &occlusion); 2073 2074 EXPECT_EQ(gfx::Rect().ToString(), 2075 occlusion.occlusion_from_outside_target().ToString()); 2076 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), 2077 occlusion.occlusion_from_inside_target().ToString()); 2078 2079 this->VisitLayer(surface, &occlusion); 2080 2081 // Render target with replica ignores occlusion from outside. 2082 EXPECT_EQ(gfx::Rect().ToString(), 2083 occlusion.occlusion_from_outside_target().ToString()); 2084 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 2085 occlusion.occlusion_from_inside_target().ToString()); 2086 2087 this->EnterContributingSurface(surface, &occlusion); 2088 2089 // Only occlusion from outside the surface occludes the surface/replica. 2090 EXPECT_EQ(gfx::Rect().ToString(), 2091 occlusion.occlusion_on_contributing_surface_from_outside_target() 2092 .ToString()); 2093 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), 2094 occlusion.occlusion_on_contributing_surface_from_inside_target() 2095 .ToString()); 2096 } 2097 }; 2098 2099 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded); 2100 2101 template <class Types> 2102 class OcclusionTrackerTestSurfaceChildOfSurface 2103 : public OcclusionTrackerTest<Types> { 2104 protected: 2105 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers) 2106 : OcclusionTrackerTest<Types>(opaque_layers) {} 2107 void RunMyTest() { 2108 // This test verifies that the surface cliprect does not end up empty and 2109 // clip away the entire unoccluded rect. 2110 2111 typename Types::ContentLayerType* parent = this->CreateRoot( 2112 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 2113 typename Types::LayerType* surface = 2114 this->CreateDrawingSurface(parent, 2115 this->identity_matrix, 2116 gfx::PointF(), 2117 gfx::Size(100, 100), 2118 false); 2119 typename Types::LayerType* surface_child = 2120 this->CreateDrawingSurface(surface, 2121 this->identity_matrix, 2122 gfx::PointF(0.f, 10.f), 2123 gfx::Size(100, 50), 2124 true); 2125 typename Types::LayerType* topmost = this->CreateDrawingLayer( 2126 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true); 2127 this->CalcDrawEtc(parent); 2128 2129 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2130 gfx::Rect(-100, -100, 1000, 1000)); 2131 2132 // |topmost| occludes everything partially so we know occlusion is happening 2133 // at all. 2134 this->VisitLayer(topmost, &occlusion); 2135 2136 EXPECT_EQ(gfx::Rect().ToString(), 2137 occlusion.occlusion_from_outside_target().ToString()); 2138 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 2139 occlusion.occlusion_from_inside_target().ToString()); 2140 2141 this->VisitLayer(surface_child, &occlusion); 2142 2143 // surface_child increases the occlusion in the screen by a narrow sliver. 2144 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(), 2145 occlusion.occlusion_from_outside_target().ToString()); 2146 // In its own surface, surface_child is at 0,0 as is its occlusion. 2147 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 2148 occlusion.occlusion_from_inside_target().ToString()); 2149 2150 // The root layer always has a clip rect. So the parent of |surface| has a 2151 // clip rect. However, the owning layer for |surface| does not mask to 2152 // bounds, so it doesn't have a clip rect of its own. Thus the parent of 2153 // |surface_child| exercises different code paths as its parent does not 2154 // have a clip rect. 2155 2156 this->EnterContributingSurface(surface_child, &occlusion); 2157 // The |surface_child| can't occlude its own surface, but occlusion from 2158 // |topmost| can. 2159 EXPECT_EQ(gfx::Rect().ToString(), 2160 occlusion.occlusion_on_contributing_surface_from_outside_target() 2161 .ToString()); 2162 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 2163 occlusion.occlusion_on_contributing_surface_from_inside_target() 2164 .ToString()); 2165 this->LeaveContributingSurface(surface_child, &occlusion); 2166 2167 // When the surface_child's occlusion is transformed up to its parent, make 2168 // sure it is not clipped away inappropriately. 2169 this->EnterLayer(surface, &occlusion); 2170 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 2171 occlusion.occlusion_from_outside_target().ToString()); 2172 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), 2173 occlusion.occlusion_from_inside_target().ToString()); 2174 this->LeaveLayer(surface, &occlusion); 2175 2176 this->EnterContributingSurface(surface, &occlusion); 2177 // The occlusion from inside |surface| can't affect the surface, but 2178 // |topmost| can. 2179 EXPECT_EQ(gfx::Rect().ToString(), 2180 occlusion.occlusion_on_contributing_surface_from_outside_target() 2181 .ToString()); 2182 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 2183 occlusion.occlusion_on_contributing_surface_from_inside_target() 2184 .ToString()); 2185 2186 this->LeaveContributingSurface(surface, &occlusion); 2187 this->EnterLayer(parent, &occlusion); 2188 // The occlusion in |surface| and without are merged into the parent. 2189 EXPECT_EQ(gfx::Rect().ToString(), 2190 occlusion.occlusion_from_outside_target().ToString()); 2191 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), 2192 occlusion.occlusion_from_inside_target().ToString()); 2193 } 2194 }; 2195 2196 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface); 2197 2198 template <class Types> 2199 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter 2200 : public OcclusionTrackerTest<Types> { 2201 protected: 2202 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter( 2203 bool opaque_layers) 2204 : OcclusionTrackerTest<Types>(opaque_layers) {} 2205 void RunMyTest() { 2206 gfx::Transform scale_by_half; 2207 scale_by_half.Scale(0.5, 0.5); 2208 2209 FilterOperations filters; 2210 filters.Append(FilterOperation::CreateBlurFilter(10.f)); 2211 2212 // Save the distance of influence for the blur effect. 2213 int outset_top, outset_right, outset_bottom, outset_left; 2214 filters.GetOutsets( 2215 &outset_top, &outset_right, &outset_bottom, &outset_left); 2216 2217 enum Direction { 2218 LEFT, 2219 RIGHT, 2220 TOP, 2221 BOTTOM, 2222 LAST_DIRECTION = BOTTOM, 2223 }; 2224 2225 for (int i = 0; i <= LAST_DIRECTION; ++i) { 2226 SCOPED_TRACE(i); 2227 2228 // Make a 50x50 filtered surface that is adjacent to occluding layers 2229 // which are above it in the z-order in various configurations. The 2230 // surface is scaled to test that the pixel moving is done in the target 2231 // space, where the background filter is applied. 2232 typename Types::ContentLayerType* parent = this->CreateRoot( 2233 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 2234 typename Types::LayerType* filtered_surface = 2235 this->CreateDrawingLayer(parent, 2236 scale_by_half, 2237 gfx::PointF(50.f, 50.f), 2238 gfx::Size(100, 100), 2239 false); 2240 filtered_surface->SetBackgroundFilters(filters); 2241 2242 gfx::Rect occlusion_rect; 2243 switch (i) { 2244 case LEFT: 2245 occlusion_rect = gfx::Rect(0, 0, 50, 200); 2246 break; 2247 case RIGHT: 2248 occlusion_rect = gfx::Rect(100, 0, 50, 200); 2249 break; 2250 case TOP: 2251 occlusion_rect = gfx::Rect(0, 0, 200, 50); 2252 break; 2253 case BOTTOM: 2254 occlusion_rect = gfx::Rect(0, 100, 200, 50); 2255 break; 2256 } 2257 2258 typename Types::LayerType* occluding_layer = 2259 this->CreateDrawingLayer(parent, 2260 this->identity_matrix, 2261 occlusion_rect.origin(), 2262 occlusion_rect.size(), 2263 true); 2264 this->CalcDrawEtc(parent); 2265 2266 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2267 gfx::Rect(0, 0, 200, 200)); 2268 2269 // This layer occludes pixels directly beside the filtered_surface. 2270 // Because filtered surface blends pixels in a radius, it will need to see 2271 // some of the pixels (up to radius far) underneath the occluding layers. 2272 this->VisitLayer(occluding_layer, &occlusion); 2273 2274 EXPECT_EQ(occlusion_rect.ToString(), 2275 occlusion.occlusion_from_inside_target().ToString()); 2276 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2277 2278 this->VisitLayer(filtered_surface, &occlusion); 2279 2280 // The occlusion is used fully inside the surface. 2281 gfx::Rect occlusion_inside_surface = 2282 occlusion_rect - gfx::Vector2d(50, 50); 2283 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 2284 EXPECT_EQ(occlusion_inside_surface.ToString(), 2285 occlusion.occlusion_from_outside_target().ToString()); 2286 2287 // The surface has a background blur, so it needs pixels that are 2288 // currently considered occluded in order to be drawn. So the pixels it 2289 // needs should be removed some the occluded area so that when we get to 2290 // the parent they are drawn. 2291 this->VisitContributingSurface(filtered_surface, &occlusion); 2292 this->EnterLayer(parent, &occlusion); 2293 2294 gfx::Rect expected_occlusion = occlusion_rect; 2295 switch (i) { 2296 case LEFT: 2297 expected_occlusion.Inset(0, 0, outset_right, 0); 2298 break; 2299 case RIGHT: 2300 expected_occlusion.Inset(outset_right, 0, 0, 0); 2301 break; 2302 case TOP: 2303 expected_occlusion.Inset(0, 0, 0, outset_right); 2304 break; 2305 case BOTTOM: 2306 expected_occlusion.Inset(0, outset_right, 0, 0); 2307 break; 2308 } 2309 2310 EXPECT_EQ(expected_occlusion.ToString(), 2311 occlusion.occlusion_from_inside_target().ToString()); 2312 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2313 2314 this->DestroyLayers(); 2315 } 2316 } 2317 }; 2318 2319 ALL_OCCLUSIONTRACKER_TEST( 2320 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter); 2321 2322 template <class Types> 2323 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice 2324 : public OcclusionTrackerTest<Types> { 2325 protected: 2326 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice( 2327 bool opaque_layers) 2328 : OcclusionTrackerTest<Types>(opaque_layers) {} 2329 void RunMyTest() { 2330 gfx::Transform scale_by_half; 2331 scale_by_half.Scale(0.5, 0.5); 2332 2333 // Makes two surfaces that completely cover |parent|. The occlusion both 2334 // above and below the filters will be reduced by each of them. 2335 typename Types::ContentLayerType* root = this->CreateRoot( 2336 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75)); 2337 typename Types::LayerType* parent = this->CreateSurface( 2338 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150)); 2339 parent->SetMasksToBounds(true); 2340 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer( 2341 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); 2342 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer( 2343 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); 2344 typename Types::LayerType* occluding_layer_above = 2345 this->CreateDrawingLayer(parent, 2346 this->identity_matrix, 2347 gfx::PointF(100.f, 100.f), 2348 gfx::Size(50, 50), 2349 true); 2350 2351 // Filters make the layers own surfaces. 2352 FilterOperations filters; 2353 filters.Append(FilterOperation::CreateBlurFilter(1.f)); 2354 filtered_surface1->SetBackgroundFilters(filters); 2355 filtered_surface2->SetBackgroundFilters(filters); 2356 2357 // Save the distance of influence for the blur effect. 2358 int outset_top, outset_right, outset_bottom, outset_left; 2359 filters.GetOutsets( 2360 &outset_top, &outset_right, &outset_bottom, &outset_left); 2361 2362 this->CalcDrawEtc(root); 2363 2364 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2365 gfx::Rect(0, 0, 1000, 1000)); 2366 2367 this->VisitLayer(occluding_layer_above, &occlusion); 2368 EXPECT_EQ(gfx::Rect().ToString(), 2369 occlusion.occlusion_from_outside_target().ToString()); 2370 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), 2371 occlusion.occlusion_from_inside_target().ToString()); 2372 2373 this->VisitLayer(filtered_surface2, &occlusion); 2374 this->VisitContributingSurface(filtered_surface2, &occlusion); 2375 this->VisitLayer(filtered_surface1, &occlusion); 2376 this->VisitContributingSurface(filtered_surface1, &occlusion); 2377 2378 // Test expectations in the target. 2379 gfx::Rect expected_occlusion = 2380 gfx::Rect(100 / 2 + outset_right * 2, 2381 100 / 2 + outset_bottom * 2, 2382 50 / 2 - (outset_left + outset_right) * 2, 2383 50 / 2 - (outset_top + outset_bottom) * 2); 2384 EXPECT_EQ(expected_occlusion.ToString(), 2385 occlusion.occlusion_from_inside_target().ToString()); 2386 2387 // Test expectations in the screen are the same as in the target, as the 2388 // render surface is 1:1 with the screen. 2389 EXPECT_EQ(expected_occlusion.ToString(), 2390 occlusion.occlusion_from_outside_target().ToString()); 2391 } 2392 }; 2393 2394 ALL_OCCLUSIONTRACKER_TEST( 2395 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice); 2396 2397 template <class Types> 2398 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter 2399 : public OcclusionTrackerTest<Types> { 2400 protected: 2401 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter( 2402 bool opaque_layers) 2403 : OcclusionTrackerTest<Types>(opaque_layers) {} 2404 void RunMyTest() { 2405 gfx::Transform scale_by_half; 2406 scale_by_half.Scale(0.5, 0.5); 2407 2408 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer 2409 // centered below each. The surface is scaled to test that the pixel moving 2410 // is done in the target space, where the background filter is applied, but 2411 // the surface appears at 50, 50 and the replica at 200, 50. 2412 typename Types::ContentLayerType* parent = this->CreateRoot( 2413 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); 2414 typename Types::LayerType* behind_surface_layer = 2415 this->CreateDrawingLayer(parent, 2416 this->identity_matrix, 2417 gfx::PointF(60.f, 60.f), 2418 gfx::Size(30, 30), 2419 true); 2420 typename Types::LayerType* behind_replica_layer = 2421 this->CreateDrawingLayer(parent, 2422 this->identity_matrix, 2423 gfx::PointF(210.f, 60.f), 2424 gfx::Size(30, 30), 2425 true); 2426 typename Types::LayerType* filtered_surface = 2427 this->CreateDrawingLayer(parent, 2428 scale_by_half, 2429 gfx::PointF(50.f, 50.f), 2430 gfx::Size(100, 100), 2431 false); 2432 this->CreateReplicaLayer(filtered_surface, 2433 this->identity_matrix, 2434 gfx::PointF(300.f, 0.f), 2435 gfx::Size()); 2436 2437 // Filters make the layer own a surface. 2438 FilterOperations filters; 2439 filters.Append(FilterOperation::CreateBlurFilter(3.f)); 2440 filtered_surface->SetBackgroundFilters(filters); 2441 2442 this->CalcDrawEtc(parent); 2443 2444 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2445 gfx::Rect(0, 0, 1000, 1000)); 2446 2447 // The surface has a background blur, so it blurs non-opaque pixels below 2448 // it. 2449 this->VisitLayer(filtered_surface, &occlusion); 2450 this->VisitContributingSurface(filtered_surface, &occlusion); 2451 2452 this->VisitLayer(behind_replica_layer, &occlusion); 2453 2454 // The layers behind the surface are not blurred, and their occlusion does 2455 // not change, until we leave the surface. So it should not be modified by 2456 // the filter here. 2457 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30); 2458 EXPECT_EQ(occlusion_behind_replica.ToString(), 2459 occlusion.occlusion_from_inside_target().ToString()); 2460 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2461 2462 // Clear the occlusion so the |behind_surface_layer| can add its occlusion 2463 // without existing occlusion interfering. 2464 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); 2465 2466 this->VisitLayer(behind_surface_layer, &occlusion); 2467 2468 // The layers behind the surface are not blurred, and their occlusion does 2469 // not change, until we leave the surface. So it should not be modified by 2470 // the filter here. 2471 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30); 2472 EXPECT_EQ(occlusion_behind_surface.ToString(), 2473 occlusion.occlusion_from_inside_target().ToString()); 2474 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2475 } 2476 }; 2477 2478 ALL_OCCLUSIONTRACKER_TEST( 2479 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter); 2480 2481 template <class Types> 2482 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded 2483 : public OcclusionTrackerTest<Types> { 2484 protected: 2485 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded( 2486 bool opaque_layers) 2487 : OcclusionTrackerTest<Types>(opaque_layers) {} 2488 void RunMyTest() { 2489 gfx::Transform scale_by_half; 2490 scale_by_half.Scale(0.5, 0.5); 2491 2492 // Make a 50x50 filtered surface that is completely occluded by an opaque 2493 // layer which is above it in the z-order. The surface is 2494 // scaled to test that the pixel moving is done in the target space, where 2495 // the background filter is applied, but the surface appears at 50, 50. 2496 typename Types::ContentLayerType* parent = this->CreateRoot( 2497 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150)); 2498 typename Types::LayerType* filtered_surface = 2499 this->CreateDrawingLayer(parent, 2500 scale_by_half, 2501 gfx::PointF(50.f, 50.f), 2502 gfx::Size(100, 100), 2503 false); 2504 typename Types::LayerType* occluding_layer = 2505 this->CreateDrawingLayer(parent, 2506 this->identity_matrix, 2507 gfx::PointF(50.f, 50.f), 2508 gfx::Size(50, 50), 2509 true); 2510 2511 // Filters make the layer own a surface. 2512 FilterOperations filters; 2513 filters.Append(FilterOperation::CreateBlurFilter(3.f)); 2514 filtered_surface->SetBackgroundFilters(filters); 2515 2516 this->CalcDrawEtc(parent); 2517 2518 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2519 gfx::Rect(0, 0, 1000, 1000)); 2520 2521 this->VisitLayer(occluding_layer, &occlusion); 2522 2523 this->VisitLayer(filtered_surface, &occlusion); 2524 { 2525 // The layers above the filtered surface occlude from outside. 2526 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50); 2527 2528 EXPECT_EQ(gfx::Rect().ToString(), 2529 occlusion.occlusion_from_inside_target().ToString()); 2530 EXPECT_EQ(occlusion_above_surface.ToString(), 2531 occlusion.occlusion_from_outside_target().ToString()); 2532 } 2533 2534 // The surface has a background blur, so it blurs non-opaque pixels below 2535 // it. 2536 this->VisitContributingSurface(filtered_surface, &occlusion); 2537 { 2538 // The filter is completely occluded, so it should not blur anything and 2539 // reduce any occlusion. 2540 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50); 2541 2542 EXPECT_EQ(occlusion_above_surface.ToString(), 2543 occlusion.occlusion_from_inside_target().ToString()); 2544 EXPECT_EQ(gfx::Rect().ToString(), 2545 occlusion.occlusion_from_outside_target().ToString()); 2546 } 2547 } 2548 }; 2549 2550 ALL_OCCLUSIONTRACKER_TEST( 2551 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded); 2552 2553 template <class Types> 2554 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded 2555 : public OcclusionTrackerTest<Types> { 2556 protected: 2557 explicit 2558 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded( 2559 bool opaque_layers) 2560 : OcclusionTrackerTest<Types>(opaque_layers) {} 2561 void RunMyTest() { 2562 gfx::Transform scale_by_half; 2563 scale_by_half.Scale(0.5, 0.5); 2564 2565 // Make a surface and its replica, each 50x50, that are partially occluded 2566 // by opaque layers which are above them in the z-order. The surface is 2567 // scaled to test that the pixel moving is done in the target space, where 2568 // the background filter is applied, but the surface appears at 50, 50 and 2569 // the replica at 200, 50. 2570 typename Types::ContentLayerType* parent = this->CreateRoot( 2571 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); 2572 typename Types::LayerType* filtered_surface = 2573 this->CreateDrawingLayer(parent, 2574 scale_by_half, 2575 gfx::PointF(50.f, 50.f), 2576 gfx::Size(100, 100), 2577 false); 2578 this->CreateReplicaLayer(filtered_surface, 2579 this->identity_matrix, 2580 gfx::PointF(300.f, 0.f), 2581 gfx::Size()); 2582 typename Types::LayerType* above_surface_layer = 2583 this->CreateDrawingLayer(parent, 2584 this->identity_matrix, 2585 gfx::PointF(70.f, 50.f), 2586 gfx::Size(30, 50), 2587 true); 2588 typename Types::LayerType* above_replica_layer = 2589 this->CreateDrawingLayer(parent, 2590 this->identity_matrix, 2591 gfx::PointF(200.f, 50.f), 2592 gfx::Size(30, 50), 2593 true); 2594 typename Types::LayerType* beside_surface_layer = 2595 this->CreateDrawingLayer(parent, 2596 this->identity_matrix, 2597 gfx::PointF(90.f, 40.f), 2598 gfx::Size(10, 10), 2599 true); 2600 typename Types::LayerType* beside_replica_layer = 2601 this->CreateDrawingLayer(parent, 2602 this->identity_matrix, 2603 gfx::PointF(200.f, 40.f), 2604 gfx::Size(10, 10), 2605 true); 2606 2607 // Filters make the layer own a surface. 2608 FilterOperations filters; 2609 filters.Append(FilterOperation::CreateBlurFilter(3.f)); 2610 filtered_surface->SetBackgroundFilters(filters); 2611 2612 // Save the distance of influence for the blur effect. 2613 int outset_top, outset_right, outset_bottom, outset_left; 2614 filters.GetOutsets( 2615 &outset_top, &outset_right, &outset_bottom, &outset_left); 2616 2617 this->CalcDrawEtc(parent); 2618 2619 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2620 gfx::Rect(0, 0, 1000, 1000)); 2621 2622 this->VisitLayer(beside_replica_layer, &occlusion); 2623 this->VisitLayer(beside_surface_layer, &occlusion); 2624 this->VisitLayer(above_replica_layer, &occlusion); 2625 this->VisitLayer(above_surface_layer, &occlusion); 2626 2627 // The surface has a background blur, so it blurs non-opaque pixels below 2628 // it. 2629 this->VisitLayer(filtered_surface, &occlusion); 2630 this->VisitContributingSurface(filtered_surface, &occlusion); 2631 2632 // The filter in the surface and replica are partially unoccluded. Only the 2633 // unoccluded parts should reduce occlusion. This means it will push back 2634 // the occlusion that touches the unoccluded part (occlusion_above___), but 2635 // it will not touch occlusion_beside____ since that is not beside the 2636 // unoccluded part of the surface, even though it is beside the occluded 2637 // part of the surface. 2638 gfx::Rect occlusion_above_surface = 2639 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50); 2640 gfx::Rect occlusion_above_replica = 2641 gfx::Rect(200, 50, 30 - outset_left, 50); 2642 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10); 2643 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10); 2644 2645 SimpleEnclosedRegion expected_occlusion; 2646 expected_occlusion.Union(occlusion_beside_replica); 2647 expected_occlusion.Union(occlusion_beside_surface); 2648 expected_occlusion.Union(occlusion_above_replica); 2649 expected_occlusion.Union(occlusion_above_surface); 2650 2651 EXPECT_EQ(expected_occlusion.ToString(), 2652 occlusion.occlusion_from_inside_target().ToString()); 2653 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2654 2655 const SimpleEnclosedRegion& actual_occlusion = 2656 occlusion.occlusion_from_inside_target(); 2657 for (size_t i = 0; i < expected_occlusion.GetRegionComplexity(); ++i) { 2658 ASSERT_LT(i, actual_occlusion.GetRegionComplexity()); 2659 EXPECT_EQ(expected_occlusion.GetRect(i), actual_occlusion.GetRect(i)); 2660 } 2661 } 2662 }; 2663 2664 ALL_OCCLUSIONTRACKER_TEST( 2665 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded); 2666 2667 template <class Types> 2668 class OcclusionTrackerTestMinimumTrackingSize 2669 : public OcclusionTrackerTest<Types> { 2670 protected: 2671 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers) 2672 : OcclusionTrackerTest<Types>(opaque_layers) {} 2673 void RunMyTest() { 2674 gfx::Size tracking_size(100, 100); 2675 gfx::Size below_tracking_size(99, 99); 2676 2677 typename Types::ContentLayerType* parent = this->CreateRoot( 2678 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 2679 typename Types::LayerType* large = this->CreateDrawingLayer( 2680 parent, this->identity_matrix, gfx::PointF(), tracking_size, true); 2681 typename Types::LayerType* small = 2682 this->CreateDrawingLayer(parent, 2683 this->identity_matrix, 2684 gfx::PointF(), 2685 below_tracking_size, 2686 true); 2687 this->CalcDrawEtc(parent); 2688 2689 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2690 gfx::Rect(0, 0, 1000, 1000)); 2691 occlusion.set_minimum_tracking_size(tracking_size); 2692 2693 // The small layer is not tracked because it is too small. 2694 this->VisitLayer(small, &occlusion); 2695 2696 EXPECT_EQ(gfx::Rect().ToString(), 2697 occlusion.occlusion_from_outside_target().ToString()); 2698 EXPECT_EQ(gfx::Rect().ToString(), 2699 occlusion.occlusion_from_inside_target().ToString()); 2700 2701 // The large layer is tracked as it is large enough. 2702 this->VisitLayer(large, &occlusion); 2703 2704 EXPECT_EQ(gfx::Rect().ToString(), 2705 occlusion.occlusion_from_outside_target().ToString()); 2706 EXPECT_EQ(gfx::Rect(tracking_size).ToString(), 2707 occlusion.occlusion_from_inside_target().ToString()); 2708 } 2709 }; 2710 2711 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize); 2712 2713 template <class Types> 2714 class OcclusionTrackerTestScaledLayerIsClipped 2715 : public OcclusionTrackerTest<Types> { 2716 protected: 2717 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers) 2718 : OcclusionTrackerTest<Types>(opaque_layers) {} 2719 void RunMyTest() { 2720 gfx::Transform scale_transform; 2721 scale_transform.Scale(512.0, 512.0); 2722 2723 typename Types::ContentLayerType* parent = this->CreateRoot( 2724 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 2725 typename Types::LayerType* clip = this->CreateLayer(parent, 2726 this->identity_matrix, 2727 gfx::PointF(10.f, 10.f), 2728 gfx::Size(50, 50)); 2729 clip->SetMasksToBounds(true); 2730 typename Types::LayerType* scale = this->CreateLayer( 2731 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1)); 2732 typename Types::LayerType* scaled = this->CreateDrawingLayer( 2733 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); 2734 this->CalcDrawEtc(parent); 2735 2736 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2737 gfx::Rect(0, 0, 1000, 1000)); 2738 2739 this->VisitLayer(scaled, &occlusion); 2740 2741 EXPECT_EQ(gfx::Rect().ToString(), 2742 occlusion.occlusion_from_outside_target().ToString()); 2743 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), 2744 occlusion.occlusion_from_inside_target().ToString()); 2745 } 2746 }; 2747 2748 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped) 2749 2750 template <class Types> 2751 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped 2752 : public OcclusionTrackerTest<Types> { 2753 protected: 2754 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers) 2755 : OcclusionTrackerTest<Types>(opaque_layers) {} 2756 void RunMyTest() { 2757 gfx::Transform scale_transform; 2758 scale_transform.Scale(512.0, 512.0); 2759 2760 typename Types::ContentLayerType* parent = this->CreateRoot( 2761 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 2762 typename Types::LayerType* clip = this->CreateLayer(parent, 2763 this->identity_matrix, 2764 gfx::PointF(10.f, 10.f), 2765 gfx::Size(50, 50)); 2766 clip->SetMasksToBounds(true); 2767 typename Types::LayerType* surface = this->CreateDrawingSurface( 2768 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false); 2769 typename Types::LayerType* scale = this->CreateLayer( 2770 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1)); 2771 typename Types::LayerType* scaled = this->CreateDrawingLayer( 2772 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); 2773 this->CalcDrawEtc(parent); 2774 2775 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2776 gfx::Rect(0, 0, 1000, 1000)); 2777 2778 this->VisitLayer(scaled, &occlusion); 2779 this->VisitLayer(surface, &occlusion); 2780 this->VisitContributingSurface(surface, &occlusion); 2781 2782 EXPECT_EQ(gfx::Rect().ToString(), 2783 occlusion.occlusion_from_outside_target().ToString()); 2784 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), 2785 occlusion.occlusion_from_inside_target().ToString()); 2786 } 2787 }; 2788 2789 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped) 2790 2791 template <class Types> 2792 class OcclusionTrackerTestCopyRequestDoesOcclude 2793 : public OcclusionTrackerTest<Types> { 2794 protected: 2795 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers) 2796 : OcclusionTrackerTest<Types>(opaque_layers) {} 2797 void RunMyTest() { 2798 typename Types::ContentLayerType* root = this->CreateRoot( 2799 this->identity_matrix, gfx::Point(), gfx::Size(400, 400)); 2800 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 2801 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true); 2802 typename Types::LayerType* copy = this->CreateLayer(parent, 2803 this->identity_matrix, 2804 gfx::Point(100, 0), 2805 gfx::Size(200, 400)); 2806 this->AddCopyRequest(copy); 2807 typename Types::LayerType* copy_child = this->CreateDrawingLayer( 2808 copy, 2809 this->identity_matrix, 2810 gfx::PointF(), 2811 gfx::Size(200, 400), 2812 true); 2813 this->CalcDrawEtc(root); 2814 2815 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2816 gfx::Rect(0, 0, 1000, 1000)); 2817 2818 this->VisitLayer(copy_child, &occlusion); 2819 EXPECT_EQ(gfx::Rect().ToString(), 2820 occlusion.occlusion_from_outside_target().ToString()); 2821 EXPECT_EQ(gfx::Rect(200, 400).ToString(), 2822 occlusion.occlusion_from_inside_target().ToString()); 2823 2824 // CopyRequests cause the layer to own a surface. 2825 this->VisitContributingSurface(copy, &occlusion); 2826 2827 // The occlusion from the copy should be kept. 2828 EXPECT_EQ(gfx::Rect().ToString(), 2829 occlusion.occlusion_from_outside_target().ToString()); 2830 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(), 2831 occlusion.occlusion_from_inside_target().ToString()); 2832 } 2833 }; 2834 2835 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude) 2836 2837 template <class Types> 2838 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude 2839 : public OcclusionTrackerTest<Types> { 2840 protected: 2841 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude( 2842 bool opaque_layers) 2843 : OcclusionTrackerTest<Types>(opaque_layers) {} 2844 void RunMyTest() { 2845 typename Types::ContentLayerType* root = this->CreateRoot( 2846 this->identity_matrix, gfx::Point(), gfx::Size(400, 400)); 2847 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 2848 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true); 2849 typename Types::LayerType* hide = this->CreateLayer( 2850 parent, this->identity_matrix, gfx::Point(), gfx::Size()); 2851 typename Types::LayerType* copy = this->CreateLayer( 2852 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400)); 2853 this->AddCopyRequest(copy); 2854 typename Types::LayerType* copy_child = this->CreateDrawingLayer( 2855 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true); 2856 2857 // The |copy| layer is hidden but since it is being copied, it will be 2858 // drawn. 2859 hide->SetHideLayerAndSubtree(true); 2860 2861 this->CalcDrawEtc(root); 2862 2863 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2864 gfx::Rect(0, 0, 1000, 1000)); 2865 2866 this->VisitLayer(copy_child, &occlusion); 2867 EXPECT_EQ(gfx::Rect().ToString(), 2868 occlusion.occlusion_from_outside_target().ToString()); 2869 EXPECT_EQ(gfx::Rect(200, 400).ToString(), 2870 occlusion.occlusion_from_inside_target().ToString()); 2871 2872 // CopyRequests cause the layer to own a surface. 2873 this->VisitContributingSurface(copy, &occlusion); 2874 2875 // The occlusion from the copy should be dropped since it is hidden. 2876 EXPECT_EQ(gfx::Rect().ToString(), 2877 occlusion.occlusion_from_outside_target().ToString()); 2878 EXPECT_EQ(gfx::Rect().ToString(), 2879 occlusion.occlusion_from_inside_target().ToString()); 2880 } 2881 }; 2882 2883 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude) 2884 2885 template <class Types> 2886 class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest<Types> { 2887 protected: 2888 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers) 2889 : OcclusionTrackerTest<Types>(opaque_layers) {} 2890 void RunMyTest() { 2891 gfx::Transform translate; 2892 translate.Translate(10.0, 20.0); 2893 typename Types::ContentLayerType* root = this->CreateRoot( 2894 this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); 2895 typename Types::LayerType* surface = this->CreateSurface( 2896 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); 2897 typename Types::LayerType* layer = this->CreateDrawingLayer( 2898 surface, translate, gfx::Point(), gfx::Size(200, 200), false); 2899 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( 2900 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); 2901 this->CalcDrawEtc(root); 2902 2903 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2904 gfx::Rect(0, 0, 200, 200)); 2905 this->VisitLayer(outside_layer, &occlusion); 2906 this->EnterLayer(layer, &occlusion); 2907 2908 // No occlusion, is not occluded. 2909 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); 2910 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); 2911 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100))); 2912 2913 // Partial occlusion from outside, is not occluded. 2914 occlusion.set_occlusion_from_outside_target( 2915 SimpleEnclosedRegion(50, 50, 100, 100)); 2916 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); 2917 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2918 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); 2919 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); 2920 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); 2921 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); 2922 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); 2923 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); 2924 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); 2925 2926 // Full occlusion from outside, is occluded. 2927 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); 2928 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); 2929 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); 2930 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); 2931 2932 // Partial occlusion from inside, is not occluded. 2933 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); 2934 occlusion.set_occlusion_from_inside_target( 2935 SimpleEnclosedRegion(50, 50, 100, 100)); 2936 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2937 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); 2938 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); 2939 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); 2940 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); 2941 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); 2942 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); 2943 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); 2944 2945 // Full occlusion from inside, is occluded. 2946 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); 2947 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); 2948 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); 2949 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); 2950 2951 // Partial occlusion from both, is not occluded. 2952 occlusion.set_occlusion_from_outside_target( 2953 SimpleEnclosedRegion(50, 50, 100, 50)); 2954 occlusion.set_occlusion_from_inside_target( 2955 SimpleEnclosedRegion(50, 100, 100, 50)); 2956 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2957 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); 2958 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); 2959 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); 2960 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); 2961 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); 2962 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); 2963 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); 2964 2965 // Full occlusion from both, is occluded. 2966 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); 2967 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); 2968 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); 2969 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); 2970 } 2971 }; 2972 2973 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer) 2974 2975 template <class Types> 2976 class OcclusionTrackerTestUnoccludedLayerQuery 2977 : public OcclusionTrackerTest<Types> { 2978 protected: 2979 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers) 2980 : OcclusionTrackerTest<Types>(opaque_layers) {} 2981 void RunMyTest() { 2982 gfx::Transform translate; 2983 translate.Translate(10.0, 20.0); 2984 typename Types::ContentLayerType* root = this->CreateRoot( 2985 this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); 2986 typename Types::LayerType* surface = this->CreateSurface( 2987 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); 2988 typename Types::LayerType* layer = this->CreateDrawingLayer( 2989 surface, translate, gfx::Point(), gfx::Size(200, 200), false); 2990 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( 2991 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); 2992 this->CalcDrawEtc(root); 2993 2994 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 2995 gfx::Rect(0, 0, 200, 200)); 2996 this->VisitLayer(outside_layer, &occlusion); 2997 this->EnterLayer(layer, &occlusion); 2998 2999 // No occlusion, is not occluded. 3000 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); 3001 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); 3002 EXPECT_EQ(gfx::Rect(100, 100), 3003 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(100, 100))); 3004 3005 // Partial occlusion from outside. 3006 occlusion.set_occlusion_from_outside_target( 3007 SimpleEnclosedRegion(50, 50, 100, 100)); 3008 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); 3009 EXPECT_EQ( 3010 gfx::Rect(0, 0, 100, 100), 3011 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); 3012 EXPECT_EQ(gfx::Rect(140, 30, 50, 100), 3013 occlusion.UnoccludedLayerContentRect( 3014 layer, gfx::Rect(90, 30, 100, 100))); 3015 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), 3016 occlusion.UnoccludedLayerContentRect(layer, 3017 gfx::Rect(40, 0, 100, 100))); 3018 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), 3019 occlusion.UnoccludedLayerContentRect( 3020 layer, gfx::Rect(40, 80, 100, 100))); 3021 EXPECT_EQ( 3022 gfx::Rect(0, 0, 80, 100), 3023 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); 3024 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), 3025 occlusion.UnoccludedLayerContentRect( 3026 layer, gfx::Rect(90, 80, 100, 100))); 3027 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), 3028 occlusion.UnoccludedLayerContentRect(layer, 3029 gfx::Rect(0, 80, 100, 100))); 3030 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), 3031 occlusion.UnoccludedLayerContentRect(layer, 3032 gfx::Rect(90, 0, 100, 100))); 3033 3034 // Full occlusion from outside, is occluded. 3035 EXPECT_EQ(gfx::Rect(), 3036 occlusion.UnoccludedLayerContentRect( 3037 layer, gfx::Rect(40, 30, 100, 100))); 3038 EXPECT_EQ( 3039 gfx::Rect(), 3040 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); 3041 EXPECT_EQ(gfx::Rect(), 3042 occlusion.UnoccludedLayerContentRect( 3043 layer, gfx::Rect(130, 120, 10, 10))); 3044 EXPECT_EQ( 3045 gfx::Rect(), 3046 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); 3047 3048 // Partial occlusion from inside, is not occluded. 3049 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); 3050 occlusion.set_occlusion_from_inside_target( 3051 SimpleEnclosedRegion(50, 50, 100, 100)); 3052 EXPECT_EQ( 3053 gfx::Rect(0, 0, 100, 100), 3054 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); 3055 EXPECT_EQ(gfx::Rect(140, 30, 50, 100), 3056 occlusion.UnoccludedLayerContentRect( 3057 layer, gfx::Rect(90, 30, 100, 100))); 3058 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), 3059 occlusion.UnoccludedLayerContentRect(layer, 3060 gfx::Rect(40, 0, 100, 100))); 3061 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), 3062 occlusion.UnoccludedLayerContentRect( 3063 layer, gfx::Rect(40, 80, 100, 100))); 3064 EXPECT_EQ( 3065 gfx::Rect(0, 0, 80, 100), 3066 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); 3067 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), 3068 occlusion.UnoccludedLayerContentRect( 3069 layer, gfx::Rect(90, 80, 100, 100))); 3070 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), 3071 occlusion.UnoccludedLayerContentRect(layer, 3072 gfx::Rect(0, 80, 100, 100))); 3073 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), 3074 occlusion.UnoccludedLayerContentRect(layer, 3075 gfx::Rect(90, 0, 100, 100))); 3076 3077 // Full occlusion from inside, is occluded. 3078 EXPECT_EQ(gfx::Rect(), 3079 occlusion.UnoccludedLayerContentRect( 3080 layer, gfx::Rect(40, 30, 100, 100))); 3081 EXPECT_EQ( 3082 gfx::Rect(), 3083 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); 3084 EXPECT_EQ(gfx::Rect(), 3085 occlusion.UnoccludedLayerContentRect( 3086 layer, gfx::Rect(130, 120, 10, 10))); 3087 EXPECT_EQ( 3088 gfx::Rect(), 3089 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); 3090 3091 // Partial occlusion from both, is not occluded. 3092 occlusion.set_occlusion_from_outside_target( 3093 SimpleEnclosedRegion(50, 50, 100, 50)); 3094 occlusion.set_occlusion_from_inside_target( 3095 SimpleEnclosedRegion(50, 100, 100, 50)); 3096 EXPECT_EQ( 3097 gfx::Rect(0, 0, 100, 100), 3098 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); 3099 // This could be (140, 30, 50, 100). But because we do a lossy subtract, 3100 // it's larger. 3101 EXPECT_EQ(gfx::Rect(90, 30, 100, 100), 3102 occlusion.UnoccludedLayerContentRect( 3103 layer, gfx::Rect(90, 30, 100, 100))); 3104 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), 3105 occlusion.UnoccludedLayerContentRect(layer, 3106 gfx::Rect(40, 0, 100, 100))); 3107 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), 3108 occlusion.UnoccludedLayerContentRect( 3109 layer, gfx::Rect(40, 80, 100, 100))); 3110 EXPECT_EQ( 3111 gfx::Rect(0, 0, 80, 100), 3112 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); 3113 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), 3114 occlusion.UnoccludedLayerContentRect( 3115 layer, gfx::Rect(90, 80, 100, 100))); 3116 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), 3117 occlusion.UnoccludedLayerContentRect(layer, 3118 gfx::Rect(0, 80, 100, 100))); 3119 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), 3120 occlusion.UnoccludedLayerContentRect(layer, 3121 gfx::Rect(90, 0, 100, 100))); 3122 3123 // Full occlusion from both, is occluded. 3124 EXPECT_EQ(gfx::Rect(), 3125 occlusion.UnoccludedLayerContentRect( 3126 layer, gfx::Rect(40, 30, 100, 100))); 3127 EXPECT_EQ( 3128 gfx::Rect(), 3129 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); 3130 EXPECT_EQ(gfx::Rect(), 3131 occlusion.UnoccludedLayerContentRect( 3132 layer, gfx::Rect(130, 120, 10, 10))); 3133 EXPECT_EQ( 3134 gfx::Rect(), 3135 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); 3136 } 3137 }; 3138 3139 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery) 3140 3141 template <class Types> 3142 class OcclusionTrackerTestUnoccludedSurfaceQuery 3143 : public OcclusionTrackerTest<Types> { 3144 protected: 3145 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers) 3146 : OcclusionTrackerTest<Types>(opaque_layers) {} 3147 void RunMyTest() { 3148 gfx::Transform translate; 3149 translate.Translate(10.0, 20.0); 3150 typename Types::ContentLayerType* root = this->CreateRoot( 3151 this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); 3152 typename Types::LayerType* surface = 3153 this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200)); 3154 typename Types::LayerType* layer = 3155 this->CreateDrawingLayer(surface, 3156 this->identity_matrix, 3157 gfx::Point(), 3158 gfx::Size(200, 200), 3159 false); 3160 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( 3161 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); 3162 this->CalcDrawEtc(root); 3163 3164 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( 3165 gfx::Rect(0, 0, 200, 200)); 3166 this->VisitLayer(outside_layer, &occlusion); 3167 this->VisitLayer(layer, &occlusion); 3168 this->EnterContributingSurface(surface, &occlusion); 3169 3170 // No occlusion, is not occluded. 3171 occlusion.set_occlusion_on_contributing_surface_from_outside_target( 3172 SimpleEnclosedRegion()); 3173 occlusion.set_occlusion_on_contributing_surface_from_inside_target( 3174 SimpleEnclosedRegion()); 3175 EXPECT_EQ( 3176 gfx::Rect(100, 100), 3177 occlusion.UnoccludedSurfaceContentRect(surface, gfx::Rect(100, 100))); 3178 3179 // Partial occlusion from outside. 3180 occlusion.set_occlusion_on_contributing_surface_from_outside_target( 3181 SimpleEnclosedRegion(50, 50, 100, 100)); 3182 occlusion.set_occlusion_on_contributing_surface_from_inside_target( 3183 SimpleEnclosedRegion()); 3184 EXPECT_EQ(gfx::Rect(0, 0, 100, 100), 3185 occlusion.UnoccludedSurfaceContentRect( 3186 surface, gfx::Rect(0, 0, 100, 100))); 3187 EXPECT_EQ(gfx::Rect(140, 30, 50, 100), 3188 occlusion.UnoccludedSurfaceContentRect( 3189 surface, gfx::Rect(90, 30, 100, 100))); 3190 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), 3191 occlusion.UnoccludedSurfaceContentRect( 3192 surface, gfx::Rect(40, 0, 100, 100))); 3193 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), 3194 occlusion.UnoccludedSurfaceContentRect( 3195 surface, gfx::Rect(40, 80, 100, 100))); 3196 EXPECT_EQ(gfx::Rect(0, 0, 80, 100), 3197 occlusion.UnoccludedSurfaceContentRect(surface, 3198 gfx::Rect(0, 0, 80, 100))); 3199 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), 3200 occlusion.UnoccludedSurfaceContentRect( 3201 surface, gfx::Rect(90, 80, 100, 100))); 3202 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), 3203 occlusion.UnoccludedSurfaceContentRect( 3204 surface, gfx::Rect(0, 80, 100, 100))); 3205 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), 3206 occlusion.UnoccludedSurfaceContentRect( 3207 surface, gfx::Rect(90, 0, 100, 100))); 3208 3209 // Full occlusion from outside, is occluded. 3210 EXPECT_EQ(gfx::Rect(), 3211 occlusion.UnoccludedSurfaceContentRect( 3212 surface, gfx::Rect(40, 30, 100, 100))); 3213 EXPECT_EQ(gfx::Rect(), 3214 occlusion.UnoccludedSurfaceContentRect( 3215 surface, gfx::Rect(40, 30, 10, 10))); 3216 EXPECT_EQ(gfx::Rect(), 3217 occlusion.UnoccludedSurfaceContentRect( 3218 surface, gfx::Rect(130, 120, 10, 10))); 3219 EXPECT_EQ(gfx::Rect(), 3220 occlusion.UnoccludedSurfaceContentRect( 3221 surface, gfx::Rect(80, 70, 50, 50))); 3222 3223 // Partial occlusion from inside, is not occluded. 3224 occlusion.set_occlusion_on_contributing_surface_from_outside_target( 3225 SimpleEnclosedRegion()); 3226 occlusion.set_occlusion_on_contributing_surface_from_inside_target( 3227 SimpleEnclosedRegion(50, 50, 100, 100)); 3228 EXPECT_EQ(gfx::Rect(0, 0, 100, 100), 3229 occlusion.UnoccludedSurfaceContentRect( 3230 surface, gfx::Rect(0, 0, 100, 100))); 3231 EXPECT_EQ(gfx::Rect(140, 30, 50, 100), 3232 occlusion.UnoccludedSurfaceContentRect( 3233 surface, gfx::Rect(90, 30, 100, 100))); 3234 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), 3235 occlusion.UnoccludedSurfaceContentRect( 3236 surface, gfx::Rect(40, 0, 100, 100))); 3237 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), 3238 occlusion.UnoccludedSurfaceContentRect( 3239 surface, gfx::Rect(40, 80, 100, 100))); 3240 EXPECT_EQ(gfx::Rect(0, 0, 80, 100), 3241 occlusion.UnoccludedSurfaceContentRect(surface, 3242 gfx::Rect(0, 0, 80, 100))); 3243 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), 3244 occlusion.UnoccludedSurfaceContentRect( 3245 surface, gfx::Rect(90, 80, 100, 100))); 3246 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), 3247 occlusion.UnoccludedSurfaceContentRect( 3248 surface, gfx::Rect(0, 80, 100, 100))); 3249 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), 3250 occlusion.UnoccludedSurfaceContentRect( 3251 surface, gfx::Rect(90, 0, 100, 100))); 3252 3253 // Full occlusion from inside, is occluded. 3254 EXPECT_EQ(gfx::Rect(), 3255 occlusion.UnoccludedSurfaceContentRect( 3256 surface, gfx::Rect(40, 30, 100, 100))); 3257 EXPECT_EQ(gfx::Rect(), 3258 occlusion.UnoccludedSurfaceContentRect( 3259 surface, gfx::Rect(40, 30, 10, 10))); 3260 EXPECT_EQ(gfx::Rect(), 3261 occlusion.UnoccludedSurfaceContentRect( 3262 surface, gfx::Rect(130, 120, 10, 10))); 3263 EXPECT_EQ(gfx::Rect(), 3264 occlusion.UnoccludedSurfaceContentRect( 3265 surface, gfx::Rect(80, 70, 50, 50))); 3266 3267 // Partial occlusion from both, is not occluded. 3268 occlusion.set_occlusion_on_contributing_surface_from_outside_target( 3269 SimpleEnclosedRegion(50, 50, 100, 50)); 3270 occlusion.set_occlusion_on_contributing_surface_from_inside_target( 3271 SimpleEnclosedRegion(50, 100, 100, 50)); 3272 EXPECT_EQ(gfx::Rect(0, 0, 100, 100), 3273 occlusion.UnoccludedSurfaceContentRect( 3274 surface, gfx::Rect(0, 0, 100, 100))); 3275 // This could be (140, 30, 50, 100). But because we do a lossy subtract, 3276 // it's larger. 3277 EXPECT_EQ(gfx::Rect(90, 30, 100, 100), 3278 occlusion.UnoccludedSurfaceContentRect( 3279 surface, gfx::Rect(90, 30, 100, 100))); 3280 EXPECT_EQ(gfx::Rect(40, 0, 100, 30), 3281 occlusion.UnoccludedSurfaceContentRect( 3282 surface, gfx::Rect(40, 0, 100, 100))); 3283 EXPECT_EQ(gfx::Rect(40, 130, 100, 50), 3284 occlusion.UnoccludedSurfaceContentRect( 3285 surface, gfx::Rect(40, 80, 100, 100))); 3286 EXPECT_EQ(gfx::Rect(0, 0, 80, 100), 3287 occlusion.UnoccludedSurfaceContentRect(surface, 3288 gfx::Rect(0, 0, 80, 100))); 3289 EXPECT_EQ(gfx::Rect(90, 80, 100, 100), 3290 occlusion.UnoccludedSurfaceContentRect( 3291 surface, gfx::Rect(90, 80, 100, 100))); 3292 EXPECT_EQ(gfx::Rect(0, 80, 100, 100), 3293 occlusion.UnoccludedSurfaceContentRect( 3294 surface, gfx::Rect(0, 80, 100, 100))); 3295 EXPECT_EQ(gfx::Rect(90, 0, 100, 100), 3296 occlusion.UnoccludedSurfaceContentRect( 3297 surface, gfx::Rect(90, 0, 100, 100))); 3298 3299 // Full occlusion from both, is occluded. 3300 EXPECT_EQ(gfx::Rect(), 3301 occlusion.UnoccludedSurfaceContentRect( 3302 surface, gfx::Rect(40, 30, 100, 100))); 3303 EXPECT_EQ(gfx::Rect(), 3304 occlusion.UnoccludedSurfaceContentRect( 3305 surface, gfx::Rect(40, 30, 10, 10))); 3306 EXPECT_EQ(gfx::Rect(), 3307 occlusion.UnoccludedSurfaceContentRect( 3308 surface, gfx::Rect(130, 120, 10, 10))); 3309 EXPECT_EQ(gfx::Rect(), 3310 occlusion.UnoccludedSurfaceContentRect( 3311 surface, gfx::Rect(80, 70, 50, 50))); 3312 } 3313 }; 3314 3315 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery) 3316 3317 } // namespace 3318 } // namespace cc 3319