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