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