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/debug/overdraw_metrics.h"
10 #include "cc/layers/layer.h"
11 #include "cc/layers/layer_impl.h"
12 #include "cc/test/animation_test_common.h"
13 #include "cc/test/fake_impl_proxy.h"
14 #include "cc/test/fake_layer_tree_host_impl.h"
15 #include "cc/test/geometry_test_utils.h"
16 #include "cc/test/occlusion_tracker_test_common.h"
17 #include "cc/trees/layer_tree_host_common.h"
18 #include "cc/trees/single_thread_proxy.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.h"
22 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h"
23 #include "ui/gfx/transform.h"
28 class TestContentLayer
: public Layer
{
30 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {}
32 virtual bool DrawsContent() const OVERRIDE
{ return true; }
33 virtual Region
VisibleContentOpaqueRegion() const OVERRIDE
{
34 if (override_opaque_contents_rect_
)
35 return gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect());
36 return Layer::VisibleContentOpaqueRegion();
38 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect
) {
39 override_opaque_contents_rect_
= true;
40 opaque_contents_rect_
= opaque_contents_rect
;
44 virtual ~TestContentLayer() {}
46 bool override_opaque_contents_rect_
;
47 gfx::Rect opaque_contents_rect_
;
50 class TestContentLayerImpl
: public LayerImpl
{
52 TestContentLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
53 : LayerImpl(tree_impl
, id
), override_opaque_contents_rect_(false) {
54 SetDrawsContent(true);
57 virtual Region
VisibleContentOpaqueRegion() const OVERRIDE
{
58 if (override_opaque_contents_rect_
)
59 return gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect());
60 return LayerImpl::VisibleContentOpaqueRegion();
62 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect
) {
63 override_opaque_contents_rect_
= true;
64 opaque_contents_rect_
= opaque_contents_rect
;
68 bool override_opaque_contents_rect_
;
69 gfx::Rect opaque_contents_rect_
;
72 static inline bool LayerImplDrawTransformIsUnknown(const Layer
* layer
) {
73 return layer
->draw_transform_is_animating();
75 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl
* layer
) {
79 template <typename LayerType
, typename RenderSurfaceType
>
80 class TestOcclusionTrackerWithClip
81 : public TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
> {
83 TestOcclusionTrackerWithClip(gfx::Rect viewport_rect
,
84 bool record_metrics_for_frame
)
85 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(
87 record_metrics_for_frame
) {}
88 explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect
)
89 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(viewport_rect
,
92 bool OccludedLayer(const LayerType
* layer
, gfx::Rect content_rect
) {
94 return OccludedLayer(layer
, content_rect
, &temp
);
97 bool OccludedLayer(const LayerType
* layer
,
98 gfx::Rect content_rect
,
99 bool* has_occlusion_from_outside_target_surface
) const {
100 return this->Occluded(layer
->render_target(),
102 layer
->draw_transform(),
103 LayerImplDrawTransformIsUnknown(layer
),
106 has_occlusion_from_outside_target_surface
);
108 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
109 // layer. Simple wrapper around UnoccludedContentRect.
110 gfx::Rect
UnoccludedLayerContentRect(const LayerType
* layer
,
111 gfx::Rect content_rect
) const {
113 return UnoccludedLayerContentRect(layer
, content_rect
, &temp
);
116 gfx::Rect
UnoccludedLayerContentRect(
117 const LayerType
* layer
,
118 gfx::Rect content_rect
,
119 bool* has_occlusion_from_outside_target_surface
) const {
120 return this->UnoccludedContentRect(
121 layer
->render_target(),
123 layer
->draw_transform(),
124 LayerImplDrawTransformIsUnknown(layer
),
127 has_occlusion_from_outside_target_surface
);
131 struct OcclusionTrackerTestMainThreadTypes
{
132 typedef Layer LayerType
;
133 typedef LayerTreeHost HostType
;
134 typedef RenderSurface RenderSurfaceType
;
135 typedef TestContentLayer ContentLayerType
;
136 typedef scoped_refptr
<Layer
> LayerPtrType
;
137 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
138 typedef LayerIterator
<Layer
,
141 LayerIteratorActions::FrontToBack
> TestLayerIterator
;
142 typedef OcclusionTracker OcclusionTrackerType
;
144 static LayerPtrType
CreateLayer(HostType
* host
) { return Layer::Create(); }
145 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
146 return make_scoped_refptr(new ContentLayerType());
149 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
150 LayerPtrType
ref(*layer
);
155 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
156 LayerPtrType
ref(*layer
);
161 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
164 struct OcclusionTrackerTestImplThreadTypes
{
165 typedef LayerImpl LayerType
;
166 typedef LayerTreeImpl HostType
;
167 typedef RenderSurfaceImpl RenderSurfaceType
;
168 typedef TestContentLayerImpl ContentLayerType
;
169 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
170 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
171 typedef LayerIterator
<LayerImpl
,
174 LayerIteratorActions::FrontToBack
> TestLayerIterator
;
175 typedef OcclusionTrackerImpl OcclusionTrackerType
;
177 static LayerPtrType
CreateLayer(HostType
* host
) {
178 return LayerImpl::Create(host
, next_layer_impl_id
++);
180 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
181 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
183 static int next_layer_impl_id
;
185 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
186 return layer
->Pass();
189 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
190 return layer
->PassAs
<LayerType
>();
193 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
196 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
198 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
200 explicit OcclusionTrackerTest(bool opaque_layers
)
201 : host_impl_(&proxy_
), opaque_layers_(opaque_layers
) {}
203 virtual void RunMyTest() = 0;
205 virtual void TearDown() {
206 Types::DestroyLayer(&root_
);
207 render_surface_layer_list_
.clear();
208 render_surface_layer_list_impl_
.clear();
209 replica_layers_
.clear();
210 mask_layers_
.clear();
213 typename
Types::HostType
* GetHost();
215 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
216 gfx::PointF position
,
218 typename
Types::ContentLayerPtrType
layer(
219 Types::CreateContentLayer(GetHost()));
220 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
221 SetProperties(layer_ptr
, transform
, position
, bounds
);
224 root_
= Types::PassLayerPtr(&layer
);
228 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
229 const gfx::Transform
& transform
,
230 gfx::PointF position
,
232 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
233 typename
Types::LayerType
* layer_ptr
= layer
.get();
234 SetProperties(layer_ptr
, transform
, position
, bounds
);
235 parent
->AddChild(Types::PassLayerPtr(&layer
));
239 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
240 const gfx::Transform
& transform
,
241 gfx::PointF position
,
243 typename
Types::LayerType
* layer
=
244 CreateLayer(parent
, transform
, position
, bounds
);
245 layer
->SetForceRenderSurface(true);
249 typename
Types::ContentLayerType
* CreateDrawingLayer(
250 typename
Types::LayerType
* parent
,
251 const gfx::Transform
& transform
,
252 gfx::PointF position
,
255 typename
Types::ContentLayerPtrType
layer(
256 Types::CreateContentLayer(GetHost()));
257 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
258 SetProperties(layer_ptr
, transform
, position
, bounds
);
260 if (opaque_layers_
) {
261 layer_ptr
->SetContentsOpaque(opaque
);
263 layer_ptr
->SetContentsOpaque(false);
265 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
267 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
270 parent
->AddChild(Types::PassLayerPtr(&layer
));
274 typename
Types::LayerType
* CreateReplicaLayer(
275 typename
Types::LayerType
* owning_layer
,
276 const gfx::Transform
& transform
,
277 gfx::PointF position
,
279 typename
Types::ContentLayerPtrType
layer(
280 Types::CreateContentLayer(GetHost()));
281 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
282 SetProperties(layer_ptr
, transform
, position
, bounds
);
283 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
287 typename
Types::LayerType
* CreateMaskLayer(
288 typename
Types::LayerType
* owning_layer
,
290 typename
Types::ContentLayerPtrType
layer(
291 Types::CreateContentLayer(GetHost()));
292 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
293 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
294 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
298 typename
Types::ContentLayerType
* CreateDrawingSurface(
299 typename
Types::LayerType
* parent
,
300 const gfx::Transform
& transform
,
301 gfx::PointF position
,
304 typename
Types::ContentLayerType
* layer
=
305 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
306 layer
->SetForceRenderSurface(true);
310 void CalcDrawEtc(TestContentLayerImpl
* root
) {
311 DCHECK(root
== root_
.get());
312 int dummy_max_texture_size
= 512;
314 DCHECK(!root
->render_surface());
316 LayerTreeHostCommon::CalculateDrawProperties(
322 dummy_max_texture_size
,
324 &render_surface_layer_list_impl_
,
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 int dummy_max_texture_size
= 512;
335 DCHECK(!root
->render_surface());
337 LayerTreeHostCommon::CalculateDrawProperties(root
,
342 dummy_max_texture_size
,
344 &render_surface_layer_list_
);
346 layer_iterator_
= layer_iterator_begin_
=
347 Types::TestLayerIterator::Begin(&render_surface_layer_list_
);
350 void EnterLayer(typename
Types::LayerType
* layer
,
351 typename
Types::OcclusionTrackerType
* occlusion
,
352 bool prevent_occlusion
) {
353 ASSERT_EQ(layer
, *layer_iterator_
);
354 ASSERT_TRUE(layer_iterator_
.represents_itself());
355 occlusion
->EnterLayer(layer_iterator_
, prevent_occlusion
);
358 void LeaveLayer(typename
Types::LayerType
* layer
,
359 typename
Types::OcclusionTrackerType
* occlusion
) {
360 ASSERT_EQ(layer
, *layer_iterator_
);
361 ASSERT_TRUE(layer_iterator_
.represents_itself());
362 occlusion
->LeaveLayer(layer_iterator_
);
366 void VisitLayer(typename
Types::LayerType
* layer
,
367 typename
Types::OcclusionTrackerType
* occlusion
) {
368 EnterLayer(layer
, occlusion
, false);
369 LeaveLayer(layer
, occlusion
);
372 void EnterContributingSurface(
373 typename
Types::LayerType
* layer
,
374 typename
Types::OcclusionTrackerType
* occlusion
,
375 bool prevent_occlusion
) {
376 ASSERT_EQ(layer
, *layer_iterator_
);
377 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
378 occlusion
->EnterLayer(layer_iterator_
, false);
379 occlusion
->LeaveLayer(layer_iterator_
);
381 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
382 occlusion
->EnterLayer(layer_iterator_
, prevent_occlusion
);
385 void LeaveContributingSurface(
386 typename
Types::LayerType
* layer
,
387 typename
Types::OcclusionTrackerType
* occlusion
) {
388 ASSERT_EQ(layer
, *layer_iterator_
);
389 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
390 occlusion
->LeaveLayer(layer_iterator_
);
394 void VisitContributingSurface(
395 typename
Types::LayerType
* layer
,
396 typename
Types::OcclusionTrackerType
* occlusion
) {
397 EnterContributingSurface(layer
, occlusion
, false);
398 LeaveContributingSurface(layer
, occlusion
);
401 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
403 const gfx::Transform identity_matrix
;
406 void SetBaseProperties(typename
Types::LayerType
* layer
,
407 const gfx::Transform
& transform
,
408 gfx::PointF position
,
410 layer
->SetTransform(transform
);
411 layer
->SetSublayerTransform(gfx::Transform());
412 layer
->SetAnchorPoint(gfx::PointF());
413 layer
->SetPosition(position
);
414 layer
->SetBounds(bounds
);
417 void SetProperties(Layer
* layer
,
418 const gfx::Transform
& transform
,
419 gfx::PointF position
,
421 SetBaseProperties(layer
, transform
, position
, bounds
);
424 void SetProperties(LayerImpl
* layer
,
425 const gfx::Transform
& transform
,
426 gfx::PointF position
,
428 SetBaseProperties(layer
, transform
, position
, bounds
);
430 layer
->SetContentBounds(layer
->bounds());
433 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
434 owning_layer
->SetReplicaLayer(layer
.get());
435 replica_layers_
.push_back(layer
);
438 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
439 owning_layer
->SetReplicaLayer(layer
.Pass());
442 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
443 owning_layer
->SetMaskLayer(layer
.get());
444 mask_layers_
.push_back(layer
);
447 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
448 owning_layer
->SetMaskLayer(layer
.Pass());
451 FakeImplProxy proxy_
;
452 FakeLayerTreeHostImpl host_impl_
;
454 // These hold ownership of the layers for the duration of the test.
455 typename
Types::LayerPtrType root_
;
456 LayerList render_surface_layer_list_
;
457 LayerImplList render_surface_layer_list_impl_
;
458 typename
Types::TestLayerIterator layer_iterator_begin_
;
459 typename
Types::TestLayerIterator layer_iterator_
;
460 typename
Types::LayerType
* last_layer_visited_
;
461 LayerList replica_layers_
;
462 LayerList mask_layers_
;
467 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
473 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
474 return host_impl_
.active_tree();
477 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
478 class ClassName##MainThreadOpaqueLayers \
479 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
480 public: /* NOLINT(whitespace/indent) */ \
481 ClassName##MainThreadOpaqueLayers() \
482 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
484 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
485 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
486 class ClassName##MainThreadOpaquePaints \
487 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
488 public: /* NOLINT(whitespace/indent) */ \
489 ClassName##MainThreadOpaquePaints() \
490 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
492 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
494 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
495 class ClassName##ImplThreadOpaqueLayers \
496 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
497 public: /* NOLINT(whitespace/indent) */ \
498 ClassName##ImplThreadOpaqueLayers() \
499 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
501 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
502 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
503 class ClassName##ImplThreadOpaquePaints \
504 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
505 public: /* NOLINT(whitespace/indent) */ \
506 ClassName##ImplThreadOpaquePaints() \
507 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
509 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
511 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
512 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
513 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
514 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
515 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
517 #define MAIN_THREAD_TEST(ClassName) \
518 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
520 #define IMPL_THREAD_TEST(ClassName) \
521 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
523 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
524 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
525 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
527 template <class Types
>
528 class OcclusionTrackerTestIdentityTransforms
529 : public OcclusionTrackerTest
<Types
> {
531 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
532 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
535 typename
Types::ContentLayerType
* root
= this->CreateRoot(
536 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
537 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
538 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
539 typename
Types::ContentLayerType
* layer
=
540 this->CreateDrawingLayer(parent
,
541 this->identity_matrix
,
542 gfx::PointF(30.f
, 30.f
),
545 parent
->SetMasksToBounds(true);
546 this->CalcDrawEtc(root
);
548 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
549 typename
Types::RenderSurfaceType
> occlusion(
550 gfx::Rect(0, 0, 1000, 1000), false);
552 this->VisitLayer(layer
, &occlusion
);
553 this->EnterLayer(parent
, &occlusion
, false);
555 EXPECT_EQ(gfx::Rect().ToString(),
556 occlusion
.occlusion_from_outside_target().ToString());
557 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
558 occlusion
.occlusion_from_inside_target().ToString());
560 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
561 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
562 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
563 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
564 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
566 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
567 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
568 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
569 occlusion
.UnoccludedLayerContentRect(
570 parent
, gfx::Rect(29, 30, 70, 70)));
571 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
572 occlusion
.UnoccludedLayerContentRect(
573 parent
, gfx::Rect(29, 29, 70, 70)));
574 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
575 occlusion
.UnoccludedLayerContentRect(
576 parent
, gfx::Rect(30, 29, 70, 70)));
577 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
578 occlusion
.UnoccludedLayerContentRect(
579 parent
, gfx::Rect(31, 29, 70, 70)));
580 EXPECT_RECT_EQ(gfx::Rect(),
581 occlusion
.UnoccludedLayerContentRect(
582 parent
, gfx::Rect(31, 30, 70, 70)));
583 EXPECT_RECT_EQ(gfx::Rect(),
584 occlusion
.UnoccludedLayerContentRect(
585 parent
, gfx::Rect(31, 31, 70, 70)));
586 EXPECT_RECT_EQ(gfx::Rect(),
587 occlusion
.UnoccludedLayerContentRect(
588 parent
, gfx::Rect(30, 31, 70, 70)));
589 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
590 occlusion
.UnoccludedLayerContentRect(
591 parent
, gfx::Rect(29, 31, 70, 70)));
595 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
597 template <class Types
>
598 class OcclusionTrackerTestQuadsMismatchLayer
599 : public OcclusionTrackerTest
<Types
> {
601 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers
)
602 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
604 gfx::Transform layer_transform
;
605 layer_transform
.Translate(10.0, 10.0);
607 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
608 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(100, 100));
609 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
610 parent
, layer_transform
, gfx::PointF(), gfx::Size(90, 90), true);
611 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
612 layer1
, layer_transform
, gfx::PointF(), gfx::Size(50, 50), true);
613 this->CalcDrawEtc(parent
);
615 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
616 typename
Types::RenderSurfaceType
> occlusion(
617 gfx::Rect(0, 0, 1000, 1000));
619 this->VisitLayer(layer2
, &occlusion
);
620 this->EnterLayer(layer1
, &occlusion
, false);
622 EXPECT_EQ(gfx::Rect().ToString(),
623 occlusion
.occlusion_from_outside_target().ToString());
624 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
625 occlusion
.occlusion_from_inside_target().ToString());
627 // This checks cases where the quads don't match their "containing"
628 // layers, e.g. in terms of transforms or clip rect. This is typical for
629 // DelegatedRendererLayer.
631 gfx::Transform quad_transform
;
632 quad_transform
.Translate(30.0, 30.0);
633 gfx::Rect
clip_rect_in_target(0, 0, 100, 100);
635 EXPECT_TRUE(occlusion
.UnoccludedContentRect(parent
,
636 gfx::Rect(0, 0, 10, 10),
642 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
643 occlusion
.UnoccludedContentRect(parent
,
644 gfx::Rect(0, 0, 10, 10),
650 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
651 occlusion
.UnoccludedContentRect(parent
,
652 gfx::Rect(40, 40, 10, 10),
658 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
659 occlusion
.UnoccludedContentRect(parent
,
660 gfx::Rect(35, 30, 10, 10),
666 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5),
667 occlusion
.UnoccludedContentRect(parent
,
668 gfx::Rect(40, 40, 10, 10),
672 gfx::Rect(0, 0, 75, 75),
677 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
679 template <class Types
>
680 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
682 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
683 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
685 gfx::Transform layer_transform
;
686 layer_transform
.Translate(250.0, 250.0);
687 layer_transform
.Rotate(90.0);
688 layer_transform
.Translate(-250.0, -250.0);
690 typename
Types::ContentLayerType
* root
= this->CreateRoot(
691 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
692 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
693 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
694 typename
Types::ContentLayerType
* layer
=
695 this->CreateDrawingLayer(parent
,
697 gfx::PointF(30.f
, 30.f
),
700 parent
->SetMasksToBounds(true);
701 this->CalcDrawEtc(root
);
703 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
704 typename
Types::RenderSurfaceType
> occlusion(
705 gfx::Rect(0, 0, 1000, 1000));
707 this->VisitLayer(layer
, &occlusion
);
708 this->EnterLayer(parent
, &occlusion
, false);
710 EXPECT_EQ(gfx::Rect().ToString(),
711 occlusion
.occlusion_from_outside_target().ToString());
712 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
713 occlusion
.occlusion_from_inside_target().ToString());
715 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
716 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
717 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
718 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
719 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
721 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
722 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
723 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
724 occlusion
.UnoccludedLayerContentRect(
725 parent
, gfx::Rect(29, 30, 70, 70)));
726 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
727 occlusion
.UnoccludedLayerContentRect(
728 parent
, gfx::Rect(29, 29, 70, 70)));
729 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
730 occlusion
.UnoccludedLayerContentRect(
731 parent
, gfx::Rect(30, 29, 70, 70)));
732 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
733 occlusion
.UnoccludedLayerContentRect(
734 parent
, gfx::Rect(31, 29, 70, 70)));
735 EXPECT_RECT_EQ(gfx::Rect(),
736 occlusion
.UnoccludedLayerContentRect(
737 parent
, gfx::Rect(31, 30, 70, 70)));
738 EXPECT_RECT_EQ(gfx::Rect(),
739 occlusion
.UnoccludedLayerContentRect(
740 parent
, gfx::Rect(31, 31, 70, 70)));
741 EXPECT_RECT_EQ(gfx::Rect(),
742 occlusion
.UnoccludedLayerContentRect(
743 parent
, gfx::Rect(30, 31, 70, 70)));
744 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
745 occlusion
.UnoccludedLayerContentRect(
746 parent
, gfx::Rect(29, 31, 70, 70)));
750 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
752 template <class Types
>
753 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
755 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
756 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
758 gfx::Transform layer_transform
;
759 layer_transform
.Translate(20.0, 20.0);
761 typename
Types::ContentLayerType
* root
= this->CreateRoot(
762 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
763 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
764 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
765 typename
Types::ContentLayerType
* layer
=
766 this->CreateDrawingLayer(parent
,
768 gfx::PointF(30.f
, 30.f
),
771 parent
->SetMasksToBounds(true);
772 this->CalcDrawEtc(root
);
774 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
775 typename
Types::RenderSurfaceType
> occlusion(
776 gfx::Rect(0, 0, 1000, 1000));
778 this->VisitLayer(layer
, &occlusion
);
779 this->EnterLayer(parent
, &occlusion
, false);
781 EXPECT_EQ(gfx::Rect().ToString(),
782 occlusion
.occlusion_from_outside_target().ToString());
783 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
784 occlusion
.occlusion_from_inside_target().ToString());
786 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
787 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
788 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
789 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(51, 50, 50, 50)));
790 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 51, 50, 50)));
792 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
793 parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
794 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
795 occlusion
.UnoccludedLayerContentRect(
796 parent
, gfx::Rect(49, 50, 50, 50)));
797 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
798 occlusion
.UnoccludedLayerContentRect(
799 parent
, gfx::Rect(49, 49, 50, 50)));
800 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
801 occlusion
.UnoccludedLayerContentRect(
802 parent
, gfx::Rect(50, 49, 50, 50)));
803 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
804 occlusion
.UnoccludedLayerContentRect(
805 parent
, gfx::Rect(51, 49, 50, 50)));
806 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
807 parent
, gfx::Rect(51, 50, 50, 50)).IsEmpty());
808 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
809 parent
, gfx::Rect(51, 51, 50, 50)).IsEmpty());
810 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
811 parent
, gfx::Rect(50, 51, 50, 50)).IsEmpty());
812 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
813 occlusion
.UnoccludedLayerContentRect(
814 parent
, gfx::Rect(49, 51, 50, 50)));
818 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
820 template <class Types
>
821 class OcclusionTrackerTestChildInRotatedChild
822 : public OcclusionTrackerTest
<Types
> {
824 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
825 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
827 gfx::Transform child_transform
;
828 child_transform
.Translate(250.0, 250.0);
829 child_transform
.Rotate(90.0);
830 child_transform
.Translate(-250.0, -250.0);
832 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
833 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
834 parent
->SetMasksToBounds(true);
835 typename
Types::LayerType
* child
= this->CreateLayer(
836 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
837 child
->SetMasksToBounds(true);
838 typename
Types::ContentLayerType
* layer
=
839 this->CreateDrawingLayer(child
,
840 this->identity_matrix
,
841 gfx::PointF(10.f
, 10.f
),
844 this->CalcDrawEtc(parent
);
846 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
847 typename
Types::RenderSurfaceType
> occlusion(
848 gfx::Rect(0, 0, 1000, 1000));
850 this->VisitLayer(layer
, &occlusion
);
851 this->EnterContributingSurface(child
, &occlusion
, false);
853 EXPECT_EQ(gfx::Rect().ToString(),
854 occlusion
.occlusion_from_outside_target().ToString());
855 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
856 occlusion
.occlusion_from_inside_target().ToString());
858 this->LeaveContributingSurface(child
, &occlusion
);
859 this->EnterLayer(parent
, &occlusion
, false);
861 EXPECT_EQ(gfx::Rect().ToString(),
862 occlusion
.occlusion_from_outside_target().ToString());
863 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
864 occlusion
.occlusion_from_inside_target().ToString());
866 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
867 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
868 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
869 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 40, 70, 60)));
870 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 41, 70, 60)));
872 /* Justification for the above occlusion from |layer|:
874 +---------------------+
877 | 30 + ---------------------------------+
879 | |10+---------------------------------+
883 +----|--|-------------+ | |
891 +--|-------------------------------+ |
893 +---------------------------------+
896 +---------------------+
897 | |30 Visible region of |layer|: /////
899 | +---------------------------------+
901 | +---------------------------------+ |
902 | | |///////////////| 420 | |
903 | | |///////////////|60 | |
904 | | |///////////////| | |
905 +--|--|---------------+ | |
913 | +------------------------------|--+
915 +---------------------------------+
922 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
924 template <class Types
>
925 class OcclusionTrackerTestScaledRenderSurface
926 : public OcclusionTrackerTest
<Types
> {
928 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
929 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
932 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
933 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
935 gfx::Transform layer1_matrix
;
936 layer1_matrix
.Scale(2.0, 2.0);
937 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
938 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
939 layer1
->SetForceRenderSurface(true);
941 gfx::Transform layer2_matrix
;
942 layer2_matrix
.Translate(25.0, 25.0);
943 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
944 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
945 typename
Types::ContentLayerType
* occluder
=
946 this->CreateDrawingLayer(parent
,
947 this->identity_matrix
,
948 gfx::PointF(100.f
, 100.f
),
951 this->CalcDrawEtc(parent
);
953 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
954 typename
Types::RenderSurfaceType
> occlusion(
955 gfx::Rect(0, 0, 1000, 1000));
957 this->VisitLayer(occluder
, &occlusion
);
958 this->EnterLayer(layer2
, &occlusion
, false);
960 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
961 occlusion
.occlusion_from_outside_target().ToString());
962 EXPECT_EQ(gfx::Rect().ToString(),
963 occlusion
.occlusion_from_inside_target().ToString());
966 gfx::Rect(0, 0, 25, 25),
967 occlusion
.UnoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
968 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
969 occlusion
.UnoccludedLayerContentRect(
970 layer2
, gfx::Rect(10, 25, 25, 25)));
971 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
972 occlusion
.UnoccludedLayerContentRect(
973 layer2
, gfx::Rect(25, 10, 25, 25)));
974 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
975 layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
979 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
981 template <class Types
>
982 class OcclusionTrackerTestVisitTargetTwoTimes
983 : public OcclusionTrackerTest
<Types
> {
985 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
986 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
988 gfx::Transform child_transform
;
989 child_transform
.Translate(250.0, 250.0);
990 child_transform
.Rotate(90.0);
991 child_transform
.Translate(-250.0, -250.0);
993 typename
Types::ContentLayerType
* root
= this->CreateRoot(
994 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
995 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
996 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
997 parent
->SetMasksToBounds(true);
998 typename
Types::LayerType
* child
= this->CreateLayer(
999 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1000 child
->SetMasksToBounds(true);
1001 typename
Types::ContentLayerType
* layer
=
1002 this->CreateDrawingLayer(child
,
1003 this->identity_matrix
,
1004 gfx::PointF(10.f
, 10.f
),
1005 gfx::Size(500, 500),
1007 // |child2| makes |parent|'s surface get considered by OcclusionTracker
1008 // first, instead of |child|'s. This exercises different code in
1009 // LeaveToRenderTarget, as the target surface has already been seen.
1010 typename
Types::ContentLayerType
* child2
=
1011 this->CreateDrawingLayer(parent
,
1012 this->identity_matrix
,
1013 gfx::PointF(30.f
, 30.f
),
1016 this->CalcDrawEtc(root
);
1018 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1019 typename
Types::RenderSurfaceType
> occlusion(
1020 gfx::Rect(0, 0, 1000, 1000));
1022 this->VisitLayer(child2
, &occlusion
);
1024 EXPECT_EQ(gfx::Rect().ToString(),
1025 occlusion
.occlusion_from_outside_target().ToString());
1026 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1027 occlusion
.occlusion_from_inside_target().ToString());
1029 this->VisitLayer(layer
, &occlusion
);
1031 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1032 occlusion
.occlusion_from_outside_target().ToString());
1033 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1034 occlusion
.occlusion_from_inside_target().ToString());
1036 this->EnterContributingSurface(child
, &occlusion
, false);
1038 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1039 occlusion
.occlusion_from_outside_target().ToString());
1040 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1041 occlusion
.occlusion_from_inside_target().ToString());
1043 // Occlusion in |child2| should get merged with the |child| surface we are
1045 this->LeaveContributingSurface(child
, &occlusion
);
1046 this->EnterLayer(parent
, &occlusion
, false);
1048 EXPECT_EQ(gfx::Rect().ToString(),
1049 occlusion
.occlusion_from_outside_target().ToString());
1050 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1052 occlusion
.occlusion_from_inside_target().ToString());
1054 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
1055 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1056 occlusion
.UnoccludedLayerContentRect(
1057 parent
, gfx::Rect(30, 30, 70, 70)));
1059 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
1060 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
1061 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
1062 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
1063 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
1065 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1066 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1067 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1069 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1070 parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1071 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1072 occlusion
.UnoccludedLayerContentRect(
1073 parent
, gfx::Rect(29, 30, 60, 10)));
1074 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1075 occlusion
.UnoccludedLayerContentRect(
1076 parent
, gfx::Rect(30, 29, 60, 10)));
1077 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1078 occlusion
.UnoccludedLayerContentRect(
1079 parent
, gfx::Rect(31, 30, 60, 10)));
1080 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1081 parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1083 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1084 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1085 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1086 occlusion
.UnoccludedLayerContentRect(
1087 parent
, gfx::Rect(29, 40, 70, 60)));
1088 // This rect is mostly occluded by |child2|.
1089 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1090 occlusion
.UnoccludedLayerContentRect(
1091 parent
, gfx::Rect(30, 39, 70, 60)));
1092 // This rect extends past top/right ends of |child2|.
1093 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1094 occlusion
.UnoccludedLayerContentRect(
1095 parent
, gfx::Rect(30, 29, 70, 70)));
1096 // This rect extends past left/right ends of |child2|.
1097 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1098 occlusion
.UnoccludedLayerContentRect(
1099 parent
, gfx::Rect(20, 39, 80, 60)));
1100 EXPECT_RECT_EQ(gfx::Rect(),
1101 occlusion
.UnoccludedLayerContentRect(
1102 parent
, gfx::Rect(31, 40, 70, 60)));
1103 EXPECT_RECT_EQ(gfx::Rect(),
1104 occlusion
.UnoccludedLayerContentRect(
1105 parent
, gfx::Rect(30, 41, 70, 60)));
1107 /* Justification for the above occlusion from |layer|:
1109 +---------------------+
1112 | 30 + ------------+--------------------+
1113 100 | | 10 | | | ==>
1114 | |10+----------|----------------------+
1115 | + ------------+ | | |
1118 +----|--|-------------+ | |
1126 +--|-------------------------------+ |
1128 +---------------------------------+
1132 +---------------------+
1133 | |30 Visible region of |layer|: /////
1134 | 30 60 | |child2|: \\\\\
1135 | 30 +------------+--------------------+
1136 | |\\\\\\\\\\\\| |10 |
1137 | +--|\\\\\\\\\\\\|-----------------+ |
1138 | | +------------+//| 420 | |
1139 | | |///////////////|60 | |
1140 | | |///////////////| | |
1141 +--|--|---------------+ | |
1149 | +------------------------------|--+
1151 +---------------------------------+
1157 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
1159 template <class Types
>
1160 class OcclusionTrackerTestSurfaceRotatedOffAxis
1161 : public OcclusionTrackerTest
<Types
> {
1163 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
1164 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1166 gfx::Transform child_transform
;
1167 child_transform
.Translate(250.0, 250.0);
1168 child_transform
.Rotate(95.0);
1169 child_transform
.Translate(-250.0, -250.0);
1171 gfx::Transform layer_transform
;
1172 layer_transform
.Translate(10.0, 10.0);
1174 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1175 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1176 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1177 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1178 typename
Types::LayerType
* child
= this->CreateLayer(
1179 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1180 child
->SetMasksToBounds(true);
1181 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1182 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
1183 this->CalcDrawEtc(root
);
1185 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1186 typename
Types::RenderSurfaceType
> occlusion(
1187 gfx::Rect(0, 0, 1000, 1000));
1189 gfx::Rect clipped_layer_in_child
= MathUtil::MapClippedRect(
1190 layer_transform
, layer
->visible_content_rect());
1192 this->VisitLayer(layer
, &occlusion
);
1193 this->EnterContributingSurface(child
, &occlusion
, false);
1195 EXPECT_EQ(gfx::Rect().ToString(),
1196 occlusion
.occlusion_from_outside_target().ToString());
1197 EXPECT_EQ(clipped_layer_in_child
.ToString(),
1198 occlusion
.occlusion_from_inside_target().ToString());
1200 this->LeaveContributingSurface(child
, &occlusion
);
1201 this->EnterLayer(parent
, &occlusion
, false);
1203 EXPECT_EQ(gfx::Rect().ToString(),
1204 occlusion
.occlusion_from_outside_target().ToString());
1205 EXPECT_EQ(gfx::Rect().ToString(),
1206 occlusion
.occlusion_from_inside_target().ToString());
1208 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
1210 gfx::Rect(75, 55, 1, 1),
1211 occlusion
.UnoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
1215 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
1217 template <class Types
>
1218 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1219 : public OcclusionTrackerTest
<Types
> {
1221 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
1222 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1224 gfx::Transform child_transform
;
1225 child_transform
.Translate(250.0, 250.0);
1226 child_transform
.Rotate(90.0);
1227 child_transform
.Translate(-250.0, -250.0);
1229 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1230 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1231 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1232 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1233 parent
->SetMasksToBounds(true);
1234 typename
Types::ContentLayerType
* child
=
1235 this->CreateDrawingLayer(parent
,
1237 gfx::PointF(30.f
, 30.f
),
1238 gfx::Size(500, 500),
1240 child
->SetMasksToBounds(true);
1241 typename
Types::ContentLayerType
* layer1
=
1242 this->CreateDrawingLayer(child
,
1243 this->identity_matrix
,
1244 gfx::PointF(10.f
, 10.f
),
1245 gfx::Size(500, 500),
1247 typename
Types::ContentLayerType
* layer2
=
1248 this->CreateDrawingLayer(child
,
1249 this->identity_matrix
,
1250 gfx::PointF(10.f
, 450.f
),
1253 this->CalcDrawEtc(root
);
1255 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1256 typename
Types::RenderSurfaceType
> occlusion(
1257 gfx::Rect(0, 0, 1000, 1000));
1259 this->VisitLayer(layer2
, &occlusion
);
1260 this->VisitLayer(layer1
, &occlusion
);
1261 this->VisitLayer(child
, &occlusion
);
1262 this->EnterContributingSurface(child
, &occlusion
, false);
1264 EXPECT_EQ(gfx::Rect().ToString(),
1265 occlusion
.occlusion_from_outside_target().ToString());
1266 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1267 occlusion
.occlusion_from_inside_target().ToString());
1269 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
1270 EXPECT_FALSE(occlusion
.OccludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
1271 // These rects are occluded except for the part outside the bounds of the
1273 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 429, 60, 70)));
1274 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(11, 430, 60, 70)));
1275 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 431, 60, 70)));
1277 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1278 child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1280 gfx::Rect(9, 430, 1, 70),
1281 occlusion
.UnoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
1282 // These rects are occluded except for the part outside the bounds of the
1284 EXPECT_RECT_EQ(gfx::Rect(),
1285 occlusion
.UnoccludedLayerContentRect(
1286 child
, gfx::Rect(10, 429, 60, 70)));
1287 EXPECT_RECT_EQ(gfx::Rect(),
1288 occlusion
.UnoccludedLayerContentRect(
1289 child
, gfx::Rect(11, 430, 60, 70)));
1290 EXPECT_RECT_EQ(gfx::Rect(),
1291 occlusion
.UnoccludedLayerContentRect(
1292 child
, gfx::Rect(10, 431, 60, 70)));
1294 this->LeaveContributingSurface(child
, &occlusion
);
1295 this->EnterLayer(parent
, &occlusion
, false);
1297 EXPECT_EQ(gfx::Rect().ToString(),
1298 occlusion
.occlusion_from_outside_target().ToString());
1299 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1300 occlusion
.occlusion_from_inside_target().ToString());
1302 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1303 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1304 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1306 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1307 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1308 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1309 occlusion
.UnoccludedLayerContentRect(
1310 parent
, gfx::Rect(29, 40, 70, 60)));
1311 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1312 occlusion
.UnoccludedLayerContentRect(
1313 parent
, gfx::Rect(30, 39, 70, 60)));
1314 EXPECT_RECT_EQ(gfx::Rect(),
1315 occlusion
.UnoccludedLayerContentRect(
1316 parent
, gfx::Rect(31, 40, 70, 60)));
1317 EXPECT_RECT_EQ(gfx::Rect(),
1318 occlusion
.UnoccludedLayerContentRect(
1319 parent
, gfx::Rect(30, 41, 70, 60)));
1321 /* Justification for the above occlusion from |layer1| and |layer2|:
1323 +---------------------+
1324 | |30 Visible region of |layer1|: /////
1325 | | Visible region of |layer2|: \\\\\
1326 | +---------------------------------+
1328 | +---------------+-----------------+ |
1329 | | |\\\\\\\\\\\\|//| 420 | |
1330 | | |\\\\\\\\\\\\|//|60 | |
1331 | | |\\\\\\\\\\\\|//| | |
1332 +--|--|------------|--+ | |
1340 | +------------|-----------------|--+
1342 +---------------+-----------------+
1348 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1350 template <class Types
>
1351 class OcclusionTrackerTestOverlappingSurfaceSiblings
1352 : public OcclusionTrackerTest
<Types
> {
1354 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
1355 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1357 gfx::Transform child_transform
;
1358 child_transform
.Translate(250.0, 250.0);
1359 child_transform
.Rotate(90.0);
1360 child_transform
.Translate(-250.0, -250.0);
1362 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1363 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1364 parent
->SetMasksToBounds(true);
1365 typename
Types::LayerType
* child1
= this->CreateSurface(
1366 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(10, 10));
1367 typename
Types::LayerType
* child2
= this->CreateSurface(
1368 parent
, child_transform
, gfx::PointF(20.f
, 40.f
), gfx::Size(10, 10));
1369 typename
Types::ContentLayerType
* layer1
=
1370 this->CreateDrawingLayer(child1
,
1371 this->identity_matrix
,
1372 gfx::PointF(-10.f
, -10.f
),
1373 gfx::Size(510, 510),
1375 typename
Types::ContentLayerType
* layer2
=
1376 this->CreateDrawingLayer(child2
,
1377 this->identity_matrix
,
1378 gfx::PointF(-10.f
, -10.f
),
1379 gfx::Size(510, 510),
1381 this->CalcDrawEtc(parent
);
1383 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1384 typename
Types::RenderSurfaceType
> occlusion(
1385 gfx::Rect(0, 0, 1000, 1000));
1387 this->VisitLayer(layer2
, &occlusion
);
1388 this->EnterContributingSurface(child2
, &occlusion
, false);
1390 EXPECT_EQ(gfx::Rect().ToString(),
1391 occlusion
.occlusion_from_outside_target().ToString());
1392 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1393 occlusion
.occlusion_from_inside_target().ToString());
1395 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1396 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1397 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1398 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1399 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1401 // There is nothing above child2's surface in the z-order.
1402 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1403 occlusion
.UnoccludedContributingSurfaceContentRect(
1404 child2
, false, gfx::Rect(-10, 420, 70, 80), NULL
));
1406 this->LeaveContributingSurface(child2
, &occlusion
);
1407 this->VisitLayer(layer1
, &occlusion
);
1408 this->EnterContributingSurface(child1
, &occlusion
, false);
1410 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1411 occlusion
.occlusion_from_outside_target().ToString());
1412 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1413 occlusion
.occlusion_from_inside_target().ToString());
1415 // child2's contents will occlude child1 below it.
1416 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1417 occlusion
.UnoccludedContributingSurfaceContentRect(
1418 child1
, false, gfx::Rect(-10, 430, 80, 70), NULL
));
1420 this->LeaveContributingSurface(child1
, &occlusion
);
1421 this->EnterLayer(parent
, &occlusion
, false);
1423 EXPECT_EQ(gfx::Rect().ToString(),
1424 occlusion
.occlusion_from_outside_target().ToString());
1425 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1427 occlusion
.occlusion_from_inside_target().ToString());
1429 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1431 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1432 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1433 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1435 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1436 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1437 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1439 /* Justification for the above occlusion:
1441 +---------------------+
1443 | 30+ ---------------------------------+
1444 100 | 30| | layer2 |
1445 |20+----------------------------------+ |
1449 +--|-|----------------+ | |
1457 | +--------------------------------|-+
1459 +----------------------------------+
1465 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1467 template <class Types
>
1468 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1469 : public OcclusionTrackerTest
<Types
> {
1471 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1473 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1475 gfx::Transform child1_transform
;
1476 child1_transform
.Translate(250.0, 250.0);
1477 child1_transform
.Rotate(-90.0);
1478 child1_transform
.Translate(-250.0, -250.0);
1480 gfx::Transform child2_transform
;
1481 child2_transform
.Translate(250.0, 250.0);
1482 child2_transform
.Rotate(90.0);
1483 child2_transform
.Translate(-250.0, -250.0);
1485 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1486 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1487 parent
->SetMasksToBounds(true);
1488 typename
Types::LayerType
* child1
= this->CreateSurface(
1489 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1490 typename
Types::LayerType
* child2
=
1491 this->CreateDrawingSurface(parent
,
1493 gfx::PointF(20.f
, 40.f
),
1496 typename
Types::ContentLayerType
* layer1
=
1497 this->CreateDrawingLayer(child1
,
1498 this->identity_matrix
,
1499 gfx::PointF(-10.f
, -20.f
),
1500 gfx::Size(510, 510),
1502 typename
Types::ContentLayerType
* layer2
=
1503 this->CreateDrawingLayer(child2
,
1504 this->identity_matrix
,
1505 gfx::PointF(-10.f
, -10.f
),
1506 gfx::Size(510, 510),
1508 this->CalcDrawEtc(parent
);
1510 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1511 typename
Types::RenderSurfaceType
> occlusion(
1512 gfx::Rect(0, 0, 1000, 1000));
1514 this->VisitLayer(layer2
, &occlusion
);
1515 this->EnterLayer(child2
, &occlusion
, false);
1517 EXPECT_EQ(gfx::Rect().ToString(),
1518 occlusion
.occlusion_from_outside_target().ToString());
1519 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1520 occlusion
.occlusion_from_inside_target().ToString());
1522 this->LeaveLayer(child2
, &occlusion
);
1523 this->EnterContributingSurface(child2
, &occlusion
, false);
1525 // There is nothing above child2's surface in the z-order.
1526 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1527 occlusion
.UnoccludedContributingSurfaceContentRect(
1528 child2
, false, gfx::Rect(-10, 420, 70, 80), NULL
));
1530 this->LeaveContributingSurface(child2
, &occlusion
);
1531 this->VisitLayer(layer1
, &occlusion
);
1532 this->EnterContributingSurface(child1
, &occlusion
, false);
1534 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1535 occlusion
.occlusion_from_outside_target().ToString());
1536 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1537 occlusion
.occlusion_from_inside_target().ToString());
1539 // child2's contents will occlude child1 below it.
1540 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1541 occlusion
.UnoccludedContributingSurfaceContentRect(
1542 child1
, false, gfx::Rect(420, -20, 80, 90), NULL
));
1543 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1544 occlusion
.UnoccludedContributingSurfaceContentRect(
1545 child1
, false, gfx::Rect(420, -10, 80, 90), NULL
));
1546 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1547 occlusion
.UnoccludedContributingSurfaceContentRect(
1548 child1
, false, gfx::Rect(420, -20, 70, 90), NULL
));
1550 this->LeaveContributingSurface(child1
, &occlusion
);
1551 this->EnterLayer(parent
, &occlusion
, false);
1553 EXPECT_EQ(gfx::Rect().ToString(),
1554 occlusion
.occlusion_from_outside_target().ToString());
1555 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1556 occlusion
.occlusion_from_inside_target().ToString());
1558 /* Justification for the above occlusion:
1560 +---------------------+
1562 10+----------------------------------+
1563 100 || 30 | layer2 |
1564 |20+----------------------------------+
1568 +|-|------------------+ | |
1576 +----------------------------------+ |
1578 +----------------------------------+
1584 ALL_OCCLUSIONTRACKER_TEST(
1585 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1587 template <class Types
>
1588 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1590 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1591 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1593 gfx::Transform layer_transform
;
1594 layer_transform
.Translate(250.0, 250.0);
1595 layer_transform
.Rotate(90.0);
1596 layer_transform
.Translate(-250.0, -250.0);
1598 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1599 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1600 parent
->SetMasksToBounds(true);
1601 typename
Types::ContentLayerType
* blur_layer
=
1602 this->CreateDrawingLayer(parent
,
1604 gfx::PointF(30.f
, 30.f
),
1605 gfx::Size(500, 500),
1607 typename
Types::ContentLayerType
* opaque_layer
=
1608 this->CreateDrawingLayer(parent
,
1610 gfx::PointF(30.f
, 30.f
),
1611 gfx::Size(500, 500),
1613 typename
Types::ContentLayerType
* opacity_layer
=
1614 this->CreateDrawingLayer(parent
,
1616 gfx::PointF(30.f
, 30.f
),
1617 gfx::Size(500, 500),
1620 WebKit::WebFilterOperations filters
;
1621 filters
.append(WebKit::WebFilterOperation::createBlurFilter(10.f
));
1622 blur_layer
->SetFilters(filters
);
1625 filters
.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5f
));
1626 opaque_layer
->SetFilters(filters
);
1629 filters
.append(WebKit::WebFilterOperation::createOpacityFilter(0.5f
));
1630 opacity_layer
->SetFilters(filters
);
1632 this->CalcDrawEtc(parent
);
1634 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1635 typename
Types::RenderSurfaceType
> occlusion(
1636 gfx::Rect(0, 0, 1000, 1000));
1638 // Opacity layer won't contribute to occlusion.
1639 this->VisitLayer(opacity_layer
, &occlusion
);
1640 this->EnterContributingSurface(opacity_layer
, &occlusion
, false);
1642 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1643 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1645 // And has nothing to contribute to its parent surface.
1646 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1647 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1648 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1650 // Opaque layer will contribute to occlusion.
1651 this->VisitLayer(opaque_layer
, &occlusion
);
1652 this->EnterContributingSurface(opaque_layer
, &occlusion
, false);
1654 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1655 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1656 occlusion
.occlusion_from_inside_target().ToString());
1658 // And it gets translated to the parent surface.
1659 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1660 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1661 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1662 occlusion
.occlusion_from_inside_target().ToString());
1664 // The blur layer needs to throw away any occlusion from outside its
1666 this->EnterLayer(blur_layer
, &occlusion
, false);
1667 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1668 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1670 // And it won't contribute to occlusion.
1671 this->LeaveLayer(blur_layer
, &occlusion
);
1672 this->EnterContributingSurface(blur_layer
, &occlusion
, false);
1673 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1674 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1676 // But the opaque layer's occlusion is preserved on the parent.
1677 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1678 this->EnterLayer(parent
, &occlusion
, false);
1679 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1680 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1681 occlusion
.occlusion_from_inside_target().ToString());
1685 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1687 template <class Types
>
1688 class OcclusionTrackerTestReplicaDoesOcclude
1689 : public OcclusionTrackerTest
<Types
> {
1691 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1692 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1694 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1695 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1696 typename
Types::LayerType
* surface
=
1697 this->CreateDrawingSurface(parent
,
1698 this->identity_matrix
,
1699 gfx::PointF(0.f
, 100.f
),
1702 this->CreateReplicaLayer(
1703 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1704 this->CalcDrawEtc(parent
);
1706 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1707 typename
Types::RenderSurfaceType
> occlusion(
1708 gfx::Rect(0, 0, 1000, 1000));
1710 this->VisitLayer(surface
, &occlusion
);
1712 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1713 occlusion
.occlusion_from_inside_target().ToString());
1715 this->VisitContributingSurface(surface
, &occlusion
);
1716 this->EnterLayer(parent
, &occlusion
, false);
1718 // The surface and replica should both be occluding the parent.
1720 UnionRegions(gfx::Rect(0, 100, 50, 50),
1721 gfx::Rect(50, 150, 50, 50)).ToString(),
1722 occlusion
.occlusion_from_inside_target().ToString());
1726 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1728 template <class Types
>
1729 class OcclusionTrackerTestReplicaWithClipping
1730 : public OcclusionTrackerTest
<Types
> {
1732 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1733 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1735 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1736 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1737 parent
->SetMasksToBounds(true);
1738 typename
Types::LayerType
* surface
=
1739 this->CreateDrawingSurface(parent
,
1740 this->identity_matrix
,
1741 gfx::PointF(0.f
, 100.f
),
1744 this->CreateReplicaLayer(
1745 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1746 this->CalcDrawEtc(parent
);
1748 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1749 typename
Types::RenderSurfaceType
> occlusion(
1750 gfx::Rect(0, 0, 1000, 1000));
1752 this->VisitLayer(surface
, &occlusion
);
1754 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1755 occlusion
.occlusion_from_inside_target().ToString());
1757 this->VisitContributingSurface(surface
, &occlusion
);
1758 this->EnterLayer(parent
, &occlusion
, false);
1760 // The surface and replica should both be occluding the parent.
1762 UnionRegions(gfx::Rect(0, 100, 50, 50),
1763 gfx::Rect(50, 150, 50, 20)).ToString(),
1764 occlusion
.occlusion_from_inside_target().ToString());
1768 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1770 template <class Types
>
1771 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1773 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1774 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1776 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1777 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1778 typename
Types::LayerType
* surface
=
1779 this->CreateDrawingSurface(parent
,
1780 this->identity_matrix
,
1781 gfx::PointF(0.f
, 100.f
),
1784 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1785 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1786 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1787 this->CalcDrawEtc(parent
);
1789 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1790 typename
Types::RenderSurfaceType
> occlusion(
1791 gfx::Rect(0, 0, 1000, 1000));
1793 this->VisitLayer(surface
, &occlusion
);
1795 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1796 occlusion
.occlusion_from_inside_target().ToString());
1798 this->VisitContributingSurface(surface
, &occlusion
);
1799 this->EnterLayer(parent
, &occlusion
, false);
1801 // The replica should not be occluding the parent, since it has a mask
1803 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1804 occlusion
.occlusion_from_inside_target().ToString());
1808 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1810 template <class Types
>
1811 class OcclusionTrackerTestLayerClipRectOutsideChild
1812 : public OcclusionTrackerTest
<Types
> {
1814 explicit OcclusionTrackerTestLayerClipRectOutsideChild(bool opaque_layers
)
1815 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1817 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1818 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1819 typename
Types::ContentLayerType
* clip
=
1820 this->CreateDrawingLayer(parent
,
1821 this->identity_matrix
,
1822 gfx::PointF(200.f
, 100.f
),
1823 gfx::Size(100, 100),
1825 clip
->SetMasksToBounds(true);
1826 typename
Types::ContentLayerType
* layer
=
1827 this->CreateDrawingLayer(clip
,
1828 this->identity_matrix
,
1829 gfx::PointF(-200.f
, -100.f
),
1830 gfx::Size(200, 200),
1832 this->CalcDrawEtc(parent
);
1834 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1835 typename
Types::RenderSurfaceType
> occlusion(
1836 gfx::Rect(0, 0, 1000, 1000));
1838 this->EnterLayer(layer
, &occlusion
, false);
1840 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1841 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1842 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1843 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1844 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1846 this->LeaveLayer(layer
, &occlusion
);
1847 this->EnterLayer(clip
, &occlusion
, false);
1849 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(-100, 0, 100, 100)));
1850 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, -100, 100, 100)));
1851 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 0, 100, 100)));
1852 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 100, 100, 100)));
1853 EXPECT_FALSE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 0, 100, 100)));
1855 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
1856 occlusion
.UnoccludedLayerContentRect(
1857 clip
, gfx::Rect(-100, -100, 300, 300)));
1861 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild
);
1863 template <class Types
>
1864 class OcclusionTrackerTestViewportRectOutsideChild
1865 : public OcclusionTrackerTest
<Types
> {
1867 explicit OcclusionTrackerTestViewportRectOutsideChild(bool opaque_layers
)
1868 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1870 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1871 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1872 typename
Types::ContentLayerType
* layer
=
1873 this->CreateDrawingSurface(parent
,
1874 this->identity_matrix
,
1876 gfx::Size(200, 200),
1878 this->CalcDrawEtc(parent
);
1880 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1881 typename
Types::RenderSurfaceType
> occlusion(
1882 gfx::Rect(200, 100, 100, 100));
1884 this->EnterLayer(layer
, &occlusion
, false);
1886 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1887 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1888 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1889 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1890 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1892 this->LeaveLayer(layer
, &occlusion
);
1893 this->VisitContributingSurface(layer
, &occlusion
);
1894 this->EnterLayer(parent
, &occlusion
, false);
1896 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1897 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1898 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1899 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1901 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1902 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1903 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1904 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1905 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1907 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100),
1908 occlusion
.UnoccludedLayerContentRect(
1909 parent
, gfx::Rect(0, 0, 300, 300)));
1913 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild
);
1915 template <class Types
>
1916 class OcclusionTrackerTestLayerClipRectOverChild
1917 : public OcclusionTrackerTest
<Types
> {
1919 explicit OcclusionTrackerTestLayerClipRectOverChild(bool opaque_layers
)
1920 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1922 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1923 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1924 typename
Types::ContentLayerType
* clip
=
1925 this->CreateDrawingLayer(parent
,
1926 this->identity_matrix
,
1927 gfx::PointF(100.f
, 100.f
),
1928 gfx::Size(100, 100),
1930 clip
->SetMasksToBounds(true);
1931 typename
Types::ContentLayerType
* layer
=
1932 this->CreateDrawingSurface(clip
,
1933 this->identity_matrix
,
1934 gfx::PointF(-100.f
, -100.f
),
1935 gfx::Size(200, 200),
1937 this->CalcDrawEtc(parent
);
1939 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1940 typename
Types::RenderSurfaceType
> occlusion(
1941 gfx::Rect(0, 0, 1000, 1000));
1943 this->EnterLayer(layer
, &occlusion
, false);
1945 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1946 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1947 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1948 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1950 this->LeaveLayer(layer
, &occlusion
);
1951 this->VisitContributingSurface(layer
, &occlusion
);
1953 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1954 occlusion
.occlusion_from_inside_target().ToString());
1956 this->EnterLayer(clip
, &occlusion
, false);
1958 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 0, 100, 100)));
1959 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 100, 100, 100)));
1960 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 0, 100, 100)));
1961 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 100, 100, 100)));
1962 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 100, 100, 100)));
1963 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 0, 100, 100)));
1964 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 200, 100, 100)));
1965 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 200, 100, 100)));
1966 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 200, 100, 100)));
1968 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1969 clip
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1973 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild
);
1975 template <class Types
>
1976 class OcclusionTrackerTestViewportRectOverChild
1977 : public OcclusionTrackerTest
<Types
> {
1979 explicit OcclusionTrackerTestViewportRectOverChild(bool opaque_layers
)
1980 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1982 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1983 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1984 typename
Types::ContentLayerType
* layer
=
1985 this->CreateDrawingSurface(parent
,
1986 this->identity_matrix
,
1988 gfx::Size(200, 200),
1990 this->CalcDrawEtc(parent
);
1992 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1993 typename
Types::RenderSurfaceType
> occlusion(
1994 gfx::Rect(100, 100, 100, 100));
1996 this->EnterLayer(layer
, &occlusion
, false);
1998 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1999 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2000 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2001 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2003 this->LeaveLayer(layer
, &occlusion
);
2004 this->VisitContributingSurface(layer
, &occlusion
);
2005 this->EnterLayer(parent
, &occlusion
, false);
2007 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2008 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2009 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2010 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2011 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2012 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2013 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2014 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2015 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2017 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2018 parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2022 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild
);
2024 template <class Types
>
2025 class OcclusionTrackerTestLayerClipRectPartlyOverChild
2026 : public OcclusionTrackerTest
<Types
> {
2028 explicit OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaque_layers
)
2029 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2031 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2032 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2033 typename
Types::ContentLayerType
* clip
=
2034 this->CreateDrawingLayer(parent
,
2035 this->identity_matrix
,
2036 gfx::PointF(50.f
, 50.f
),
2037 gfx::Size(200, 200),
2039 clip
->SetMasksToBounds(true);
2040 typename
Types::ContentLayerType
* layer
=
2041 this->CreateDrawingSurface(clip
,
2042 this->identity_matrix
,
2043 gfx::PointF(-50.f
, -50.f
),
2044 gfx::Size(200, 200),
2046 this->CalcDrawEtc(parent
);
2048 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2049 typename
Types::RenderSurfaceType
> occlusion(
2050 gfx::Rect(0, 0, 1000, 1000));
2052 this->EnterLayer(layer
, &occlusion
, false);
2054 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2055 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2056 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2057 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2059 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 50)));
2060 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 50, 100)));
2061 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 50)));
2062 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 50, 100)));
2064 this->LeaveLayer(layer
, &occlusion
);
2065 this->VisitContributingSurface(layer
, &occlusion
);
2066 this->EnterLayer(clip
, &occlusion
, false);
2068 EXPECT_EQ(gfx::Rect(50, 50, 150, 150).ToString(),
2069 occlusion
.occlusion_from_inside_target().ToString());
2073 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild
);
2075 template <class Types
>
2076 class OcclusionTrackerTestViewportRectPartlyOverChild
2077 : public OcclusionTrackerTest
<Types
> {
2079 explicit OcclusionTrackerTestViewportRectPartlyOverChild(bool opaque_layers
)
2080 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2082 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2083 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2084 typename
Types::ContentLayerType
* layer
=
2085 this->CreateDrawingSurface(parent
,
2086 this->identity_matrix
,
2088 gfx::Size(200, 200),
2090 this->CalcDrawEtc(parent
);
2092 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2093 typename
Types::RenderSurfaceType
> occlusion(
2094 gfx::Rect(50, 50, 200, 200));
2096 this->EnterLayer(layer
, &occlusion
, false);
2098 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2099 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2100 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2101 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2103 this->LeaveLayer(layer
, &occlusion
);
2104 this->VisitContributingSurface(layer
, &occlusion
);
2105 this->EnterLayer(parent
, &occlusion
, false);
2107 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2108 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2109 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2110 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2112 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2113 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2114 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2116 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2118 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2120 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200),
2121 occlusion
.UnoccludedLayerContentRect(
2122 parent
, gfx::Rect(0, 0, 300, 300)));
2123 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50),
2124 occlusion
.UnoccludedLayerContentRect(
2125 parent
, gfx::Rect(0, 0, 300, 100)));
2126 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2127 occlusion
.UnoccludedLayerContentRect(
2128 parent
, gfx::Rect(0, 100, 300, 100)));
2129 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2130 occlusion
.UnoccludedLayerContentRect(
2131 parent
, gfx::Rect(200, 100, 100, 100)));
2132 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50),
2133 occlusion
.UnoccludedLayerContentRect(
2134 parent
, gfx::Rect(100, 200, 100, 100)));
2138 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild
);
2140 template <class Types
>
2141 class OcclusionTrackerTestViewportRectOverNothing
2142 : public OcclusionTrackerTest
<Types
> {
2144 explicit OcclusionTrackerTestViewportRectOverNothing(bool opaque_layers
)
2145 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2147 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2148 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2149 typename
Types::ContentLayerType
* layer
=
2150 this->CreateDrawingSurface(parent
,
2151 this->identity_matrix
,
2153 gfx::Size(200, 200),
2155 this->CalcDrawEtc(parent
);
2157 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2158 typename
Types::RenderSurfaceType
> occlusion(
2159 gfx::Rect(500, 500, 100, 100));
2161 this->EnterLayer(layer
, &occlusion
, false);
2163 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2164 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2165 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2166 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2168 this->LeaveLayer(layer
, &occlusion
);
2169 this->VisitContributingSurface(layer
, &occlusion
);
2170 this->EnterLayer(parent
, &occlusion
, false);
2172 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2173 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2174 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2175 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2176 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2177 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2178 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2179 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2180 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2182 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2183 parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2184 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2185 parent
, gfx::Rect(0, 0, 300, 100)).IsEmpty());
2186 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2187 parent
, gfx::Rect(0, 100, 300, 100)).IsEmpty());
2188 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2189 parent
, gfx::Rect(200, 100, 100, 100)).IsEmpty());
2190 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2191 parent
, gfx::Rect(100, 200, 100, 100)).IsEmpty());
2195 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing
);
2197 template <class Types
>
2198 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
2199 : public OcclusionTrackerTest
<Types
> {
2201 explicit OcclusionTrackerTestLayerClipRectForLayerOffOrigin(
2203 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2205 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2206 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2207 typename
Types::ContentLayerType
* layer
=
2208 this->CreateDrawingSurface(parent
,
2209 this->identity_matrix
,
2211 gfx::Size(200, 200),
2213 this->CalcDrawEtc(parent
);
2215 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2216 typename
Types::RenderSurfaceType
> occlusion(
2217 gfx::Rect(0, 0, 1000, 1000));
2218 this->EnterLayer(layer
, &occlusion
, false);
2220 // This layer is translated when drawn into its target. So if the clip rect
2221 // given from the target surface is not in that target space, then after
2222 // translating these query rects into the target, they will fall outside the
2223 // clip and be considered occluded.
2224 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2225 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2226 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2227 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2231 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin
);
2233 template <class Types
>
2234 class OcclusionTrackerTestOpaqueContentsRegionEmpty
2235 : public OcclusionTrackerTest
<Types
> {
2237 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
2238 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2240 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2241 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2242 typename
Types::ContentLayerType
* layer
=
2243 this->CreateDrawingSurface(parent
,
2244 this->identity_matrix
,
2246 gfx::Size(200, 200),
2248 this->CalcDrawEtc(parent
);
2250 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2251 typename
Types::RenderSurfaceType
> occlusion(
2252 gfx::Rect(0, 0, 1000, 1000));
2253 this->EnterLayer(layer
, &occlusion
, false);
2255 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2256 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2257 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2258 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2260 // Occluded since its outside the surface bounds.
2261 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
2263 this->LeaveLayer(layer
, &occlusion
);
2264 this->VisitContributingSurface(layer
, &occlusion
);
2265 this->EnterLayer(parent
, &occlusion
, false);
2267 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2271 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
2273 template <class Types
>
2274 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
2275 : public OcclusionTrackerTest
<Types
> {
2277 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
2278 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2280 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2281 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2282 typename
Types::ContentLayerType
* layer
=
2283 this->CreateDrawingLayer(parent
,
2284 this->identity_matrix
,
2285 gfx::PointF(100.f
, 100.f
),
2286 gfx::Size(200, 200),
2288 this->CalcDrawEtc(parent
);
2290 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2291 typename
Types::RenderSurfaceType
> occlusion(
2292 gfx::Rect(0, 0, 1000, 1000));
2293 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
2295 this->ResetLayerIterator();
2296 this->VisitLayer(layer
, &occlusion
);
2297 this->EnterLayer(parent
, &occlusion
, false);
2299 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
2300 occlusion
.occlusion_from_inside_target().ToString());
2303 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2305 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2307 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2310 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2311 typename
Types::RenderSurfaceType
> occlusion(
2312 gfx::Rect(0, 0, 1000, 1000));
2313 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
2315 this->ResetLayerIterator();
2316 this->VisitLayer(layer
, &occlusion
);
2317 this->EnterLayer(parent
, &occlusion
, false);
2319 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
2320 occlusion
.occlusion_from_inside_target().ToString());
2323 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2325 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2327 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2330 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2331 typename
Types::RenderSurfaceType
> occlusion(
2332 gfx::Rect(0, 0, 1000, 1000));
2333 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
2335 this->ResetLayerIterator();
2336 this->VisitLayer(layer
, &occlusion
);
2337 this->EnterLayer(parent
, &occlusion
, false);
2339 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
2340 occlusion
.occlusion_from_inside_target().ToString());
2343 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2345 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2347 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2352 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
2354 template <class Types
>
2355 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
2357 explicit OcclusionTrackerTest3dTransform(bool opaque_layers
)
2358 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2360 gfx::Transform transform
;
2361 transform
.RotateAboutYAxis(30.0);
2363 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2364 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2365 typename
Types::LayerType
* container
= this->CreateLayer(
2366 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2367 typename
Types::ContentLayerType
* layer
=
2368 this->CreateDrawingLayer(container
,
2370 gfx::PointF(100.f
, 100.f
),
2371 gfx::Size(200, 200),
2373 this->CalcDrawEtc(parent
);
2375 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2376 typename
Types::RenderSurfaceType
> occlusion(
2377 gfx::Rect(0, 0, 1000, 1000));
2378 this->EnterLayer(layer
, &occlusion
, false);
2380 // The layer is rotated in 3d but without preserving 3d, so it only gets
2383 gfx::Rect(0, 0, 200, 200),
2384 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
2388 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
2390 template <class Types
>
2391 class OcclusionTrackerTestUnsorted3dLayers
2392 : public OcclusionTrackerTest
<Types
> {
2394 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
2395 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2397 // Currently, The main thread layer iterator does not iterate over 3d items
2398 // in sorted order, because layer sorting is not performed on the main
2399 // thread. Because of this, the occlusion tracker cannot assume that a 3d
2400 // layer occludes other layers that have not yet been iterated over. For
2401 // now, the expected behavior is that a 3d layer simply does not add any
2402 // occlusion to the occlusion tracker.
2404 gfx::Transform translation_to_front
;
2405 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
2406 gfx::Transform translation_to_back
;
2407 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
2409 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2410 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2411 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
2412 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
2413 typename
Types::ContentLayerType
* child2
=
2414 this->CreateDrawingLayer(parent
,
2415 translation_to_front
,
2416 gfx::PointF(50.f
, 50.f
),
2417 gfx::Size(100, 100),
2419 parent
->SetPreserves3d(true);
2421 this->CalcDrawEtc(parent
);
2423 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2424 typename
Types::RenderSurfaceType
> occlusion(
2425 gfx::Rect(0, 0, 1000, 1000));
2426 this->VisitLayer(child2
, &occlusion
);
2427 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2428 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2430 this->VisitLayer(child1
, &occlusion
);
2431 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2432 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2436 // This test will have different layer ordering on the impl thread; the test
2437 // will only work on the main thread.
2438 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
2440 template <class Types
>
2441 class OcclusionTrackerTestPerspectiveTransform
2442 : public OcclusionTrackerTest
<Types
> {
2444 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers
)
2445 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2447 gfx::Transform transform
;
2448 transform
.Translate(150.0, 150.0);
2449 transform
.ApplyPerspectiveDepth(400.0);
2450 transform
.RotateAboutXAxis(-30.0);
2451 transform
.Translate(-150.0, -150.0);
2453 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2454 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2455 typename
Types::LayerType
* container
= this->CreateLayer(
2456 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2457 typename
Types::ContentLayerType
* layer
=
2458 this->CreateDrawingLayer(container
,
2460 gfx::PointF(100.f
, 100.f
),
2461 gfx::Size(200, 200),
2463 container
->SetPreserves3d(true);
2464 layer
->SetPreserves3d(true);
2465 this->CalcDrawEtc(parent
);
2467 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2468 typename
Types::RenderSurfaceType
> occlusion(
2469 gfx::Rect(0, 0, 1000, 1000));
2470 this->EnterLayer(layer
, &occlusion
, false);
2473 gfx::Rect(0, 0, 200, 200),
2474 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
2478 // This test requires accumulating occlusion of 3d layers, which are skipped by
2479 // the occlusion tracker on the main thread. So this test should run on the impl
2481 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
2483 template <class Types
>
2484 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2485 : public OcclusionTrackerTest
<Types
> {
2487 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2489 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2491 // This test is based on the platform/chromium/compositing/3d-corners.html
2493 gfx::Transform transform
;
2494 transform
.Translate(250.0, 50.0);
2495 transform
.ApplyPerspectiveDepth(10.0);
2496 transform
.Translate(-250.0, -50.0);
2497 transform
.Translate(250.0, 50.0);
2498 transform
.RotateAboutXAxis(-167.0);
2499 transform
.Translate(-250.0, -50.0);
2501 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2502 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 100));
2503 typename
Types::LayerType
* container
= this->CreateLayer(
2504 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2505 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2506 container
, transform
, gfx::PointF(), gfx::Size(500, 500), true);
2507 container
->SetPreserves3d(true);
2508 layer
->SetPreserves3d(true);
2509 this->CalcDrawEtc(parent
);
2511 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2512 typename
Types::RenderSurfaceType
> occlusion(
2513 gfx::Rect(0, 0, 1000, 1000));
2514 this->EnterLayer(layer
, &occlusion
, false);
2516 // The bottom 11 pixel rows of this layer remain visible inside the
2517 // container, after translation to the target surface. When translated back,
2518 // this will include many more pixels but must include at least the bottom
2520 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2521 layer
, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
2525 // This test requires accumulating occlusion of 3d layers, which are skipped by
2526 // the occlusion tracker on the main thread. So this test should run on the impl
2528 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
2530 template <class Types
>
2531 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2532 : public OcclusionTrackerTest
<Types
> {
2534 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2536 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2538 gfx::Transform transform
;
2539 transform
.Translate(50.0, 50.0);
2540 transform
.ApplyPerspectiveDepth(100.0);
2541 transform
.Translate3d(0.0, 0.0, 110.0);
2542 transform
.Translate(-50.0, -50.0);
2544 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2545 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2546 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2547 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2548 parent
->SetPreserves3d(true);
2549 layer
->SetPreserves3d(true);
2550 this->CalcDrawEtc(parent
);
2552 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2553 typename
Types::RenderSurfaceType
> occlusion(
2554 gfx::Rect(0, 0, 1000, 1000));
2556 // The |layer| is entirely behind the camera and should not occlude.
2557 this->VisitLayer(layer
, &occlusion
);
2558 this->EnterLayer(parent
, &occlusion
, false);
2559 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2560 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2564 // This test requires accumulating occlusion of 3d layers, which are skipped by
2565 // the occlusion tracker on the main thread. So this test should run on the impl
2567 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2569 template <class Types
>
2570 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2571 : public OcclusionTrackerTest
<Types
> {
2573 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2575 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2577 gfx::Transform transform
;
2578 transform
.Translate(50.0, 50.0);
2579 transform
.ApplyPerspectiveDepth(100.0);
2580 transform
.Translate3d(0.0, 0.0, 99.0);
2581 transform
.Translate(-50.0, -50.0);
2583 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2584 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2585 parent
->SetMasksToBounds(true);
2586 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2587 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2588 parent
->SetPreserves3d(true);
2589 layer
->SetPreserves3d(true);
2590 this->CalcDrawEtc(parent
);
2592 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2593 typename
Types::RenderSurfaceType
> occlusion(
2594 gfx::Rect(0, 0, 1000, 1000));
2596 // This is very close to the camera, so pixels in its visible_content_rect()
2597 // will actually go outside of the layer's clip rect. Ensure that those
2598 // pixels don't occlude things outside the clip rect.
2599 this->VisitLayer(layer
, &occlusion
);
2600 this->EnterLayer(parent
, &occlusion
, false);
2601 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2602 occlusion
.occlusion_from_inside_target().ToString());
2603 EXPECT_EQ(gfx::Rect().ToString(),
2604 occlusion
.occlusion_from_outside_target().ToString());
2608 // This test requires accumulating occlusion of 3d layers, which are skipped by
2609 // the occlusion tracker on the main thread. So this test should run on the impl
2611 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2613 template <class Types
>
2614 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2615 : public OcclusionTrackerTest
<Types
> {
2617 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
2618 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2623 // | +--surface_child
2624 // | +--surface_child2
2628 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2629 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2630 typename
Types::ContentLayerType
* layer
=
2631 this->CreateDrawingLayer(parent
,
2632 this->identity_matrix
,
2634 gfx::Size(300, 300),
2636 typename
Types::ContentLayerType
* surface
=
2637 this->CreateDrawingSurface(parent
,
2638 this->identity_matrix
,
2640 gfx::Size(300, 300),
2642 typename
Types::ContentLayerType
* surface_child
=
2643 this->CreateDrawingLayer(surface
,
2644 this->identity_matrix
,
2646 gfx::Size(200, 300),
2648 typename
Types::ContentLayerType
* surface_child2
=
2649 this->CreateDrawingLayer(surface
,
2650 this->identity_matrix
,
2652 gfx::Size(100, 300),
2654 typename
Types::ContentLayerType
* parent2
=
2655 this->CreateDrawingLayer(parent
,
2656 this->identity_matrix
,
2658 gfx::Size(300, 300),
2660 typename
Types::ContentLayerType
* topmost
=
2661 this->CreateDrawingLayer(parent
,
2662 this->identity_matrix
,
2663 gfx::PointF(250.f
, 0.f
),
2667 AddOpacityTransitionToController(
2668 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2669 AddOpacityTransitionToController(
2670 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2671 this->CalcDrawEtc(parent
);
2673 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2674 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2675 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2677 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2678 typename
Types::RenderSurfaceType
> occlusion(
2679 gfx::Rect(0, 0, 1000, 1000));
2681 this->VisitLayer(topmost
, &occlusion
);
2682 this->EnterLayer(parent2
, &occlusion
, false);
2683 // This occlusion will affect all surfaces.
2684 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2685 occlusion
.occlusion_from_inside_target().ToString());
2686 EXPECT_EQ(gfx::Rect().ToString(),
2687 occlusion
.occlusion_from_outside_target().ToString());
2688 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2689 occlusion
.UnoccludedLayerContentRect(
2690 parent2
, gfx::Rect(0, 0, 300, 300)).ToString());
2691 this->LeaveLayer(parent2
, &occlusion
);
2693 this->VisitLayer(surface_child2
, &occlusion
);
2694 this->EnterLayer(surface_child
, &occlusion
, false);
2695 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2696 occlusion
.occlusion_from_inside_target().ToString());
2697 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2698 occlusion
.occlusion_from_outside_target().ToString());
2699 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2700 occlusion
.UnoccludedLayerContentRect(
2701 surface_child
, gfx::Rect(0, 0, 200, 300)));
2702 this->LeaveLayer(surface_child
, &occlusion
);
2703 this->EnterLayer(surface
, &occlusion
, false);
2704 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2705 occlusion
.occlusion_from_inside_target().ToString());
2706 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2707 occlusion
.occlusion_from_outside_target().ToString());
2708 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2709 occlusion
.UnoccludedLayerContentRect(
2710 surface
, gfx::Rect(0, 0, 300, 300)));
2711 this->LeaveLayer(surface
, &occlusion
);
2713 this->EnterContributingSurface(surface
, &occlusion
, false);
2714 // Occlusion within the surface is lost when leaving the animating surface.
2715 EXPECT_EQ(gfx::Rect().ToString(),
2716 occlusion
.occlusion_from_inside_target().ToString());
2717 EXPECT_EQ(gfx::Rect().ToString(),
2718 occlusion
.occlusion_from_outside_target().ToString());
2719 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2720 occlusion
.UnoccludedContributingSurfaceContentRect(
2721 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
2722 this->LeaveContributingSurface(surface
, &occlusion
);
2724 // Occlusion from outside the animating surface still exists.
2725 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2726 occlusion
.occlusion_from_inside_target().ToString());
2727 EXPECT_EQ(gfx::Rect().ToString(),
2728 occlusion
.occlusion_from_outside_target().ToString());
2730 this->VisitLayer(layer
, &occlusion
);
2731 this->EnterLayer(parent
, &occlusion
, false);
2733 // Occlusion is not added for the animating |layer|.
2734 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2735 occlusion
.UnoccludedLayerContentRect(
2736 parent
, gfx::Rect(0, 0, 300, 300)));
2740 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2742 template <class Types
>
2743 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2744 : public OcclusionTrackerTest
<Types
> {
2746 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
2747 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2749 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2750 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2751 typename
Types::ContentLayerType
* layer
=
2752 this->CreateDrawingLayer(parent
,
2753 this->identity_matrix
,
2755 gfx::Size(300, 300),
2757 typename
Types::ContentLayerType
* surface
=
2758 this->CreateDrawingSurface(parent
,
2759 this->identity_matrix
,
2761 gfx::Size(300, 300),
2763 typename
Types::ContentLayerType
* surface_child
=
2764 this->CreateDrawingLayer(surface
,
2765 this->identity_matrix
,
2767 gfx::Size(200, 300),
2769 typename
Types::ContentLayerType
* surface_child2
=
2770 this->CreateDrawingLayer(surface
,
2771 this->identity_matrix
,
2773 gfx::Size(100, 300),
2775 typename
Types::ContentLayerType
* parent2
=
2776 this->CreateDrawingLayer(parent
,
2777 this->identity_matrix
,
2779 gfx::Size(300, 300),
2781 typename
Types::ContentLayerType
* topmost
=
2782 this->CreateDrawingLayer(parent
,
2783 this->identity_matrix
,
2784 gfx::PointF(250.f
, 0.f
),
2788 AddOpacityTransitionToController(
2789 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2790 AddOpacityTransitionToController(
2791 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2792 this->CalcDrawEtc(parent
);
2794 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2795 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2796 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2798 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2799 typename
Types::RenderSurfaceType
> occlusion(
2800 gfx::Rect(0, 0, 1000, 1000));
2802 this->VisitLayer(topmost
, &occlusion
);
2803 this->EnterLayer(parent2
, &occlusion
, false);
2804 // This occlusion will affect all surfaces.
2805 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2806 occlusion
.occlusion_from_inside_target().ToString());
2807 EXPECT_EQ(gfx::Rect().ToString(),
2808 occlusion
.occlusion_from_outside_target().ToString());
2809 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2810 occlusion
.UnoccludedLayerContentRect(
2811 parent
, gfx::Rect(0, 0, 300, 300)));
2812 this->LeaveLayer(parent2
, &occlusion
);
2814 this->VisitLayer(surface_child2
, &occlusion
);
2815 this->EnterLayer(surface_child
, &occlusion
, false);
2816 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2817 occlusion
.occlusion_from_inside_target().ToString());
2818 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2819 occlusion
.occlusion_from_outside_target().ToString());
2820 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2821 occlusion
.UnoccludedLayerContentRect(
2822 surface_child
, gfx::Rect(0, 0, 200, 300)));
2823 this->LeaveLayer(surface_child
, &occlusion
);
2824 this->EnterLayer(surface
, &occlusion
, false);
2825 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2826 occlusion
.occlusion_from_inside_target().ToString());
2827 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2828 occlusion
.occlusion_from_outside_target().ToString());
2829 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2830 occlusion
.UnoccludedLayerContentRect(
2831 surface
, gfx::Rect(0, 0, 300, 300)));
2832 this->LeaveLayer(surface
, &occlusion
);
2834 this->EnterContributingSurface(surface
, &occlusion
, false);
2835 // Occlusion within the surface is lost when leaving the animating surface.
2836 EXPECT_EQ(gfx::Rect().ToString(),
2837 occlusion
.occlusion_from_inside_target().ToString());
2838 EXPECT_EQ(gfx::Rect().ToString(),
2839 occlusion
.occlusion_from_outside_target().ToString());
2840 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2841 occlusion
.UnoccludedContributingSurfaceContentRect(
2842 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
2843 this->LeaveContributingSurface(surface
, &occlusion
);
2845 // Occlusion from outside the animating surface still exists.
2846 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2847 occlusion
.occlusion_from_inside_target().ToString());
2848 EXPECT_EQ(gfx::Rect().ToString(),
2849 occlusion
.occlusion_from_outside_target().ToString());
2851 this->VisitLayer(layer
, &occlusion
);
2852 this->EnterLayer(parent
, &occlusion
, false);
2854 // Occlusion is not added for the animating |layer|.
2855 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2856 occlusion
.UnoccludedLayerContentRect(
2857 parent
, gfx::Rect(0, 0, 300, 300)));
2861 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2863 template <class Types
>
2864 class OcclusionTrackerTestAnimationTranslateOnMainThread
2865 : public OcclusionTrackerTest
<Types
> {
2867 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2869 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2871 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2872 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2873 typename
Types::ContentLayerType
* layer
=
2874 this->CreateDrawingLayer(parent
,
2875 this->identity_matrix
,
2877 gfx::Size(300, 300),
2879 typename
Types::ContentLayerType
* surface
=
2880 this->CreateDrawingSurface(parent
,
2881 this->identity_matrix
,
2883 gfx::Size(300, 300),
2885 typename
Types::ContentLayerType
* surface_child
=
2886 this->CreateDrawingLayer(surface
,
2887 this->identity_matrix
,
2889 gfx::Size(200, 300),
2891 typename
Types::ContentLayerType
* surface_child2
=
2892 this->CreateDrawingLayer(surface
,
2893 this->identity_matrix
,
2895 gfx::Size(100, 300),
2897 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
2898 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
2900 AddAnimatedTransformToController(
2901 layer
->layer_animation_controller(), 10.0, 30, 0);
2902 AddAnimatedTransformToController(
2903 surface
->layer_animation_controller(), 10.0, 30, 0);
2904 AddAnimatedTransformToController(
2905 surface_child
->layer_animation_controller(), 10.0, 30, 0);
2906 this->CalcDrawEtc(parent
);
2908 EXPECT_TRUE(layer
->draw_transform_is_animating());
2909 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
2911 surface
->render_surface()->target_surface_transforms_are_animating());
2913 surface
->render_surface()->screen_space_transforms_are_animating());
2914 // The surface owning layer doesn't animate against its own surface.
2915 EXPECT_FALSE(surface
->draw_transform_is_animating());
2916 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
2917 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
2918 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
2920 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2921 typename
Types::RenderSurfaceType
> occlusion(
2922 gfx::Rect(0, 0, 1000, 1000));
2924 this->VisitLayer(surface2
, &occlusion
);
2925 this->EnterContributingSurface(surface2
, &occlusion
, false);
2927 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2928 occlusion
.occlusion_from_inside_target().ToString());
2930 this->LeaveContributingSurface(surface2
, &occlusion
);
2931 this->EnterLayer(surface_child2
, &occlusion
, false);
2933 // surface_child2 is moving in screen space but not relative to its target,
2934 // so occlusion should happen in its target space only. It also means that
2935 // things occluding from outside the target (e.g. surface2) cannot occlude
2937 EXPECT_EQ(gfx::Rect().ToString(),
2938 occlusion
.occlusion_from_outside_target().ToString());
2940 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2941 occlusion
.UnoccludedLayerContentRect(
2942 surface_child2
, gfx::Rect(0, 0, 100, 300)));
2944 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2946 this->LeaveLayer(surface_child2
, &occlusion
);
2947 this->EnterLayer(surface_child
, &occlusion
, false);
2949 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 100, 300)));
2950 EXPECT_EQ(gfx::Rect().ToString(),
2951 occlusion
.occlusion_from_outside_target().ToString());
2952 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2953 occlusion
.occlusion_from_inside_target().ToString());
2954 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2955 occlusion
.UnoccludedLayerContentRect(
2956 surface
, gfx::Rect(0, 0, 300, 300)));
2958 // The surface_child is occluded by the surface_child2, but is moving
2959 // relative its target, so it can't be occluded.
2960 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2961 occlusion
.UnoccludedLayerContentRect(
2962 surface_child
, gfx::Rect(0, 0, 200, 300)));
2964 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2966 this->LeaveLayer(surface_child
, &occlusion
);
2967 this->EnterLayer(surface
, &occlusion
, false);
2968 // The surface_child is moving in screen space but not relative to its
2969 // target, so occlusion should happen from within the target only.
2970 EXPECT_EQ(gfx::Rect().ToString(),
2971 occlusion
.occlusion_from_outside_target().ToString());
2972 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2973 occlusion
.occlusion_from_inside_target().ToString());
2974 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2975 occlusion
.UnoccludedLayerContentRect(
2976 surface
, gfx::Rect(0, 0, 300, 300)));
2978 this->LeaveLayer(surface
, &occlusion
);
2979 // The surface's owning layer is moving in screen space but not relative to
2980 // its target, so occlusion should happen within the target only.
2981 EXPECT_EQ(gfx::Rect().ToString(),
2982 occlusion
.occlusion_from_outside_target().ToString());
2983 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2984 occlusion
.occlusion_from_inside_target().ToString());
2985 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2986 occlusion
.UnoccludedLayerContentRect(
2987 surface
, gfx::Rect(0, 0, 300, 300)));
2989 this->EnterContributingSurface(surface
, &occlusion
, false);
2990 // The contributing |surface| is animating so it can't be occluded.
2991 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2992 occlusion
.UnoccludedContributingSurfaceContentRect(
2993 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
2994 this->LeaveContributingSurface(surface
, &occlusion
);
2996 this->EnterLayer(layer
, &occlusion
, false);
2997 // The |surface| is moving in the screen and in its target, so all occlusion
2998 // within the surface is lost when leaving it.
2999 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3000 occlusion
.UnoccludedLayerContentRect(
3001 parent
, gfx::Rect(0, 0, 300, 300)));
3002 this->LeaveLayer(layer
, &occlusion
);
3004 this->EnterLayer(parent
, &occlusion
, false);
3005 // The |layer| is animating in the screen and in its target, so no occlusion
3007 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3008 occlusion
.UnoccludedLayerContentRect(
3009 parent
, gfx::Rect(0, 0, 300, 300)));
3013 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
3015 template <class Types
>
3016 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
3017 : public OcclusionTrackerTest
<Types
> {
3019 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
3021 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3023 gfx::Transform surface_transform
;
3024 surface_transform
.Translate(300.0, 300.0);
3025 surface_transform
.Scale(2.0, 2.0);
3026 surface_transform
.Translate(-150.0, -150.0);
3028 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3029 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
3030 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
3031 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
3032 typename
Types::ContentLayerType
* surface2
=
3033 this->CreateDrawingSurface(parent
,
3034 this->identity_matrix
,
3035 gfx::PointF(50.f
, 50.f
),
3036 gfx::Size(300, 300),
3038 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3039 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3040 this->CalcDrawEtc(parent
);
3042 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3043 typename
Types::RenderSurfaceType
> occlusion(
3044 gfx::Rect(0, 0, 1000, 1000));
3046 this->VisitLayer(surface2
, &occlusion
);
3047 this->VisitContributingSurface(surface2
, &occlusion
);
3049 EXPECT_EQ(gfx::Rect().ToString(),
3050 occlusion
.occlusion_from_outside_target().ToString());
3051 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
3052 occlusion
.occlusion_from_inside_target().ToString());
3054 // Clear any stored occlusion.
3055 occlusion
.set_occlusion_from_outside_target(Region());
3056 occlusion
.set_occlusion_from_inside_target(Region());
3058 this->VisitLayer(surface
, &occlusion
);
3059 this->VisitContributingSurface(surface
, &occlusion
);
3061 EXPECT_EQ(gfx::Rect().ToString(),
3062 occlusion
.occlusion_from_outside_target().ToString());
3063 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
3064 occlusion
.occlusion_from_inside_target().ToString());
3068 MAIN_AND_IMPL_THREAD_TEST(
3069 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
3071 template <class Types
>
3072 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
3073 : public OcclusionTrackerTest
<Types
> {
3075 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
3077 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3079 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3080 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
3081 parent
->SetMasksToBounds(true);
3082 typename
Types::ContentLayerType
* surface
=
3083 this->CreateDrawingSurface(parent
,
3084 this->identity_matrix
,
3086 gfx::Size(500, 300),
3088 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
3089 this->CalcDrawEtc(parent
);
3091 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3092 typename
Types::RenderSurfaceType
> occlusion(
3093 gfx::Rect(0, 0, 1000, 1000));
3095 this->VisitLayer(surface
, &occlusion
);
3096 this->VisitContributingSurface(surface
, &occlusion
);
3098 EXPECT_EQ(gfx::Rect().ToString(),
3099 occlusion
.occlusion_from_outside_target().ToString());
3100 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
3101 occlusion
.occlusion_from_inside_target().ToString());
3105 MAIN_AND_IMPL_THREAD_TEST(
3106 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
3108 template <class Types
>
3109 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
3111 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers
)
3112 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3114 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3115 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3116 typename
Types::LayerType
* surface
=
3117 this->CreateDrawingSurface(parent
,
3118 this->identity_matrix
,
3120 gfx::Size(100, 100),
3122 this->CreateReplicaLayer(surface
,
3123 this->identity_matrix
,
3124 gfx::PointF(0.f
, 100.f
),
3125 gfx::Size(100, 100));
3126 typename
Types::LayerType
* topmost
=
3127 this->CreateDrawingLayer(parent
,
3128 this->identity_matrix
,
3129 gfx::PointF(0.f
, 100.f
),
3130 gfx::Size(100, 100),
3132 this->CalcDrawEtc(parent
);
3134 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3135 typename
Types::RenderSurfaceType
> occlusion(
3136 gfx::Rect(0, 0, 1000, 1000));
3138 // |topmost| occludes the replica, but not the surface itself.
3139 this->VisitLayer(topmost
, &occlusion
);
3141 EXPECT_EQ(gfx::Rect().ToString(),
3142 occlusion
.occlusion_from_outside_target().ToString());
3143 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3144 occlusion
.occlusion_from_inside_target().ToString());
3146 this->VisitLayer(surface
, &occlusion
);
3148 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3149 occlusion
.occlusion_from_outside_target().ToString());
3150 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3151 occlusion
.occlusion_from_inside_target().ToString());
3153 this->EnterContributingSurface(surface
, &occlusion
, false);
3155 // Surface is not occluded so it shouldn't think it is.
3156 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3157 occlusion
.UnoccludedContributingSurfaceContentRect(
3158 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3162 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
3164 template <class Types
>
3165 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
3166 : public OcclusionTrackerTest
<Types
> {
3168 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
3169 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3171 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3172 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3173 typename
Types::LayerType
* surface
=
3174 this->CreateDrawingSurface(parent
,
3175 this->identity_matrix
,
3177 gfx::Size(100, 100),
3179 this->CreateReplicaLayer(surface
,
3180 this->identity_matrix
,
3181 gfx::PointF(0.f
, 100.f
),
3182 gfx::Size(100, 100));
3183 typename
Types::LayerType
* topmost
=
3184 this->CreateDrawingLayer(parent
,
3185 this->identity_matrix
,
3187 gfx::Size(100, 110),
3189 this->CalcDrawEtc(parent
);
3191 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3192 typename
Types::RenderSurfaceType
> occlusion(
3193 gfx::Rect(0, 0, 1000, 1000));
3195 // |topmost| occludes the surface, but not the entire surface's replica.
3196 this->VisitLayer(topmost
, &occlusion
);
3198 EXPECT_EQ(gfx::Rect().ToString(),
3199 occlusion
.occlusion_from_outside_target().ToString());
3200 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3201 occlusion
.occlusion_from_inside_target().ToString());
3203 this->VisitLayer(surface
, &occlusion
);
3205 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3206 occlusion
.occlusion_from_outside_target().ToString());
3207 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3208 occlusion
.occlusion_from_inside_target().ToString());
3210 this->EnterContributingSurface(surface
, &occlusion
, false);
3212 // Surface is occluded, but only the top 10px of the replica.
3213 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3214 occlusion
.UnoccludedContributingSurfaceContentRect(
3215 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3216 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
3217 occlusion
.UnoccludedContributingSurfaceContentRect(
3218 surface
, true, gfx::Rect(0, 0, 100, 100), NULL
));
3222 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
3224 template <class Types
>
3225 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
3226 : public OcclusionTrackerTest
<Types
> {
3228 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
3230 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3232 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3233 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3234 typename
Types::LayerType
* surface
=
3235 this->CreateDrawingSurface(parent
,
3236 this->identity_matrix
,
3238 gfx::Size(100, 100),
3240 this->CreateReplicaLayer(surface
,
3241 this->identity_matrix
,
3242 gfx::PointF(0.f
, 100.f
),
3243 gfx::Size(100, 100));
3244 typename
Types::LayerType
* over_surface
= this->CreateDrawingLayer(
3245 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 100), true);
3246 typename
Types::LayerType
* over_replica
=
3247 this->CreateDrawingLayer(parent
,
3248 this->identity_matrix
,
3249 gfx::PointF(0.f
, 100.f
),
3252 this->CalcDrawEtc(parent
);
3254 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3255 typename
Types::RenderSurfaceType
> occlusion(
3256 gfx::Rect(0, 0, 1000, 1000));
3258 // These occlude the surface and replica differently, so we can test each
3260 this->VisitLayer(over_replica
, &occlusion
);
3261 this->VisitLayer(over_surface
, &occlusion
);
3263 EXPECT_EQ(gfx::Rect().ToString(),
3264 occlusion
.occlusion_from_outside_target().ToString());
3265 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3267 occlusion
.occlusion_from_inside_target().ToString());
3269 this->VisitLayer(surface
, &occlusion
);
3271 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3273 occlusion
.occlusion_from_outside_target().ToString());
3274 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3275 occlusion
.occlusion_from_inside_target().ToString());
3277 this->EnterContributingSurface(surface
, &occlusion
, false);
3279 // Surface and replica are occluded different amounts.
3280 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
3281 occlusion
.UnoccludedContributingSurfaceContentRect(
3282 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3283 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
3284 occlusion
.UnoccludedContributingSurfaceContentRect(
3285 surface
, true, gfx::Rect(0, 0, 100, 100), NULL
));
3289 ALL_OCCLUSIONTRACKER_TEST(
3290 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
3292 template <class Types
>
3293 class OcclusionTrackerTestSurfaceChildOfSurface
3294 : public OcclusionTrackerTest
<Types
> {
3296 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
3297 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3299 // This test verifies that the surface cliprect does not end up empty and
3300 // clip away the entire unoccluded rect.
3302 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3303 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3304 typename
Types::LayerType
* surface
=
3305 this->CreateDrawingSurface(parent
,
3306 this->identity_matrix
,
3308 gfx::Size(100, 100),
3310 typename
Types::LayerType
* surface_child
=
3311 this->CreateDrawingSurface(surface
,
3312 this->identity_matrix
,
3313 gfx::PointF(0.f
, 10.f
),
3316 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
3317 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
3318 this->CalcDrawEtc(parent
);
3320 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3321 typename
Types::RenderSurfaceType
> occlusion(
3322 gfx::Rect(-100, -100, 1000, 1000));
3324 // |topmost| occludes everything partially so we know occlusion is happening
3326 this->VisitLayer(topmost
, &occlusion
);
3328 EXPECT_EQ(gfx::Rect().ToString(),
3329 occlusion
.occlusion_from_outside_target().ToString());
3330 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3331 occlusion
.occlusion_from_inside_target().ToString());
3333 this->VisitLayer(surface_child
, &occlusion
);
3335 // surface_child increases the occlusion in the screen by a narrow sliver.
3336 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
3337 occlusion
.occlusion_from_outside_target().ToString());
3338 // In its own surface, surface_child is at 0,0 as is its occlusion.
3339 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3340 occlusion
.occlusion_from_inside_target().ToString());
3342 // The root layer always has a clip rect. So the parent of |surface| has a
3343 // clip rect. However, the owning layer for |surface| does not mask to
3344 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3345 // |surface_child| exercises different code paths as its parent does not
3346 // have a clip rect.
3348 this->EnterContributingSurface(surface_child
, &occlusion
, false);
3349 // The surface_child's parent does not have a clip rect as it owns a render
3350 // surface. Make sure the unoccluded rect does not get clipped away
3352 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
3353 occlusion
.UnoccludedContributingSurfaceContentRect(
3354 surface_child
, false, gfx::Rect(0, 0, 100, 50), NULL
));
3355 this->LeaveContributingSurface(surface_child
, &occlusion
);
3357 // When the surface_child's occlusion is transformed up to its parent, make
3358 // sure it is not clipped away inappropriately also.
3359 this->EnterLayer(surface
, &occlusion
, false);
3360 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3361 occlusion
.occlusion_from_outside_target().ToString());
3362 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
3363 occlusion
.occlusion_from_inside_target().ToString());
3364 this->LeaveLayer(surface
, &occlusion
);
3366 this->EnterContributingSurface(surface
, &occlusion
, false);
3367 // The surface's parent does have a clip rect as it is the root layer.
3368 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
3369 occlusion
.UnoccludedContributingSurfaceContentRect(
3370 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3374 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
3376 template <class Types
>
3377 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
3378 : public OcclusionTrackerTest
<Types
> {
3380 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
3382 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3384 // This test verifies that the top-most surface is considered occluded
3385 // outside of its target's clip rect and outside the viewport rect.
3387 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3388 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3389 typename
Types::LayerType
* surface
=
3390 this->CreateDrawingSurface(parent
,
3391 this->identity_matrix
,
3393 gfx::Size(100, 300),
3395 this->CalcDrawEtc(parent
);
3397 // Make a viewport rect that is larger than the root layer.
3398 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3399 typename
Types::RenderSurfaceType
> occlusion(
3400 gfx::Rect(0, 0, 1000, 1000));
3402 this->VisitLayer(surface
, &occlusion
);
3404 // The root layer always has a clip rect. So the parent of |surface| has a
3405 // clip rect giving the surface itself a clip rect.
3406 this->EnterContributingSurface(surface
, &occlusion
, false);
3407 // Make sure the parent's clip rect clips the unoccluded region of the
3409 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
3410 occlusion
.UnoccludedContributingSurfaceContentRect(
3411 surface
, false, gfx::Rect(0, 0, 100, 300), NULL
));
3413 this->ResetLayerIterator();
3415 // Make a viewport rect that is smaller than the root layer.
3416 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3417 typename
Types::RenderSurfaceType
> occlusion(
3418 gfx::Rect(0, 0, 100, 100));
3420 this->VisitLayer(surface
, &occlusion
);
3422 // The root layer always has a clip rect. So the parent of |surface| has a
3423 // clip rect giving the surface itself a clip rect.
3424 this->EnterContributingSurface(surface
, &occlusion
, false);
3425 // Make sure the viewport rect clips the unoccluded region of the child
3427 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3428 occlusion
.UnoccludedContributingSurfaceContentRect(
3429 surface
, false, gfx::Rect(0, 0, 100, 300), NULL
));
3434 ALL_OCCLUSIONTRACKER_TEST(
3435 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
);
3437 template <class Types
>
3438 class OcclusionTrackerTestSurfaceChildOfClippingSurface
3439 : public OcclusionTrackerTest
<Types
> {
3441 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers
)
3442 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3444 // This test verifies that the surface cliprect does not end up empty and
3445 // clip away the entire unoccluded rect.
3447 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3448 this->identity_matrix
, gfx::PointF(), gfx::Size(80, 200));
3449 parent
->SetMasksToBounds(true);
3450 typename
Types::LayerType
* surface
=
3451 this->CreateDrawingSurface(parent
,
3452 this->identity_matrix
,
3454 gfx::Size(100, 100),
3456 typename
Types::LayerType
* surface_child
=
3457 this->CreateDrawingSurface(surface
,
3458 this->identity_matrix
,
3460 gfx::Size(100, 100),
3462 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
3463 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
3464 this->CalcDrawEtc(parent
);
3466 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3467 typename
Types::RenderSurfaceType
> occlusion(
3468 gfx::Rect(0, 0, 1000, 1000));
3470 // |topmost| occludes everything partially so we know occlusion is happening
3472 this->VisitLayer(topmost
, &occlusion
);
3474 EXPECT_EQ(gfx::Rect().ToString(),
3475 occlusion
.occlusion_from_outside_target().ToString());
3476 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3477 occlusion
.occlusion_from_inside_target().ToString());
3479 // surface_child is not opaque and does not occlude, so we have a non-empty
3480 // unoccluded area on surface.
3481 this->VisitLayer(surface_child
, &occlusion
);
3483 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3484 occlusion
.occlusion_from_outside_target().ToString());
3485 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3486 occlusion
.occlusion_from_inside_target().ToString());
3488 // The root layer always has a clip rect. So the parent of |surface| has a
3489 // clip rect. However, the owning layer for |surface| does not mask to
3490 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3491 // |surface_child| exercises different code paths as its parent does not
3492 // have a clip rect.
3494 this->EnterContributingSurface(surface_child
, &occlusion
, false);
3495 // The surface_child's parent does not have a clip rect as it owns a render
3498 gfx::Rect(0, 50, 80, 50).ToString(),
3499 occlusion
.UnoccludedContributingSurfaceContentRect(
3500 surface_child
, false, gfx::Rect(0, 0, 100, 100), NULL
).ToString());
3501 this->LeaveContributingSurface(surface_child
, &occlusion
);
3503 this->VisitLayer(surface
, &occlusion
);
3504 this->EnterContributingSurface(surface
, &occlusion
, false);
3505 // The surface's parent does have a clip rect as it is the root layer.
3506 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3507 occlusion
.UnoccludedContributingSurfaceContentRect(
3508 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
).ToString());
3512 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface
);
3514 template <class Types
>
3515 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3516 : public OcclusionTrackerTest
<Types
> {
3518 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3520 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3522 gfx::Transform scale_by_half
;
3523 scale_by_half
.Scale(0.5, 0.5);
3525 // Make a surface and its replica, each 50x50, that are completely
3526 // surrounded by opaque layers which are above them in the z-order. The
3527 // surface is scaled to test that the pixel moving is done in the target
3528 // space, where the background filter is applied, but the surface appears at
3529 // 50, 50 and the replica at 200, 50.
3530 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3531 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3532 typename
Types::LayerType
* filtered_surface
=
3533 this->CreateDrawingLayer(parent
,
3535 gfx::PointF(50.f
, 50.f
),
3536 gfx::Size(100, 100),
3538 this->CreateReplicaLayer(filtered_surface
,
3539 this->identity_matrix
,
3540 gfx::PointF(300.f
, 0.f
),
3542 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3543 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 50), true);
3544 typename
Types::LayerType
* occluding_layer2
=
3545 this->CreateDrawingLayer(parent
,
3546 this->identity_matrix
,
3547 gfx::PointF(0.f
, 100.f
),
3550 typename
Types::LayerType
* occluding_layer3
=
3551 this->CreateDrawingLayer(parent
,
3552 this->identity_matrix
,
3553 gfx::PointF(0.f
, 50.f
),
3556 typename
Types::LayerType
* occluding_layer4
=
3557 this->CreateDrawingLayer(parent
,
3558 this->identity_matrix
,
3559 gfx::PointF(100.f
, 50.f
),
3562 typename
Types::LayerType
* occluding_layer5
=
3563 this->CreateDrawingLayer(parent
,
3564 this->identity_matrix
,
3565 gfx::PointF(250.f
, 50.f
),
3569 // Filters make the layer own a surface.
3570 WebKit::WebFilterOperations filters
;
3571 filters
.append(WebKit::WebFilterOperation::createBlurFilter(10.f
));
3572 filtered_surface
->SetBackgroundFilters(filters
);
3574 // Save the distance of influence for the blur effect.
3575 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3576 filters
.getOutsets(outset_top
, outset_right
, outset_bottom
, outset_left
);
3578 this->CalcDrawEtc(parent
);
3580 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3581 typename
Types::RenderSurfaceType
> occlusion(
3582 gfx::Rect(0, 0, 1000, 1000));
3584 // These layers occlude pixels directly beside the filtered_surface. Because
3585 // filtered surface blends pixels in a radius, it will need to see some of
3586 // the pixels (up to radius far) underneath the occluding layers.
3587 this->VisitLayer(occluding_layer5
, &occlusion
);
3588 this->VisitLayer(occluding_layer4
, &occlusion
);
3589 this->VisitLayer(occluding_layer3
, &occlusion
);
3590 this->VisitLayer(occluding_layer2
, &occlusion
);
3591 this->VisitLayer(occluding_layer1
, &occlusion
);
3593 Region expected_occlusion
;
3594 expected_occlusion
.Union(gfx::Rect(0, 0, 300, 50));
3595 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3596 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3597 expected_occlusion
.Union(gfx::Rect(250, 50, 50, 50));
3598 expected_occlusion
.Union(gfx::Rect(0, 100, 300, 50));
3600 EXPECT_EQ(expected_occlusion
.ToString(),
3601 occlusion
.occlusion_from_inside_target().ToString());
3602 EXPECT_EQ(gfx::Rect().ToString(),
3603 occlusion
.occlusion_from_outside_target().ToString());
3605 this->VisitLayer(filtered_surface
, &occlusion
);
3607 // The filtered layer/replica does not occlude.
3608 Region expected_occlusion_outside_surface
;
3609 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 300, 50));
3610 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3611 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3612 expected_occlusion_outside_surface
.Union(gfx::Rect(200, 0, 50, 50));
3613 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 300, 50));
3615 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3616 occlusion
.occlusion_from_outside_target().ToString());
3617 EXPECT_EQ(gfx::Rect().ToString(),
3618 occlusion
.occlusion_from_inside_target().ToString());
3620 // The surface has a background blur, so it needs pixels that are currently
3621 // considered occluded in order to be drawn. So the pixels it needs should
3622 // be removed some the occluded area so that when we get to the parent they
3624 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3626 this->EnterLayer(parent
, &occlusion
, false);
3628 Region expected_blurred_occlusion
;
3629 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 300, 50 - outset_top
));
3630 expected_blurred_occlusion
.Union(gfx::Rect(
3631 0, 50 - outset_top
, 50 - outset_left
, 50 + outset_top
+ outset_bottom
));
3632 expected_blurred_occlusion
.Union(
3633 gfx::Rect(100 + outset_right
,
3635 100 - outset_right
- outset_left
,
3636 50 + outset_top
+ outset_bottom
));
3637 expected_blurred_occlusion
.Union(
3638 gfx::Rect(250 + outset_right
,
3641 50 + outset_top
+ outset_bottom
));
3642 expected_blurred_occlusion
.Union(
3643 gfx::Rect(0, 100 + outset_bottom
, 300, 50 - outset_bottom
));
3645 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3646 occlusion
.occlusion_from_inside_target().ToString());
3647 EXPECT_EQ(gfx::Rect().ToString(),
3648 occlusion
.occlusion_from_outside_target().ToString());
3650 gfx::Rect outset_rect
;
3651 gfx::Rect test_rect
;
3653 // Nothing in the blur outsets for the filtered_surface is occluded.
3654 outset_rect
= gfx::Rect(50 - outset_left
,
3656 50 + outset_left
+ outset_right
,
3657 50 + outset_top
+ outset_bottom
);
3658 test_rect
= outset_rect
;
3660 outset_rect
.ToString(),
3661 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3663 // Stuff outside the blur outsets is still occluded though.
3664 test_rect
= outset_rect
;
3665 test_rect
.Inset(0, 0, -1, 0);
3667 outset_rect
.ToString(),
3668 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3669 test_rect
= outset_rect
;
3670 test_rect
.Inset(0, 0, 0, -1);
3672 outset_rect
.ToString(),
3673 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3674 test_rect
= outset_rect
;
3675 test_rect
.Inset(-1, 0, 0, 0);
3677 outset_rect
.ToString(),
3678 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3679 test_rect
= outset_rect
;
3680 test_rect
.Inset(0, -1, 0, 0);
3682 outset_rect
.ToString(),
3683 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3685 // Nothing in the blur outsets for the filtered_surface's replica is
3687 outset_rect
= gfx::Rect(200 - outset_left
,
3689 50 + outset_left
+ outset_right
,
3690 50 + outset_top
+ outset_bottom
);
3691 test_rect
= outset_rect
;
3693 outset_rect
.ToString(),
3694 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3696 // Stuff outside the blur outsets is still occluded though.
3697 test_rect
= outset_rect
;
3698 test_rect
.Inset(0, 0, -1, 0);
3700 outset_rect
.ToString(),
3701 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3702 test_rect
= outset_rect
;
3703 test_rect
.Inset(0, 0, 0, -1);
3705 outset_rect
.ToString(),
3706 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3707 test_rect
= outset_rect
;
3708 test_rect
.Inset(-1, 0, 0, 0);
3710 outset_rect
.ToString(),
3711 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3712 test_rect
= outset_rect
;
3713 test_rect
.Inset(0, -1, 0, 0);
3715 outset_rect
.ToString(),
3716 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3720 ALL_OCCLUSIONTRACKER_TEST(
3721 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
3723 template <class Types
>
3724 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3725 : public OcclusionTrackerTest
<Types
> {
3727 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3729 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3731 gfx::Transform scale_by_half
;
3732 scale_by_half
.Scale(0.5, 0.5);
3734 // Makes two surfaces that completely cover |parent|. The occlusion both
3735 // above and below the filters will be reduced by each of them.
3736 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3737 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
3738 typename
Types::LayerType
* parent
= this->CreateSurface(
3739 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
3740 parent
->SetMasksToBounds(true);
3741 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
3742 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3743 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
3744 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3745 typename
Types::LayerType
* occluding_layer_above
=
3746 this->CreateDrawingLayer(parent
,
3747 this->identity_matrix
,
3748 gfx::PointF(100.f
, 100.f
),
3752 // Filters make the layers own surfaces.
3753 WebKit::WebFilterOperations filters
;
3754 filters
.append(WebKit::WebFilterOperation::createBlurFilter(1.f
));
3755 filtered_surface1
->SetBackgroundFilters(filters
);
3756 filtered_surface2
->SetBackgroundFilters(filters
);
3758 // Save the distance of influence for the blur effect.
3759 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3760 filters
.getOutsets(outset_top
, outset_right
, outset_bottom
, outset_left
);
3762 this->CalcDrawEtc(root
);
3764 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3765 typename
Types::RenderSurfaceType
> occlusion(
3766 gfx::Rect(0, 0, 1000, 1000));
3768 this->VisitLayer(occluding_layer_above
, &occlusion
);
3769 EXPECT_EQ(gfx::Rect().ToString(),
3770 occlusion
.occlusion_from_outside_target().ToString());
3771 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3772 occlusion
.occlusion_from_inside_target().ToString());
3774 this->VisitLayer(filtered_surface2
, &occlusion
);
3775 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
3776 this->VisitLayer(filtered_surface1
, &occlusion
);
3777 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
3779 // Test expectations in the target.
3780 gfx::Rect expected_occlusion
=
3781 gfx::Rect(100 / 2 + outset_right
* 2,
3782 100 / 2 + outset_bottom
* 2,
3783 50 / 2 - (outset_left
+ outset_right
) * 2,
3784 50 / 2 - (outset_top
+ outset_bottom
) * 2);
3785 EXPECT_EQ(expected_occlusion
.ToString(),
3786 occlusion
.occlusion_from_inside_target().ToString());
3788 // Test expectations in the screen are the same as in the target, as the
3789 // render surface is 1:1 with the screen.
3790 EXPECT_EQ(expected_occlusion
.ToString(),
3791 occlusion
.occlusion_from_outside_target().ToString());
3795 ALL_OCCLUSIONTRACKER_TEST(
3796 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
3798 template <class Types
>
3799 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
3800 : public OcclusionTrackerTest
<Types
> {
3803 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(
3805 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3807 // Make a surface and its replica, Each 50x50, that are completely
3808 // surrounded by opaque layers which are above them in the z-order.
3809 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3810 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3811 // We stick the filtered surface inside a clipping surface so that we can
3812 // make sure the clip is honored when exposing pixels for
3813 // the background filter.
3814 typename
Types::LayerType
* clipping_surface
=
3815 this->CreateDrawingSurface(parent
,
3816 this->identity_matrix
,
3820 clipping_surface
->SetMasksToBounds(true);
3821 typename
Types::LayerType
* filtered_surface
=
3822 this->CreateDrawingLayer(clipping_surface
,
3823 this->identity_matrix
,
3824 gfx::PointF(50.f
, 50.f
),
3827 this->CreateReplicaLayer(filtered_surface
,
3828 this->identity_matrix
,
3829 gfx::PointF(150.f
, 0.f
),
3831 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3832 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 50), true);
3833 typename
Types::LayerType
* occluding_layer2
=
3834 this->CreateDrawingLayer(parent
,
3835 this->identity_matrix
,
3836 gfx::PointF(0.f
, 100.f
),
3839 typename
Types::LayerType
* occluding_layer3
=
3840 this->CreateDrawingLayer(parent
,
3841 this->identity_matrix
,
3842 gfx::PointF(0.f
, 50.f
),
3845 typename
Types::LayerType
* occluding_layer4
=
3846 this->CreateDrawingLayer(parent
,
3847 this->identity_matrix
,
3848 gfx::PointF(100.f
, 50.f
),
3851 typename
Types::LayerType
* occluding_layer5
=
3852 this->CreateDrawingLayer(parent
,
3853 this->identity_matrix
,
3854 gfx::PointF(250.f
, 50.f
),
3858 // Filters make the layer own a surface. This filter is large enough that it
3859 // goes outside the bottom of the clipping_surface.
3860 WebKit::WebFilterOperations filters
;
3861 filters
.append(WebKit::WebFilterOperation::createBlurFilter(12.f
));
3862 filtered_surface
->SetBackgroundFilters(filters
);
3864 // Save the distance of influence for the blur effect.
3865 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3866 filters
.getOutsets(outset_top
, outset_right
, outset_bottom
, outset_left
);
3868 this->CalcDrawEtc(parent
);
3870 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3871 typename
Types::RenderSurfaceType
> occlusion(
3872 gfx::Rect(0, 0, 1000, 1000));
3874 // These layers occlude pixels directly beside the filtered_surface. Because
3875 // filtered surface blends pixels in a radius, it will need to see some of
3876 // the pixels (up to radius far) underneath the occluding layers.
3877 this->VisitLayer(occluding_layer5
, &occlusion
);
3878 this->VisitLayer(occluding_layer4
, &occlusion
);
3879 this->VisitLayer(occluding_layer3
, &occlusion
);
3880 this->VisitLayer(occluding_layer2
, &occlusion
);
3881 this->VisitLayer(occluding_layer1
, &occlusion
);
3883 Region expected_occlusion
;
3884 expected_occlusion
.Union(gfx::Rect(0, 0, 300, 50));
3885 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3886 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3887 expected_occlusion
.Union(gfx::Rect(250, 50, 50, 50));
3888 expected_occlusion
.Union(gfx::Rect(0, 100, 300, 50));
3890 EXPECT_EQ(expected_occlusion
.ToString(),
3891 occlusion
.occlusion_from_inside_target().ToString());
3892 EXPECT_EQ(gfx::Rect().ToString(),
3893 occlusion
.occlusion_from_outside_target().ToString());
3895 // Everything outside the surface/replica is occluded but the
3896 // surface/replica itself is not.
3897 this->VisitLayer(filtered_surface
, &occlusion
);
3899 // The filtered layer/replica does not occlude.
3900 Region expected_occlusion_outside_surface
;
3901 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 300, 50));
3902 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3903 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3904 expected_occlusion_outside_surface
.Union(gfx::Rect(200, 0, 50, 50));
3905 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 300, 50));
3907 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3908 occlusion
.occlusion_from_outside_target().ToString());
3909 EXPECT_EQ(gfx::Rect().ToString(),
3910 occlusion
.occlusion_from_inside_target().ToString());
3912 // The surface has a background blur, so it needs pixels that are currently
3913 // considered occluded in order to be drawn. So the pixels it needs should
3914 // be removed some the occluded area so that when we get to the parent they
3916 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3918 this->VisitLayer(clipping_surface
, &occlusion
);
3919 this->EnterContributingSurface(clipping_surface
, &occlusion
, false);
3921 Region expected_blurred_occlusion
;
3922 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 300, 50 - outset_top
));
3923 expected_blurred_occlusion
.Union(gfx::Rect(
3924 0, 50 - outset_top
, 50 - outset_left
, 20 + outset_top
+ outset_bottom
));
3925 expected_blurred_occlusion
.Union(
3926 gfx::Rect(100 + outset_right
,
3928 100 - outset_right
- outset_left
,
3929 20 + outset_top
+ outset_bottom
));
3930 expected_blurred_occlusion
.Union(
3931 gfx::Rect(250 + outset_right
,
3934 20 + outset_top
+ outset_bottom
));
3935 expected_blurred_occlusion
.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
3937 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3938 occlusion
.occlusion_from_outside_target().ToString());
3939 EXPECT_EQ(gfx::Rect().ToString(),
3940 occlusion
.occlusion_from_inside_target().ToString());
3942 gfx::Rect outset_rect
;
3943 gfx::Rect clipped_outset_rect
;
3944 gfx::Rect test_rect
;
3946 // Nothing in the (clipped) blur outsets for the filtered_surface is
3948 outset_rect
= gfx::Rect(50 - outset_left
,
3950 50 + outset_left
+ outset_right
,
3951 50 + outset_top
+ outset_bottom
);
3952 clipped_outset_rect
= outset_rect
;
3953 clipped_outset_rect
.Intersect(gfx::Rect(0 - outset_left
,
3955 300 + outset_left
+ outset_right
,
3956 70 + outset_top
+ outset_bottom
));
3957 clipped_outset_rect
.Intersect(gfx::Rect(0, 0, 300, 70));
3958 test_rect
= outset_rect
;
3960 clipped_outset_rect
,
3961 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3963 // Stuff outside the (clipped) blur outsets is still occluded though.
3964 test_rect
= outset_rect
;
3965 test_rect
.Inset(0, 0, -1, 0);
3967 clipped_outset_rect
,
3968 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3969 test_rect
= outset_rect
;
3970 test_rect
.Inset(0, 0, 0, -1);
3972 clipped_outset_rect
,
3973 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3974 test_rect
= outset_rect
;
3975 test_rect
.Inset(-1, 0, 0, 0);
3977 clipped_outset_rect
,
3978 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3979 test_rect
= outset_rect
;
3980 test_rect
.Inset(0, -1, 0, 0);
3982 clipped_outset_rect
,
3983 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3985 // Nothing in the (clipped) blur outsets for the filtered_surface's replica
3987 outset_rect
= gfx::Rect(200 - outset_left
,
3989 50 + outset_left
+ outset_right
,
3990 50 + outset_top
+ outset_bottom
);
3991 clipped_outset_rect
= outset_rect
;
3992 clipped_outset_rect
.Intersect(gfx::Rect(0 - outset_left
,
3994 300 + outset_left
+ outset_right
,
3995 70 + outset_top
+ outset_bottom
));
3996 clipped_outset_rect
.Intersect(gfx::Rect(0, 0, 300, 70));
3997 test_rect
= outset_rect
;
3999 clipped_outset_rect
,
4000 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4002 // Stuff outside the (clipped) blur outsets is still occluded though.
4003 test_rect
= outset_rect
;
4004 test_rect
.Inset(0, 0, -1, 0);
4006 clipped_outset_rect
,
4007 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4008 test_rect
= outset_rect
;
4009 test_rect
.Inset(0, 0, 0, -1);
4011 clipped_outset_rect
,
4012 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4013 test_rect
= outset_rect
;
4014 test_rect
.Inset(-1, 0, 0, 0);
4016 clipped_outset_rect
,
4017 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4018 test_rect
= outset_rect
;
4019 test_rect
.Inset(0, -1, 0, 0);
4021 clipped_outset_rect
,
4022 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4026 ALL_OCCLUSIONTRACKER_TEST(
4027 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
);
4029 template <class Types
>
4030 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
4031 : public OcclusionTrackerTest
<Types
> {
4033 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
4035 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4037 gfx::Transform scale_by_half
;
4038 scale_by_half
.Scale(0.5, 0.5);
4040 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
4041 // centered below each. The surface is scaled to test that the pixel moving
4042 // is done in the target space, where the background filter is applied, but
4043 // the surface appears at 50, 50 and the replica at 200, 50.
4044 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4045 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4046 typename
Types::LayerType
* behind_surface_layer
=
4047 this->CreateDrawingLayer(parent
,
4048 this->identity_matrix
,
4049 gfx::PointF(60.f
, 60.f
),
4052 typename
Types::LayerType
* behind_replica_layer
=
4053 this->CreateDrawingLayer(parent
,
4054 this->identity_matrix
,
4055 gfx::PointF(210.f
, 60.f
),
4058 typename
Types::LayerType
* filtered_surface
=
4059 this->CreateDrawingLayer(parent
,
4061 gfx::PointF(50.f
, 50.f
),
4062 gfx::Size(100, 100),
4064 this->CreateReplicaLayer(filtered_surface
,
4065 this->identity_matrix
,
4066 gfx::PointF(300.f
, 0.f
),
4069 // Filters make the layer own a surface.
4070 WebKit::WebFilterOperations filters
;
4071 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3.f
));
4072 filtered_surface
->SetBackgroundFilters(filters
);
4074 this->CalcDrawEtc(parent
);
4076 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4077 typename
Types::RenderSurfaceType
> occlusion(
4078 gfx::Rect(0, 0, 1000, 1000));
4080 // The surface has a background blur, so it blurs non-opaque pixels below
4082 this->VisitLayer(filtered_surface
, &occlusion
);
4083 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4085 this->VisitLayer(behind_replica_layer
, &occlusion
);
4086 this->VisitLayer(behind_surface_layer
, &occlusion
);
4088 // The layers behind the surface are not blurred, and their occlusion does
4089 // not change, until we leave the surface. So it should not be modified by
4091 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
4092 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
4094 Region expected_opaque_bounds
=
4095 UnionRegions(occlusion_behind_surface
, occlusion_behind_replica
);
4096 EXPECT_EQ(expected_opaque_bounds
.ToString(),
4097 occlusion
.occlusion_from_inside_target().ToString());
4099 EXPECT_EQ(gfx::Rect().ToString(),
4100 occlusion
.occlusion_from_outside_target().ToString());
4104 ALL_OCCLUSIONTRACKER_TEST(
4105 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
4107 template <class Types
>
4108 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
4109 : public OcclusionTrackerTest
<Types
> {
4111 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
4113 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4115 gfx::Transform scale_by_half
;
4116 scale_by_half
.Scale(0.5, 0.5);
4118 // Make a surface and its replica, each 50x50, that are completely occluded
4119 // by opaque layers which are above them in the z-order. The surface is
4120 // scaled to test that the pixel moving is done in the target space, where
4121 // the background filter is applied, but the surface appears at 50, 50 and
4122 // the replica at 200, 50.
4123 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4124 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4125 typename
Types::LayerType
* filtered_surface
=
4126 this->CreateDrawingLayer(parent
,
4128 gfx::PointF(50.f
, 50.f
),
4129 gfx::Size(100, 100),
4131 this->CreateReplicaLayer(filtered_surface
,
4132 this->identity_matrix
,
4133 gfx::PointF(300.f
, 0.f
),
4135 typename
Types::LayerType
* above_surface_layer
=
4136 this->CreateDrawingLayer(parent
,
4137 this->identity_matrix
,
4138 gfx::PointF(50.f
, 50.f
),
4141 typename
Types::LayerType
* above_replica_layer
=
4142 this->CreateDrawingLayer(parent
,
4143 this->identity_matrix
,
4144 gfx::PointF(200.f
, 50.f
),
4148 // Filters make the layer own a surface.
4149 WebKit::WebFilterOperations filters
;
4150 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3.f
));
4151 filtered_surface
->SetBackgroundFilters(filters
);
4153 this->CalcDrawEtc(parent
);
4155 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4156 typename
Types::RenderSurfaceType
> occlusion(
4157 gfx::Rect(0, 0, 1000, 1000));
4159 this->VisitLayer(above_replica_layer
, &occlusion
);
4160 this->VisitLayer(above_surface_layer
, &occlusion
);
4162 this->VisitLayer(filtered_surface
, &occlusion
);
4164 // The layers above the filtered surface occlude from outside.
4165 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
4166 gfx::Rect occlusion_above_replica
= gfx::Rect(150, 0, 50, 50);
4167 Region expected_opaque_region
=
4168 UnionRegions(occlusion_above_surface
, occlusion_above_replica
);
4170 EXPECT_EQ(gfx::Rect().ToString(),
4171 occlusion
.occlusion_from_inside_target().ToString());
4172 EXPECT_EQ(expected_opaque_region
.ToString(),
4173 occlusion
.occlusion_from_outside_target().ToString());
4176 // The surface has a background blur, so it blurs non-opaque pixels below
4178 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4180 // The filter is completely occluded, so it should not blur anything and
4181 // reduce any occlusion.
4182 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
4183 gfx::Rect occlusion_above_replica
= gfx::Rect(200, 50, 50, 50);
4184 Region expected_opaque_region
=
4185 UnionRegions(occlusion_above_surface
, occlusion_above_replica
);
4187 EXPECT_EQ(expected_opaque_region
.ToString(),
4188 occlusion
.occlusion_from_inside_target().ToString());
4189 EXPECT_EQ(gfx::Rect().ToString(),
4190 occlusion
.occlusion_from_outside_target().ToString());
4195 ALL_OCCLUSIONTRACKER_TEST(
4196 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
4198 template <class Types
>
4199 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
4200 : public OcclusionTrackerTest
<Types
> {
4203 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
4205 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4207 gfx::Transform scale_by_half
;
4208 scale_by_half
.Scale(0.5, 0.5);
4210 // Make a surface and its replica, each 50x50, that are partially occluded
4211 // by opaque layers which are above them in the z-order. The surface is
4212 // scaled to test that the pixel moving is done in the target space, where
4213 // the background filter is applied, but the surface appears at 50, 50 and
4214 // the replica at 200, 50.
4215 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4216 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4217 typename
Types::LayerType
* filtered_surface
=
4218 this->CreateDrawingLayer(parent
,
4220 gfx::PointF(50.f
, 50.f
),
4221 gfx::Size(100, 100),
4223 this->CreateReplicaLayer(filtered_surface
,
4224 this->identity_matrix
,
4225 gfx::PointF(300.f
, 0.f
),
4227 typename
Types::LayerType
* above_surface_layer
=
4228 this->CreateDrawingLayer(parent
,
4229 this->identity_matrix
,
4230 gfx::PointF(70.f
, 50.f
),
4233 typename
Types::LayerType
* above_replica_layer
=
4234 this->CreateDrawingLayer(parent
,
4235 this->identity_matrix
,
4236 gfx::PointF(200.f
, 50.f
),
4239 typename
Types::LayerType
* beside_surface_layer
=
4240 this->CreateDrawingLayer(parent
,
4241 this->identity_matrix
,
4242 gfx::PointF(90.f
, 40.f
),
4245 typename
Types::LayerType
* beside_replica_layer
=
4246 this->CreateDrawingLayer(parent
,
4247 this->identity_matrix
,
4248 gfx::PointF(200.f
, 40.f
),
4252 // Filters make the layer own a surface.
4253 WebKit::WebFilterOperations filters
;
4254 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3.f
));
4255 filtered_surface
->SetBackgroundFilters(filters
);
4257 // Save the distance of influence for the blur effect.
4258 int outset_top
, outset_right
, outset_bottom
, outset_left
;
4259 filters
.getOutsets(outset_top
, outset_right
, outset_bottom
, outset_left
);
4261 this->CalcDrawEtc(parent
);
4263 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4264 typename
Types::RenderSurfaceType
> occlusion(
4265 gfx::Rect(0, 0, 1000, 1000));
4267 this->VisitLayer(beside_replica_layer
, &occlusion
);
4268 this->VisitLayer(beside_surface_layer
, &occlusion
);
4269 this->VisitLayer(above_replica_layer
, &occlusion
);
4270 this->VisitLayer(above_surface_layer
, &occlusion
);
4272 // The surface has a background blur, so it blurs non-opaque pixels below
4274 this->VisitLayer(filtered_surface
, &occlusion
);
4275 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4277 // The filter in the surface and replica are partially unoccluded. Only the
4278 // unoccluded parts should reduce occlusion. This means it will push back
4279 // the occlusion that touches the unoccluded part (occlusion_above___), but
4280 // it will not touch occlusion_beside____ since that is not beside the
4281 // unoccluded part of the surface, even though it is beside the occluded
4282 // part of the surface.
4283 gfx::Rect occlusion_above_surface
=
4284 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
4285 gfx::Rect occlusion_above_replica
=
4286 gfx::Rect(200, 50, 30 - outset_left
, 50);
4287 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
4288 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
4290 Region expected_occlusion
;
4291 expected_occlusion
.Union(occlusion_above_surface
);
4292 expected_occlusion
.Union(occlusion_above_replica
);
4293 expected_occlusion
.Union(occlusion_beside_surface
);
4294 expected_occlusion
.Union(occlusion_beside_replica
);
4296 ASSERT_EQ(expected_occlusion
.ToString(),
4297 occlusion
.occlusion_from_inside_target().ToString());
4298 EXPECT_EQ(gfx::Rect().ToString(),
4299 occlusion
.occlusion_from_outside_target().ToString());
4301 Region::Iterator
expected_rects(expected_occlusion
);
4302 Region::Iterator
target_surface_rects(
4303 occlusion
.occlusion_from_inside_target());
4304 for (; expected_rects
.has_rect();
4305 expected_rects
.next(), target_surface_rects
.next()) {
4306 ASSERT_TRUE(target_surface_rects
.has_rect());
4307 EXPECT_EQ(expected_rects
.rect(), target_surface_rects
.rect());
4312 ALL_OCCLUSIONTRACKER_TEST(
4313 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
4315 template <class Types
>
4316 class OcclusionTrackerTestMinimumTrackingSize
4317 : public OcclusionTrackerTest
<Types
> {
4319 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
4320 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4322 gfx::Size
tracking_size(100, 100);
4323 gfx::Size
below_tracking_size(99, 99);
4325 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4326 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4327 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
4328 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
4329 typename
Types::LayerType
* small
=
4330 this->CreateDrawingLayer(parent
,
4331 this->identity_matrix
,
4333 below_tracking_size
,
4335 this->CalcDrawEtc(parent
);
4337 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4338 typename
Types::RenderSurfaceType
> occlusion(
4339 gfx::Rect(0, 0, 1000, 1000));
4340 occlusion
.set_minimum_tracking_size(tracking_size
);
4342 // The small layer is not tracked because it is too small.
4343 this->VisitLayer(small
, &occlusion
);
4345 EXPECT_EQ(gfx::Rect().ToString(),
4346 occlusion
.occlusion_from_outside_target().ToString());
4347 EXPECT_EQ(gfx::Rect().ToString(),
4348 occlusion
.occlusion_from_inside_target().ToString());
4350 // The large layer is tracked as it is large enough.
4351 this->VisitLayer(large
, &occlusion
);
4353 EXPECT_EQ(gfx::Rect().ToString(),
4354 occlusion
.occlusion_from_outside_target().ToString());
4355 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
4356 occlusion
.occlusion_from_inside_target().ToString());
4360 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
4362 template <class Types
>
4363 class OcclusionTrackerTestViewportClipIsExternalOcclusion
4364 : public OcclusionTrackerTest
<Types
> {
4366 explicit OcclusionTrackerTestViewportClipIsExternalOcclusion(
4368 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4370 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4371 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4372 typename
Types::LayerType
* small
=
4373 this->CreateDrawingSurface(parent
,
4374 this->identity_matrix
,
4376 gfx::Size(200, 200),
4378 typename
Types::LayerType
* large
=
4379 this->CreateDrawingLayer(small
,
4380 this->identity_matrix
,
4382 gfx::Size(400, 400),
4384 small
->SetMasksToBounds(true);
4385 this->CalcDrawEtc(parent
);
4387 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4388 typename
Types::RenderSurfaceType
> occlusion(
4389 gfx::Rect(0, 0, 100, 100));
4391 this->EnterLayer(large
, &occlusion
, false);
4393 bool has_occlusion_from_outside_target_surface
= false;
4394 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4395 occlusion
.UnoccludedLayerContentRect(
4397 gfx::Rect(0, 0, 400, 400),
4398 &has_occlusion_from_outside_target_surface
));
4399 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4401 has_occlusion_from_outside_target_surface
= false;
4403 occlusion
.OccludedLayer(large
,
4404 gfx::Rect(0, 0, 400, 400),
4405 &has_occlusion_from_outside_target_surface
));
4406 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4408 this->LeaveLayer(large
, &occlusion
);
4409 this->VisitLayer(small
, &occlusion
);
4411 has_occlusion_from_outside_target_surface
= false;
4412 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4413 occlusion
.UnoccludedLayerContentRect(
4415 gfx::Rect(0, 0, 200, 200),
4416 &has_occlusion_from_outside_target_surface
));
4417 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4419 has_occlusion_from_outside_target_surface
= false;
4421 occlusion
.OccludedLayer(small
,
4422 gfx::Rect(0, 0, 200, 200),
4423 &has_occlusion_from_outside_target_surface
));
4424 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4426 this->EnterContributingSurface(small
, &occlusion
, false);
4428 has_occlusion_from_outside_target_surface
= false;
4429 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4430 occlusion
.UnoccludedContributingSurfaceContentRect(
4433 gfx::Rect(0, 0, 200, 200),
4434 &has_occlusion_from_outside_target_surface
));
4435 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4439 ALL_OCCLUSIONTRACKER_TEST(
4440 OcclusionTrackerTestViewportClipIsExternalOcclusion
)
4442 template <class Types
>
4443 class OcclusionTrackerTestLayerClipIsExternalOcclusion
4444 : public OcclusionTrackerTest
<Types
> {
4446 explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers
)
4447 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4449 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4450 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4451 typename
Types::LayerType
* smallest
= this->CreateDrawingLayer(
4452 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4453 typename
Types::LayerType
* smaller
=
4454 this->CreateDrawingSurface(smallest
,
4455 this->identity_matrix
,
4457 gfx::Size(100, 100),
4459 typename
Types::LayerType
* small
=
4460 this->CreateDrawingSurface(smaller
,
4461 this->identity_matrix
,
4463 gfx::Size(200, 200),
4465 typename
Types::LayerType
* large
=
4466 this->CreateDrawingLayer(small
,
4467 this->identity_matrix
,
4469 gfx::Size(400, 400),
4471 smallest
->SetMasksToBounds(true);
4472 smaller
->SetMasksToBounds(true);
4473 small
->SetMasksToBounds(true);
4474 this->CalcDrawEtc(parent
);
4476 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4477 typename
Types::RenderSurfaceType
> occlusion(
4478 gfx::Rect(0, 0, 1000, 1000));
4480 this->EnterLayer(large
, &occlusion
, false);
4482 // Clipping from the smaller layer is from outside the target surface.
4483 bool has_occlusion_from_outside_target_surface
= false;
4484 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4485 occlusion
.UnoccludedLayerContentRect(
4487 gfx::Rect(0, 0, 400, 400),
4488 &has_occlusion_from_outside_target_surface
));
4489 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4491 has_occlusion_from_outside_target_surface
= false;
4493 occlusion
.OccludedLayer(large
,
4494 gfx::Rect(0, 0, 400, 400),
4495 &has_occlusion_from_outside_target_surface
));
4496 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4498 this->LeaveLayer(large
, &occlusion
);
4499 this->VisitLayer(small
, &occlusion
);
4501 // Clipping from the smaller layer is from outside the target surface.
4502 has_occlusion_from_outside_target_surface
= false;
4503 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4504 occlusion
.UnoccludedLayerContentRect(
4506 gfx::Rect(0, 0, 200, 200),
4507 &has_occlusion_from_outside_target_surface
));
4508 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4510 has_occlusion_from_outside_target_surface
= false;
4512 occlusion
.OccludedLayer(small
,
4513 gfx::Rect(0, 0, 200, 200),
4514 &has_occlusion_from_outside_target_surface
));
4515 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4517 this->EnterContributingSurface(small
, &occlusion
, false);
4519 // The |small| surface is clipped from outside its target by |smallest|.
4520 has_occlusion_from_outside_target_surface
= false;
4521 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4522 occlusion
.UnoccludedContributingSurfaceContentRect(
4525 gfx::Rect(0, 0, 200, 200),
4526 &has_occlusion_from_outside_target_surface
));
4527 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4529 this->LeaveContributingSurface(small
, &occlusion
);
4530 this->VisitLayer(smaller
, &occlusion
);
4531 this->EnterContributingSurface(smaller
, &occlusion
, false);
4533 // The |smaller| surface is clipped from inside its target by |smallest|.
4534 has_occlusion_from_outside_target_surface
= false;
4535 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4536 occlusion
.UnoccludedContributingSurfaceContentRect(
4539 gfx::Rect(0, 0, 100, 100),
4540 &has_occlusion_from_outside_target_surface
));
4541 EXPECT_FALSE(has_occlusion_from_outside_target_surface
);
4545 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion
)
4547 template <class Types
>
4548 class OcclusionTrackerTestPreventOcclusionOnLayer
4549 : public OcclusionTrackerTest
<Types
> {
4551 explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers
)
4552 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4554 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4555 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4556 typename
Types::LayerType
* unprevented
= this->CreateDrawingLayer(
4557 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4558 typename
Types::LayerType
* prevented
= this->CreateDrawingLayer(
4559 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4560 typename
Types::LayerType
* occluding
= this->CreateDrawingLayer(
4561 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
4562 this->CalcDrawEtc(parent
);
4564 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4565 typename
Types::RenderSurfaceType
> occlusion(
4566 gfx::Rect(0, 0, 1000, 1000));
4567 bool external_occlusion
= false;
4569 this->VisitLayer(occluding
, &occlusion
);
4570 this->EnterLayer(prevented
, &occlusion
, true);
4572 // This layer is not occluded because it is prevented.
4573 EXPECT_FALSE(occlusion
.OccludedLayer(prevented
,
4575 &external_occlusion
));
4576 EXPECT_FALSE(external_occlusion
);
4578 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4579 occlusion
.UnoccludedLayerContentRect(
4582 &external_occlusion
).ToString());
4583 EXPECT_FALSE(external_occlusion
);
4585 this->LeaveLayer(prevented
, &occlusion
);
4586 this->EnterLayer(unprevented
, &occlusion
, false);
4588 // This layer is fully occluded.
4589 EXPECT_TRUE(occlusion
.OccludedLayer(unprevented
,
4591 &external_occlusion
));
4592 EXPECT_FALSE(external_occlusion
);
4594 EXPECT_EQ(gfx::Rect().ToString(),
4595 occlusion
.UnoccludedLayerContentRect(
4598 &external_occlusion
).ToString());
4599 EXPECT_FALSE(external_occlusion
);
4601 this->LeaveLayer(unprevented
, &occlusion
);
4605 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer
)
4607 template <class Types
>
4608 class OcclusionTrackerTestPreventOcclusionOnContributingSurface
4609 : public OcclusionTrackerTest
<Types
> {
4611 explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface(
4613 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4615 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4616 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4617 typename
Types::LayerType
* unprevented
= this->CreateDrawingSurface(
4618 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4619 typename
Types::LayerType
* prevented
= this->CreateDrawingSurface(
4620 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4621 typename
Types::LayerType
* occluding
= this->CreateDrawingLayer(
4622 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
4623 this->CalcDrawEtc(parent
);
4625 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4626 typename
Types::RenderSurfaceType
> occlusion(
4627 gfx::Rect(0, 0, 1000, 1000));
4628 bool external_occlusion
= false;
4630 this->VisitLayer(occluding
, &occlusion
);
4631 this->EnterLayer(prevented
, &occlusion
, true);
4633 // This layer is not occluded because it is prevented.
4634 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4635 occlusion
.UnoccludedLayerContentRect(
4638 &external_occlusion
).ToString());
4639 EXPECT_FALSE(external_occlusion
);
4641 this->LeaveLayer(prevented
, &occlusion
);
4642 this->EnterContributingSurface(prevented
, &occlusion
, true);
4644 // This contributing surface is not occluded because it is prevented.
4645 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4646 occlusion
.UnoccludedContributingSurfaceContentRect(
4648 false, // is_replica
4650 &external_occlusion
).ToString());
4651 EXPECT_FALSE(external_occlusion
);
4653 this->LeaveContributingSurface(prevented
, &occlusion
);
4654 this->EnterLayer(unprevented
, &occlusion
, false);
4656 // This layer is fully occluded from outside its surface.
4657 EXPECT_EQ(gfx::Rect().ToString(),
4658 occlusion
.UnoccludedLayerContentRect(
4661 &external_occlusion
).ToString());
4662 EXPECT_TRUE(external_occlusion
);
4664 this->LeaveLayer(unprevented
, &occlusion
);
4665 this->EnterContributingSurface(unprevented
, &occlusion
, false);
4667 // This contributing surface is fully occluded.
4668 EXPECT_EQ(gfx::Rect().ToString(),
4669 occlusion
.UnoccludedContributingSurfaceContentRect(
4671 false, // is_replica
4673 &external_occlusion
).ToString());
4674 EXPECT_FALSE(external_occlusion
);
4676 this->LeaveContributingSurface(unprevented
, &occlusion
);
4680 ALL_OCCLUSIONTRACKER_TEST(
4681 OcclusionTrackerTestPreventOcclusionOnContributingSurface
)
4683 template <class Types
>
4684 class OcclusionTrackerTestPreventOcclusionByClipping
4685 : public OcclusionTrackerTest
<Types
> {
4687 explicit OcclusionTrackerTestPreventOcclusionByClipping(bool opaque_layers
)
4688 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4690 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4691 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4692 typename
Types::LayerType
* unprevented
= this->CreateDrawingLayer(
4693 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4694 typename
Types::LayerType
* prevented
= this->CreateDrawingLayer(
4695 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4696 this->CalcDrawEtc(parent
);
4698 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4699 typename
Types::RenderSurfaceType
> occlusion(
4700 gfx::Rect(0, 0, 10, 10));
4701 bool external_occlusion
= false;
4703 this->EnterLayer(prevented
, &occlusion
, true);
4705 // This layer is not occluded because it is prevented.
4706 EXPECT_FALSE(occlusion
.OccludedLayer(prevented
,
4708 &external_occlusion
));
4709 EXPECT_FALSE(external_occlusion
);
4711 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4712 occlusion
.UnoccludedLayerContentRect(
4715 &external_occlusion
).ToString());
4716 EXPECT_FALSE(external_occlusion
);
4718 this->LeaveLayer(prevented
, &occlusion
);
4719 this->EnterLayer(unprevented
, &occlusion
, false);
4721 // This layer is clipped by the screen space clip rect.
4722 EXPECT_EQ(gfx::Rect(10, 10).ToString(),
4723 occlusion
.UnoccludedLayerContentRect(
4726 &external_occlusion
).ToString());
4727 EXPECT_TRUE(external_occlusion
);
4729 this->LeaveLayer(unprevented
, &occlusion
);
4733 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionByClipping
)
4735 template <class Types
>
4736 class OcclusionTrackerTestScaledLayerIsClipped
4737 : public OcclusionTrackerTest
<Types
> {
4739 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
4740 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4742 gfx::Transform scale_transform
;
4743 scale_transform
.Scale(512.0, 512.0);
4745 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4746 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4747 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
4748 this->identity_matrix
,
4749 gfx::PointF(10.f
, 10.f
),
4751 clip
->SetMasksToBounds(true);
4752 typename
Types::LayerType
* scale
= this->CreateLayer(
4753 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
4754 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
4755 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
4756 this->CalcDrawEtc(parent
);
4758 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4759 typename
Types::RenderSurfaceType
> occlusion(
4760 gfx::Rect(0, 0, 1000, 1000));
4762 this->VisitLayer(scaled
, &occlusion
);
4764 EXPECT_EQ(gfx::Rect().ToString(),
4765 occlusion
.occlusion_from_outside_target().ToString());
4766 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
4767 occlusion
.occlusion_from_inside_target().ToString());
4771 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
4773 template <class Types
>
4774 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
4775 : public OcclusionTrackerTest
<Types
> {
4777 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
4778 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4780 gfx::Transform scale_transform
;
4781 scale_transform
.Scale(512.0, 512.0);
4783 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4784 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4785 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
4786 this->identity_matrix
,
4787 gfx::PointF(10.f
, 10.f
),
4789 clip
->SetMasksToBounds(true);
4790 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
4791 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
4792 typename
Types::LayerType
* scale
= this->CreateLayer(
4793 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
4794 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
4795 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
4796 this->CalcDrawEtc(parent
);
4798 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4799 typename
Types::RenderSurfaceType
> occlusion(
4800 gfx::Rect(0, 0, 1000, 1000));
4802 this->VisitLayer(scaled
, &occlusion
);
4803 this->VisitLayer(surface
, &occlusion
);
4804 this->VisitContributingSurface(surface
, &occlusion
);
4806 EXPECT_EQ(gfx::Rect().ToString(),
4807 occlusion
.occlusion_from_outside_target().ToString());
4808 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
4809 occlusion
.occlusion_from_inside_target().ToString());
4813 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)