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/debug/overdraw_metrics.h" 10 #include "cc/layers/layer.h" 11 #include "cc/layers/layer_impl.h" 12 #include "cc/output/copy_output_request.h" 13 #include "cc/output/copy_output_result.h" 14 #include "cc/output/filter_operation.h" 15 #include "cc/output/filter_operations.h" 16 #include "cc/test/animation_test_common.h" 17 #include "cc/test/fake_impl_proxy.h" 18 #include "cc/test/fake_layer_tree_host.h" 19 #include "cc/test/fake_layer_tree_host_impl.h" 20 #include "cc/test/geometry_test_utils.h" 21 #include "cc/test/occlusion_tracker_test_common.h" 22 #include "cc/trees/layer_tree_host_common.h" 23 #include "cc/trees/single_thread_proxy.h" 24 #include "testing/gmock/include/gmock/gmock.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 #include "ui/gfx/transform.h" 27 28 namespace cc { 29 namespace { 30 31 class TestContentLayer : public Layer { 32 public: 33 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {} 34 35 virtual bool DrawsContent() const OVERRIDE { return true; } 36 virtual Region VisibleContentOpaqueRegion() const OVERRIDE { 37 if (override_opaque_contents_rect_) 38 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()); 39 return Layer::VisibleContentOpaqueRegion(); 40 } 41 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) { 42 override_opaque_contents_rect_ = true; 43 opaque_contents_rect_ = opaque_contents_rect; 44 } 45 46 private: 47 virtual ~TestContentLayer() {} 48 49 bool override_opaque_contents_rect_; 50 gfx::Rect opaque_contents_rect_; 51 }; 52 53 class TestContentLayerImpl : public LayerImpl { 54 public: 55 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id) 56 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) { 57 SetDrawsContent(true); 58 } 59 60 virtual Region VisibleContentOpaqueRegion() const OVERRIDE { 61 if (override_opaque_contents_rect_) 62 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()); 63 return LayerImpl::VisibleContentOpaqueRegion(); 64 } 65 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) { 66 override_opaque_contents_rect_ = true; 67 opaque_contents_rect_ = opaque_contents_rect; 68 } 69 70 private: 71 bool override_opaque_contents_rect_; 72 gfx::Rect opaque_contents_rect_; 73 }; 74 75 static inline bool LayerImplDrawTransformIsUnknown(const Layer* layer) { 76 return layer->draw_transform_is_animating(); 77 } 78 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl* layer) { 79 return false; 80 } 81 82 template <typename LayerType, typename RenderSurfaceType> 83 class TestOcclusionTrackerWithClip 84 : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> { 85 public: 86 TestOcclusionTrackerWithClip(gfx::Rect viewport_rect, 87 bool record_metrics_for_frame) 88 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>( 89 viewport_rect, 90 record_metrics_for_frame) {} 91 explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect) 92 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewport_rect, 93 false) {} 94 95 bool OccludedLayer(const LayerType* layer, gfx::Rect content_rect) { 96 bool temp; 97 return OccludedLayer(layer, content_rect, &temp); 98 } 99 100 bool OccludedLayer(const LayerType* layer, 101 gfx::Rect content_rect, 102 bool* has_occlusion_from_outside_target_surface) const { 103 return this->Occluded(layer->render_target(), 104 content_rect, 105 layer->draw_transform(), 106 LayerImplDrawTransformIsUnknown(layer), 107 layer->is_clipped(), 108 layer->clip_rect(), 109 has_occlusion_from_outside_target_surface); 110 } 111 // Gives an unoccluded sub-rect of |content_rect| in the content space of the 112 // layer. Simple wrapper around UnoccludedContentRect. 113 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer, 114 gfx::Rect content_rect) const { 115 bool temp; 116 return UnoccludedLayerContentRect(layer, content_rect, &temp); 117 } 118 119 gfx::Rect UnoccludedLayerContentRect( 120 const LayerType* layer, 121 gfx::Rect content_rect, 122 bool* has_occlusion_from_outside_target_surface) const { 123 return this->UnoccludedContentRect( 124 layer->render_target(), 125 content_rect, 126 layer->draw_transform(), 127 LayerImplDrawTransformIsUnknown(layer), 128 layer->is_clipped(), 129 layer->clip_rect(), 130 has_occlusion_from_outside_target_surface); 131 } 132 }; 133 134 struct OcclusionTrackerTestMainThreadTypes { 135 typedef Layer LayerType; 136 typedef FakeLayerTreeHost HostType; 137 typedef RenderSurface RenderSurfaceType; 138 typedef TestContentLayer ContentLayerType; 139 typedef scoped_refptr<Layer> LayerPtrType; 140 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType; 141 typedef LayerIterator<Layer, 142 RenderSurfaceLayerList, 143 RenderSurface, 144 LayerIteratorActions::FrontToBack> TestLayerIterator; 145 typedef OcclusionTracker OcclusionTrackerType; 146 147 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); } 148 static ContentLayerPtrType CreateContentLayer(HostType* host) { 149 return make_scoped_refptr(new ContentLayerType()); 150 } 151 152 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) { 153 LayerPtrType ref(*layer); 154 *layer = NULL; 155 return ref; 156 } 157 158 static LayerPtrType PassLayerPtr(LayerPtrType* layer) { 159 LayerPtrType ref(*layer); 160 *layer = NULL; 161 return ref; 162 } 163 164 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; } 165 }; 166 167 struct OcclusionTrackerTestImplThreadTypes { 168 typedef LayerImpl LayerType; 169 typedef LayerTreeImpl HostType; 170 typedef RenderSurfaceImpl RenderSurfaceType; 171 typedef TestContentLayerImpl ContentLayerType; 172 typedef scoped_ptr<LayerImpl> LayerPtrType; 173 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType; 174 typedef LayerIterator<LayerImpl, 175 LayerImplList, 176 RenderSurfaceImpl, 177 LayerIteratorActions::FrontToBack> TestLayerIterator; 178 typedef OcclusionTrackerImpl OcclusionTrackerType; 179 180 static LayerPtrType CreateLayer(HostType* host) { 181 return LayerImpl::Create(host, next_layer_impl_id++); 182 } 183 static ContentLayerPtrType CreateContentLayer(HostType* host) { 184 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++)); 185 } 186 static int next_layer_impl_id; 187 188 static LayerPtrType PassLayerPtr(LayerPtrType* layer) { 189 return layer->Pass(); 190 } 191 192 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) { 193 return layer->PassAs<LayerType>(); 194 } 195 196 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); } 197 }; 198 199 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1; 200 201 template <typename Types> class OcclusionTrackerTest : public testing::Test { 202 protected: 203 explicit OcclusionTrackerTest(bool opaque_layers) 204 : opaque_layers_(opaque_layers), host_(FakeLayerTreeHost::Create()) {} 205 206 virtual void RunMyTest() = 0; 207 208 virtual void TearDown() { 209 Types::DestroyLayer(&root_); 210 render_surface_layer_list_.reset(); 211 render_surface_layer_list_impl_.clear(); 212 replica_layers_.clear(); 213 mask_layers_.clear(); 214 } 215 216 typename Types::HostType* GetHost(); 217 218 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform, 219 gfx::PointF position, 220 gfx::Size bounds) { 221 typename Types::ContentLayerPtrType layer( 222 Types::CreateContentLayer(GetHost())); 223 typename Types::ContentLayerType* layer_ptr = layer.get(); 224 SetProperties(layer_ptr, transform, position, bounds); 225 226 DCHECK(!root_.get()); 227 root_ = Types::PassLayerPtr(&layer); 228 229 SetRootLayerOnMainThread(layer_ptr); 230 231 return layer_ptr; 232 } 233 234 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent, 235 const gfx::Transform& transform, 236 gfx::PointF position, 237 gfx::Size bounds) { 238 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost())); 239 typename Types::LayerType* layer_ptr = layer.get(); 240 SetProperties(layer_ptr, transform, position, bounds); 241 parent->AddChild(Types::PassLayerPtr(&layer)); 242 return layer_ptr; 243 } 244 245 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent, 246 const gfx::Transform& transform, 247 gfx::PointF position, 248 gfx::Size bounds) { 249 typename Types::LayerType* layer = 250 CreateLayer(parent, transform, position, bounds); 251 layer->SetForceRenderSurface(true); 252 return layer; 253 } 254 255 typename Types::ContentLayerType* CreateDrawingLayer( 256 typename Types::LayerType* parent, 257 const gfx::Transform& transform, 258 gfx::PointF position, 259 gfx::Size bounds, 260 bool opaque) { 261 typename Types::ContentLayerPtrType layer( 262 Types::CreateContentLayer(GetHost())); 263 typename Types::ContentLayerType* layer_ptr = layer.get(); 264 SetProperties(layer_ptr, transform, position, bounds); 265 266 if (opaque_layers_) { 267 layer_ptr->SetContentsOpaque(opaque); 268 } else { 269 layer_ptr->SetContentsOpaque(false); 270 if (opaque) 271 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds)); 272 else 273 layer_ptr->SetOpaqueContentsRect(gfx::Rect()); 274 } 275 276 parent->AddChild(Types::PassLayerPtr(&layer)); 277 return layer_ptr; 278 } 279 280 typename Types::LayerType* CreateReplicaLayer( 281 typename Types::LayerType* owning_layer, 282 const gfx::Transform& transform, 283 gfx::PointF position, 284 gfx::Size bounds) { 285 typename Types::ContentLayerPtrType layer( 286 Types::CreateContentLayer(GetHost())); 287 typename Types::ContentLayerType* layer_ptr = layer.get(); 288 SetProperties(layer_ptr, transform, position, bounds); 289 SetReplica(owning_layer, Types::PassLayerPtr(&layer)); 290 return layer_ptr; 291 } 292 293 typename Types::LayerType* CreateMaskLayer( 294 typename Types::LayerType* owning_layer, 295 gfx::Size bounds) { 296 typename Types::ContentLayerPtrType layer( 297 Types::CreateContentLayer(GetHost())); 298 typename Types::ContentLayerType* layer_ptr = layer.get(); 299 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds); 300 SetMask(owning_layer, Types::PassLayerPtr(&layer)); 301 return layer_ptr; 302 } 303 304 typename Types::ContentLayerType* CreateDrawingSurface( 305 typename Types::LayerType* parent, 306 const gfx::Transform& transform, 307 gfx::PointF position, 308 gfx::Size bounds, 309 bool opaque) { 310 typename Types::ContentLayerType* layer = 311 CreateDrawingLayer(parent, transform, position, bounds, opaque); 312 layer->SetForceRenderSurface(true); 313 return layer; 314 } 315 316 317 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} 318 319 void AddCopyRequest(Layer* layer) { 320 layer->RequestCopyOfOutput( 321 CopyOutputRequest::CreateBitmapRequest(base::Bind( 322 &OcclusionTrackerTest<Types>::CopyOutputCallback, 323 base::Unretained(this)))); 324 } 325 326 void AddCopyRequest(LayerImpl* layer) { 327 ScopedPtrVector<CopyOutputRequest> requests; 328 requests.push_back( 329 CopyOutputRequest::CreateBitmapRequest(base::Bind( 330 &OcclusionTrackerTest<Types>::CopyOutputCallback, 331 base::Unretained(this)))); 332 layer->PassCopyRequests(&requests); 333 } 334 335 void CalcDrawEtc(TestContentLayerImpl* root) { 336 DCHECK(root == root_.get()); 337 DCHECK(!root->render_surface()); 338 339 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 340 root, root->bounds(), &render_surface_layer_list_impl_); 341 inputs.can_adjust_raster_scales = true; 342 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 343 344 layer_iterator_ = layer_iterator_begin_ = 345 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_); 346 } 347 348 void CalcDrawEtc(TestContentLayer* root) { 349 DCHECK(root == root_.get()); 350 DCHECK(!root->render_surface()); 351 352 render_surface_layer_list_.reset(new RenderSurfaceLayerList); 353 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 354 root, root->bounds(), render_surface_layer_list_.get()); 355 inputs.can_adjust_raster_scales = true; 356 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 357 358 layer_iterator_ = layer_iterator_begin_ = 359 Types::TestLayerIterator::Begin(render_surface_layer_list_.get()); 360 } 361 362 void EnterLayer(typename Types::LayerType* layer, 363 typename Types::OcclusionTrackerType* occlusion, 364 bool prevent_occlusion) { 365 ASSERT_EQ(layer, *layer_iterator_); 366 ASSERT_TRUE(layer_iterator_.represents_itself()); 367 occlusion->EnterLayer(layer_iterator_, prevent_occlusion); 368 } 369 370 void LeaveLayer(typename Types::LayerType* layer, 371 typename Types::OcclusionTrackerType* occlusion) { 372 ASSERT_EQ(layer, *layer_iterator_); 373 ASSERT_TRUE(layer_iterator_.represents_itself()); 374 occlusion->LeaveLayer(layer_iterator_); 375 ++layer_iterator_; 376 } 377 378 void VisitLayer(typename Types::LayerType* layer, 379 typename Types::OcclusionTrackerType* occlusion) { 380 EnterLayer(layer, occlusion, false); 381 LeaveLayer(layer, occlusion); 382 } 383 384 void EnterContributingSurface( 385 typename Types::LayerType* layer, 386 typename Types::OcclusionTrackerType* occlusion, 387 bool prevent_occlusion) { 388 ASSERT_EQ(layer, *layer_iterator_); 389 ASSERT_TRUE(layer_iterator_.represents_target_render_surface()); 390 occlusion->EnterLayer(layer_iterator_, false); 391 occlusion->LeaveLayer(layer_iterator_); 392 ++layer_iterator_; 393 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface()); 394 occlusion->EnterLayer(layer_iterator_, prevent_occlusion); 395 } 396 397 void LeaveContributingSurface( 398 typename Types::LayerType* layer, 399 typename Types::OcclusionTrackerType* occlusion) { 400 ASSERT_EQ(layer, *layer_iterator_); 401 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface()); 402 occlusion->LeaveLayer(layer_iterator_); 403 ++layer_iterator_; 404 } 405 406 void VisitContributingSurface( 407 typename Types::LayerType* layer, 408 typename Types::OcclusionTrackerType* occlusion) { 409 EnterContributingSurface(layer, occlusion, false); 410 LeaveContributingSurface(layer, occlusion); 411 } 412 413 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; } 414 415 const gfx::Transform identity_matrix; 416 417 private: 418 void SetRootLayerOnMainThread(Layer* root) { 419 host_->SetRootLayer(scoped_refptr<Layer>(root)); 420 } 421 422 void SetRootLayerOnMainThread(LayerImpl* root) {} 423 424 void SetBaseProperties(typename Types::LayerType* layer, 425 const gfx::Transform& transform, 426 gfx::PointF position, 427 gfx::Size bounds) { 428 layer->SetTransform(transform); 429 layer->SetSublayerTransform(gfx::Transform()); 430 layer->SetAnchorPoint(gfx::PointF()); 431 layer->SetPosition(position); 432 layer->SetBounds(bounds); 433 } 434 435 void SetProperties(Layer* layer, 436 const gfx::Transform& transform, 437 gfx::PointF position, 438 gfx::Size bounds) { 439 SetBaseProperties(layer, transform, position, bounds); 440 } 441 442 void SetProperties(LayerImpl* layer, 443 const gfx::Transform& transform, 444 gfx::PointF position, 445 gfx::Size bounds) { 446 SetBaseProperties(layer, transform, position, bounds); 447 448 layer->SetContentBounds(layer->bounds()); 449 } 450 451 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) { 452 owning_layer->SetReplicaLayer(layer.get()); 453 replica_layers_.push_back(layer); 454 } 455 456 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) { 457 owning_layer->SetReplicaLayer(layer.Pass()); 458 } 459 460 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) { 461 owning_layer->SetMaskLayer(layer.get()); 462 mask_layers_.push_back(layer); 463 } 464 465 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) { 466 owning_layer->SetMaskLayer(layer.Pass()); 467 } 468 469 bool opaque_layers_; 470 scoped_ptr<FakeLayerTreeHost> host_; 471 // These hold ownership of the layers for the duration of the test. 472 typename Types::LayerPtrType root_; 473 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_; 474 LayerImplList render_surface_layer_list_impl_; 475 typename Types::TestLayerIterator layer_iterator_begin_; 476 typename Types::TestLayerIterator layer_iterator_; 477 typename Types::LayerType* last_layer_visited_; 478 LayerList replica_layers_; 479 LayerList mask_layers_; 480 }; 481 482 template <> 483 FakeLayerTreeHost* 484 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() { 485 return host_.get(); 486 } 487 488 template <> 489 LayerTreeImpl* 490 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() { 491 return host_->host_impl()->active_tree(); 492 } 493 494 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ 495 class ClassName##MainThreadOpaqueLayers \ 496 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \ 497 public: /* NOLINT(whitespace/indent) */ \ 498 ClassName##MainThreadOpaqueLayers() \ 499 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \ 500 }; \ 501 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); } 502 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \ 503 class ClassName##MainThreadOpaquePaints \ 504 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \ 505 public: /* NOLINT(whitespace/indent) */ \ 506 ClassName##MainThreadOpaquePaints() \ 507 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \ 508 }; \ 509 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); } 510 511 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \ 512 class ClassName##ImplThreadOpaqueLayers \ 513 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \ 514 public: /* NOLINT(whitespace/indent) */ \ 515 ClassName##ImplThreadOpaqueLayers() \ 516 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \ 517 }; \ 518 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); } 519 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \ 520 class ClassName##ImplThreadOpaquePaints \ 521 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \ 522 public: /* NOLINT(whitespace/indent) */ \ 523 ClassName##ImplThreadOpaquePaints() \ 524 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \ 525 }; \ 526 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); } 527 528 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \ 529 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ 530 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \ 531 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \ 532 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) 533 534 #define MAIN_THREAD_TEST(ClassName) \ 535 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) 536 537 #define IMPL_THREAD_TEST(ClassName) \ 538 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) 539 540 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \ 541 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ 542 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) 543 544 template <class Types> 545 class OcclusionTrackerTestIdentityTransforms 546 : public OcclusionTrackerTest<Types> { 547 protected: 548 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers) 549 : OcclusionTrackerTest<Types>(opaque_layers) {} 550 551 void RunMyTest() { 552 typename Types::ContentLayerType* root = this->CreateRoot( 553 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 554 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 555 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 556 typename Types::ContentLayerType* layer = 557 this->CreateDrawingLayer(parent, 558 this->identity_matrix, 559 gfx::PointF(30.f, 30.f), 560 gfx::Size(500, 500), 561 true); 562 parent->SetMasksToBounds(true); 563 this->CalcDrawEtc(root); 564 565 TestOcclusionTrackerWithClip<typename Types::LayerType, 566 typename Types::RenderSurfaceType> occlusion( 567 gfx::Rect(0, 0, 1000, 1000), false); 568 569 this->VisitLayer(layer, &occlusion); 570 this->EnterLayer(parent, &occlusion, false); 571 572 EXPECT_EQ(gfx::Rect().ToString(), 573 occlusion.occlusion_from_outside_target().ToString()); 574 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), 575 occlusion.occlusion_from_inside_target().ToString()); 576 577 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70))); 578 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70))); 579 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70))); 580 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70))); 581 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70))); 582 583 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 584 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty()); 585 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), 586 occlusion.UnoccludedLayerContentRect( 587 parent, gfx::Rect(29, 30, 70, 70))); 588 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), 589 occlusion.UnoccludedLayerContentRect( 590 parent, gfx::Rect(29, 29, 70, 70))); 591 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), 592 occlusion.UnoccludedLayerContentRect( 593 parent, gfx::Rect(30, 29, 70, 70))); 594 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1), 595 occlusion.UnoccludedLayerContentRect( 596 parent, gfx::Rect(31, 29, 70, 70))); 597 EXPECT_RECT_EQ(gfx::Rect(), 598 occlusion.UnoccludedLayerContentRect( 599 parent, gfx::Rect(31, 30, 70, 70))); 600 EXPECT_RECT_EQ(gfx::Rect(), 601 occlusion.UnoccludedLayerContentRect( 602 parent, gfx::Rect(31, 31, 70, 70))); 603 EXPECT_RECT_EQ(gfx::Rect(), 604 occlusion.UnoccludedLayerContentRect( 605 parent, gfx::Rect(30, 31, 70, 70))); 606 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69), 607 occlusion.UnoccludedLayerContentRect( 608 parent, gfx::Rect(29, 31, 70, 70))); 609 } 610 }; 611 612 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms); 613 614 template <class Types> 615 class OcclusionTrackerTestQuadsMismatchLayer 616 : public OcclusionTrackerTest<Types> { 617 protected: 618 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers) 619 : OcclusionTrackerTest<Types>(opaque_layers) {} 620 void RunMyTest() { 621 gfx::Transform layer_transform; 622 layer_transform.Translate(10.0, 10.0); 623 624 typename Types::ContentLayerType* parent = this->CreateRoot( 625 this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100)); 626 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer( 627 parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true); 628 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer( 629 layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true); 630 this->CalcDrawEtc(parent); 631 632 TestOcclusionTrackerWithClip<typename Types::LayerType, 633 typename Types::RenderSurfaceType> occlusion( 634 gfx::Rect(0, 0, 1000, 1000)); 635 636 this->VisitLayer(layer2, &occlusion); 637 this->EnterLayer(layer1, &occlusion, false); 638 639 EXPECT_EQ(gfx::Rect().ToString(), 640 occlusion.occlusion_from_outside_target().ToString()); 641 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), 642 occlusion.occlusion_from_inside_target().ToString()); 643 644 // This checks cases where the quads don't match their "containing" 645 // layers, e.g. in terms of transforms or clip rect. This is typical for 646 // DelegatedRendererLayer. 647 648 gfx::Transform quad_transform; 649 quad_transform.Translate(30.0, 30.0); 650 gfx::Rect clip_rect_in_target(0, 0, 100, 100); 651 652 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent, 653 gfx::Rect(0, 0, 10, 10), 654 quad_transform, 655 false, 656 true, 657 clip_rect_in_target, 658 NULL).IsEmpty()); 659 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10), 660 occlusion.UnoccludedContentRect(parent, 661 gfx::Rect(0, 0, 10, 10), 662 quad_transform, 663 true, 664 true, 665 clip_rect_in_target, 666 NULL)); 667 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), 668 occlusion.UnoccludedContentRect(parent, 669 gfx::Rect(40, 40, 10, 10), 670 quad_transform, 671 false, 672 true, 673 clip_rect_in_target, 674 NULL)); 675 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), 676 occlusion.UnoccludedContentRect(parent, 677 gfx::Rect(35, 30, 10, 10), 678 quad_transform, 679 false, 680 true, 681 clip_rect_in_target, 682 NULL)); 683 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5), 684 occlusion.UnoccludedContentRect(parent, 685 gfx::Rect(40, 40, 10, 10), 686 quad_transform, 687 false, 688 true, 689 gfx::Rect(0, 0, 75, 75), 690 NULL)); 691 } 692 }; 693 694 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer); 695 696 template <class Types> 697 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> { 698 protected: 699 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers) 700 : OcclusionTrackerTest<Types>(opaque_layers) {} 701 void RunMyTest() { 702 gfx::Transform layer_transform; 703 layer_transform.Translate(250.0, 250.0); 704 layer_transform.Rotate(90.0); 705 layer_transform.Translate(-250.0, -250.0); 706 707 typename Types::ContentLayerType* root = this->CreateRoot( 708 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200)); 709 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 710 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 711 typename Types::ContentLayerType* layer = 712 this->CreateDrawingLayer(parent, 713 layer_transform, 714 gfx::PointF(30.f, 30.f), 715 gfx::Size(500, 500), 716 true); 717 parent->SetMasksToBounds(true); 718 this->CalcDrawEtc(root); 719 720 TestOcclusionTrackerWithClip<typename Types::LayerType, 721 typename Types::RenderSurfaceType> occlusion( 722 gfx::Rect(0, 0, 1000, 1000)); 723 724 this->VisitLayer(layer, &occlusion); 725 this->EnterLayer(parent, &occlusion, false); 726 727 EXPECT_EQ(gfx::Rect().ToString(), 728 occlusion.occlusion_from_outside_target().ToString()); 729 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), 730 occlusion.occlusion_from_inside_target().ToString()); 731 732 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70))); 733 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70))); 734 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70))); 735 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70))); 736 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70))); 737 738 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 739 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty()); 740 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), 741 occlusion.UnoccludedLayerContentRect( 742 parent, gfx::Rect(29, 30, 70, 70))); 743 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), 744 occlusion.UnoccludedLayerContentRect( 745 parent, gfx::Rect(29, 29, 70, 70))); 746 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), 747 occlusion.UnoccludedLayerContentRect( 748 parent, gfx::Rect(30, 29, 70, 70))); 749 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1), 750 occlusion.UnoccludedLayerContentRect( 751 parent, gfx::Rect(31, 29, 70, 70))); 752 EXPECT_RECT_EQ(gfx::Rect(), 753 occlusion.UnoccludedLayerContentRect( 754 parent, gfx::Rect(31, 30, 70, 70))); 755 EXPECT_RECT_EQ(gfx::Rect(), 756 occlusion.UnoccludedLayerContentRect( 757 parent, gfx::Rect(31, 31, 70, 70))); 758 EXPECT_RECT_EQ(gfx::Rect(), 759 occlusion.UnoccludedLayerContentRect( 760 parent, gfx::Rect(30, 31, 70, 70))); 761 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69), 762 occlusion.UnoccludedLayerContentRect( 763 parent, gfx::Rect(29, 31, 70, 70))); 764 } 765 }; 766 767 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild); 768 769 template <class Types> 770 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> { 771 protected: 772 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers) 773 : OcclusionTrackerTest<Types>(opaque_layers) {} 774 void RunMyTest() { 775 gfx::Transform layer_transform; 776 layer_transform.Translate(20.0, 20.0); 777 778 typename Types::ContentLayerType* root = this->CreateRoot( 779 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 780 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 781 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 782 typename Types::ContentLayerType* layer = 783 this->CreateDrawingLayer(parent, 784 layer_transform, 785 gfx::PointF(30.f, 30.f), 786 gfx::Size(500, 500), 787 true); 788 parent->SetMasksToBounds(true); 789 this->CalcDrawEtc(root); 790 791 TestOcclusionTrackerWithClip<typename Types::LayerType, 792 typename Types::RenderSurfaceType> occlusion( 793 gfx::Rect(0, 0, 1000, 1000)); 794 795 this->VisitLayer(layer, &occlusion); 796 this->EnterLayer(parent, &occlusion, false); 797 798 EXPECT_EQ(gfx::Rect().ToString(), 799 occlusion.occlusion_from_outside_target().ToString()); 800 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), 801 occlusion.occlusion_from_inside_target().ToString()); 802 803 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50))); 804 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50))); 805 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50))); 806 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 50, 50))); 807 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 50))); 808 809 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 810 parent, gfx::Rect(50, 50, 50, 50)).IsEmpty()); 811 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), 812 occlusion.UnoccludedLayerContentRect( 813 parent, gfx::Rect(49, 50, 50, 50))); 814 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), 815 occlusion.UnoccludedLayerContentRect( 816 parent, gfx::Rect(49, 49, 50, 50))); 817 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), 818 occlusion.UnoccludedLayerContentRect( 819 parent, gfx::Rect(50, 49, 50, 50))); 820 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1), 821 occlusion.UnoccludedLayerContentRect( 822 parent, gfx::Rect(51, 49, 50, 50))); 823 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 824 parent, gfx::Rect(51, 50, 50, 50)).IsEmpty()); 825 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 826 parent, gfx::Rect(51, 51, 50, 50)).IsEmpty()); 827 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 828 parent, gfx::Rect(50, 51, 50, 50)).IsEmpty()); 829 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49), 830 occlusion.UnoccludedLayerContentRect( 831 parent, gfx::Rect(49, 51, 50, 50))); 832 } 833 }; 834 835 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild); 836 837 template <class Types> 838 class OcclusionTrackerTestChildInRotatedChild 839 : public OcclusionTrackerTest<Types> { 840 protected: 841 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers) 842 : OcclusionTrackerTest<Types>(opaque_layers) {} 843 void RunMyTest() { 844 gfx::Transform child_transform; 845 child_transform.Translate(250.0, 250.0); 846 child_transform.Rotate(90.0); 847 child_transform.Translate(-250.0, -250.0); 848 849 typename Types::ContentLayerType* parent = this->CreateRoot( 850 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 851 parent->SetMasksToBounds(true); 852 typename Types::LayerType* child = this->CreateSurface( 853 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); 854 child->SetMasksToBounds(true); 855 typename Types::ContentLayerType* layer = 856 this->CreateDrawingLayer(child, 857 this->identity_matrix, 858 gfx::PointF(10.f, 10.f), 859 gfx::Size(500, 500), 860 true); 861 this->CalcDrawEtc(parent); 862 863 TestOcclusionTrackerWithClip<typename Types::LayerType, 864 typename Types::RenderSurfaceType> occlusion( 865 gfx::Rect(0, 0, 1000, 1000)); 866 867 this->VisitLayer(layer, &occlusion); 868 this->EnterContributingSurface(child, &occlusion, false); 869 870 EXPECT_EQ(gfx::Rect().ToString(), 871 occlusion.occlusion_from_outside_target().ToString()); 872 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), 873 occlusion.occlusion_from_inside_target().ToString()); 874 875 this->LeaveContributingSurface(child, &occlusion); 876 this->EnterLayer(parent, &occlusion, false); 877 878 EXPECT_EQ(gfx::Rect().ToString(), 879 occlusion.occlusion_from_outside_target().ToString()); 880 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), 881 occlusion.occlusion_from_inside_target().ToString()); 882 883 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60))); 884 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60))); 885 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60))); 886 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 70, 60))); 887 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 60))); 888 889 /* Justification for the above occlusion from |layer|: 890 100 891 +---------------------+ 892 | | 893 | 30 | rotate(90) 894 | 30 + ---------------------------------+ 895 100 | | 10 | | ==> 896 | |10+---------------------------------+ 897 | | | | | | 898 | | | | | | 899 | | | | | | 900 +----|--|-------------+ | | 901 | | | | 902 | | | | 903 | | | |500 904 | | | | 905 | | | | 906 | | | | 907 | | | | 908 +--|-------------------------------+ | 909 | | 910 +---------------------------------+ 911 500 912 913 +---------------------+ 914 | |30 Visible region of |layer|: ///// 915 | | 916 | +---------------------------------+ 917 100| | |10 | 918 | +---------------------------------+ | 919 | | |///////////////| 420 | | 920 | | |///////////////|60 | | 921 | | |///////////////| | | 922 +--|--|---------------+ | | 923 20|10| 70 | | 924 | | | | 925 | | | | 926 | | | | 927 | | | | 928 | | | | 929 | | |10| 930 | +------------------------------|--+ 931 | 490 | 932 +---------------------------------+ 933 500 934 935 */ 936 } 937 }; 938 939 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild); 940 941 template <class Types> 942 class OcclusionTrackerTestScaledRenderSurface 943 : public OcclusionTrackerTest<Types> { 944 protected: 945 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers) 946 : OcclusionTrackerTest<Types>(opaque_layers) {} 947 948 void RunMyTest() { 949 typename Types::ContentLayerType* parent = this->CreateRoot( 950 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 951 952 gfx::Transform layer1_matrix; 953 layer1_matrix.Scale(2.0, 2.0); 954 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer( 955 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true); 956 layer1->SetForceRenderSurface(true); 957 958 gfx::Transform layer2_matrix; 959 layer2_matrix.Translate(25.0, 25.0); 960 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer( 961 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true); 962 typename Types::ContentLayerType* occluder = 963 this->CreateDrawingLayer(parent, 964 this->identity_matrix, 965 gfx::PointF(100.f, 100.f), 966 gfx::Size(500, 500), 967 true); 968 this->CalcDrawEtc(parent); 969 970 TestOcclusionTrackerWithClip<typename Types::LayerType, 971 typename Types::RenderSurfaceType> occlusion( 972 gfx::Rect(0, 0, 1000, 1000)); 973 974 this->VisitLayer(occluder, &occlusion); 975 this->EnterLayer(layer2, &occlusion, false); 976 977 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), 978 occlusion.occlusion_from_outside_target().ToString()); 979 EXPECT_EQ(gfx::Rect().ToString(), 980 occlusion.occlusion_from_inside_target().ToString()); 981 982 EXPECT_RECT_EQ( 983 gfx::Rect(0, 0, 25, 25), 984 occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25))); 985 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25), 986 occlusion.UnoccludedLayerContentRect( 987 layer2, gfx::Rect(10, 25, 25, 25))); 988 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15), 989 occlusion.UnoccludedLayerContentRect( 990 layer2, gfx::Rect(25, 10, 25, 25))); 991 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 992 layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty()); 993 } 994 }; 995 996 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface); 997 998 template <class Types> 999 class OcclusionTrackerTestVisitTargetTwoTimes 1000 : public OcclusionTrackerTest<Types> { 1001 protected: 1002 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers) 1003 : OcclusionTrackerTest<Types>(opaque_layers) {} 1004 void RunMyTest() { 1005 gfx::Transform child_transform; 1006 child_transform.Translate(250.0, 250.0); 1007 child_transform.Rotate(90.0); 1008 child_transform.Translate(-250.0, -250.0); 1009 1010 typename Types::ContentLayerType* root = this->CreateRoot( 1011 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); 1012 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 1013 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 1014 parent->SetMasksToBounds(true); 1015 typename Types::LayerType* child = this->CreateSurface( 1016 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); 1017 child->SetMasksToBounds(true); 1018 typename Types::ContentLayerType* layer = 1019 this->CreateDrawingLayer(child, 1020 this->identity_matrix, 1021 gfx::PointF(10.f, 10.f), 1022 gfx::Size(500, 500), 1023 true); 1024 // |child2| makes |parent|'s surface get considered by OcclusionTracker 1025 // first, instead of |child|'s. This exercises different code in 1026 // LeaveToRenderTarget, as the target surface has already been seen. 1027 typename Types::ContentLayerType* child2 = 1028 this->CreateDrawingLayer(parent, 1029 this->identity_matrix, 1030 gfx::PointF(30.f, 30.f), 1031 gfx::Size(60, 20), 1032 true); 1033 this->CalcDrawEtc(root); 1034 1035 TestOcclusionTrackerWithClip<typename Types::LayerType, 1036 typename Types::RenderSurfaceType> occlusion( 1037 gfx::Rect(0, 0, 1000, 1000)); 1038 1039 this->VisitLayer(child2, &occlusion); 1040 1041 EXPECT_EQ(gfx::Rect().ToString(), 1042 occlusion.occlusion_from_outside_target().ToString()); 1043 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), 1044 occlusion.occlusion_from_inside_target().ToString()); 1045 1046 this->VisitLayer(layer, &occlusion); 1047 1048 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), 1049 occlusion.occlusion_from_outside_target().ToString()); 1050 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), 1051 occlusion.occlusion_from_inside_target().ToString()); 1052 1053 this->EnterContributingSurface(child, &occlusion, false); 1054 1055 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), 1056 occlusion.occlusion_from_outside_target().ToString()); 1057 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), 1058 occlusion.occlusion_from_inside_target().ToString()); 1059 1060 // Occlusion in |child2| should get merged with the |child| surface we are 1061 // leaving now. 1062 this->LeaveContributingSurface(child, &occlusion); 1063 this->EnterLayer(parent, &occlusion, false); 1064 1065 EXPECT_EQ(gfx::Rect().ToString(), 1066 occlusion.occlusion_from_outside_target().ToString()); 1067 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)) 1068 .ToString(), 1069 occlusion.occlusion_from_inside_target().ToString()); 1070 1071 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70))); 1072 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10), 1073 occlusion.UnoccludedLayerContentRect( 1074 parent, gfx::Rect(30, 30, 70, 70))); 1075 1076 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10))); 1077 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10))); 1078 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10))); 1079 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10))); 1080 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10))); 1081 1082 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60))); 1083 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60))); 1084 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60))); 1085 1086 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 1087 parent, gfx::Rect(30, 30, 60, 10)).IsEmpty()); 1088 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10), 1089 occlusion.UnoccludedLayerContentRect( 1090 parent, gfx::Rect(29, 30, 60, 10))); 1091 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1), 1092 occlusion.UnoccludedLayerContentRect( 1093 parent, gfx::Rect(30, 29, 60, 10))); 1094 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10), 1095 occlusion.UnoccludedLayerContentRect( 1096 parent, gfx::Rect(31, 30, 60, 10))); 1097 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 1098 parent, gfx::Rect(30, 31, 60, 10)).IsEmpty()); 1099 1100 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 1101 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty()); 1102 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), 1103 occlusion.UnoccludedLayerContentRect( 1104 parent, gfx::Rect(29, 40, 70, 60))); 1105 // This rect is mostly occluded by |child2|. 1106 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1), 1107 occlusion.UnoccludedLayerContentRect( 1108 parent, gfx::Rect(30, 39, 70, 60))); 1109 // This rect extends past top/right ends of |child2|. 1110 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11), 1111 occlusion.UnoccludedLayerContentRect( 1112 parent, gfx::Rect(30, 29, 70, 70))); 1113 // This rect extends past left/right ends of |child2|. 1114 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60), 1115 occlusion.UnoccludedLayerContentRect( 1116 parent, gfx::Rect(20, 39, 80, 60))); 1117 EXPECT_RECT_EQ(gfx::Rect(), 1118 occlusion.UnoccludedLayerContentRect( 1119 parent, gfx::Rect(31, 40, 70, 60))); 1120 EXPECT_RECT_EQ(gfx::Rect(), 1121 occlusion.UnoccludedLayerContentRect( 1122 parent, gfx::Rect(30, 41, 70, 60))); 1123 1124 /* Justification for the above occlusion from |layer|: 1125 100 1126 +---------------------+ 1127 | | 1128 | 30 | rotate(90) 1129 | 30 + ------------+--------------------+ 1130 100 | | 10 | | | ==> 1131 | |10+----------|----------------------+ 1132 | + ------------+ | | | 1133 | | | | | | 1134 | | | | | | 1135 +----|--|-------------+ | | 1136 | | | | 1137 | | | | 1138 | | | |500 1139 | | | | 1140 | | | | 1141 | | | | 1142 | | | | 1143 +--|-------------------------------+ | 1144 | | 1145 +---------------------------------+ 1146 500 1147 1148 1149 +---------------------+ 1150 | |30 Visible region of |layer|: ///// 1151 | 30 60 | |child2|: \\\\\ 1152 | 30 +------------+--------------------+ 1153 | |\\\\\\\\\\\\| |10 | 1154 | +--|\\\\\\\\\\\\|-----------------+ | 1155 | | +------------+//| 420 | | 1156 | | |///////////////|60 | | 1157 | | |///////////////| | | 1158 +--|--|---------------+ | | 1159 20|10| 70 | | 1160 | | | | 1161 | | | | 1162 | | | | 1163 | | | | 1164 | | | | 1165 | | |10| 1166 | +------------------------------|--+ 1167 | 490 | 1168 +---------------------------------+ 1169 500 1170 */ 1171 } 1172 }; 1173 1174 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes); 1175 1176 template <class Types> 1177 class OcclusionTrackerTestSurfaceRotatedOffAxis 1178 : public OcclusionTrackerTest<Types> { 1179 protected: 1180 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers) 1181 : OcclusionTrackerTest<Types>(opaque_layers) {} 1182 void RunMyTest() { 1183 gfx::Transform child_transform; 1184 child_transform.Translate(250.0, 250.0); 1185 child_transform.Rotate(95.0); 1186 child_transform.Translate(-250.0, -250.0); 1187 1188 gfx::Transform layer_transform; 1189 layer_transform.Translate(10.0, 10.0); 1190 1191 typename Types::ContentLayerType* root = this->CreateRoot( 1192 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); 1193 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 1194 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 1195 typename Types::LayerType* child = this->CreateLayer( 1196 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); 1197 child->SetMasksToBounds(true); 1198 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( 1199 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true); 1200 this->CalcDrawEtc(root); 1201 1202 TestOcclusionTrackerWithClip<typename Types::LayerType, 1203 typename Types::RenderSurfaceType> occlusion( 1204 gfx::Rect(0, 0, 1000, 1000)); 1205 1206 gfx::Rect clipped_layer_in_child = MathUtil::MapClippedRect( 1207 layer_transform, layer->visible_content_rect()); 1208 1209 this->VisitLayer(layer, &occlusion); 1210 this->EnterContributingSurface(child, &occlusion, false); 1211 1212 EXPECT_EQ(gfx::Rect().ToString(), 1213 occlusion.occlusion_from_outside_target().ToString()); 1214 EXPECT_EQ(clipped_layer_in_child.ToString(), 1215 occlusion.occlusion_from_inside_target().ToString()); 1216 1217 this->LeaveContributingSurface(child, &occlusion); 1218 this->EnterLayer(parent, &occlusion, false); 1219 1220 EXPECT_EQ(gfx::Rect().ToString(), 1221 occlusion.occlusion_from_outside_target().ToString()); 1222 EXPECT_EQ(gfx::Rect().ToString(), 1223 occlusion.occlusion_from_inside_target().ToString()); 1224 1225 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1))); 1226 EXPECT_RECT_EQ( 1227 gfx::Rect(75, 55, 1, 1), 1228 occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1))); 1229 } 1230 }; 1231 1232 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis); 1233 1234 template <class Types> 1235 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren 1236 : public OcclusionTrackerTest<Types> { 1237 protected: 1238 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers) 1239 : OcclusionTrackerTest<Types>(opaque_layers) {} 1240 void RunMyTest() { 1241 gfx::Transform child_transform; 1242 child_transform.Translate(250.0, 250.0); 1243 child_transform.Rotate(90.0); 1244 child_transform.Translate(-250.0, -250.0); 1245 1246 typename Types::ContentLayerType* root = this->CreateRoot( 1247 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); 1248 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 1249 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); 1250 parent->SetMasksToBounds(true); 1251 typename Types::ContentLayerType* child = 1252 this->CreateDrawingSurface(parent, 1253 child_transform, 1254 gfx::PointF(30.f, 30.f), 1255 gfx::Size(500, 500), 1256 false); 1257 child->SetMasksToBounds(true); 1258 typename Types::ContentLayerType* layer1 = 1259 this->CreateDrawingLayer(child, 1260 this->identity_matrix, 1261 gfx::PointF(10.f, 10.f), 1262 gfx::Size(500, 500), 1263 true); 1264 typename Types::ContentLayerType* layer2 = 1265 this->CreateDrawingLayer(child, 1266 this->identity_matrix, 1267 gfx::PointF(10.f, 450.f), 1268 gfx::Size(500, 60), 1269 true); 1270 this->CalcDrawEtc(root); 1271 1272 TestOcclusionTrackerWithClip<typename Types::LayerType, 1273 typename Types::RenderSurfaceType> occlusion( 1274 gfx::Rect(0, 0, 1000, 1000)); 1275 1276 this->VisitLayer(layer2, &occlusion); 1277 this->VisitLayer(layer1, &occlusion); 1278 this->VisitLayer(child, &occlusion); 1279 this->EnterContributingSurface(child, &occlusion, false); 1280 1281 EXPECT_EQ(gfx::Rect().ToString(), 1282 occlusion.occlusion_from_outside_target().ToString()); 1283 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), 1284 occlusion.occlusion_from_inside_target().ToString()); 1285 1286 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70))); 1287 EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70))); 1288 // These rects are occluded except for the part outside the bounds of the 1289 // target surface. 1290 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 429, 60, 70))); 1291 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 60, 70))); 1292 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 70))); 1293 1294 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 1295 child, gfx::Rect(10, 430, 60, 70)).IsEmpty()); 1296 EXPECT_RECT_EQ( 1297 gfx::Rect(9, 430, 1, 70), 1298 occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70))); 1299 // These rects are occluded except for the part outside the bounds of the 1300 // target surface. 1301 EXPECT_RECT_EQ(gfx::Rect(), 1302 occlusion.UnoccludedLayerContentRect( 1303 child, gfx::Rect(10, 429, 60, 70))); 1304 EXPECT_RECT_EQ(gfx::Rect(), 1305 occlusion.UnoccludedLayerContentRect( 1306 child, gfx::Rect(11, 430, 60, 70))); 1307 EXPECT_RECT_EQ(gfx::Rect(), 1308 occlusion.UnoccludedLayerContentRect( 1309 child, gfx::Rect(10, 431, 60, 70))); 1310 1311 this->LeaveContributingSurface(child, &occlusion); 1312 this->EnterLayer(parent, &occlusion, false); 1313 1314 EXPECT_EQ(gfx::Rect().ToString(), 1315 occlusion.occlusion_from_outside_target().ToString()); 1316 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), 1317 occlusion.occlusion_from_inside_target().ToString()); 1318 1319 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60))); 1320 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60))); 1321 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60))); 1322 1323 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 1324 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty()); 1325 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), 1326 occlusion.UnoccludedLayerContentRect( 1327 parent, gfx::Rect(29, 40, 70, 60))); 1328 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1), 1329 occlusion.UnoccludedLayerContentRect( 1330 parent, gfx::Rect(30, 39, 70, 60))); 1331 EXPECT_RECT_EQ(gfx::Rect(), 1332 occlusion.UnoccludedLayerContentRect( 1333 parent, gfx::Rect(31, 40, 70, 60))); 1334 EXPECT_RECT_EQ(gfx::Rect(), 1335 occlusion.UnoccludedLayerContentRect( 1336 parent, gfx::Rect(30, 41, 70, 60))); 1337 1338 /* Justification for the above occlusion from |layer1| and |layer2|: 1339 1340 +---------------------+ 1341 | |30 Visible region of |layer1|: ///// 1342 | | Visible region of |layer2|: \\\\\ 1343 | +---------------------------------+ 1344 | | |10 | 1345 | +---------------+-----------------+ | 1346 | | |\\\\\\\\\\\\|//| 420 | | 1347 | | |\\\\\\\\\\\\|//|60 | | 1348 | | |\\\\\\\\\\\\|//| | | 1349 +--|--|------------|--+ | | 1350 20|10| 70 | | | 1351 | | | | | 1352 | | | | | 1353 | | | | | 1354 | | | | | 1355 | | | | | 1356 | | | |10| 1357 | +------------|-----------------|--+ 1358 | | 490 | 1359 +---------------+-----------------+ 1360 60 440 1361 */ 1362 } 1363 }; 1364 1365 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren); 1366 1367 template <class Types> 1368 class OcclusionTrackerTestOverlappingSurfaceSiblings 1369 : public OcclusionTrackerTest<Types> { 1370 protected: 1371 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers) 1372 : OcclusionTrackerTest<Types>(opaque_layers) {} 1373 void RunMyTest() { 1374 gfx::Transform child_transform; 1375 child_transform.Translate(250.0, 250.0); 1376 child_transform.Rotate(90.0); 1377 child_transform.Translate(-250.0, -250.0); 1378 1379 typename Types::ContentLayerType* parent = this->CreateRoot( 1380 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 1381 parent->SetMasksToBounds(true); 1382 typename Types::LayerType* child1 = this->CreateSurface( 1383 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10)); 1384 typename Types::LayerType* child2 = this->CreateSurface( 1385 parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10)); 1386 typename Types::ContentLayerType* layer1 = 1387 this->CreateDrawingLayer(child1, 1388 this->identity_matrix, 1389 gfx::PointF(-10.f, -10.f), 1390 gfx::Size(510, 510), 1391 true); 1392 typename Types::ContentLayerType* layer2 = 1393 this->CreateDrawingLayer(child2, 1394 this->identity_matrix, 1395 gfx::PointF(-10.f, -10.f), 1396 gfx::Size(510, 510), 1397 true); 1398 this->CalcDrawEtc(parent); 1399 1400 TestOcclusionTrackerWithClip<typename Types::LayerType, 1401 typename Types::RenderSurfaceType> occlusion( 1402 gfx::Rect(0, 0, 1000, 1000)); 1403 1404 this->VisitLayer(layer2, &occlusion); 1405 this->EnterContributingSurface(child2, &occlusion, false); 1406 1407 EXPECT_EQ(gfx::Rect().ToString(), 1408 occlusion.occlusion_from_outside_target().ToString()); 1409 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), 1410 occlusion.occlusion_from_inside_target().ToString()); 1411 1412 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 80))); 1413 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-11, 420, 70, 80))); 1414 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 419, 70, 80))); 1415 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 71, 80))); 1416 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 81))); 1417 1418 // There is nothing above child2's surface in the z-order. 1419 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), 1420 occlusion.UnoccludedContributingSurfaceContentRect( 1421 child2, false, gfx::Rect(-10, 420, 70, 80), NULL)); 1422 1423 this->LeaveContributingSurface(child2, &occlusion); 1424 this->VisitLayer(layer1, &occlusion); 1425 this->EnterContributingSurface(child1, &occlusion, false); 1426 1427 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(), 1428 occlusion.occlusion_from_outside_target().ToString()); 1429 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(), 1430 occlusion.occlusion_from_inside_target().ToString()); 1431 1432 // child2's contents will occlude child1 below it. 1433 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70), 1434 occlusion.UnoccludedContributingSurfaceContentRect( 1435 child1, false, gfx::Rect(-10, 430, 80, 70), NULL)); 1436 1437 this->LeaveContributingSurface(child1, &occlusion); 1438 this->EnterLayer(parent, &occlusion, false); 1439 1440 EXPECT_EQ(gfx::Rect().ToString(), 1441 occlusion.occlusion_from_outside_target().ToString()); 1442 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)) 1443 .ToString(), 1444 occlusion.occlusion_from_inside_target().ToString()); 1445 1446 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80))); 1447 1448 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80))); 1449 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80))); 1450 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80))); 1451 1452 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70))); 1453 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70))); 1454 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70))); 1455 1456 /* Justification for the above occlusion: 1457 100 1458 +---------------------+ 1459 | 20 | layer1 1460 | 30+ ---------------------------------+ 1461 100 | 30| | layer2 | 1462 |20+----------------------------------+ | 1463 | | | | | | 1464 | | | | | | 1465 | | | | | | 1466 +--|-|----------------+ | | 1467 | | | | 510 1468 | | | | 1469 | | | | 1470 | | | | 1471 | | | | 1472 | | | | 1473 | | | | 1474 | +--------------------------------|-+ 1475 | | 1476 +----------------------------------+ 1477 510 1478 */ 1479 } 1480 }; 1481 1482 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings); 1483 1484 template <class Types> 1485 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms 1486 : public OcclusionTrackerTest<Types> { 1487 protected: 1488 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms( 1489 bool opaque_layers) 1490 : OcclusionTrackerTest<Types>(opaque_layers) {} 1491 void RunMyTest() { 1492 gfx::Transform child1_transform; 1493 child1_transform.Translate(250.0, 250.0); 1494 child1_transform.Rotate(-90.0); 1495 child1_transform.Translate(-250.0, -250.0); 1496 1497 gfx::Transform child2_transform; 1498 child2_transform.Translate(250.0, 250.0); 1499 child2_transform.Rotate(90.0); 1500 child2_transform.Translate(-250.0, -250.0); 1501 1502 typename Types::ContentLayerType* parent = this->CreateRoot( 1503 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 1504 parent->SetMasksToBounds(true); 1505 typename Types::LayerType* child1 = this->CreateSurface( 1506 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10)); 1507 typename Types::LayerType* child2 = 1508 this->CreateDrawingSurface(parent, 1509 child2_transform, 1510 gfx::PointF(20.f, 40.f), 1511 gfx::Size(10, 10), 1512 false); 1513 typename Types::ContentLayerType* layer1 = 1514 this->CreateDrawingLayer(child1, 1515 this->identity_matrix, 1516 gfx::PointF(-10.f, -20.f), 1517 gfx::Size(510, 510), 1518 true); 1519 typename Types::ContentLayerType* layer2 = 1520 this->CreateDrawingLayer(child2, 1521 this->identity_matrix, 1522 gfx::PointF(-10.f, -10.f), 1523 gfx::Size(510, 510), 1524 true); 1525 this->CalcDrawEtc(parent); 1526 1527 TestOcclusionTrackerWithClip<typename Types::LayerType, 1528 typename Types::RenderSurfaceType> occlusion( 1529 gfx::Rect(0, 0, 1000, 1000)); 1530 1531 this->VisitLayer(layer2, &occlusion); 1532 this->EnterLayer(child2, &occlusion, false); 1533 1534 EXPECT_EQ(gfx::Rect().ToString(), 1535 occlusion.occlusion_from_outside_target().ToString()); 1536 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), 1537 occlusion.occlusion_from_inside_target().ToString()); 1538 1539 this->LeaveLayer(child2, &occlusion); 1540 this->EnterContributingSurface(child2, &occlusion, false); 1541 1542 // There is nothing above child2's surface in the z-order. 1543 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), 1544 occlusion.UnoccludedContributingSurfaceContentRect( 1545 child2, false, gfx::Rect(-10, 420, 70, 80), NULL)); 1546 1547 this->LeaveContributingSurface(child2, &occlusion); 1548 this->VisitLayer(layer1, &occlusion); 1549 this->EnterContributingSurface(child1, &occlusion, false); 1550 1551 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(), 1552 occlusion.occlusion_from_outside_target().ToString()); 1553 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), 1554 occlusion.occlusion_from_inside_target().ToString()); 1555 1556 // child2's contents will occlude child1 below it. 1557 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90), 1558 occlusion.UnoccludedContributingSurfaceContentRect( 1559 child1, false, gfx::Rect(420, -20, 80, 90), NULL)); 1560 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80), 1561 occlusion.UnoccludedContributingSurfaceContentRect( 1562 child1, false, gfx::Rect(420, -10, 80, 90), NULL)); 1563 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10), 1564 occlusion.UnoccludedContributingSurfaceContentRect( 1565 child1, false, gfx::Rect(420, -20, 70, 90), NULL)); 1566 1567 this->LeaveContributingSurface(child1, &occlusion); 1568 this->EnterLayer(parent, &occlusion, false); 1569 1570 EXPECT_EQ(gfx::Rect().ToString(), 1571 occlusion.occlusion_from_outside_target().ToString()); 1572 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), 1573 occlusion.occlusion_from_inside_target().ToString()); 1574 1575 /* Justification for the above occlusion: 1576 100 1577 +---------------------+ 1578 |20 | layer1 1579 10+----------------------------------+ 1580 100 || 30 | layer2 | 1581 |20+----------------------------------+ 1582 || | | | | 1583 || | | | | 1584 || | | | | 1585 +|-|------------------+ | | 1586 | | | | 510 1587 | | 510 | | 1588 | | | | 1589 | | | | 1590 | | | | 1591 | | | | 1592 | | 520 | | 1593 +----------------------------------+ | 1594 | | 1595 +----------------------------------+ 1596 510 1597 */ 1598 } 1599 }; 1600 1601 ALL_OCCLUSIONTRACKER_TEST( 1602 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms); 1603 1604 template <class Types> 1605 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> { 1606 protected: 1607 explicit OcclusionTrackerTestFilters(bool opaque_layers) 1608 : OcclusionTrackerTest<Types>(opaque_layers) {} 1609 void RunMyTest() { 1610 gfx::Transform layer_transform; 1611 layer_transform.Translate(250.0, 250.0); 1612 layer_transform.Rotate(90.0); 1613 layer_transform.Translate(-250.0, -250.0); 1614 1615 typename Types::ContentLayerType* parent = this->CreateRoot( 1616 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 1617 parent->SetMasksToBounds(true); 1618 typename Types::ContentLayerType* blur_layer = 1619 this->CreateDrawingLayer(parent, 1620 layer_transform, 1621 gfx::PointF(30.f, 30.f), 1622 gfx::Size(500, 500), 1623 true); 1624 typename Types::ContentLayerType* opaque_layer = 1625 this->CreateDrawingLayer(parent, 1626 layer_transform, 1627 gfx::PointF(30.f, 30.f), 1628 gfx::Size(500, 500), 1629 true); 1630 typename Types::ContentLayerType* opacity_layer = 1631 this->CreateDrawingLayer(parent, 1632 layer_transform, 1633 gfx::PointF(30.f, 30.f), 1634 gfx::Size(500, 500), 1635 true); 1636 1637 FilterOperations filters; 1638 filters.Append(FilterOperation::CreateBlurFilter(10.f)); 1639 blur_layer->SetFilters(filters); 1640 1641 filters.Clear(); 1642 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); 1643 opaque_layer->SetFilters(filters); 1644 1645 filters.Clear(); 1646 filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); 1647 opacity_layer->SetFilters(filters); 1648 1649 this->CalcDrawEtc(parent); 1650 1651 TestOcclusionTrackerWithClip<typename Types::LayerType, 1652 typename Types::RenderSurfaceType> occlusion( 1653 gfx::Rect(0, 0, 1000, 1000)); 1654 1655 // Opacity layer won't contribute to occlusion. 1656 this->VisitLayer(opacity_layer, &occlusion); 1657 this->EnterContributingSurface(opacity_layer, &occlusion, false); 1658 1659 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1660 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1661 1662 // And has nothing to contribute to its parent surface. 1663 this->LeaveContributingSurface(opacity_layer, &occlusion); 1664 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1665 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1666 1667 // Opaque layer will contribute to occlusion. 1668 this->VisitLayer(opaque_layer, &occlusion); 1669 this->EnterContributingSurface(opaque_layer, &occlusion, false); 1670 1671 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1672 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), 1673 occlusion.occlusion_from_inside_target().ToString()); 1674 1675 // And it gets translated to the parent surface. 1676 this->LeaveContributingSurface(opaque_layer, &occlusion); 1677 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1678 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), 1679 occlusion.occlusion_from_inside_target().ToString()); 1680 1681 // The blur layer needs to throw away any occlusion from outside its 1682 // subtree. 1683 this->EnterLayer(blur_layer, &occlusion, false); 1684 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1685 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1686 1687 // And it won't contribute to occlusion. 1688 this->LeaveLayer(blur_layer, &occlusion); 1689 this->EnterContributingSurface(blur_layer, &occlusion, false); 1690 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1691 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 1692 1693 // But the opaque layer's occlusion is preserved on the parent. 1694 this->LeaveContributingSurface(blur_layer, &occlusion); 1695 this->EnterLayer(parent, &occlusion, false); 1696 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 1697 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), 1698 occlusion.occlusion_from_inside_target().ToString()); 1699 } 1700 }; 1701 1702 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters); 1703 1704 template <class Types> 1705 class OcclusionTrackerTestReplicaDoesOcclude 1706 : public OcclusionTrackerTest<Types> { 1707 protected: 1708 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers) 1709 : OcclusionTrackerTest<Types>(opaque_layers) {} 1710 void RunMyTest() { 1711 typename Types::ContentLayerType* parent = this->CreateRoot( 1712 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 1713 typename Types::LayerType* surface = 1714 this->CreateDrawingSurface(parent, 1715 this->identity_matrix, 1716 gfx::PointF(0.f, 100.f), 1717 gfx::Size(50, 50), 1718 true); 1719 this->CreateReplicaLayer( 1720 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size()); 1721 this->CalcDrawEtc(parent); 1722 1723 TestOcclusionTrackerWithClip<typename Types::LayerType, 1724 typename Types::RenderSurfaceType> occlusion( 1725 gfx::Rect(0, 0, 1000, 1000)); 1726 1727 this->VisitLayer(surface, &occlusion); 1728 1729 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 1730 occlusion.occlusion_from_inside_target().ToString()); 1731 1732 this->VisitContributingSurface(surface, &occlusion); 1733 this->EnterLayer(parent, &occlusion, false); 1734 1735 // The surface and replica should both be occluding the parent. 1736 EXPECT_EQ( 1737 UnionRegions(gfx::Rect(0, 100, 50, 50), 1738 gfx::Rect(50, 150, 50, 50)).ToString(), 1739 occlusion.occlusion_from_inside_target().ToString()); 1740 } 1741 }; 1742 1743 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude); 1744 1745 template <class Types> 1746 class OcclusionTrackerTestReplicaWithClipping 1747 : public OcclusionTrackerTest<Types> { 1748 protected: 1749 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers) 1750 : OcclusionTrackerTest<Types>(opaque_layers) {} 1751 void RunMyTest() { 1752 typename Types::ContentLayerType* parent = this->CreateRoot( 1753 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170)); 1754 parent->SetMasksToBounds(true); 1755 typename Types::LayerType* surface = 1756 this->CreateDrawingSurface(parent, 1757 this->identity_matrix, 1758 gfx::PointF(0.f, 100.f), 1759 gfx::Size(50, 50), 1760 true); 1761 this->CreateReplicaLayer( 1762 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size()); 1763 this->CalcDrawEtc(parent); 1764 1765 TestOcclusionTrackerWithClip<typename Types::LayerType, 1766 typename Types::RenderSurfaceType> occlusion( 1767 gfx::Rect(0, 0, 1000, 1000)); 1768 1769 this->VisitLayer(surface, &occlusion); 1770 1771 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 1772 occlusion.occlusion_from_inside_target().ToString()); 1773 1774 this->VisitContributingSurface(surface, &occlusion); 1775 this->EnterLayer(parent, &occlusion, false); 1776 1777 // The surface and replica should both be occluding the parent. 1778 EXPECT_EQ( 1779 UnionRegions(gfx::Rect(0, 100, 50, 50), 1780 gfx::Rect(50, 150, 50, 20)).ToString(), 1781 occlusion.occlusion_from_inside_target().ToString()); 1782 } 1783 }; 1784 1785 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping); 1786 1787 template <class Types> 1788 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> { 1789 protected: 1790 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers) 1791 : OcclusionTrackerTest<Types>(opaque_layers) {} 1792 void RunMyTest() { 1793 typename Types::ContentLayerType* parent = this->CreateRoot( 1794 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 1795 typename Types::LayerType* surface = 1796 this->CreateDrawingSurface(parent, 1797 this->identity_matrix, 1798 gfx::PointF(0.f, 100.f), 1799 gfx::Size(50, 50), 1800 true); 1801 typename Types::LayerType* replica = this->CreateReplicaLayer( 1802 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size()); 1803 this->CreateMaskLayer(replica, gfx::Size(10, 10)); 1804 this->CalcDrawEtc(parent); 1805 1806 TestOcclusionTrackerWithClip<typename Types::LayerType, 1807 typename Types::RenderSurfaceType> occlusion( 1808 gfx::Rect(0, 0, 1000, 1000)); 1809 1810 this->VisitLayer(surface, &occlusion); 1811 1812 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 1813 occlusion.occlusion_from_inside_target().ToString()); 1814 1815 this->VisitContributingSurface(surface, &occlusion); 1816 this->EnterLayer(parent, &occlusion, false); 1817 1818 // The replica should not be occluding the parent, since it has a mask 1819 // applied to it. 1820 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), 1821 occlusion.occlusion_from_inside_target().ToString()); 1822 } 1823 }; 1824 1825 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask); 1826 1827 template <class Types> 1828 class OcclusionTrackerTestLayerClipRectOutsideChild 1829 : public OcclusionTrackerTest<Types> { 1830 protected: 1831 explicit OcclusionTrackerTestLayerClipRectOutsideChild(bool opaque_layers) 1832 : OcclusionTrackerTest<Types>(opaque_layers) {} 1833 void RunMyTest() { 1834 typename Types::ContentLayerType* parent = this->CreateRoot( 1835 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1836 typename Types::ContentLayerType* clip = 1837 this->CreateDrawingLayer(parent, 1838 this->identity_matrix, 1839 gfx::PointF(200.f, 100.f), 1840 gfx::Size(100, 100), 1841 false); 1842 clip->SetMasksToBounds(true); 1843 typename Types::ContentLayerType* layer = 1844 this->CreateDrawingLayer(clip, 1845 this->identity_matrix, 1846 gfx::PointF(-200.f, -100.f), 1847 gfx::Size(200, 200), 1848 false); 1849 this->CalcDrawEtc(parent); 1850 1851 TestOcclusionTrackerWithClip<typename Types::LayerType, 1852 typename Types::RenderSurfaceType> occlusion( 1853 gfx::Rect(0, 0, 1000, 1000)); 1854 1855 this->EnterLayer(layer, &occlusion, false); 1856 1857 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 1858 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 1859 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 1860 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 1861 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100))); 1862 1863 this->LeaveLayer(layer, &occlusion); 1864 this->EnterLayer(clip, &occlusion, false); 1865 1866 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(-100, 0, 100, 100))); 1867 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, -100, 100, 100))); 1868 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100))); 1869 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100))); 1870 EXPECT_FALSE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100))); 1871 1872 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 1873 occlusion.UnoccludedLayerContentRect( 1874 clip, gfx::Rect(-100, -100, 300, 300))); 1875 } 1876 }; 1877 1878 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild); 1879 1880 template <class Types> 1881 class OcclusionTrackerTestViewportRectOutsideChild 1882 : public OcclusionTrackerTest<Types> { 1883 protected: 1884 explicit OcclusionTrackerTestViewportRectOutsideChild(bool opaque_layers) 1885 : OcclusionTrackerTest<Types>(opaque_layers) {} 1886 void RunMyTest() { 1887 typename Types::ContentLayerType* parent = this->CreateRoot( 1888 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1889 typename Types::ContentLayerType* layer = 1890 this->CreateDrawingSurface(parent, 1891 this->identity_matrix, 1892 gfx::PointF(), 1893 gfx::Size(200, 200), 1894 true); 1895 this->CalcDrawEtc(parent); 1896 1897 TestOcclusionTrackerWithClip<typename Types::LayerType, 1898 typename Types::RenderSurfaceType> occlusion( 1899 gfx::Rect(200, 100, 100, 100)); 1900 1901 this->EnterLayer(layer, &occlusion, false); 1902 1903 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 1904 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 1905 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 1906 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 1907 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100))); 1908 1909 this->LeaveLayer(layer, &occlusion); 1910 this->VisitContributingSurface(layer, &occlusion); 1911 this->EnterLayer(parent, &occlusion, false); 1912 1913 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100))); 1914 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); 1915 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100))); 1916 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); 1917 EXPECT_FALSE( 1918 occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100))); 1919 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100))); 1920 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100))); 1921 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100))); 1922 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); 1923 1924 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), 1925 occlusion.UnoccludedLayerContentRect( 1926 parent, gfx::Rect(0, 0, 300, 300))); 1927 } 1928 }; 1929 1930 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild); 1931 1932 template <class Types> 1933 class OcclusionTrackerTestLayerClipRectOverChild 1934 : public OcclusionTrackerTest<Types> { 1935 protected: 1936 explicit OcclusionTrackerTestLayerClipRectOverChild(bool opaque_layers) 1937 : OcclusionTrackerTest<Types>(opaque_layers) {} 1938 void RunMyTest() { 1939 typename Types::ContentLayerType* parent = this->CreateRoot( 1940 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 1941 typename Types::ContentLayerType* clip = 1942 this->CreateDrawingLayer(parent, 1943 this->identity_matrix, 1944 gfx::PointF(100.f, 100.f), 1945 gfx::Size(100, 100), 1946 false); 1947 clip->SetMasksToBounds(true); 1948 typename Types::ContentLayerType* layer = 1949 this->CreateDrawingSurface(clip, 1950 this->identity_matrix, 1951 gfx::PointF(-100.f, -100.f), 1952 gfx::Size(200, 200), 1953 true); 1954 this->CalcDrawEtc(parent); 1955 1956 TestOcclusionTrackerWithClip<typename Types::LayerType, 1957 typename Types::RenderSurfaceType> occlusion( 1958 gfx::Rect(0, 0, 1000, 1000)); 1959 1960 this->EnterLayer(layer, &occlusion, false); 1961 1962 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 1963 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 1964 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 1965 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 1966 1967 this->LeaveLayer(layer, &occlusion); 1968 this->VisitContributingSurface(layer, &occlusion); 1969 1970 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), 1971 occlusion.occlusion_from_inside_target().ToString()); 1972 1973 this->EnterLayer(clip, &occlusion, false); 1974 1975 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100))); 1976 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100))); 1977 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100))); 1978 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 100, 100, 100))); 1979 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 100, 100, 100))); 1980 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 0, 100, 100))); 1981 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 200, 100, 100))); 1982 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 200, 100, 100))); 1983 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 200, 100, 100))); 1984 1985 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 1986 clip, gfx::Rect(0, 0, 300, 300)).IsEmpty()); 1987 } 1988 }; 1989 1990 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild); 1991 1992 template <class Types> 1993 class OcclusionTrackerTestViewportRectOverChild 1994 : public OcclusionTrackerTest<Types> { 1995 protected: 1996 explicit OcclusionTrackerTestViewportRectOverChild(bool opaque_layers) 1997 : OcclusionTrackerTest<Types>(opaque_layers) {} 1998 void RunMyTest() { 1999 typename Types::ContentLayerType* parent = this->CreateRoot( 2000 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2001 typename Types::ContentLayerType* layer = 2002 this->CreateDrawingSurface(parent, 2003 this->identity_matrix, 2004 gfx::PointF(), 2005 gfx::Size(200, 200), 2006 true); 2007 this->CalcDrawEtc(parent); 2008 2009 TestOcclusionTrackerWithClip<typename Types::LayerType, 2010 typename Types::RenderSurfaceType> occlusion( 2011 gfx::Rect(100, 100, 100, 100)); 2012 2013 this->EnterLayer(layer, &occlusion, false); 2014 2015 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2016 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 2017 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 2018 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 2019 2020 this->LeaveLayer(layer, &occlusion); 2021 this->VisitContributingSurface(layer, &occlusion); 2022 this->EnterLayer(parent, &occlusion, false); 2023 2024 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100))); 2025 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); 2026 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100))); 2027 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); 2028 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100))); 2029 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100))); 2030 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100))); 2031 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100))); 2032 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); 2033 2034 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 2035 parent, gfx::Rect(0, 0, 300, 300)).IsEmpty()); 2036 } 2037 }; 2038 2039 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild); 2040 2041 template <class Types> 2042 class OcclusionTrackerTestLayerClipRectPartlyOverChild 2043 : public OcclusionTrackerTest<Types> { 2044 protected: 2045 explicit OcclusionTrackerTestLayerClipRectPartlyOverChild(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(300, 300)); 2050 typename Types::ContentLayerType* clip = 2051 this->CreateDrawingLayer(parent, 2052 this->identity_matrix, 2053 gfx::PointF(50.f, 50.f), 2054 gfx::Size(200, 200), 2055 false); 2056 clip->SetMasksToBounds(true); 2057 typename Types::ContentLayerType* layer = 2058 this->CreateDrawingSurface(clip, 2059 this->identity_matrix, 2060 gfx::PointF(-50.f, -50.f), 2061 gfx::Size(200, 200), 2062 true); 2063 this->CalcDrawEtc(parent); 2064 2065 TestOcclusionTrackerWithClip<typename Types::LayerType, 2066 typename Types::RenderSurfaceType> occlusion( 2067 gfx::Rect(0, 0, 1000, 1000)); 2068 2069 this->EnterLayer(layer, &occlusion, false); 2070 2071 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2072 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 2073 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 2074 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 2075 2076 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 50))); 2077 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 50, 100))); 2078 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 50))); 2079 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 50, 100))); 2080 2081 this->LeaveLayer(layer, &occlusion); 2082 this->VisitContributingSurface(layer, &occlusion); 2083 this->EnterLayer(clip, &occlusion, false); 2084 2085 EXPECT_EQ(gfx::Rect(50, 50, 150, 150).ToString(), 2086 occlusion.occlusion_from_inside_target().ToString()); 2087 } 2088 }; 2089 2090 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild); 2091 2092 template <class Types> 2093 class OcclusionTrackerTestViewportRectPartlyOverChild 2094 : public OcclusionTrackerTest<Types> { 2095 protected: 2096 explicit OcclusionTrackerTestViewportRectPartlyOverChild(bool opaque_layers) 2097 : OcclusionTrackerTest<Types>(opaque_layers) {} 2098 void RunMyTest() { 2099 typename Types::ContentLayerType* parent = this->CreateRoot( 2100 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2101 typename Types::ContentLayerType* layer = 2102 this->CreateDrawingSurface(parent, 2103 this->identity_matrix, 2104 gfx::PointF(), 2105 gfx::Size(200, 200), 2106 true); 2107 this->CalcDrawEtc(parent); 2108 2109 TestOcclusionTrackerWithClip<typename Types::LayerType, 2110 typename Types::RenderSurfaceType> occlusion( 2111 gfx::Rect(50, 50, 200, 200)); 2112 2113 this->EnterLayer(layer, &occlusion, false); 2114 2115 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2116 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 2117 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 2118 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 2119 2120 this->LeaveLayer(layer, &occlusion); 2121 this->VisitContributingSurface(layer, &occlusion); 2122 this->EnterLayer(parent, &occlusion, false); 2123 2124 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100))); 2125 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); 2126 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100))); 2127 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); 2128 EXPECT_FALSE( 2129 occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100))); 2130 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100))); 2131 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100))); 2132 EXPECT_FALSE( 2133 occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100))); 2134 EXPECT_FALSE( 2135 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); 2136 2137 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), 2138 occlusion.UnoccludedLayerContentRect( 2139 parent, gfx::Rect(0, 0, 300, 300))); 2140 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), 2141 occlusion.UnoccludedLayerContentRect( 2142 parent, gfx::Rect(0, 0, 300, 100))); 2143 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), 2144 occlusion.UnoccludedLayerContentRect( 2145 parent, gfx::Rect(0, 100, 300, 100))); 2146 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), 2147 occlusion.UnoccludedLayerContentRect( 2148 parent, gfx::Rect(200, 100, 100, 100))); 2149 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), 2150 occlusion.UnoccludedLayerContentRect( 2151 parent, gfx::Rect(100, 200, 100, 100))); 2152 } 2153 }; 2154 2155 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild); 2156 2157 template <class Types> 2158 class OcclusionTrackerTestViewportRectOverNothing 2159 : public OcclusionTrackerTest<Types> { 2160 protected: 2161 explicit OcclusionTrackerTestViewportRectOverNothing(bool opaque_layers) 2162 : OcclusionTrackerTest<Types>(opaque_layers) {} 2163 void RunMyTest() { 2164 typename Types::ContentLayerType* parent = this->CreateRoot( 2165 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2166 typename Types::ContentLayerType* layer = 2167 this->CreateDrawingSurface(parent, 2168 this->identity_matrix, 2169 gfx::PointF(), 2170 gfx::Size(200, 200), 2171 true); 2172 this->CalcDrawEtc(parent); 2173 2174 TestOcclusionTrackerWithClip<typename Types::LayerType, 2175 typename Types::RenderSurfaceType> occlusion( 2176 gfx::Rect(500, 500, 100, 100)); 2177 2178 this->EnterLayer(layer, &occlusion, false); 2179 2180 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2181 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 2182 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 2183 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 2184 2185 this->LeaveLayer(layer, &occlusion); 2186 this->VisitContributingSurface(layer, &occlusion); 2187 this->EnterLayer(parent, &occlusion, false); 2188 2189 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100))); 2190 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); 2191 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100))); 2192 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); 2193 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100))); 2194 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100))); 2195 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100))); 2196 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100))); 2197 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); 2198 2199 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 2200 parent, gfx::Rect(0, 0, 300, 300)).IsEmpty()); 2201 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 2202 parent, gfx::Rect(0, 0, 300, 100)).IsEmpty()); 2203 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 2204 parent, gfx::Rect(0, 100, 300, 100)).IsEmpty()); 2205 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 2206 parent, gfx::Rect(200, 100, 100, 100)).IsEmpty()); 2207 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 2208 parent, gfx::Rect(100, 200, 100, 100)).IsEmpty()); 2209 } 2210 }; 2211 2212 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing); 2213 2214 template <class Types> 2215 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin 2216 : public OcclusionTrackerTest<Types> { 2217 protected: 2218 explicit OcclusionTrackerTestLayerClipRectForLayerOffOrigin( 2219 bool opaque_layers) 2220 : OcclusionTrackerTest<Types>(opaque_layers) {} 2221 void RunMyTest() { 2222 typename Types::ContentLayerType* parent = this->CreateRoot( 2223 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2224 typename Types::ContentLayerType* layer = 2225 this->CreateDrawingSurface(parent, 2226 this->identity_matrix, 2227 gfx::PointF(), 2228 gfx::Size(200, 200), 2229 true); 2230 this->CalcDrawEtc(parent); 2231 2232 TestOcclusionTrackerWithClip<typename Types::LayerType, 2233 typename Types::RenderSurfaceType> occlusion( 2234 gfx::Rect(0, 0, 1000, 1000)); 2235 this->EnterLayer(layer, &occlusion, false); 2236 2237 // This layer is translated when drawn into its target. So if the clip rect 2238 // given from the target surface is not in that target space, then after 2239 // translating these query rects into the target, they will fall outside the 2240 // clip and be considered occluded. 2241 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2242 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 2243 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 2244 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 2245 } 2246 }; 2247 2248 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin); 2249 2250 template <class Types> 2251 class OcclusionTrackerTestOpaqueContentsRegionEmpty 2252 : public OcclusionTrackerTest<Types> { 2253 protected: 2254 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers) 2255 : OcclusionTrackerTest<Types>(opaque_layers) {} 2256 void RunMyTest() { 2257 typename Types::ContentLayerType* parent = this->CreateRoot( 2258 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2259 typename Types::ContentLayerType* layer = 2260 this->CreateDrawingSurface(parent, 2261 this->identity_matrix, 2262 gfx::PointF(), 2263 gfx::Size(200, 200), 2264 false); 2265 this->CalcDrawEtc(parent); 2266 2267 TestOcclusionTrackerWithClip<typename Types::LayerType, 2268 typename Types::RenderSurfaceType> occlusion( 2269 gfx::Rect(0, 0, 1000, 1000)); 2270 this->EnterLayer(layer, &occlusion, false); 2271 2272 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); 2273 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); 2274 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); 2275 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); 2276 2277 // Occluded since its outside the surface bounds. 2278 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100))); 2279 2280 this->LeaveLayer(layer, &occlusion); 2281 this->VisitContributingSurface(layer, &occlusion); 2282 this->EnterLayer(parent, &occlusion, false); 2283 2284 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2285 } 2286 }; 2287 2288 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty); 2289 2290 template <class Types> 2291 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty 2292 : public OcclusionTrackerTest<Types> { 2293 protected: 2294 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers) 2295 : OcclusionTrackerTest<Types>(opaque_layers) {} 2296 void RunMyTest() { 2297 typename Types::ContentLayerType* parent = this->CreateRoot( 2298 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2299 typename Types::ContentLayerType* layer = 2300 this->CreateDrawingLayer(parent, 2301 this->identity_matrix, 2302 gfx::PointF(100.f, 100.f), 2303 gfx::Size(200, 200), 2304 false); 2305 this->CalcDrawEtc(parent); 2306 { 2307 TestOcclusionTrackerWithClip<typename Types::LayerType, 2308 typename Types::RenderSurfaceType> occlusion( 2309 gfx::Rect(0, 0, 1000, 1000)); 2310 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100)); 2311 2312 this->ResetLayerIterator(); 2313 this->VisitLayer(layer, &occlusion); 2314 this->EnterLayer(parent, &occlusion, false); 2315 2316 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), 2317 occlusion.occlusion_from_inside_target().ToString()); 2318 2319 EXPECT_FALSE( 2320 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); 2321 EXPECT_TRUE( 2322 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); 2323 EXPECT_FALSE( 2324 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); 2325 } 2326 { 2327 TestOcclusionTrackerWithClip<typename Types::LayerType, 2328 typename Types::RenderSurfaceType> occlusion( 2329 gfx::Rect(0, 0, 1000, 1000)); 2330 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180)); 2331 2332 this->ResetLayerIterator(); 2333 this->VisitLayer(layer, &occlusion); 2334 this->EnterLayer(parent, &occlusion, false); 2335 2336 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), 2337 occlusion.occlusion_from_inside_target().ToString()); 2338 2339 EXPECT_FALSE( 2340 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); 2341 EXPECT_FALSE( 2342 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); 2343 EXPECT_TRUE( 2344 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); 2345 } 2346 { 2347 TestOcclusionTrackerWithClip<typename Types::LayerType, 2348 typename Types::RenderSurfaceType> occlusion( 2349 gfx::Rect(0, 0, 1000, 1000)); 2350 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100)); 2351 2352 this->ResetLayerIterator(); 2353 this->VisitLayer(layer, &occlusion); 2354 this->EnterLayer(parent, &occlusion, false); 2355 2356 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), 2357 occlusion.occlusion_from_inside_target().ToString()); 2358 2359 EXPECT_FALSE( 2360 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); 2361 EXPECT_FALSE( 2362 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); 2363 EXPECT_FALSE( 2364 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); 2365 } 2366 } 2367 }; 2368 2369 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty); 2370 2371 template <class Types> 2372 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> { 2373 protected: 2374 explicit OcclusionTrackerTest3dTransform(bool opaque_layers) 2375 : OcclusionTrackerTest<Types>(opaque_layers) {} 2376 void RunMyTest() { 2377 gfx::Transform transform; 2378 transform.RotateAboutYAxis(30.0); 2379 2380 typename Types::ContentLayerType* parent = this->CreateRoot( 2381 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2382 typename Types::LayerType* container = this->CreateLayer( 2383 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2384 typename Types::ContentLayerType* layer = 2385 this->CreateDrawingLayer(container, 2386 transform, 2387 gfx::PointF(100.f, 100.f), 2388 gfx::Size(200, 200), 2389 true); 2390 this->CalcDrawEtc(parent); 2391 2392 TestOcclusionTrackerWithClip<typename Types::LayerType, 2393 typename Types::RenderSurfaceType> occlusion( 2394 gfx::Rect(0, 0, 1000, 1000)); 2395 this->EnterLayer(layer, &occlusion, false); 2396 2397 // The layer is rotated in 3d but without preserving 3d, so it only gets 2398 // resized. 2399 EXPECT_RECT_EQ( 2400 gfx::Rect(0, 0, 200, 200), 2401 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200))); 2402 } 2403 }; 2404 2405 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform); 2406 2407 template <class Types> 2408 class OcclusionTrackerTestUnsorted3dLayers 2409 : public OcclusionTrackerTest<Types> { 2410 protected: 2411 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers) 2412 : OcclusionTrackerTest<Types>(opaque_layers) {} 2413 void RunMyTest() { 2414 // Currently, The main thread layer iterator does not iterate over 3d items 2415 // in sorted order, because layer sorting is not performed on the main 2416 // thread. Because of this, the occlusion tracker cannot assume that a 3d 2417 // layer occludes other layers that have not yet been iterated over. For 2418 // now, the expected behavior is that a 3d layer simply does not add any 2419 // occlusion to the occlusion tracker. 2420 2421 gfx::Transform translation_to_front; 2422 translation_to_front.Translate3d(0.0, 0.0, -10.0); 2423 gfx::Transform translation_to_back; 2424 translation_to_front.Translate3d(0.0, 0.0, -100.0); 2425 2426 typename Types::ContentLayerType* parent = this->CreateRoot( 2427 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2428 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer( 2429 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true); 2430 typename Types::ContentLayerType* child2 = 2431 this->CreateDrawingLayer(parent, 2432 translation_to_front, 2433 gfx::PointF(50.f, 50.f), 2434 gfx::Size(100, 100), 2435 true); 2436 parent->SetPreserves3d(true); 2437 2438 this->CalcDrawEtc(parent); 2439 2440 TestOcclusionTrackerWithClip<typename Types::LayerType, 2441 typename Types::RenderSurfaceType> occlusion( 2442 gfx::Rect(0, 0, 1000, 1000)); 2443 this->VisitLayer(child2, &occlusion); 2444 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2445 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 2446 2447 this->VisitLayer(child1, &occlusion); 2448 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2449 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 2450 } 2451 }; 2452 2453 // This test will have different layer ordering on the impl thread; the test 2454 // will only work on the main thread. 2455 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers); 2456 2457 template <class Types> 2458 class OcclusionTrackerTestPerspectiveTransform 2459 : public OcclusionTrackerTest<Types> { 2460 protected: 2461 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers) 2462 : OcclusionTrackerTest<Types>(opaque_layers) {} 2463 void RunMyTest() { 2464 gfx::Transform transform; 2465 transform.Translate(150.0, 150.0); 2466 transform.ApplyPerspectiveDepth(400.0); 2467 transform.RotateAboutXAxis(-30.0); 2468 transform.Translate(-150.0, -150.0); 2469 2470 typename Types::ContentLayerType* parent = this->CreateRoot( 2471 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2472 typename Types::LayerType* container = this->CreateLayer( 2473 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2474 typename Types::ContentLayerType* layer = 2475 this->CreateDrawingLayer(container, 2476 transform, 2477 gfx::PointF(100.f, 100.f), 2478 gfx::Size(200, 200), 2479 true); 2480 container->SetPreserves3d(true); 2481 layer->SetPreserves3d(true); 2482 this->CalcDrawEtc(parent); 2483 2484 TestOcclusionTrackerWithClip<typename Types::LayerType, 2485 typename Types::RenderSurfaceType> occlusion( 2486 gfx::Rect(0, 0, 1000, 1000)); 2487 this->EnterLayer(layer, &occlusion, false); 2488 2489 EXPECT_RECT_EQ( 2490 gfx::Rect(0, 0, 200, 200), 2491 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200))); 2492 } 2493 }; 2494 2495 // This test requires accumulating occlusion of 3d layers, which are skipped by 2496 // the occlusion tracker on the main thread. So this test should run on the impl 2497 // thread. 2498 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform); 2499 2500 template <class Types> 2501 class OcclusionTrackerTestPerspectiveTransformBehindCamera 2502 : public OcclusionTrackerTest<Types> { 2503 protected: 2504 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera( 2505 bool opaque_layers) 2506 : OcclusionTrackerTest<Types>(opaque_layers) {} 2507 void RunMyTest() { 2508 // This test is based on the platform/chromium/compositing/3d-corners.html 2509 // layout test. 2510 gfx::Transform transform; 2511 transform.Translate(250.0, 50.0); 2512 transform.ApplyPerspectiveDepth(10.0); 2513 transform.Translate(-250.0, -50.0); 2514 transform.Translate(250.0, 50.0); 2515 transform.RotateAboutXAxis(-167.0); 2516 transform.Translate(-250.0, -50.0); 2517 2518 typename Types::ContentLayerType* parent = this->CreateRoot( 2519 this->identity_matrix, gfx::PointF(), gfx::Size(500, 100)); 2520 typename Types::LayerType* container = this->CreateLayer( 2521 parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500)); 2522 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( 2523 container, transform, gfx::PointF(), gfx::Size(500, 500), true); 2524 container->SetPreserves3d(true); 2525 layer->SetPreserves3d(true); 2526 this->CalcDrawEtc(parent); 2527 2528 TestOcclusionTrackerWithClip<typename Types::LayerType, 2529 typename Types::RenderSurfaceType> occlusion( 2530 gfx::Rect(0, 0, 1000, 1000)); 2531 this->EnterLayer(layer, &occlusion, false); 2532 2533 // The bottom 11 pixel rows of this layer remain visible inside the 2534 // container, after translation to the target surface. When translated back, 2535 // this will include many more pixels but must include at least the bottom 2536 // 11 rows. 2537 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( 2538 layer, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11))); 2539 } 2540 }; 2541 2542 // This test requires accumulating occlusion of 3d layers, which are skipped by 2543 // the occlusion tracker on the main thread. So this test should run on the impl 2544 // thread. 2545 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera); 2546 2547 template <class Types> 2548 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude 2549 : public OcclusionTrackerTest<Types> { 2550 protected: 2551 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude( 2552 bool opaque_layers) 2553 : OcclusionTrackerTest<Types>(opaque_layers) {} 2554 void RunMyTest() { 2555 gfx::Transform transform; 2556 transform.Translate(50.0, 50.0); 2557 transform.ApplyPerspectiveDepth(100.0); 2558 transform.Translate3d(0.0, 0.0, 110.0); 2559 transform.Translate(-50.0, -50.0); 2560 2561 typename Types::ContentLayerType* parent = this->CreateRoot( 2562 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 2563 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( 2564 parent, transform, gfx::PointF(), gfx::Size(100, 100), true); 2565 parent->SetPreserves3d(true); 2566 layer->SetPreserves3d(true); 2567 this->CalcDrawEtc(parent); 2568 2569 TestOcclusionTrackerWithClip<typename Types::LayerType, 2570 typename Types::RenderSurfaceType> occlusion( 2571 gfx::Rect(0, 0, 1000, 1000)); 2572 2573 // The |layer| is entirely behind the camera and should not occlude. 2574 this->VisitLayer(layer, &occlusion); 2575 this->EnterLayer(parent, &occlusion, false); 2576 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); 2577 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); 2578 } 2579 }; 2580 2581 // This test requires accumulating occlusion of 3d layers, which are skipped by 2582 // the occlusion tracker on the main thread. So this test should run on the impl 2583 // thread. 2584 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude); 2585 2586 template <class Types> 2587 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect 2588 : public OcclusionTrackerTest<Types> { 2589 protected: 2590 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect( 2591 bool opaque_layers) 2592 : OcclusionTrackerTest<Types>(opaque_layers) {} 2593 void RunMyTest() { 2594 gfx::Transform transform; 2595 transform.Translate(50.0, 50.0); 2596 transform.ApplyPerspectiveDepth(100.0); 2597 transform.Translate3d(0.0, 0.0, 99.0); 2598 transform.Translate(-50.0, -50.0); 2599 2600 typename Types::ContentLayerType* parent = this->CreateRoot( 2601 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); 2602 parent->SetMasksToBounds(true); 2603 typename Types::ContentLayerType* layer = this->CreateDrawingLayer( 2604 parent, transform, gfx::PointF(), gfx::Size(100, 100), true); 2605 parent->SetPreserves3d(true); 2606 layer->SetPreserves3d(true); 2607 this->CalcDrawEtc(parent); 2608 2609 TestOcclusionTrackerWithClip<typename Types::LayerType, 2610 typename Types::RenderSurfaceType> occlusion( 2611 gfx::Rect(0, 0, 1000, 1000)); 2612 2613 // This is very close to the camera, so pixels in its visible_content_rect() 2614 // will actually go outside of the layer's clip rect. Ensure that those 2615 // pixels don't occlude things outside the clip rect. 2616 this->VisitLayer(layer, &occlusion); 2617 this->EnterLayer(parent, &occlusion, false); 2618 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 2619 occlusion.occlusion_from_inside_target().ToString()); 2620 EXPECT_EQ(gfx::Rect().ToString(), 2621 occlusion.occlusion_from_outside_target().ToString()); 2622 } 2623 }; 2624 2625 // This test requires accumulating occlusion of 3d layers, which are skipped by 2626 // the occlusion tracker on the main thread. So this test should run on the impl 2627 // thread. 2628 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect); 2629 2630 template <class Types> 2631 class OcclusionTrackerTestAnimationOpacity1OnMainThread 2632 : public OcclusionTrackerTest<Types> { 2633 protected: 2634 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers) 2635 : OcclusionTrackerTest<Types>(opaque_layers) {} 2636 void RunMyTest() { 2637 // parent 2638 // +--layer 2639 // +--surface 2640 // | +--surface_child 2641 // | +--surface_child2 2642 // +--parent2 2643 // +--topmost 2644 2645 typename Types::ContentLayerType* parent = this->CreateRoot( 2646 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2647 typename Types::ContentLayerType* layer = 2648 this->CreateDrawingLayer(parent, 2649 this->identity_matrix, 2650 gfx::PointF(), 2651 gfx::Size(300, 300), 2652 true); 2653 typename Types::ContentLayerType* surface = 2654 this->CreateDrawingSurface(parent, 2655 this->identity_matrix, 2656 gfx::PointF(), 2657 gfx::Size(300, 300), 2658 true); 2659 typename Types::ContentLayerType* surface_child = 2660 this->CreateDrawingLayer(surface, 2661 this->identity_matrix, 2662 gfx::PointF(), 2663 gfx::Size(200, 300), 2664 true); 2665 typename Types::ContentLayerType* surface_child2 = 2666 this->CreateDrawingLayer(surface, 2667 this->identity_matrix, 2668 gfx::PointF(), 2669 gfx::Size(100, 300), 2670 true); 2671 typename Types::ContentLayerType* parent2 = 2672 this->CreateDrawingLayer(parent, 2673 this->identity_matrix, 2674 gfx::PointF(), 2675 gfx::Size(300, 300), 2676 false); 2677 typename Types::ContentLayerType* topmost = 2678 this->CreateDrawingLayer(parent, 2679 this->identity_matrix, 2680 gfx::PointF(250.f, 0.f), 2681 gfx::Size(50, 300), 2682 true); 2683 2684 AddOpacityTransitionToController( 2685 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false); 2686 AddOpacityTransitionToController( 2687 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false); 2688 this->CalcDrawEtc(parent); 2689 2690 EXPECT_TRUE(layer->draw_opacity_is_animating()); 2691 EXPECT_FALSE(surface->draw_opacity_is_animating()); 2692 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating()); 2693 2694 TestOcclusionTrackerWithClip<typename Types::LayerType, 2695 typename Types::RenderSurfaceType> occlusion( 2696 gfx::Rect(0, 0, 1000, 1000)); 2697 2698 this->VisitLayer(topmost, &occlusion); 2699 this->EnterLayer(parent2, &occlusion, false); 2700 // This occlusion will affect all surfaces. 2701 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 2702 occlusion.occlusion_from_inside_target().ToString()); 2703 EXPECT_EQ(gfx::Rect().ToString(), 2704 occlusion.occlusion_from_outside_target().ToString()); 2705 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(), 2706 occlusion.UnoccludedLayerContentRect( 2707 parent2, gfx::Rect(0, 0, 300, 300)).ToString()); 2708 this->LeaveLayer(parent2, &occlusion); 2709 2710 this->VisitLayer(surface_child2, &occlusion); 2711 this->EnterLayer(surface_child, &occlusion, false); 2712 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 2713 occlusion.occlusion_from_inside_target().ToString()); 2714 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 2715 occlusion.occlusion_from_outside_target().ToString()); 2716 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), 2717 occlusion.UnoccludedLayerContentRect( 2718 surface_child, gfx::Rect(0, 0, 200, 300))); 2719 this->LeaveLayer(surface_child, &occlusion); 2720 this->EnterLayer(surface, &occlusion, false); 2721 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), 2722 occlusion.occlusion_from_inside_target().ToString()); 2723 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 2724 occlusion.occlusion_from_outside_target().ToString()); 2725 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), 2726 occlusion.UnoccludedLayerContentRect( 2727 surface, gfx::Rect(0, 0, 300, 300))); 2728 this->LeaveLayer(surface, &occlusion); 2729 2730 this->EnterContributingSurface(surface, &occlusion, false); 2731 // Occlusion within the surface is lost when leaving the animating surface. 2732 EXPECT_EQ(gfx::Rect().ToString(), 2733 occlusion.occlusion_from_inside_target().ToString()); 2734 EXPECT_EQ(gfx::Rect().ToString(), 2735 occlusion.occlusion_from_outside_target().ToString()); 2736 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), 2737 occlusion.UnoccludedContributingSurfaceContentRect( 2738 surface, false, gfx::Rect(0, 0, 300, 300), NULL)); 2739 this->LeaveContributingSurface(surface, &occlusion); 2740 2741 // Occlusion from outside the animating surface still exists. 2742 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 2743 occlusion.occlusion_from_inside_target().ToString()); 2744 EXPECT_EQ(gfx::Rect().ToString(), 2745 occlusion.occlusion_from_outside_target().ToString()); 2746 2747 this->VisitLayer(layer, &occlusion); 2748 this->EnterLayer(parent, &occlusion, false); 2749 2750 // Occlusion is not added for the animating |layer|. 2751 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), 2752 occlusion.UnoccludedLayerContentRect( 2753 parent, gfx::Rect(0, 0, 300, 300))); 2754 } 2755 }; 2756 2757 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread); 2758 2759 template <class Types> 2760 class OcclusionTrackerTestAnimationOpacity0OnMainThread 2761 : public OcclusionTrackerTest<Types> { 2762 protected: 2763 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers) 2764 : OcclusionTrackerTest<Types>(opaque_layers) {} 2765 void RunMyTest() { 2766 typename Types::ContentLayerType* parent = this->CreateRoot( 2767 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2768 typename Types::ContentLayerType* layer = 2769 this->CreateDrawingLayer(parent, 2770 this->identity_matrix, 2771 gfx::PointF(), 2772 gfx::Size(300, 300), 2773 true); 2774 typename Types::ContentLayerType* surface = 2775 this->CreateDrawingSurface(parent, 2776 this->identity_matrix, 2777 gfx::PointF(), 2778 gfx::Size(300, 300), 2779 true); 2780 typename Types::ContentLayerType* surface_child = 2781 this->CreateDrawingLayer(surface, 2782 this->identity_matrix, 2783 gfx::PointF(), 2784 gfx::Size(200, 300), 2785 true); 2786 typename Types::ContentLayerType* surface_child2 = 2787 this->CreateDrawingLayer(surface, 2788 this->identity_matrix, 2789 gfx::PointF(), 2790 gfx::Size(100, 300), 2791 true); 2792 typename Types::ContentLayerType* parent2 = 2793 this->CreateDrawingLayer(parent, 2794 this->identity_matrix, 2795 gfx::PointF(), 2796 gfx::Size(300, 300), 2797 false); 2798 typename Types::ContentLayerType* topmost = 2799 this->CreateDrawingLayer(parent, 2800 this->identity_matrix, 2801 gfx::PointF(250.f, 0.f), 2802 gfx::Size(50, 300), 2803 true); 2804 2805 AddOpacityTransitionToController( 2806 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false); 2807 AddOpacityTransitionToController( 2808 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false); 2809 this->CalcDrawEtc(parent); 2810 2811 EXPECT_TRUE(layer->draw_opacity_is_animating()); 2812 EXPECT_FALSE(surface->draw_opacity_is_animating()); 2813 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating()); 2814 2815 TestOcclusionTrackerWithClip<typename Types::LayerType, 2816 typename Types::RenderSurfaceType> occlusion( 2817 gfx::Rect(0, 0, 1000, 1000)); 2818 2819 this->VisitLayer(topmost, &occlusion); 2820 this->EnterLayer(parent2, &occlusion, false); 2821 // This occlusion will affect all surfaces. 2822 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 2823 occlusion.occlusion_from_inside_target().ToString()); 2824 EXPECT_EQ(gfx::Rect().ToString(), 2825 occlusion.occlusion_from_outside_target().ToString()); 2826 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), 2827 occlusion.UnoccludedLayerContentRect( 2828 parent, gfx::Rect(0, 0, 300, 300))); 2829 this->LeaveLayer(parent2, &occlusion); 2830 2831 this->VisitLayer(surface_child2, &occlusion); 2832 this->EnterLayer(surface_child, &occlusion, false); 2833 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 2834 occlusion.occlusion_from_inside_target().ToString()); 2835 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 2836 occlusion.occlusion_from_outside_target().ToString()); 2837 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), 2838 occlusion.UnoccludedLayerContentRect( 2839 surface_child, gfx::Rect(0, 0, 200, 300))); 2840 this->LeaveLayer(surface_child, &occlusion); 2841 this->EnterLayer(surface, &occlusion, false); 2842 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), 2843 occlusion.occlusion_from_inside_target().ToString()); 2844 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 2845 occlusion.occlusion_from_outside_target().ToString()); 2846 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), 2847 occlusion.UnoccludedLayerContentRect( 2848 surface, gfx::Rect(0, 0, 300, 300))); 2849 this->LeaveLayer(surface, &occlusion); 2850 2851 this->EnterContributingSurface(surface, &occlusion, false); 2852 // Occlusion within the surface is lost when leaving the animating surface. 2853 EXPECT_EQ(gfx::Rect().ToString(), 2854 occlusion.occlusion_from_inside_target().ToString()); 2855 EXPECT_EQ(gfx::Rect().ToString(), 2856 occlusion.occlusion_from_outside_target().ToString()); 2857 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), 2858 occlusion.UnoccludedContributingSurfaceContentRect( 2859 surface, false, gfx::Rect(0, 0, 300, 300), NULL)); 2860 this->LeaveContributingSurface(surface, &occlusion); 2861 2862 // Occlusion from outside the animating surface still exists. 2863 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), 2864 occlusion.occlusion_from_inside_target().ToString()); 2865 EXPECT_EQ(gfx::Rect().ToString(), 2866 occlusion.occlusion_from_outside_target().ToString()); 2867 2868 this->VisitLayer(layer, &occlusion); 2869 this->EnterLayer(parent, &occlusion, false); 2870 2871 // Occlusion is not added for the animating |layer|. 2872 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), 2873 occlusion.UnoccludedLayerContentRect( 2874 parent, gfx::Rect(0, 0, 300, 300))); 2875 } 2876 }; 2877 2878 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread); 2879 2880 template <class Types> 2881 class OcclusionTrackerTestAnimationTranslateOnMainThread 2882 : public OcclusionTrackerTest<Types> { 2883 protected: 2884 explicit OcclusionTrackerTestAnimationTranslateOnMainThread( 2885 bool opaque_layers) 2886 : OcclusionTrackerTest<Types>(opaque_layers) {} 2887 void RunMyTest() { 2888 typename Types::ContentLayerType* parent = this->CreateRoot( 2889 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 2890 typename Types::ContentLayerType* layer = 2891 this->CreateDrawingLayer(parent, 2892 this->identity_matrix, 2893 gfx::PointF(), 2894 gfx::Size(300, 300), 2895 true); 2896 typename Types::ContentLayerType* surface = 2897 this->CreateDrawingSurface(parent, 2898 this->identity_matrix, 2899 gfx::PointF(), 2900 gfx::Size(300, 300), 2901 true); 2902 typename Types::ContentLayerType* surface_child = 2903 this->CreateDrawingLayer(surface, 2904 this->identity_matrix, 2905 gfx::PointF(), 2906 gfx::Size(200, 300), 2907 true); 2908 typename Types::ContentLayerType* surface_child2 = 2909 this->CreateDrawingLayer(surface, 2910 this->identity_matrix, 2911 gfx::PointF(), 2912 gfx::Size(100, 300), 2913 true); 2914 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface( 2915 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true); 2916 2917 AddAnimatedTransformToController( 2918 layer->layer_animation_controller(), 10.0, 30, 0); 2919 AddAnimatedTransformToController( 2920 surface->layer_animation_controller(), 10.0, 30, 0); 2921 AddAnimatedTransformToController( 2922 surface_child->layer_animation_controller(), 10.0, 30, 0); 2923 this->CalcDrawEtc(parent); 2924 2925 EXPECT_TRUE(layer->draw_transform_is_animating()); 2926 EXPECT_TRUE(layer->screen_space_transform_is_animating()); 2927 EXPECT_TRUE( 2928 surface->render_surface()->target_surface_transforms_are_animating()); 2929 EXPECT_TRUE( 2930 surface->render_surface()->screen_space_transforms_are_animating()); 2931 // The surface owning layer doesn't animate against its own surface. 2932 EXPECT_FALSE(surface->draw_transform_is_animating()); 2933 EXPECT_TRUE(surface->screen_space_transform_is_animating()); 2934 EXPECT_TRUE(surface_child->draw_transform_is_animating()); 2935 EXPECT_TRUE(surface_child->screen_space_transform_is_animating()); 2936 2937 TestOcclusionTrackerWithClip<typename Types::LayerType, 2938 typename Types::RenderSurfaceType> occlusion( 2939 gfx::Rect(0, 0, 1000, 1000)); 2940 2941 this->VisitLayer(surface2, &occlusion); 2942 this->EnterContributingSurface(surface2, &occlusion, false); 2943 2944 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), 2945 occlusion.occlusion_from_inside_target().ToString()); 2946 2947 this->LeaveContributingSurface(surface2, &occlusion); 2948 this->EnterLayer(surface_child2, &occlusion, false); 2949 2950 // surface_child2 is moving in screen space but not relative to its target, 2951 // so occlusion should happen in its target space only. It also means that 2952 // things occluding from outside the target (e.g. surface2) cannot occlude 2953 // this layer. 2954 EXPECT_EQ(gfx::Rect().ToString(), 2955 occlusion.occlusion_from_outside_target().ToString()); 2956 2957 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300), 2958 occlusion.UnoccludedLayerContentRect( 2959 surface_child2, gfx::Rect(0, 0, 100, 300))); 2960 EXPECT_FALSE( 2961 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300))); 2962 2963 this->LeaveLayer(surface_child2, &occlusion); 2964 this->EnterLayer(surface_child, &occlusion, false); 2965 EXPECT_FALSE( 2966 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300))); 2967 EXPECT_EQ(gfx::Rect().ToString(), 2968 occlusion.occlusion_from_outside_target().ToString()); 2969 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 2970 occlusion.occlusion_from_inside_target().ToString()); 2971 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), 2972 occlusion.UnoccludedLayerContentRect( 2973 surface, gfx::Rect(0, 0, 300, 300))); 2974 2975 // The surface_child is occluded by the surface_child2, but is moving 2976 // relative its target, so it can't be occluded. 2977 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300), 2978 occlusion.UnoccludedLayerContentRect( 2979 surface_child, gfx::Rect(0, 0, 200, 300))); 2980 EXPECT_FALSE( 2981 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300))); 2982 2983 this->LeaveLayer(surface_child, &occlusion); 2984 this->EnterLayer(surface, &occlusion, false); 2985 // The surface_child is moving in screen space but not relative to its 2986 // target, so occlusion should happen from within the target only. 2987 EXPECT_EQ(gfx::Rect().ToString(), 2988 occlusion.occlusion_from_outside_target().ToString()); 2989 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), 2990 occlusion.occlusion_from_inside_target().ToString()); 2991 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), 2992 occlusion.UnoccludedLayerContentRect( 2993 surface, gfx::Rect(0, 0, 300, 300))); 2994 2995 this->LeaveLayer(surface, &occlusion); 2996 // The surface's owning layer is moving in screen space but not relative to 2997 // its target, so occlusion should happen within the target only. 2998 EXPECT_EQ(gfx::Rect().ToString(), 2999 occlusion.occlusion_from_outside_target().ToString()); 3000 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), 3001 occlusion.occlusion_from_inside_target().ToString()); 3002 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), 3003 occlusion.UnoccludedLayerContentRect( 3004 surface, gfx::Rect(0, 0, 300, 300))); 3005 3006 this->EnterContributingSurface(surface, &occlusion, false); 3007 // The contributing |surface| is animating so it can't be occluded. 3008 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300), 3009 occlusion.UnoccludedContributingSurfaceContentRect( 3010 surface, false, gfx::Rect(0, 0, 300, 300), NULL)); 3011 this->LeaveContributingSurface(surface, &occlusion); 3012 3013 this->EnterLayer(layer, &occlusion, false); 3014 // The |surface| is moving in the screen and in its target, so all occlusion 3015 // within the surface is lost when leaving it. 3016 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), 3017 occlusion.UnoccludedLayerContentRect( 3018 parent, gfx::Rect(0, 0, 300, 300))); 3019 this->LeaveLayer(layer, &occlusion); 3020 3021 this->EnterLayer(parent, &occlusion, false); 3022 // The |layer| is animating in the screen and in its target, so no occlusion 3023 // is added. 3024 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), 3025 occlusion.UnoccludedLayerContentRect( 3026 parent, gfx::Rect(0, 0, 300, 300))); 3027 } 3028 }; 3029 3030 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread); 3031 3032 template <class Types> 3033 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent 3034 : public OcclusionTrackerTest<Types> { 3035 protected: 3036 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent( 3037 bool opaque_layers) 3038 : OcclusionTrackerTest<Types>(opaque_layers) {} 3039 void RunMyTest() { 3040 gfx::Transform surface_transform; 3041 surface_transform.Translate(300.0, 300.0); 3042 surface_transform.Scale(2.0, 2.0); 3043 surface_transform.Translate(-150.0, -150.0); 3044 3045 typename Types::ContentLayerType* parent = this->CreateRoot( 3046 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500)); 3047 typename Types::ContentLayerType* surface = this->CreateDrawingSurface( 3048 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false); 3049 typename Types::ContentLayerType* surface2 = 3050 this->CreateDrawingSurface(parent, 3051 this->identity_matrix, 3052 gfx::PointF(50.f, 50.f), 3053 gfx::Size(300, 300), 3054 false); 3055 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); 3056 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); 3057 this->CalcDrawEtc(parent); 3058 3059 TestOcclusionTrackerWithClip<typename Types::LayerType, 3060 typename Types::RenderSurfaceType> occlusion( 3061 gfx::Rect(0, 0, 1000, 1000)); 3062 3063 this->VisitLayer(surface2, &occlusion); 3064 this->VisitContributingSurface(surface2, &occlusion); 3065 3066 EXPECT_EQ(gfx::Rect().ToString(), 3067 occlusion.occlusion_from_outside_target().ToString()); 3068 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), 3069 occlusion.occlusion_from_inside_target().ToString()); 3070 3071 // Clear any stored occlusion. 3072 occlusion.set_occlusion_from_outside_target(Region()); 3073 occlusion.set_occlusion_from_inside_target(Region()); 3074 3075 this->VisitLayer(surface, &occlusion); 3076 this->VisitContributingSurface(surface, &occlusion); 3077 3078 EXPECT_EQ(gfx::Rect().ToString(), 3079 occlusion.occlusion_from_outside_target().ToString()); 3080 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), 3081 occlusion.occlusion_from_inside_target().ToString()); 3082 } 3083 }; 3084 3085 MAIN_AND_IMPL_THREAD_TEST( 3086 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent); 3087 3088 template <class Types> 3089 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping 3090 : public OcclusionTrackerTest<Types> { 3091 protected: 3092 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping( 3093 bool opaque_layers) 3094 : OcclusionTrackerTest<Types>(opaque_layers) {} 3095 void RunMyTest() { 3096 typename Types::ContentLayerType* parent = this->CreateRoot( 3097 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); 3098 parent->SetMasksToBounds(true); 3099 typename Types::ContentLayerType* surface = 3100 this->CreateDrawingSurface(parent, 3101 this->identity_matrix, 3102 gfx::PointF(), 3103 gfx::Size(500, 300), 3104 false); 3105 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200)); 3106 this->CalcDrawEtc(parent); 3107 3108 TestOcclusionTrackerWithClip<typename Types::LayerType, 3109 typename Types::RenderSurfaceType> occlusion( 3110 gfx::Rect(0, 0, 1000, 1000)); 3111 3112 this->VisitLayer(surface, &occlusion); 3113 this->VisitContributingSurface(surface, &occlusion); 3114 3115 EXPECT_EQ(gfx::Rect().ToString(), 3116 occlusion.occlusion_from_outside_target().ToString()); 3117 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), 3118 occlusion.occlusion_from_inside_target().ToString()); 3119 } 3120 }; 3121 3122 MAIN_AND_IMPL_THREAD_TEST( 3123 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping); 3124 3125 template <class Types> 3126 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> { 3127 protected: 3128 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers) 3129 : OcclusionTrackerTest<Types>(opaque_layers) {} 3130 void RunMyTest() { 3131 typename Types::ContentLayerType* parent = this->CreateRoot( 3132 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 3133 typename Types::LayerType* surface = 3134 this->CreateDrawingSurface(parent, 3135 this->identity_matrix, 3136 gfx::PointF(), 3137 gfx::Size(100, 100), 3138 true); 3139 this->CreateReplicaLayer(surface, 3140 this->identity_matrix, 3141 gfx::PointF(0.f, 100.f), 3142 gfx::Size(100, 100)); 3143 typename Types::LayerType* topmost = 3144 this->CreateDrawingLayer(parent, 3145 this->identity_matrix, 3146 gfx::PointF(0.f, 100.f), 3147 gfx::Size(100, 100), 3148 true); 3149 this->CalcDrawEtc(parent); 3150 3151 TestOcclusionTrackerWithClip<typename Types::LayerType, 3152 typename Types::RenderSurfaceType> occlusion( 3153 gfx::Rect(0, 0, 1000, 1000)); 3154 3155 // |topmost| occludes the replica, but not the surface itself. 3156 this->VisitLayer(topmost, &occlusion); 3157 3158 EXPECT_EQ(gfx::Rect().ToString(), 3159 occlusion.occlusion_from_outside_target().ToString()); 3160 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), 3161 occlusion.occlusion_from_inside_target().ToString()); 3162 3163 this->VisitLayer(surface, &occlusion); 3164 3165 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), 3166 occlusion.occlusion_from_outside_target().ToString()); 3167 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 3168 occlusion.occlusion_from_inside_target().ToString()); 3169 3170 this->EnterContributingSurface(surface, &occlusion, false); 3171 3172 // Surface is not occluded so it shouldn't think it is. 3173 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 3174 occlusion.UnoccludedContributingSurfaceContentRect( 3175 surface, false, gfx::Rect(0, 0, 100, 100), NULL)); 3176 } 3177 }; 3178 3179 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded); 3180 3181 template <class Types> 3182 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded 3183 : public OcclusionTrackerTest<Types> { 3184 protected: 3185 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers) 3186 : OcclusionTrackerTest<Types>(opaque_layers) {} 3187 void RunMyTest() { 3188 typename Types::ContentLayerType* parent = this->CreateRoot( 3189 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 3190 typename Types::LayerType* surface = 3191 this->CreateDrawingSurface(parent, 3192 this->identity_matrix, 3193 gfx::PointF(), 3194 gfx::Size(100, 100), 3195 true); 3196 this->CreateReplicaLayer(surface, 3197 this->identity_matrix, 3198 gfx::PointF(0.f, 100.f), 3199 gfx::Size(100, 100)); 3200 typename Types::LayerType* topmost = 3201 this->CreateDrawingLayer(parent, 3202 this->identity_matrix, 3203 gfx::PointF(), 3204 gfx::Size(100, 110), 3205 true); 3206 this->CalcDrawEtc(parent); 3207 3208 TestOcclusionTrackerWithClip<typename Types::LayerType, 3209 typename Types::RenderSurfaceType> occlusion( 3210 gfx::Rect(0, 0, 1000, 1000)); 3211 3212 // |topmost| occludes the surface, but not the entire surface's replica. 3213 this->VisitLayer(topmost, &occlusion); 3214 3215 EXPECT_EQ(gfx::Rect().ToString(), 3216 occlusion.occlusion_from_outside_target().ToString()); 3217 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), 3218 occlusion.occlusion_from_inside_target().ToString()); 3219 3220 this->VisitLayer(surface, &occlusion); 3221 3222 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), 3223 occlusion.occlusion_from_outside_target().ToString()); 3224 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 3225 occlusion.occlusion_from_inside_target().ToString()); 3226 3227 this->EnterContributingSurface(surface, &occlusion, false); 3228 3229 // Surface is occluded, but only the top 10px of the replica. 3230 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), 3231 occlusion.UnoccludedContributingSurfaceContentRect( 3232 surface, false, gfx::Rect(0, 0, 100, 100), NULL)); 3233 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90), 3234 occlusion.UnoccludedContributingSurfaceContentRect( 3235 surface, true, gfx::Rect(0, 0, 100, 100), NULL)); 3236 } 3237 }; 3238 3239 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded); 3240 3241 template <class Types> 3242 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently 3243 : public OcclusionTrackerTest<Types> { 3244 protected: 3245 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently( 3246 bool opaque_layers) 3247 : OcclusionTrackerTest<Types>(opaque_layers) {} 3248 void RunMyTest() { 3249 typename Types::ContentLayerType* parent = this->CreateRoot( 3250 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 3251 typename Types::LayerType* surface = 3252 this->CreateDrawingSurface(parent, 3253 this->identity_matrix, 3254 gfx::PointF(), 3255 gfx::Size(100, 100), 3256 true); 3257 this->CreateReplicaLayer(surface, 3258 this->identity_matrix, 3259 gfx::PointF(0.f, 100.f), 3260 gfx::Size(100, 100)); 3261 typename Types::LayerType* over_surface = this->CreateDrawingLayer( 3262 parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true); 3263 typename Types::LayerType* over_replica = 3264 this->CreateDrawingLayer(parent, 3265 this->identity_matrix, 3266 gfx::PointF(0.f, 100.f), 3267 gfx::Size(50, 100), 3268 true); 3269 this->CalcDrawEtc(parent); 3270 3271 TestOcclusionTrackerWithClip<typename Types::LayerType, 3272 typename Types::RenderSurfaceType> occlusion( 3273 gfx::Rect(0, 0, 1000, 1000)); 3274 3275 // These occlude the surface and replica differently, so we can test each 3276 // one. 3277 this->VisitLayer(over_replica, &occlusion); 3278 this->VisitLayer(over_surface, &occlusion); 3279 3280 EXPECT_EQ(gfx::Rect().ToString(), 3281 occlusion.occlusion_from_outside_target().ToString()); 3282 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)) 3283 .ToString(), 3284 occlusion.occlusion_from_inside_target().ToString()); 3285 3286 this->VisitLayer(surface, &occlusion); 3287 3288 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)) 3289 .ToString(), 3290 occlusion.occlusion_from_outside_target().ToString()); 3291 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 3292 occlusion.occlusion_from_inside_target().ToString()); 3293 3294 this->EnterContributingSurface(surface, &occlusion, false); 3295 3296 // Surface and replica are occluded different amounts. 3297 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100), 3298 occlusion.UnoccludedContributingSurfaceContentRect( 3299 surface, false, gfx::Rect(0, 0, 100, 100), NULL)); 3300 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100), 3301 occlusion.UnoccludedContributingSurfaceContentRect( 3302 surface, true, gfx::Rect(0, 0, 100, 100), NULL)); 3303 } 3304 }; 3305 3306 ALL_OCCLUSIONTRACKER_TEST( 3307 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently); 3308 3309 template <class Types> 3310 class OcclusionTrackerTestSurfaceChildOfSurface 3311 : public OcclusionTrackerTest<Types> { 3312 protected: 3313 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers) 3314 : OcclusionTrackerTest<Types>(opaque_layers) {} 3315 void RunMyTest() { 3316 // This test verifies that the surface cliprect does not end up empty and 3317 // clip away the entire unoccluded rect. 3318 3319 typename Types::ContentLayerType* parent = this->CreateRoot( 3320 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 3321 typename Types::LayerType* surface = 3322 this->CreateDrawingSurface(parent, 3323 this->identity_matrix, 3324 gfx::PointF(), 3325 gfx::Size(100, 100), 3326 true); 3327 typename Types::LayerType* surface_child = 3328 this->CreateDrawingSurface(surface, 3329 this->identity_matrix, 3330 gfx::PointF(0.f, 10.f), 3331 gfx::Size(100, 50), 3332 true); 3333 typename Types::LayerType* topmost = this->CreateDrawingLayer( 3334 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true); 3335 this->CalcDrawEtc(parent); 3336 3337 TestOcclusionTrackerWithClip<typename Types::LayerType, 3338 typename Types::RenderSurfaceType> occlusion( 3339 gfx::Rect(-100, -100, 1000, 1000)); 3340 3341 // |topmost| occludes everything partially so we know occlusion is happening 3342 // at all. 3343 this->VisitLayer(topmost, &occlusion); 3344 3345 EXPECT_EQ(gfx::Rect().ToString(), 3346 occlusion.occlusion_from_outside_target().ToString()); 3347 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 3348 occlusion.occlusion_from_inside_target().ToString()); 3349 3350 this->VisitLayer(surface_child, &occlusion); 3351 3352 // surface_child increases the occlusion in the screen by a narrow sliver. 3353 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(), 3354 occlusion.occlusion_from_outside_target().ToString()); 3355 // In its own surface, surface_child is at 0,0 as is its occlusion. 3356 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 3357 occlusion.occlusion_from_inside_target().ToString()); 3358 3359 // The root layer always has a clip rect. So the parent of |surface| has a 3360 // clip rect. However, the owning layer for |surface| does not mask to 3361 // bounds, so it doesn't have a clip rect of its own. Thus the parent of 3362 // |surface_child| exercises different code paths as its parent does not 3363 // have a clip rect. 3364 3365 this->EnterContributingSurface(surface_child, &occlusion, false); 3366 // The surface_child's parent does not have a clip rect as it owns a render 3367 // surface. Make sure the unoccluded rect does not get clipped away 3368 // inappropriately. 3369 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10), 3370 occlusion.UnoccludedContributingSurfaceContentRect( 3371 surface_child, false, gfx::Rect(0, 0, 100, 50), NULL)); 3372 this->LeaveContributingSurface(surface_child, &occlusion); 3373 3374 // When the surface_child's occlusion is transformed up to its parent, make 3375 // sure it is not clipped away inappropriately also. 3376 this->EnterLayer(surface, &occlusion, false); 3377 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 3378 occlusion.occlusion_from_outside_target().ToString()); 3379 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), 3380 occlusion.occlusion_from_inside_target().ToString()); 3381 this->LeaveLayer(surface, &occlusion); 3382 3383 this->EnterContributingSurface(surface, &occlusion, false); 3384 // The surface's parent does have a clip rect as it is the root layer. 3385 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50), 3386 occlusion.UnoccludedContributingSurfaceContentRect( 3387 surface, false, gfx::Rect(0, 0, 100, 100), NULL)); 3388 } 3389 }; 3390 3391 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface); 3392 3393 template <class Types> 3394 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport 3395 : public OcclusionTrackerTest<Types> { 3396 protected: 3397 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport( 3398 bool opaque_layers) 3399 : OcclusionTrackerTest<Types>(opaque_layers) {} 3400 void RunMyTest() { 3401 // This test verifies that the top-most surface is considered occluded 3402 // outside of its target's clip rect and outside the viewport rect. 3403 3404 typename Types::ContentLayerType* parent = this->CreateRoot( 3405 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); 3406 typename Types::LayerType* surface = 3407 this->CreateDrawingSurface(parent, 3408 this->identity_matrix, 3409 gfx::PointF(), 3410 gfx::Size(100, 300), 3411 true); 3412 this->CalcDrawEtc(parent); 3413 { 3414 // Make a viewport rect that is larger than the root layer. 3415 TestOcclusionTrackerWithClip<typename Types::LayerType, 3416 typename Types::RenderSurfaceType> occlusion( 3417 gfx::Rect(0, 0, 1000, 1000)); 3418 3419 this->VisitLayer(surface, &occlusion); 3420 3421 // The root layer always has a clip rect. So the parent of |surface| has a 3422 // clip rect giving the surface itself a clip rect. 3423 this->EnterContributingSurface(surface, &occlusion, false); 3424 // Make sure the parent's clip rect clips the unoccluded region of the 3425 // child surface. 3426 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200), 3427 occlusion.UnoccludedContributingSurfaceContentRect( 3428 surface, false, gfx::Rect(0, 0, 100, 300), NULL)); 3429 } 3430 this->ResetLayerIterator(); 3431 { 3432 // Make a viewport rect that is smaller than the root layer. 3433 TestOcclusionTrackerWithClip<typename Types::LayerType, 3434 typename Types::RenderSurfaceType> occlusion( 3435 gfx::Rect(0, 0, 100, 100)); 3436 3437 this->VisitLayer(surface, &occlusion); 3438 3439 // The root layer always has a clip rect. So the parent of |surface| has a 3440 // clip rect giving the surface itself a clip rect. 3441 this->EnterContributingSurface(surface, &occlusion, false); 3442 // Make sure the viewport rect clips the unoccluded region of the child 3443 // surface. 3444 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 3445 occlusion.UnoccludedContributingSurfaceContentRect( 3446 surface, false, gfx::Rect(0, 0, 100, 300), NULL)); 3447 } 3448 } 3449 }; 3450 3451 ALL_OCCLUSIONTRACKER_TEST( 3452 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport); 3453 3454 template <class Types> 3455 class OcclusionTrackerTestSurfaceChildOfClippingSurface 3456 : public OcclusionTrackerTest<Types> { 3457 protected: 3458 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers) 3459 : OcclusionTrackerTest<Types>(opaque_layers) {} 3460 void RunMyTest() { 3461 // This test verifies that the surface cliprect does not end up empty and 3462 // clip away the entire unoccluded rect. 3463 3464 typename Types::ContentLayerType* parent = this->CreateRoot( 3465 this->identity_matrix, gfx::PointF(), gfx::Size(80, 200)); 3466 parent->SetMasksToBounds(true); 3467 typename Types::LayerType* surface = 3468 this->CreateDrawingSurface(parent, 3469 this->identity_matrix, 3470 gfx::PointF(), 3471 gfx::Size(100, 100), 3472 true); 3473 typename Types::LayerType* surface_child = 3474 this->CreateDrawingSurface(surface, 3475 this->identity_matrix, 3476 gfx::PointF(), 3477 gfx::Size(100, 100), 3478 false); 3479 typename Types::LayerType* topmost = this->CreateDrawingLayer( 3480 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true); 3481 this->CalcDrawEtc(parent); 3482 3483 TestOcclusionTrackerWithClip<typename Types::LayerType, 3484 typename Types::RenderSurfaceType> occlusion( 3485 gfx::Rect(0, 0, 1000, 1000)); 3486 3487 // |topmost| occludes everything partially so we know occlusion is happening 3488 // at all. 3489 this->VisitLayer(topmost, &occlusion); 3490 3491 EXPECT_EQ(gfx::Rect().ToString(), 3492 occlusion.occlusion_from_outside_target().ToString()); 3493 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), 3494 occlusion.occlusion_from_inside_target().ToString()); 3495 3496 // surface_child is not opaque and does not occlude, so we have a non-empty 3497 // unoccluded area on surface. 3498 this->VisitLayer(surface_child, &occlusion); 3499 3500 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), 3501 occlusion.occlusion_from_outside_target().ToString()); 3502 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(), 3503 occlusion.occlusion_from_inside_target().ToString()); 3504 3505 // The root layer always has a clip rect. So the parent of |surface| has a 3506 // clip rect. However, the owning layer for |surface| does not mask to 3507 // bounds, so it doesn't have a clip rect of its own. Thus the parent of 3508 // |surface_child| exercises different code paths as its parent does not 3509 // have a clip rect. 3510 3511 this->EnterContributingSurface(surface_child, &occlusion, false); 3512 // The surface_child's parent does not have a clip rect as it owns a render 3513 // surface. 3514 EXPECT_EQ( 3515 gfx::Rect(0, 50, 80, 50).ToString(), 3516 occlusion.UnoccludedContributingSurfaceContentRect( 3517 surface_child, false, gfx::Rect(0, 0, 100, 100), NULL).ToString()); 3518 this->LeaveContributingSurface(surface_child, &occlusion); 3519 3520 this->VisitLayer(surface, &occlusion); 3521 this->EnterContributingSurface(surface, &occlusion, false); 3522 // The surface's parent does have a clip rect as it is the root layer. 3523 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(), 3524 occlusion.UnoccludedContributingSurfaceContentRect( 3525 surface, false, gfx::Rect(0, 0, 100, 100), NULL).ToString()); 3526 } 3527 }; 3528 3529 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface); 3530 3531 template <class Types> 3532 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter 3533 : public OcclusionTrackerTest<Types> { 3534 protected: 3535 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter( 3536 bool opaque_layers) 3537 : OcclusionTrackerTest<Types>(opaque_layers) {} 3538 void RunMyTest() { 3539 gfx::Transform scale_by_half; 3540 scale_by_half.Scale(0.5, 0.5); 3541 3542 // Make a surface and its replica, each 50x50, that are completely 3543 // surrounded by opaque layers which are above them in the z-order. The 3544 // surface is scaled to test that the pixel moving is done in the target 3545 // space, where the background filter is applied, but the surface appears at 3546 // 50, 50 and the replica at 200, 50. 3547 typename Types::ContentLayerType* parent = this->CreateRoot( 3548 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); 3549 typename Types::LayerType* filtered_surface = 3550 this->CreateDrawingLayer(parent, 3551 scale_by_half, 3552 gfx::PointF(50.f, 50.f), 3553 gfx::Size(100, 100), 3554 false); 3555 this->CreateReplicaLayer(filtered_surface, 3556 this->identity_matrix, 3557 gfx::PointF(300.f, 0.f), 3558 gfx::Size()); 3559 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer( 3560 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true); 3561 typename Types::LayerType* occluding_layer2 = 3562 this->CreateDrawingLayer(parent, 3563 this->identity_matrix, 3564 gfx::PointF(0.f, 100.f), 3565 gfx::Size(300, 50), 3566 true); 3567 typename Types::LayerType* occluding_layer3 = 3568 this->CreateDrawingLayer(parent, 3569 this->identity_matrix, 3570 gfx::PointF(0.f, 50.f), 3571 gfx::Size(50, 50), 3572 true); 3573 typename Types::LayerType* occluding_layer4 = 3574 this->CreateDrawingLayer(parent, 3575 this->identity_matrix, 3576 gfx::PointF(100.f, 50.f), 3577 gfx::Size(100, 50), 3578 true); 3579 typename Types::LayerType* occluding_layer5 = 3580 this->CreateDrawingLayer(parent, 3581 this->identity_matrix, 3582 gfx::PointF(250.f, 50.f), 3583 gfx::Size(50, 50), 3584 true); 3585 3586 // Filters make the layer own a surface. 3587 FilterOperations filters; 3588 filters.Append(FilterOperation::CreateBlurFilter(10.f)); 3589 filtered_surface->SetBackgroundFilters(filters); 3590 3591 // Save the distance of influence for the blur effect. 3592 int outset_top, outset_right, outset_bottom, outset_left; 3593 filters.GetOutsets( 3594 &outset_top, &outset_right, &outset_bottom, &outset_left); 3595 3596 this->CalcDrawEtc(parent); 3597 3598 TestOcclusionTrackerWithClip<typename Types::LayerType, 3599 typename Types::RenderSurfaceType> occlusion( 3600 gfx::Rect(0, 0, 1000, 1000)); 3601 3602 // These layers occlude pixels directly beside the filtered_surface. Because 3603 // filtered surface blends pixels in a radius, it will need to see some of 3604 // the pixels (up to radius far) underneath the occluding layers. 3605 this->VisitLayer(occluding_layer5, &occlusion); 3606 this->VisitLayer(occluding_layer4, &occlusion); 3607 this->VisitLayer(occluding_layer3, &occlusion); 3608 this->VisitLayer(occluding_layer2, &occlusion); 3609 this->VisitLayer(occluding_layer1, &occlusion); 3610 3611 Region expected_occlusion; 3612 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50)); 3613 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50)); 3614 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50)); 3615 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50)); 3616 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50)); 3617 3618 EXPECT_EQ(expected_occlusion.ToString(), 3619 occlusion.occlusion_from_inside_target().ToString()); 3620 EXPECT_EQ(gfx::Rect().ToString(), 3621 occlusion.occlusion_from_outside_target().ToString()); 3622 3623 this->VisitLayer(filtered_surface, &occlusion); 3624 3625 // The filtered layer/replica does not occlude. 3626 Region expected_occlusion_outside_surface; 3627 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50)); 3628 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50)); 3629 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50)); 3630 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50)); 3631 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50)); 3632 3633 EXPECT_EQ(expected_occlusion_outside_surface.ToString(), 3634 occlusion.occlusion_from_outside_target().ToString()); 3635 EXPECT_EQ(gfx::Rect().ToString(), 3636 occlusion.occlusion_from_inside_target().ToString()); 3637 3638 // The surface has a background blur, so it needs pixels that are currently 3639 // considered occluded in order to be drawn. So the pixels it needs should 3640 // be removed some the occluded area so that when we get to the parent they 3641 // are drawn. 3642 this->VisitContributingSurface(filtered_surface, &occlusion); 3643 3644 this->EnterLayer(parent, &occlusion, false); 3645 3646 Region expected_blurred_occlusion; 3647 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top)); 3648 expected_blurred_occlusion.Union(gfx::Rect( 3649 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom)); 3650 expected_blurred_occlusion.Union( 3651 gfx::Rect(100 + outset_right, 3652 50 - outset_top, 3653 100 - outset_right - outset_left, 3654 50 + outset_top + outset_bottom)); 3655 expected_blurred_occlusion.Union( 3656 gfx::Rect(250 + outset_right, 3657 50 - outset_top, 3658 50 - outset_right, 3659 50 + outset_top + outset_bottom)); 3660 expected_blurred_occlusion.Union( 3661 gfx::Rect(0, 100 + outset_bottom, 300, 50 - outset_bottom)); 3662 3663 EXPECT_EQ(expected_blurred_occlusion.ToString(), 3664 occlusion.occlusion_from_inside_target().ToString()); 3665 EXPECT_EQ(gfx::Rect().ToString(), 3666 occlusion.occlusion_from_outside_target().ToString()); 3667 3668 gfx::Rect outset_rect; 3669 gfx::Rect test_rect; 3670 3671 // Nothing in the blur outsets for the filtered_surface is occluded. 3672 outset_rect = gfx::Rect(50 - outset_left, 3673 50 - outset_top, 3674 50 + outset_left + outset_right, 3675 50 + outset_top + outset_bottom); 3676 test_rect = outset_rect; 3677 EXPECT_EQ( 3678 outset_rect.ToString(), 3679 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3680 3681 // Stuff outside the blur outsets is still occluded though. 3682 test_rect = outset_rect; 3683 test_rect.Inset(0, 0, -1, 0); 3684 EXPECT_EQ( 3685 outset_rect.ToString(), 3686 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3687 test_rect = outset_rect; 3688 test_rect.Inset(0, 0, 0, -1); 3689 EXPECT_EQ( 3690 outset_rect.ToString(), 3691 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3692 test_rect = outset_rect; 3693 test_rect.Inset(-1, 0, 0, 0); 3694 EXPECT_EQ( 3695 outset_rect.ToString(), 3696 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3697 test_rect = outset_rect; 3698 test_rect.Inset(0, -1, 0, 0); 3699 EXPECT_EQ( 3700 outset_rect.ToString(), 3701 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3702 3703 // Nothing in the blur outsets for the filtered_surface's replica is 3704 // occluded. 3705 outset_rect = gfx::Rect(200 - outset_left, 3706 50 - outset_top, 3707 50 + outset_left + outset_right, 3708 50 + outset_top + outset_bottom); 3709 test_rect = outset_rect; 3710 EXPECT_EQ( 3711 outset_rect.ToString(), 3712 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3713 3714 // Stuff outside the blur outsets is still occluded though. 3715 test_rect = outset_rect; 3716 test_rect.Inset(0, 0, -1, 0); 3717 EXPECT_EQ( 3718 outset_rect.ToString(), 3719 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3720 test_rect = outset_rect; 3721 test_rect.Inset(0, 0, 0, -1); 3722 EXPECT_EQ( 3723 outset_rect.ToString(), 3724 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3725 test_rect = outset_rect; 3726 test_rect.Inset(-1, 0, 0, 0); 3727 EXPECT_EQ( 3728 outset_rect.ToString(), 3729 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3730 test_rect = outset_rect; 3731 test_rect.Inset(0, -1, 0, 0); 3732 EXPECT_EQ( 3733 outset_rect.ToString(), 3734 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); 3735 } 3736 }; 3737 3738 ALL_OCCLUSIONTRACKER_TEST( 3739 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter); 3740 3741 template <class Types> 3742 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice 3743 : public OcclusionTrackerTest<Types> { 3744 protected: 3745 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice( 3746 bool opaque_layers) 3747 : OcclusionTrackerTest<Types>(opaque_layers) {} 3748 void RunMyTest() { 3749 gfx::Transform scale_by_half; 3750 scale_by_half.Scale(0.5, 0.5); 3751 3752 // Makes two surfaces that completely cover |parent|. The occlusion both 3753 // above and below the filters will be reduced by each of them. 3754 typename Types::ContentLayerType* root = this->CreateRoot( 3755 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75)); 3756 typename Types::LayerType* parent = this->CreateSurface( 3757 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150)); 3758 parent->SetMasksToBounds(true); 3759 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer( 3760 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); 3761 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer( 3762 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); 3763 typename Types::LayerType* occluding_layer_above = 3764 this->CreateDrawingLayer(parent, 3765 this->identity_matrix, 3766 gfx::PointF(100.f, 100.f), 3767 gfx::Size(50, 50), 3768 true); 3769 3770 // Filters make the layers own surfaces. 3771 FilterOperations filters; 3772 filters.Append(FilterOperation::CreateBlurFilter(1.f)); 3773 filtered_surface1->SetBackgroundFilters(filters); 3774 filtered_surface2->SetBackgroundFilters(filters); 3775 3776 // Save the distance of influence for the blur effect. 3777 int outset_top, outset_right, outset_bottom, outset_left; 3778 filters.GetOutsets( 3779 &outset_top, &outset_right, &outset_bottom, &outset_left); 3780 3781 this->CalcDrawEtc(root); 3782 3783 TestOcclusionTrackerWithClip<typename Types::LayerType, 3784 typename Types::RenderSurfaceType> occlusion( 3785 gfx::Rect(0, 0, 1000, 1000)); 3786 3787 this->VisitLayer(occluding_layer_above, &occlusion); 3788 EXPECT_EQ(gfx::Rect().ToString(), 3789 occlusion.occlusion_from_outside_target().ToString()); 3790 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), 3791 occlusion.occlusion_from_inside_target().ToString()); 3792 3793 this->VisitLayer(filtered_surface2, &occlusion); 3794 this->VisitContributingSurface(filtered_surface2, &occlusion); 3795 this->VisitLayer(filtered_surface1, &occlusion); 3796 this->VisitContributingSurface(filtered_surface1, &occlusion); 3797 3798 // Test expectations in the target. 3799 gfx::Rect expected_occlusion = 3800 gfx::Rect(100 / 2 + outset_right * 2, 3801 100 / 2 + outset_bottom * 2, 3802 50 / 2 - (outset_left + outset_right) * 2, 3803 50 / 2 - (outset_top + outset_bottom) * 2); 3804 EXPECT_EQ(expected_occlusion.ToString(), 3805 occlusion.occlusion_from_inside_target().ToString()); 3806 3807 // Test expectations in the screen are the same as in the target, as the 3808 // render surface is 1:1 with the screen. 3809 EXPECT_EQ(expected_occlusion.ToString(), 3810 occlusion.occlusion_from_outside_target().ToString()); 3811 } 3812 }; 3813 3814 ALL_OCCLUSIONTRACKER_TEST( 3815 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice); 3816 3817 template <class Types> 3818 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip 3819 : public OcclusionTrackerTest<Types> { 3820 protected: 3821 explicit 3822 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip( 3823 bool opaque_layers) 3824 : OcclusionTrackerTest<Types>(opaque_layers) {} 3825 void RunMyTest() { 3826 // Make a surface and its replica, Each 50x50, that are completely 3827 // surrounded by opaque layers which are above them in the z-order. 3828 typename Types::ContentLayerType* parent = this->CreateRoot( 3829 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); 3830 // We stick the filtered surface inside a clipping surface so that we can 3831 // make sure the clip is honored when exposing pixels for 3832 // the background filter. 3833 typename Types::LayerType* clipping_surface = 3834 this->CreateDrawingSurface(parent, 3835 this->identity_matrix, 3836 gfx::PointF(), 3837 gfx::Size(300, 70), 3838 false); 3839 clipping_surface->SetMasksToBounds(true); 3840 typename Types::LayerType* filtered_surface = 3841 this->CreateDrawingLayer(clipping_surface, 3842 this->identity_matrix, 3843 gfx::PointF(50.f, 50.f), 3844 gfx::Size(50, 50), 3845 false); 3846 this->CreateReplicaLayer(filtered_surface, 3847 this->identity_matrix, 3848 gfx::PointF(150.f, 0.f), 3849 gfx::Size()); 3850 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer( 3851 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true); 3852 typename Types::LayerType* occluding_layer2 = 3853 this->CreateDrawingLayer(parent, 3854 this->identity_matrix, 3855 gfx::PointF(0.f, 100.f), 3856 gfx::Size(300, 50), 3857 true); 3858 typename Types::LayerType* occluding_layer3 = 3859 this->CreateDrawingLayer(parent, 3860 this->identity_matrix, 3861 gfx::PointF(0.f, 50.f), 3862 gfx::Size(50, 50), 3863 true); 3864 typename Types::LayerType* occluding_layer4 = 3865 this->CreateDrawingLayer(parent, 3866 this->identity_matrix, 3867 gfx::PointF(100.f, 50.f), 3868 gfx::Size(100, 50), 3869 true); 3870 typename Types::LayerType* occluding_layer5 = 3871 this->CreateDrawingLayer(parent, 3872 this->identity_matrix, 3873 gfx::PointF(250.f, 50.f), 3874 gfx::Size(50, 50), 3875 true); 3876 3877 // Filters make the layer own a surface. This filter is large enough that it 3878 // goes outside the bottom of the clipping_surface. 3879 FilterOperations filters; 3880 filters.Append(FilterOperation::CreateBlurFilter(12.f)); 3881 filtered_surface->SetBackgroundFilters(filters); 3882 3883 // Save the distance of influence for the blur effect. 3884 int outset_top, outset_right, outset_bottom, outset_left; 3885 filters.GetOutsets( 3886 &outset_top, &outset_right, &outset_bottom, &outset_left); 3887 3888 this->CalcDrawEtc(parent); 3889 3890 TestOcclusionTrackerWithClip<typename Types::LayerType, 3891 typename Types::RenderSurfaceType> occlusion( 3892 gfx::Rect(0, 0, 1000, 1000)); 3893 3894 // These layers occlude pixels directly beside the filtered_surface. Because 3895 // filtered surface blends pixels in a radius, it will need to see some of 3896 // the pixels (up to radius far) underneath the occluding layers. 3897 this->VisitLayer(occluding_layer5, &occlusion); 3898 this->VisitLayer(occluding_layer4, &occlusion); 3899 this->VisitLayer(occluding_layer3, &occlusion); 3900 this->VisitLayer(occluding_layer2, &occlusion); 3901 this->VisitLayer(occluding_layer1, &occlusion); 3902 3903 Region expected_occlusion; 3904 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50)); 3905 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50)); 3906 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50)); 3907 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50)); 3908 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50)); 3909 3910 EXPECT_EQ(expected_occlusion.ToString(), 3911 occlusion.occlusion_from_inside_target().ToString()); 3912 EXPECT_EQ(gfx::Rect().ToString(), 3913 occlusion.occlusion_from_outside_target().ToString()); 3914 3915 // Everything outside the surface/replica is occluded but the 3916 // surface/replica itself is not. 3917 this->VisitLayer(filtered_surface, &occlusion); 3918 3919 // The filtered layer/replica does not occlude. 3920 Region expected_occlusion_outside_surface; 3921 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50)); 3922 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50)); 3923 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50)); 3924 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50)); 3925 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50)); 3926 3927 EXPECT_EQ(expected_occlusion_outside_surface.ToString(), 3928 occlusion.occlusion_from_outside_target().ToString()); 3929 EXPECT_EQ(gfx::Rect().ToString(), 3930 occlusion.occlusion_from_inside_target().ToString()); 3931 3932 // The surface has a background blur, so it needs pixels that are currently 3933 // considered occluded in order to be drawn. So the pixels it needs should 3934 // be removed some the occluded area so that when we get to the parent they 3935 // are drawn. 3936 this->VisitContributingSurface(filtered_surface, &occlusion); 3937 3938 this->VisitLayer(clipping_surface, &occlusion); 3939 this->EnterContributingSurface(clipping_surface, &occlusion, false); 3940 3941 Region expected_blurred_occlusion; 3942 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top)); 3943 expected_blurred_occlusion.Union(gfx::Rect( 3944 0, 50 - outset_top, 50 - outset_left, 20 + outset_top + outset_bottom)); 3945 expected_blurred_occlusion.Union( 3946 gfx::Rect(100 + outset_right, 3947 50 - outset_top, 3948 100 - outset_right - outset_left, 3949 20 + outset_top + outset_bottom)); 3950 expected_blurred_occlusion.Union( 3951 gfx::Rect(250 + outset_right, 3952 50 - outset_top, 3953 50 - outset_right, 3954 20 + outset_top + outset_bottom)); 3955 expected_blurred_occlusion.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5)); 3956 3957 EXPECT_EQ(expected_blurred_occlusion.ToString(), 3958 occlusion.occlusion_from_outside_target().ToString()); 3959 EXPECT_EQ(gfx::Rect().ToString(), 3960 occlusion.occlusion_from_inside_target().ToString()); 3961 3962 gfx::Rect outset_rect; 3963 gfx::Rect clipped_outset_rect; 3964 gfx::Rect test_rect; 3965 3966 // Nothing in the (clipped) blur outsets for the filtered_surface is 3967 // occluded. 3968 outset_rect = gfx::Rect(50 - outset_left, 3969 50 - outset_top, 3970 50 + outset_left + outset_right, 3971 50 + outset_top + outset_bottom); 3972 clipped_outset_rect = outset_rect; 3973 clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left, 3974 0 - outset_top, 3975 300 + outset_left + outset_right, 3976 70 + outset_top + outset_bottom)); 3977 clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70)); 3978 test_rect = outset_rect; 3979 EXPECT_RECT_EQ( 3980 clipped_outset_rect, 3981 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 3982 3983 // Stuff outside the (clipped) blur outsets is still occluded though. 3984 test_rect = outset_rect; 3985 test_rect.Inset(0, 0, -1, 0); 3986 EXPECT_RECT_EQ( 3987 clipped_outset_rect, 3988 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 3989 test_rect = outset_rect; 3990 test_rect.Inset(0, 0, 0, -1); 3991 EXPECT_RECT_EQ( 3992 clipped_outset_rect, 3993 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 3994 test_rect = outset_rect; 3995 test_rect.Inset(-1, 0, 0, 0); 3996 EXPECT_RECT_EQ( 3997 clipped_outset_rect, 3998 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 3999 test_rect = outset_rect; 4000 test_rect.Inset(0, -1, 0, 0); 4001 EXPECT_RECT_EQ( 4002 clipped_outset_rect, 4003 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 4004 4005 // Nothing in the (clipped) blur outsets for the filtered_surface's replica 4006 // is occluded. 4007 outset_rect = gfx::Rect(200 - outset_left, 4008 50 - outset_top, 4009 50 + outset_left + outset_right, 4010 50 + outset_top + outset_bottom); 4011 clipped_outset_rect = outset_rect; 4012 clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left, 4013 0 - outset_top, 4014 300 + outset_left + outset_right, 4015 70 + outset_top + outset_bottom)); 4016 clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70)); 4017 test_rect = outset_rect; 4018 EXPECT_RECT_EQ( 4019 clipped_outset_rect, 4020 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 4021 4022 // Stuff outside the (clipped) blur outsets is still occluded though. 4023 test_rect = outset_rect; 4024 test_rect.Inset(0, 0, -1, 0); 4025 EXPECT_RECT_EQ( 4026 clipped_outset_rect, 4027 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 4028 test_rect = outset_rect; 4029 test_rect.Inset(0, 0, 0, -1); 4030 EXPECT_RECT_EQ( 4031 clipped_outset_rect, 4032 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 4033 test_rect = outset_rect; 4034 test_rect.Inset(-1, 0, 0, 0); 4035 EXPECT_RECT_EQ( 4036 clipped_outset_rect, 4037 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 4038 test_rect = outset_rect; 4039 test_rect.Inset(0, -1, 0, 0); 4040 EXPECT_RECT_EQ( 4041 clipped_outset_rect, 4042 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect)); 4043 } 4044 }; 4045 4046 ALL_OCCLUSIONTRACKER_TEST( 4047 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip); 4048 4049 template <class Types> 4050 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter 4051 : public OcclusionTrackerTest<Types> { 4052 protected: 4053 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter( 4054 bool opaque_layers) 4055 : OcclusionTrackerTest<Types>(opaque_layers) {} 4056 void RunMyTest() { 4057 gfx::Transform scale_by_half; 4058 scale_by_half.Scale(0.5, 0.5); 4059 4060 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer 4061 // centered below each. The surface is scaled to test that the pixel moving 4062 // is done in the target space, where the background filter is applied, but 4063 // the surface appears at 50, 50 and the replica at 200, 50. 4064 typename Types::ContentLayerType* parent = this->CreateRoot( 4065 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); 4066 typename Types::LayerType* behind_surface_layer = 4067 this->CreateDrawingLayer(parent, 4068 this->identity_matrix, 4069 gfx::PointF(60.f, 60.f), 4070 gfx::Size(30, 30), 4071 true); 4072 typename Types::LayerType* behind_replica_layer = 4073 this->CreateDrawingLayer(parent, 4074 this->identity_matrix, 4075 gfx::PointF(210.f, 60.f), 4076 gfx::Size(30, 30), 4077 true); 4078 typename Types::LayerType* filtered_surface = 4079 this->CreateDrawingLayer(parent, 4080 scale_by_half, 4081 gfx::PointF(50.f, 50.f), 4082 gfx::Size(100, 100), 4083 false); 4084 this->CreateReplicaLayer(filtered_surface, 4085 this->identity_matrix, 4086 gfx::PointF(300.f, 0.f), 4087 gfx::Size()); 4088 4089 // Filters make the layer own a surface. 4090 FilterOperations filters; 4091 filters.Append(FilterOperation::CreateBlurFilter(3.f)); 4092 filtered_surface->SetBackgroundFilters(filters); 4093 4094 this->CalcDrawEtc(parent); 4095 4096 TestOcclusionTrackerWithClip<typename Types::LayerType, 4097 typename Types::RenderSurfaceType> occlusion( 4098 gfx::Rect(0, 0, 1000, 1000)); 4099 4100 // The surface has a background blur, so it blurs non-opaque pixels below 4101 // it. 4102 this->VisitLayer(filtered_surface, &occlusion); 4103 this->VisitContributingSurface(filtered_surface, &occlusion); 4104 4105 this->VisitLayer(behind_replica_layer, &occlusion); 4106 this->VisitLayer(behind_surface_layer, &occlusion); 4107 4108 // The layers behind the surface are not blurred, and their occlusion does 4109 // not change, until we leave the surface. So it should not be modified by 4110 // the filter here. 4111 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30); 4112 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30); 4113 4114 Region expected_opaque_bounds = 4115 UnionRegions(occlusion_behind_surface, occlusion_behind_replica); 4116 EXPECT_EQ(expected_opaque_bounds.ToString(), 4117 occlusion.occlusion_from_inside_target().ToString()); 4118 4119 EXPECT_EQ(gfx::Rect().ToString(), 4120 occlusion.occlusion_from_outside_target().ToString()); 4121 } 4122 }; 4123 4124 ALL_OCCLUSIONTRACKER_TEST( 4125 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter); 4126 4127 template <class Types> 4128 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded 4129 : public OcclusionTrackerTest<Types> { 4130 protected: 4131 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded( 4132 bool opaque_layers) 4133 : OcclusionTrackerTest<Types>(opaque_layers) {} 4134 void RunMyTest() { 4135 gfx::Transform scale_by_half; 4136 scale_by_half.Scale(0.5, 0.5); 4137 4138 // Make a surface and its replica, each 50x50, that are completely occluded 4139 // by opaque layers which are above them in the z-order. The surface is 4140 // scaled to test that the pixel moving is done in the target space, where 4141 // the background filter is applied, but the surface appears at 50, 50 and 4142 // the replica at 200, 50. 4143 typename Types::ContentLayerType* parent = this->CreateRoot( 4144 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); 4145 typename Types::LayerType* filtered_surface = 4146 this->CreateDrawingLayer(parent, 4147 scale_by_half, 4148 gfx::PointF(50.f, 50.f), 4149 gfx::Size(100, 100), 4150 false); 4151 this->CreateReplicaLayer(filtered_surface, 4152 this->identity_matrix, 4153 gfx::PointF(300.f, 0.f), 4154 gfx::Size()); 4155 typename Types::LayerType* above_surface_layer = 4156 this->CreateDrawingLayer(parent, 4157 this->identity_matrix, 4158 gfx::PointF(50.f, 50.f), 4159 gfx::Size(50, 50), 4160 true); 4161 typename Types::LayerType* above_replica_layer = 4162 this->CreateDrawingLayer(parent, 4163 this->identity_matrix, 4164 gfx::PointF(200.f, 50.f), 4165 gfx::Size(50, 50), 4166 true); 4167 4168 // Filters make the layer own a surface. 4169 FilterOperations filters; 4170 filters.Append(FilterOperation::CreateBlurFilter(3.f)); 4171 filtered_surface->SetBackgroundFilters(filters); 4172 4173 this->CalcDrawEtc(parent); 4174 4175 TestOcclusionTrackerWithClip<typename Types::LayerType, 4176 typename Types::RenderSurfaceType> occlusion( 4177 gfx::Rect(0, 0, 1000, 1000)); 4178 4179 this->VisitLayer(above_replica_layer, &occlusion); 4180 this->VisitLayer(above_surface_layer, &occlusion); 4181 4182 this->VisitLayer(filtered_surface, &occlusion); 4183 { 4184 // The layers above the filtered surface occlude from outside. 4185 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50); 4186 gfx::Rect occlusion_above_replica = gfx::Rect(150, 0, 50, 50); 4187 Region expected_opaque_region = 4188 UnionRegions(occlusion_above_surface, occlusion_above_replica); 4189 4190 EXPECT_EQ(gfx::Rect().ToString(), 4191 occlusion.occlusion_from_inside_target().ToString()); 4192 EXPECT_EQ(expected_opaque_region.ToString(), 4193 occlusion.occlusion_from_outside_target().ToString()); 4194 } 4195 4196 // The surface has a background blur, so it blurs non-opaque pixels below 4197 // it. 4198 this->VisitContributingSurface(filtered_surface, &occlusion); 4199 { 4200 // The filter is completely occluded, so it should not blur anything and 4201 // reduce any occlusion. 4202 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50); 4203 gfx::Rect occlusion_above_replica = gfx::Rect(200, 50, 50, 50); 4204 Region expected_opaque_region = 4205 UnionRegions(occlusion_above_surface, occlusion_above_replica); 4206 4207 EXPECT_EQ(expected_opaque_region.ToString(), 4208 occlusion.occlusion_from_inside_target().ToString()); 4209 EXPECT_EQ(gfx::Rect().ToString(), 4210 occlusion.occlusion_from_outside_target().ToString()); 4211 } 4212 } 4213 }; 4214 4215 ALL_OCCLUSIONTRACKER_TEST( 4216 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded); 4217 4218 template <class Types> 4219 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded 4220 : public OcclusionTrackerTest<Types> { 4221 protected: 4222 explicit 4223 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded( 4224 bool opaque_layers) 4225 : OcclusionTrackerTest<Types>(opaque_layers) {} 4226 void RunMyTest() { 4227 gfx::Transform scale_by_half; 4228 scale_by_half.Scale(0.5, 0.5); 4229 4230 // Make a surface and its replica, each 50x50, that are partially occluded 4231 // by opaque layers which are above them in the z-order. The surface is 4232 // scaled to test that the pixel moving is done in the target space, where 4233 // the background filter is applied, but the surface appears at 50, 50 and 4234 // the replica at 200, 50. 4235 typename Types::ContentLayerType* parent = this->CreateRoot( 4236 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); 4237 typename Types::LayerType* filtered_surface = 4238 this->CreateDrawingLayer(parent, 4239 scale_by_half, 4240 gfx::PointF(50.f, 50.f), 4241 gfx::Size(100, 100), 4242 false); 4243 this->CreateReplicaLayer(filtered_surface, 4244 this->identity_matrix, 4245 gfx::PointF(300.f, 0.f), 4246 gfx::Size()); 4247 typename Types::LayerType* above_surface_layer = 4248 this->CreateDrawingLayer(parent, 4249 this->identity_matrix, 4250 gfx::PointF(70.f, 50.f), 4251 gfx::Size(30, 50), 4252 true); 4253 typename Types::LayerType* above_replica_layer = 4254 this->CreateDrawingLayer(parent, 4255 this->identity_matrix, 4256 gfx::PointF(200.f, 50.f), 4257 gfx::Size(30, 50), 4258 true); 4259 typename Types::LayerType* beside_surface_layer = 4260 this->CreateDrawingLayer(parent, 4261 this->identity_matrix, 4262 gfx::PointF(90.f, 40.f), 4263 gfx::Size(10, 10), 4264 true); 4265 typename Types::LayerType* beside_replica_layer = 4266 this->CreateDrawingLayer(parent, 4267 this->identity_matrix, 4268 gfx::PointF(200.f, 40.f), 4269 gfx::Size(10, 10), 4270 true); 4271 4272 // Filters make the layer own a surface. 4273 FilterOperations filters; 4274 filters.Append(FilterOperation::CreateBlurFilter(3.f)); 4275 filtered_surface->SetBackgroundFilters(filters); 4276 4277 // Save the distance of influence for the blur effect. 4278 int outset_top, outset_right, outset_bottom, outset_left; 4279 filters.GetOutsets( 4280 &outset_top, &outset_right, &outset_bottom, &outset_left); 4281 4282 this->CalcDrawEtc(parent); 4283 4284 TestOcclusionTrackerWithClip<typename Types::LayerType, 4285 typename Types::RenderSurfaceType> occlusion( 4286 gfx::Rect(0, 0, 1000, 1000)); 4287 4288 this->VisitLayer(beside_replica_layer, &occlusion); 4289 this->VisitLayer(beside_surface_layer, &occlusion); 4290 this->VisitLayer(above_replica_layer, &occlusion); 4291 this->VisitLayer(above_surface_layer, &occlusion); 4292 4293 // The surface has a background blur, so it blurs non-opaque pixels below 4294 // it. 4295 this->VisitLayer(filtered_surface, &occlusion); 4296 this->VisitContributingSurface(filtered_surface, &occlusion); 4297 4298 // The filter in the surface and replica are partially unoccluded. Only the 4299 // unoccluded parts should reduce occlusion. This means it will push back 4300 // the occlusion that touches the unoccluded part (occlusion_above___), but 4301 // it will not touch occlusion_beside____ since that is not beside the 4302 // unoccluded part of the surface, even though it is beside the occluded 4303 // part of the surface. 4304 gfx::Rect occlusion_above_surface = 4305 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50); 4306 gfx::Rect occlusion_above_replica = 4307 gfx::Rect(200, 50, 30 - outset_left, 50); 4308 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10); 4309 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10); 4310 4311 Region expected_occlusion; 4312 expected_occlusion.Union(occlusion_above_surface); 4313 expected_occlusion.Union(occlusion_above_replica); 4314 expected_occlusion.Union(occlusion_beside_surface); 4315 expected_occlusion.Union(occlusion_beside_replica); 4316 4317 ASSERT_EQ(expected_occlusion.ToString(), 4318 occlusion.occlusion_from_inside_target().ToString()); 4319 EXPECT_EQ(gfx::Rect().ToString(), 4320 occlusion.occlusion_from_outside_target().ToString()); 4321 4322 Region::Iterator expected_rects(expected_occlusion); 4323 Region::Iterator target_surface_rects( 4324 occlusion.occlusion_from_inside_target()); 4325 for (; expected_rects.has_rect(); 4326 expected_rects.next(), target_surface_rects.next()) { 4327 ASSERT_TRUE(target_surface_rects.has_rect()); 4328 EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect()); 4329 } 4330 } 4331 }; 4332 4333 ALL_OCCLUSIONTRACKER_TEST( 4334 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded); 4335 4336 template <class Types> 4337 class OcclusionTrackerTestMinimumTrackingSize 4338 : public OcclusionTrackerTest<Types> { 4339 protected: 4340 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers) 4341 : OcclusionTrackerTest<Types>(opaque_layers) {} 4342 void RunMyTest() { 4343 gfx::Size tracking_size(100, 100); 4344 gfx::Size below_tracking_size(99, 99); 4345 4346 typename Types::ContentLayerType* parent = this->CreateRoot( 4347 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 4348 typename Types::LayerType* large = this->CreateDrawingLayer( 4349 parent, this->identity_matrix, gfx::PointF(), tracking_size, true); 4350 typename Types::LayerType* small = 4351 this->CreateDrawingLayer(parent, 4352 this->identity_matrix, 4353 gfx::PointF(), 4354 below_tracking_size, 4355 true); 4356 this->CalcDrawEtc(parent); 4357 4358 TestOcclusionTrackerWithClip<typename Types::LayerType, 4359 typename Types::RenderSurfaceType> occlusion( 4360 gfx::Rect(0, 0, 1000, 1000)); 4361 occlusion.set_minimum_tracking_size(tracking_size); 4362 4363 // The small layer is not tracked because it is too small. 4364 this->VisitLayer(small, &occlusion); 4365 4366 EXPECT_EQ(gfx::Rect().ToString(), 4367 occlusion.occlusion_from_outside_target().ToString()); 4368 EXPECT_EQ(gfx::Rect().ToString(), 4369 occlusion.occlusion_from_inside_target().ToString()); 4370 4371 // The large layer is tracked as it is large enough. 4372 this->VisitLayer(large, &occlusion); 4373 4374 EXPECT_EQ(gfx::Rect().ToString(), 4375 occlusion.occlusion_from_outside_target().ToString()); 4376 EXPECT_EQ(gfx::Rect(tracking_size).ToString(), 4377 occlusion.occlusion_from_inside_target().ToString()); 4378 } 4379 }; 4380 4381 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize); 4382 4383 template <class Types> 4384 class OcclusionTrackerTestViewportClipIsExternalOcclusion 4385 : public OcclusionTrackerTest<Types> { 4386 protected: 4387 explicit OcclusionTrackerTestViewportClipIsExternalOcclusion( 4388 bool opaque_layers) 4389 : OcclusionTrackerTest<Types>(opaque_layers) {} 4390 void RunMyTest() { 4391 typename Types::ContentLayerType* parent = this->CreateRoot( 4392 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 4393 typename Types::LayerType* small = 4394 this->CreateDrawingSurface(parent, 4395 this->identity_matrix, 4396 gfx::PointF(), 4397 gfx::Size(200, 200), 4398 false); 4399 typename Types::LayerType* large = 4400 this->CreateDrawingLayer(small, 4401 this->identity_matrix, 4402 gfx::PointF(), 4403 gfx::Size(400, 400), 4404 false); 4405 small->SetMasksToBounds(true); 4406 this->CalcDrawEtc(parent); 4407 4408 TestOcclusionTrackerWithClip<typename Types::LayerType, 4409 typename Types::RenderSurfaceType> occlusion( 4410 gfx::Rect(0, 0, 100, 100)); 4411 4412 this->EnterLayer(large, &occlusion, false); 4413 4414 bool has_occlusion_from_outside_target_surface = false; 4415 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 4416 occlusion.UnoccludedLayerContentRect( 4417 large, 4418 gfx::Rect(0, 0, 400, 400), 4419 &has_occlusion_from_outside_target_surface)); 4420 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4421 4422 has_occlusion_from_outside_target_surface = false; 4423 EXPECT_FALSE( 4424 occlusion.OccludedLayer(large, 4425 gfx::Rect(0, 0, 400, 400), 4426 &has_occlusion_from_outside_target_surface)); 4427 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4428 4429 this->LeaveLayer(large, &occlusion); 4430 this->VisitLayer(small, &occlusion); 4431 4432 has_occlusion_from_outside_target_surface = false; 4433 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 4434 occlusion.UnoccludedLayerContentRect( 4435 small, 4436 gfx::Rect(0, 0, 200, 200), 4437 &has_occlusion_from_outside_target_surface)); 4438 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4439 4440 has_occlusion_from_outside_target_surface = false; 4441 EXPECT_FALSE( 4442 occlusion.OccludedLayer(small, 4443 gfx::Rect(0, 0, 200, 200), 4444 &has_occlusion_from_outside_target_surface)); 4445 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4446 4447 this->EnterContributingSurface(small, &occlusion, false); 4448 4449 has_occlusion_from_outside_target_surface = false; 4450 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 4451 occlusion.UnoccludedContributingSurfaceContentRect( 4452 small, 4453 false, 4454 gfx::Rect(0, 0, 200, 200), 4455 &has_occlusion_from_outside_target_surface)); 4456 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4457 } 4458 }; 4459 4460 ALL_OCCLUSIONTRACKER_TEST( 4461 OcclusionTrackerTestViewportClipIsExternalOcclusion) 4462 4463 template <class Types> 4464 class OcclusionTrackerTestLayerClipIsExternalOcclusion 4465 : public OcclusionTrackerTest<Types> { 4466 protected: 4467 explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers) 4468 : OcclusionTrackerTest<Types>(opaque_layers) {} 4469 void RunMyTest() { 4470 typename Types::ContentLayerType* parent = this->CreateRoot( 4471 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 4472 typename Types::LayerType* smallest = this->CreateDrawingLayer( 4473 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false); 4474 typename Types::LayerType* smaller = 4475 this->CreateDrawingSurface(smallest, 4476 this->identity_matrix, 4477 gfx::PointF(), 4478 gfx::Size(100, 100), 4479 false); 4480 typename Types::LayerType* small = 4481 this->CreateDrawingSurface(smaller, 4482 this->identity_matrix, 4483 gfx::PointF(), 4484 gfx::Size(200, 200), 4485 false); 4486 typename Types::LayerType* large = 4487 this->CreateDrawingLayer(small, 4488 this->identity_matrix, 4489 gfx::PointF(), 4490 gfx::Size(400, 400), 4491 false); 4492 smallest->SetMasksToBounds(true); 4493 smaller->SetMasksToBounds(true); 4494 small->SetMasksToBounds(true); 4495 this->CalcDrawEtc(parent); 4496 4497 TestOcclusionTrackerWithClip<typename Types::LayerType, 4498 typename Types::RenderSurfaceType> occlusion( 4499 gfx::Rect(0, 0, 1000, 1000)); 4500 4501 this->EnterLayer(large, &occlusion, false); 4502 4503 // Clipping from the smaller layer is from outside the target surface. 4504 bool has_occlusion_from_outside_target_surface = false; 4505 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 4506 occlusion.UnoccludedLayerContentRect( 4507 large, 4508 gfx::Rect(0, 0, 400, 400), 4509 &has_occlusion_from_outside_target_surface)); 4510 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4511 4512 has_occlusion_from_outside_target_surface = false; 4513 EXPECT_FALSE( 4514 occlusion.OccludedLayer(large, 4515 gfx::Rect(0, 0, 400, 400), 4516 &has_occlusion_from_outside_target_surface)); 4517 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4518 4519 this->LeaveLayer(large, &occlusion); 4520 this->VisitLayer(small, &occlusion); 4521 4522 // Clipping from the smaller layer is from outside the target surface. 4523 has_occlusion_from_outside_target_surface = false; 4524 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 4525 occlusion.UnoccludedLayerContentRect( 4526 small, 4527 gfx::Rect(0, 0, 200, 200), 4528 &has_occlusion_from_outside_target_surface)); 4529 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4530 4531 has_occlusion_from_outside_target_surface = false; 4532 EXPECT_FALSE( 4533 occlusion.OccludedLayer(small, 4534 gfx::Rect(0, 0, 200, 200), 4535 &has_occlusion_from_outside_target_surface)); 4536 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4537 4538 this->EnterContributingSurface(small, &occlusion, false); 4539 4540 // The |small| surface is clipped from outside its target by |smallest|. 4541 has_occlusion_from_outside_target_surface = false; 4542 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), 4543 occlusion.UnoccludedContributingSurfaceContentRect( 4544 small, 4545 false, 4546 gfx::Rect(0, 0, 200, 200), 4547 &has_occlusion_from_outside_target_surface)); 4548 EXPECT_TRUE(has_occlusion_from_outside_target_surface); 4549 4550 this->LeaveContributingSurface(small, &occlusion); 4551 this->VisitLayer(smaller, &occlusion); 4552 this->EnterContributingSurface(smaller, &occlusion, false); 4553 4554 // The |smaller| surface is clipped from inside its target by |smallest|. 4555 has_occlusion_from_outside_target_surface = false; 4556 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), 4557 occlusion.UnoccludedContributingSurfaceContentRect( 4558 smaller, 4559 false, 4560 gfx::Rect(0, 0, 100, 100), 4561 &has_occlusion_from_outside_target_surface)); 4562 EXPECT_FALSE(has_occlusion_from_outside_target_surface); 4563 } 4564 }; 4565 4566 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion) 4567 4568 template <class Types> 4569 class OcclusionTrackerTestPreventOcclusionOnLayer 4570 : public OcclusionTrackerTest<Types> { 4571 protected: 4572 explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers) 4573 : OcclusionTrackerTest<Types>(opaque_layers) {} 4574 void RunMyTest() { 4575 typename Types::ContentLayerType* parent = this->CreateRoot( 4576 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 4577 typename Types::LayerType* unprevented = this->CreateDrawingLayer( 4578 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false); 4579 typename Types::LayerType* prevented = this->CreateDrawingLayer( 4580 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false); 4581 typename Types::LayerType* occluding = this->CreateDrawingLayer( 4582 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true); 4583 this->CalcDrawEtc(parent); 4584 4585 TestOcclusionTrackerWithClip<typename Types::LayerType, 4586 typename Types::RenderSurfaceType> occlusion( 4587 gfx::Rect(0, 0, 1000, 1000)); 4588 bool external_occlusion = false; 4589 4590 this->VisitLayer(occluding, &occlusion); 4591 this->EnterLayer(prevented, &occlusion, true); 4592 4593 // This layer is not occluded because it is prevented. 4594 EXPECT_FALSE(occlusion.OccludedLayer(prevented, 4595 gfx::Rect(50, 50), 4596 &external_occlusion)); 4597 EXPECT_FALSE(external_occlusion); 4598 4599 EXPECT_EQ(gfx::Rect(50, 50).ToString(), 4600 occlusion.UnoccludedLayerContentRect( 4601 prevented, 4602 gfx::Rect(50, 50), 4603 &external_occlusion).ToString()); 4604 EXPECT_FALSE(external_occlusion); 4605 4606 this->LeaveLayer(prevented, &occlusion); 4607 this->EnterLayer(unprevented, &occlusion, false); 4608 4609 // This layer is fully occluded. 4610 EXPECT_TRUE(occlusion.OccludedLayer(unprevented, 4611 gfx::Rect(50, 50), 4612 &external_occlusion)); 4613 EXPECT_FALSE(external_occlusion); 4614 4615 EXPECT_EQ(gfx::Rect().ToString(), 4616 occlusion.UnoccludedLayerContentRect( 4617 unprevented, 4618 gfx::Rect(50, 50), 4619 &external_occlusion).ToString()); 4620 EXPECT_FALSE(external_occlusion); 4621 4622 this->LeaveLayer(unprevented, &occlusion); 4623 } 4624 }; 4625 4626 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer) 4627 4628 template <class Types> 4629 class OcclusionTrackerTestPreventOcclusionOnContributingSurface 4630 : public OcclusionTrackerTest<Types> { 4631 protected: 4632 explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface( 4633 bool opaque_layers) 4634 : OcclusionTrackerTest<Types>(opaque_layers) {} 4635 void RunMyTest() { 4636 typename Types::ContentLayerType* parent = this->CreateRoot( 4637 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 4638 typename Types::LayerType* unprevented = this->CreateDrawingSurface( 4639 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false); 4640 typename Types::LayerType* prevented = this->CreateDrawingSurface( 4641 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false); 4642 typename Types::LayerType* occluding = this->CreateDrawingLayer( 4643 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true); 4644 this->CalcDrawEtc(parent); 4645 4646 TestOcclusionTrackerWithClip<typename Types::LayerType, 4647 typename Types::RenderSurfaceType> occlusion( 4648 gfx::Rect(0, 0, 1000, 1000)); 4649 bool external_occlusion = false; 4650 4651 this->VisitLayer(occluding, &occlusion); 4652 this->EnterLayer(prevented, &occlusion, true); 4653 4654 // This layer is not occluded because it is prevented. 4655 EXPECT_EQ(gfx::Rect(50, 50).ToString(), 4656 occlusion.UnoccludedLayerContentRect( 4657 prevented, 4658 gfx::Rect(50, 50), 4659 &external_occlusion).ToString()); 4660 EXPECT_FALSE(external_occlusion); 4661 4662 this->LeaveLayer(prevented, &occlusion); 4663 this->EnterContributingSurface(prevented, &occlusion, true); 4664 4665 // This contributing surface is not occluded because it is prevented. 4666 EXPECT_EQ(gfx::Rect(50, 50).ToString(), 4667 occlusion.UnoccludedContributingSurfaceContentRect( 4668 prevented, 4669 false, // is_replica 4670 gfx::Rect(50, 50), 4671 &external_occlusion).ToString()); 4672 EXPECT_FALSE(external_occlusion); 4673 4674 this->LeaveContributingSurface(prevented, &occlusion); 4675 this->EnterLayer(unprevented, &occlusion, false); 4676 4677 // This layer is fully occluded from outside its surface. 4678 EXPECT_EQ(gfx::Rect().ToString(), 4679 occlusion.UnoccludedLayerContentRect( 4680 unprevented, 4681 gfx::Rect(50, 50), 4682 &external_occlusion).ToString()); 4683 EXPECT_TRUE(external_occlusion); 4684 4685 this->LeaveLayer(unprevented, &occlusion); 4686 this->EnterContributingSurface(unprevented, &occlusion, false); 4687 4688 // This contributing surface is fully occluded. 4689 EXPECT_EQ(gfx::Rect().ToString(), 4690 occlusion.UnoccludedContributingSurfaceContentRect( 4691 unprevented, 4692 false, // is_replica 4693 gfx::Rect(50, 50), 4694 &external_occlusion).ToString()); 4695 EXPECT_FALSE(external_occlusion); 4696 4697 this->LeaveContributingSurface(unprevented, &occlusion); 4698 } 4699 }; 4700 4701 ALL_OCCLUSIONTRACKER_TEST( 4702 OcclusionTrackerTestPreventOcclusionOnContributingSurface) 4703 4704 template <class Types> 4705 class OcclusionTrackerTestPreventOcclusionByClipping 4706 : public OcclusionTrackerTest<Types> { 4707 protected: 4708 explicit OcclusionTrackerTestPreventOcclusionByClipping(bool opaque_layers) 4709 : OcclusionTrackerTest<Types>(opaque_layers) {} 4710 void RunMyTest() { 4711 typename Types::ContentLayerType* parent = this->CreateRoot( 4712 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 4713 typename Types::LayerType* unprevented = this->CreateDrawingLayer( 4714 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false); 4715 typename Types::LayerType* prevented = this->CreateDrawingLayer( 4716 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false); 4717 this->CalcDrawEtc(parent); 4718 4719 TestOcclusionTrackerWithClip<typename Types::LayerType, 4720 typename Types::RenderSurfaceType> occlusion( 4721 gfx::Rect(0, 0, 10, 10)); 4722 bool external_occlusion = false; 4723 4724 this->EnterLayer(prevented, &occlusion, true); 4725 4726 // This layer is not occluded because it is prevented. 4727 EXPECT_FALSE(occlusion.OccludedLayer(prevented, 4728 gfx::Rect(50, 50), 4729 &external_occlusion)); 4730 EXPECT_FALSE(external_occlusion); 4731 4732 EXPECT_EQ(gfx::Rect(50, 50).ToString(), 4733 occlusion.UnoccludedLayerContentRect( 4734 prevented, 4735 gfx::Rect(50, 50), 4736 &external_occlusion).ToString()); 4737 EXPECT_FALSE(external_occlusion); 4738 4739 this->LeaveLayer(prevented, &occlusion); 4740 this->EnterLayer(unprevented, &occlusion, false); 4741 4742 // This layer is clipped by the screen space clip rect. 4743 EXPECT_EQ(gfx::Rect(10, 10).ToString(), 4744 occlusion.UnoccludedLayerContentRect( 4745 unprevented, 4746 gfx::Rect(50, 50), 4747 &external_occlusion).ToString()); 4748 EXPECT_TRUE(external_occlusion); 4749 4750 this->LeaveLayer(unprevented, &occlusion); 4751 } 4752 }; 4753 4754 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionByClipping) 4755 4756 template <class Types> 4757 class OcclusionTrackerTestScaledLayerIsClipped 4758 : public OcclusionTrackerTest<Types> { 4759 protected: 4760 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers) 4761 : OcclusionTrackerTest<Types>(opaque_layers) {} 4762 void RunMyTest() { 4763 gfx::Transform scale_transform; 4764 scale_transform.Scale(512.0, 512.0); 4765 4766 typename Types::ContentLayerType* parent = this->CreateRoot( 4767 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 4768 typename Types::LayerType* clip = this->CreateLayer(parent, 4769 this->identity_matrix, 4770 gfx::PointF(10.f, 10.f), 4771 gfx::Size(50, 50)); 4772 clip->SetMasksToBounds(true); 4773 typename Types::LayerType* scale = this->CreateLayer( 4774 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1)); 4775 typename Types::LayerType* scaled = this->CreateDrawingLayer( 4776 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); 4777 this->CalcDrawEtc(parent); 4778 4779 TestOcclusionTrackerWithClip<typename Types::LayerType, 4780 typename Types::RenderSurfaceType> occlusion( 4781 gfx::Rect(0, 0, 1000, 1000)); 4782 4783 this->VisitLayer(scaled, &occlusion); 4784 4785 EXPECT_EQ(gfx::Rect().ToString(), 4786 occlusion.occlusion_from_outside_target().ToString()); 4787 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), 4788 occlusion.occlusion_from_inside_target().ToString()); 4789 } 4790 }; 4791 4792 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped) 4793 4794 template <class Types> 4795 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped 4796 : public OcclusionTrackerTest<Types> { 4797 protected: 4798 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers) 4799 : OcclusionTrackerTest<Types>(opaque_layers) {} 4800 void RunMyTest() { 4801 gfx::Transform scale_transform; 4802 scale_transform.Scale(512.0, 512.0); 4803 4804 typename Types::ContentLayerType* parent = this->CreateRoot( 4805 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); 4806 typename Types::LayerType* clip = this->CreateLayer(parent, 4807 this->identity_matrix, 4808 gfx::PointF(10.f, 10.f), 4809 gfx::Size(50, 50)); 4810 clip->SetMasksToBounds(true); 4811 typename Types::LayerType* surface = this->CreateDrawingSurface( 4812 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false); 4813 typename Types::LayerType* scale = this->CreateLayer( 4814 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1)); 4815 typename Types::LayerType* scaled = this->CreateDrawingLayer( 4816 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); 4817 this->CalcDrawEtc(parent); 4818 4819 TestOcclusionTrackerWithClip<typename Types::LayerType, 4820 typename Types::RenderSurfaceType> occlusion( 4821 gfx::Rect(0, 0, 1000, 1000)); 4822 4823 this->VisitLayer(scaled, &occlusion); 4824 this->VisitLayer(surface, &occlusion); 4825 this->VisitContributingSurface(surface, &occlusion); 4826 4827 EXPECT_EQ(gfx::Rect().ToString(), 4828 occlusion.occlusion_from_outside_target().ToString()); 4829 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), 4830 occlusion.occlusion_from_inside_target().ToString()); 4831 } 4832 }; 4833 4834 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped) 4835 4836 template <class Types> 4837 class OcclusionTrackerTestCopyRequestDoesOcclude 4838 : public OcclusionTrackerTest<Types> { 4839 protected: 4840 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers) 4841 : OcclusionTrackerTest<Types>(opaque_layers) {} 4842 void RunMyTest() { 4843 typename Types::ContentLayerType* root = this->CreateRoot( 4844 this->identity_matrix, gfx::Point(), gfx::Size(400, 400)); 4845 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 4846 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true); 4847 typename Types::LayerType* copy = this->CreateLayer(parent, 4848 this->identity_matrix, 4849 gfx::Point(100, 0), 4850 gfx::Size(200, 400)); 4851 this->AddCopyRequest(copy); 4852 typename Types::LayerType* copy_child = this->CreateDrawingLayer( 4853 copy, 4854 this->identity_matrix, 4855 gfx::PointF(), 4856 gfx::Size(200, 400), 4857 true); 4858 this->CalcDrawEtc(root); 4859 4860 TestOcclusionTrackerWithClip<typename Types::LayerType, 4861 typename Types::RenderSurfaceType> occlusion( 4862 gfx::Rect(0, 0, 1000, 1000)); 4863 4864 this->VisitLayer(copy_child, &occlusion); 4865 EXPECT_EQ(gfx::Rect().ToString(), 4866 occlusion.occlusion_from_outside_target().ToString()); 4867 EXPECT_EQ(gfx::Rect(200, 400).ToString(), 4868 occlusion.occlusion_from_inside_target().ToString()); 4869 4870 // CopyRequests cause the layer to own a surface. 4871 this->VisitContributingSurface(copy, &occlusion); 4872 4873 // The occlusion from the copy should be kept. 4874 EXPECT_EQ(gfx::Rect().ToString(), 4875 occlusion.occlusion_from_outside_target().ToString()); 4876 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(), 4877 occlusion.occlusion_from_inside_target().ToString()); 4878 } 4879 }; 4880 4881 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude) 4882 4883 template <class Types> 4884 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude 4885 : public OcclusionTrackerTest<Types> { 4886 protected: 4887 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude( 4888 bool opaque_layers) 4889 : OcclusionTrackerTest<Types>(opaque_layers) {} 4890 void RunMyTest() { 4891 typename Types::ContentLayerType* root = this->CreateRoot( 4892 this->identity_matrix, gfx::Point(), gfx::Size(400, 400)); 4893 typename Types::ContentLayerType* parent = this->CreateDrawingLayer( 4894 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true); 4895 typename Types::LayerType* hide = this->CreateLayer( 4896 parent, this->identity_matrix, gfx::Point(), gfx::Size()); 4897 typename Types::LayerType* copy = this->CreateLayer( 4898 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400)); 4899 this->AddCopyRequest(copy); 4900 typename Types::LayerType* copy_child = this->CreateDrawingLayer( 4901 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true); 4902 4903 // The |copy| layer is hidden but since it is being copied, it will be 4904 // drawn. 4905 hide->SetHideLayerAndSubtree(true); 4906 4907 this->CalcDrawEtc(root); 4908 4909 TestOcclusionTrackerWithClip<typename Types::LayerType, 4910 typename Types::RenderSurfaceType> occlusion( 4911 gfx::Rect(0, 0, 1000, 1000)); 4912 4913 this->VisitLayer(copy_child, &occlusion); 4914 EXPECT_EQ(gfx::Rect().ToString(), 4915 occlusion.occlusion_from_outside_target().ToString()); 4916 EXPECT_EQ(gfx::Rect(200, 400).ToString(), 4917 occlusion.occlusion_from_inside_target().ToString()); 4918 4919 // CopyRequests cause the layer to own a surface. 4920 this->VisitContributingSurface(copy, &occlusion); 4921 4922 // The occlusion from the copy should be dropped since it is hidden. 4923 EXPECT_EQ(gfx::Rect().ToString(), 4924 occlusion.occlusion_from_outside_target().ToString()); 4925 EXPECT_EQ(gfx::Rect().ToString(), 4926 occlusion.occlusion_from_inside_target().ToString()); 4927 } 4928 }; 4929 4930 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude) 4931 4932 } // namespace 4933 } // namespace cc 4934