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(
321 dummy_max_texture_size
,
323 &render_surface_layer_list_impl_
,
326 layer_iterator_
= layer_iterator_begin_
=
327 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
330 void CalcDrawEtc(TestContentLayer
* root
) {
331 DCHECK(root
== root_
.get());
332 int dummy_max_texture_size
= 512;
334 DCHECK(!root
->render_surface());
336 LayerTreeHostCommon::CalculateDrawProperties(root
,
340 dummy_max_texture_size
,
342 &render_surface_layer_list_
);
344 layer_iterator_
= layer_iterator_begin_
=
345 Types::TestLayerIterator::Begin(&render_surface_layer_list_
);
348 void EnterLayer(typename
Types::LayerType
* layer
,
349 typename
Types::OcclusionTrackerType
* occlusion
) {
350 ASSERT_EQ(layer
, *layer_iterator_
);
351 ASSERT_TRUE(layer_iterator_
.represents_itself());
352 occlusion
->EnterLayer(layer_iterator_
);
355 void LeaveLayer(typename
Types::LayerType
* layer
,
356 typename
Types::OcclusionTrackerType
* occlusion
) {
357 ASSERT_EQ(layer
, *layer_iterator_
);
358 ASSERT_TRUE(layer_iterator_
.represents_itself());
359 occlusion
->LeaveLayer(layer_iterator_
);
363 void VisitLayer(typename
Types::LayerType
* layer
,
364 typename
Types::OcclusionTrackerType
* occlusion
) {
365 EnterLayer(layer
, occlusion
);
366 LeaveLayer(layer
, occlusion
);
369 void EnterContributingSurface(
370 typename
Types::LayerType
* layer
,
371 typename
Types::OcclusionTrackerType
* occlusion
) {
372 ASSERT_EQ(layer
, *layer_iterator_
);
373 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
374 occlusion
->EnterLayer(layer_iterator_
);
375 occlusion
->LeaveLayer(layer_iterator_
);
377 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
378 occlusion
->EnterLayer(layer_iterator_
);
381 void LeaveContributingSurface(
382 typename
Types::LayerType
* layer
,
383 typename
Types::OcclusionTrackerType
* occlusion
) {
384 ASSERT_EQ(layer
, *layer_iterator_
);
385 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
386 occlusion
->LeaveLayer(layer_iterator_
);
390 void VisitContributingSurface(
391 typename
Types::LayerType
* layer
,
392 typename
Types::OcclusionTrackerType
* occlusion
) {
393 EnterContributingSurface(layer
, occlusion
);
394 LeaveContributingSurface(layer
, occlusion
);
397 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
399 const gfx::Transform identity_matrix
;
402 void SetBaseProperties(typename
Types::LayerType
* layer
,
403 const gfx::Transform
& transform
,
404 gfx::PointF position
,
406 layer
->SetTransform(transform
);
407 layer
->SetSublayerTransform(gfx::Transform());
408 layer
->SetAnchorPoint(gfx::PointF());
409 layer
->SetPosition(position
);
410 layer
->SetBounds(bounds
);
413 void SetProperties(Layer
* layer
,
414 const gfx::Transform
& transform
,
415 gfx::PointF position
,
417 SetBaseProperties(layer
, transform
, position
, bounds
);
420 void SetProperties(LayerImpl
* layer
,
421 const gfx::Transform
& transform
,
422 gfx::PointF position
,
424 SetBaseProperties(layer
, transform
, position
, bounds
);
426 layer
->SetContentBounds(layer
->bounds());
429 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
430 owning_layer
->SetReplicaLayer(layer
.get());
431 replica_layers_
.push_back(layer
);
434 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
435 owning_layer
->SetReplicaLayer(layer
.Pass());
438 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
439 owning_layer
->SetMaskLayer(layer
.get());
440 mask_layers_
.push_back(layer
);
443 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
444 owning_layer
->SetMaskLayer(layer
.Pass());
447 FakeImplProxy proxy_
;
448 FakeLayerTreeHostImpl host_impl_
;
450 // These hold ownership of the layers for the duration of the test.
451 typename
Types::LayerPtrType root_
;
452 LayerList render_surface_layer_list_
;
453 LayerImplList render_surface_layer_list_impl_
;
454 typename
Types::TestLayerIterator layer_iterator_begin_
;
455 typename
Types::TestLayerIterator layer_iterator_
;
456 typename
Types::LayerType
* last_layer_visited_
;
457 LayerList replica_layers_
;
458 LayerList mask_layers_
;
463 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
469 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
470 return host_impl_
.active_tree();
473 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
474 class ClassName##MainThreadOpaqueLayers \
475 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
476 public: /* NOLINT(whitespace/indent) */ \
477 ClassName##MainThreadOpaqueLayers() \
478 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
480 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
481 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
482 class ClassName##MainThreadOpaquePaints \
483 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
484 public: /* NOLINT(whitespace/indent) */ \
485 ClassName##MainThreadOpaquePaints() \
486 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
488 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
490 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
491 class ClassName##ImplThreadOpaqueLayers \
492 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
493 public: /* NOLINT(whitespace/indent) */ \
494 ClassName##ImplThreadOpaqueLayers() \
495 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
497 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
498 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
499 class ClassName##ImplThreadOpaquePaints \
500 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
501 public: /* NOLINT(whitespace/indent) */ \
502 ClassName##ImplThreadOpaquePaints() \
503 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
505 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
507 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
508 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
509 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
510 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
511 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
513 #define MAIN_THREAD_TEST(ClassName) \
514 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
516 #define IMPL_THREAD_TEST(ClassName) \
517 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
519 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
520 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
521 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
523 template <class Types
>
524 class OcclusionTrackerTestIdentityTransforms
525 : public OcclusionTrackerTest
<Types
> {
527 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
528 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
531 typename
Types::ContentLayerType
* root
= this->CreateRoot(
532 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
533 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
534 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
535 typename
Types::ContentLayerType
* layer
=
536 this->CreateDrawingLayer(parent
,
537 this->identity_matrix
,
538 gfx::PointF(30.f
, 30.f
),
541 parent
->SetMasksToBounds(true);
542 this->CalcDrawEtc(root
);
544 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
545 typename
Types::RenderSurfaceType
> occlusion(
546 gfx::Rect(0, 0, 1000, 1000), false);
548 this->VisitLayer(layer
, &occlusion
);
549 this->EnterLayer(parent
, &occlusion
);
551 EXPECT_EQ(gfx::Rect().ToString(),
552 occlusion
.occlusion_from_outside_target().ToString());
553 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
554 occlusion
.occlusion_from_inside_target().ToString());
556 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
557 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
558 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
559 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
560 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
562 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
563 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
564 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
565 occlusion
.UnoccludedLayerContentRect(
566 parent
, gfx::Rect(29, 30, 70, 70)));
567 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
568 occlusion
.UnoccludedLayerContentRect(
569 parent
, gfx::Rect(29, 29, 70, 70)));
570 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
571 occlusion
.UnoccludedLayerContentRect(
572 parent
, gfx::Rect(30, 29, 70, 70)));
573 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
574 occlusion
.UnoccludedLayerContentRect(
575 parent
, gfx::Rect(31, 29, 70, 70)));
576 EXPECT_RECT_EQ(gfx::Rect(),
577 occlusion
.UnoccludedLayerContentRect(
578 parent
, gfx::Rect(31, 30, 70, 70)));
579 EXPECT_RECT_EQ(gfx::Rect(),
580 occlusion
.UnoccludedLayerContentRect(
581 parent
, gfx::Rect(31, 31, 70, 70)));
582 EXPECT_RECT_EQ(gfx::Rect(),
583 occlusion
.UnoccludedLayerContentRect(
584 parent
, gfx::Rect(30, 31, 70, 70)));
585 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
586 occlusion
.UnoccludedLayerContentRect(
587 parent
, gfx::Rect(29, 31, 70, 70)));
591 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
593 template <class Types
>
594 class OcclusionTrackerTestQuadsMismatchLayer
595 : public OcclusionTrackerTest
<Types
> {
597 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers
)
598 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
600 gfx::Transform layer_transform
;
601 layer_transform
.Translate(10.0, 10.0);
603 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
604 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(100, 100));
605 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
606 parent
, layer_transform
, gfx::PointF(), gfx::Size(90, 90), true);
607 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
608 layer1
, layer_transform
, gfx::PointF(), gfx::Size(50, 50), true);
609 this->CalcDrawEtc(parent
);
611 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
612 typename
Types::RenderSurfaceType
> occlusion(
613 gfx::Rect(0, 0, 1000, 1000));
615 this->VisitLayer(layer2
, &occlusion
);
616 this->EnterLayer(layer1
, &occlusion
);
618 EXPECT_EQ(gfx::Rect().ToString(),
619 occlusion
.occlusion_from_outside_target().ToString());
620 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
621 occlusion
.occlusion_from_inside_target().ToString());
623 // This checks cases where the quads don't match their "containing"
624 // layers, e.g. in terms of transforms or clip rect. This is typical for
625 // DelegatedRendererLayer.
627 gfx::Transform quad_transform
;
628 quad_transform
.Translate(30.0, 30.0);
629 gfx::Rect
clip_rect_in_target(0, 0, 100, 100);
631 EXPECT_TRUE(occlusion
.UnoccludedContentRect(parent
,
632 gfx::Rect(0, 0, 10, 10),
638 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
639 occlusion
.UnoccludedContentRect(parent
,
640 gfx::Rect(0, 0, 10, 10),
646 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
647 occlusion
.UnoccludedContentRect(parent
,
648 gfx::Rect(40, 40, 10, 10),
654 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
655 occlusion
.UnoccludedContentRect(parent
,
656 gfx::Rect(35, 30, 10, 10),
662 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5),
663 occlusion
.UnoccludedContentRect(parent
,
664 gfx::Rect(40, 40, 10, 10),
668 gfx::Rect(0, 0, 75, 75),
673 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
675 template <class Types
>
676 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
678 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
679 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
681 gfx::Transform layer_transform
;
682 layer_transform
.Translate(250.0, 250.0);
683 layer_transform
.Rotate(90.0);
684 layer_transform
.Translate(-250.0, -250.0);
686 typename
Types::ContentLayerType
* root
= this->CreateRoot(
687 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
688 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
689 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
690 typename
Types::ContentLayerType
* layer
=
691 this->CreateDrawingLayer(parent
,
693 gfx::PointF(30.f
, 30.f
),
696 parent
->SetMasksToBounds(true);
697 this->CalcDrawEtc(root
);
699 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
700 typename
Types::RenderSurfaceType
> occlusion(
701 gfx::Rect(0, 0, 1000, 1000));
703 this->VisitLayer(layer
, &occlusion
);
704 this->EnterLayer(parent
, &occlusion
);
706 EXPECT_EQ(gfx::Rect().ToString(),
707 occlusion
.occlusion_from_outside_target().ToString());
708 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
709 occlusion
.occlusion_from_inside_target().ToString());
711 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
712 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
713 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
714 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
715 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
717 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
718 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
719 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
720 occlusion
.UnoccludedLayerContentRect(
721 parent
, gfx::Rect(29, 30, 70, 70)));
722 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
723 occlusion
.UnoccludedLayerContentRect(
724 parent
, gfx::Rect(29, 29, 70, 70)));
725 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
726 occlusion
.UnoccludedLayerContentRect(
727 parent
, gfx::Rect(30, 29, 70, 70)));
728 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
729 occlusion
.UnoccludedLayerContentRect(
730 parent
, gfx::Rect(31, 29, 70, 70)));
731 EXPECT_RECT_EQ(gfx::Rect(),
732 occlusion
.UnoccludedLayerContentRect(
733 parent
, gfx::Rect(31, 30, 70, 70)));
734 EXPECT_RECT_EQ(gfx::Rect(),
735 occlusion
.UnoccludedLayerContentRect(
736 parent
, gfx::Rect(31, 31, 70, 70)));
737 EXPECT_RECT_EQ(gfx::Rect(),
738 occlusion
.UnoccludedLayerContentRect(
739 parent
, gfx::Rect(30, 31, 70, 70)));
740 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
741 occlusion
.UnoccludedLayerContentRect(
742 parent
, gfx::Rect(29, 31, 70, 70)));
746 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
748 template <class Types
>
749 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
751 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
752 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
754 gfx::Transform layer_transform
;
755 layer_transform
.Translate(20.0, 20.0);
757 typename
Types::ContentLayerType
* root
= this->CreateRoot(
758 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
759 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
760 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
761 typename
Types::ContentLayerType
* layer
=
762 this->CreateDrawingLayer(parent
,
764 gfx::PointF(30.f
, 30.f
),
767 parent
->SetMasksToBounds(true);
768 this->CalcDrawEtc(root
);
770 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
771 typename
Types::RenderSurfaceType
> occlusion(
772 gfx::Rect(0, 0, 1000, 1000));
774 this->VisitLayer(layer
, &occlusion
);
775 this->EnterLayer(parent
, &occlusion
);
777 EXPECT_EQ(gfx::Rect().ToString(),
778 occlusion
.occlusion_from_outside_target().ToString());
779 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
780 occlusion
.occlusion_from_inside_target().ToString());
782 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
783 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
784 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
785 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(51, 50, 50, 50)));
786 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 51, 50, 50)));
788 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
789 parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
790 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
791 occlusion
.UnoccludedLayerContentRect(
792 parent
, gfx::Rect(49, 50, 50, 50)));
793 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
794 occlusion
.UnoccludedLayerContentRect(
795 parent
, gfx::Rect(49, 49, 50, 50)));
796 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
797 occlusion
.UnoccludedLayerContentRect(
798 parent
, gfx::Rect(50, 49, 50, 50)));
799 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
800 occlusion
.UnoccludedLayerContentRect(
801 parent
, gfx::Rect(51, 49, 50, 50)));
802 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
803 parent
, gfx::Rect(51, 50, 50, 50)).IsEmpty());
804 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
805 parent
, gfx::Rect(51, 51, 50, 50)).IsEmpty());
806 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
807 parent
, gfx::Rect(50, 51, 50, 50)).IsEmpty());
808 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
809 occlusion
.UnoccludedLayerContentRect(
810 parent
, gfx::Rect(49, 51, 50, 50)));
814 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
816 template <class Types
>
817 class OcclusionTrackerTestChildInRotatedChild
818 : public OcclusionTrackerTest
<Types
> {
820 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
821 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
823 gfx::Transform child_transform
;
824 child_transform
.Translate(250.0, 250.0);
825 child_transform
.Rotate(90.0);
826 child_transform
.Translate(-250.0, -250.0);
828 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
829 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
830 parent
->SetMasksToBounds(true);
831 typename
Types::LayerType
* child
= this->CreateLayer(
832 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
833 child
->SetMasksToBounds(true);
834 typename
Types::ContentLayerType
* layer
=
835 this->CreateDrawingLayer(child
,
836 this->identity_matrix
,
837 gfx::PointF(10.f
, 10.f
),
840 this->CalcDrawEtc(parent
);
842 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
843 typename
Types::RenderSurfaceType
> occlusion(
844 gfx::Rect(0, 0, 1000, 1000));
846 this->VisitLayer(layer
, &occlusion
);
847 this->EnterContributingSurface(child
, &occlusion
);
849 EXPECT_EQ(gfx::Rect().ToString(),
850 occlusion
.occlusion_from_outside_target().ToString());
851 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
852 occlusion
.occlusion_from_inside_target().ToString());
854 this->LeaveContributingSurface(child
, &occlusion
);
855 this->EnterLayer(parent
, &occlusion
);
857 EXPECT_EQ(gfx::Rect().ToString(),
858 occlusion
.occlusion_from_outside_target().ToString());
859 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
860 occlusion
.occlusion_from_inside_target().ToString());
862 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
863 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
864 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
865 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 40, 70, 60)));
866 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 41, 70, 60)));
868 /* Justification for the above occlusion from |layer|:
870 +---------------------+
873 | 30 + ---------------------------------+
875 | |10+---------------------------------+
879 +----|--|-------------+ | |
887 +--|-------------------------------+ |
889 +---------------------------------+
892 +---------------------+
893 | |30 Visible region of |layer|: /////
895 | +---------------------------------+
897 | +---------------------------------+ |
898 | | |///////////////| 420 | |
899 | | |///////////////|60 | |
900 | | |///////////////| | |
901 +--|--|---------------+ | |
909 | +------------------------------|--+
911 +---------------------------------+
918 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
920 template <class Types
>
921 class OcclusionTrackerTestScaledRenderSurface
922 : public OcclusionTrackerTest
<Types
> {
924 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
925 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
928 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
929 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
931 gfx::Transform layer1_matrix
;
932 layer1_matrix
.Scale(2.0, 2.0);
933 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
934 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
935 layer1
->SetForceRenderSurface(true);
937 gfx::Transform layer2_matrix
;
938 layer2_matrix
.Translate(25.0, 25.0);
939 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
940 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
941 typename
Types::ContentLayerType
* occluder
=
942 this->CreateDrawingLayer(parent
,
943 this->identity_matrix
,
944 gfx::PointF(100.f
, 100.f
),
947 this->CalcDrawEtc(parent
);
949 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
950 typename
Types::RenderSurfaceType
> occlusion(
951 gfx::Rect(0, 0, 1000, 1000));
953 this->VisitLayer(occluder
, &occlusion
);
954 this->EnterLayer(layer2
, &occlusion
);
956 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
957 occlusion
.occlusion_from_outside_target().ToString());
958 EXPECT_EQ(gfx::Rect().ToString(),
959 occlusion
.occlusion_from_inside_target().ToString());
962 gfx::Rect(0, 0, 25, 25),
963 occlusion
.UnoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
964 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
965 occlusion
.UnoccludedLayerContentRect(
966 layer2
, gfx::Rect(10, 25, 25, 25)));
967 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
968 occlusion
.UnoccludedLayerContentRect(
969 layer2
, gfx::Rect(25, 10, 25, 25)));
970 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
971 layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
975 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
977 template <class Types
>
978 class OcclusionTrackerTestVisitTargetTwoTimes
979 : public OcclusionTrackerTest
<Types
> {
981 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
982 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
984 gfx::Transform child_transform
;
985 child_transform
.Translate(250.0, 250.0);
986 child_transform
.Rotate(90.0);
987 child_transform
.Translate(-250.0, -250.0);
989 typename
Types::ContentLayerType
* root
= this->CreateRoot(
990 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
991 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
992 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
993 parent
->SetMasksToBounds(true);
994 typename
Types::LayerType
* child
= this->CreateLayer(
995 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
996 child
->SetMasksToBounds(true);
997 typename
Types::ContentLayerType
* layer
=
998 this->CreateDrawingLayer(child
,
999 this->identity_matrix
,
1000 gfx::PointF(10.f
, 10.f
),
1001 gfx::Size(500, 500),
1003 // |child2| makes |parent|'s surface get considered by OcclusionTracker
1004 // first, instead of |child|'s. This exercises different code in
1005 // LeaveToRenderTarget, as the target surface has already been seen.
1006 typename
Types::ContentLayerType
* child2
=
1007 this->CreateDrawingLayer(parent
,
1008 this->identity_matrix
,
1009 gfx::PointF(30.f
, 30.f
),
1012 this->CalcDrawEtc(root
);
1014 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1015 typename
Types::RenderSurfaceType
> occlusion(
1016 gfx::Rect(0, 0, 1000, 1000));
1018 this->VisitLayer(child2
, &occlusion
);
1020 EXPECT_EQ(gfx::Rect().ToString(),
1021 occlusion
.occlusion_from_outside_target().ToString());
1022 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1023 occlusion
.occlusion_from_inside_target().ToString());
1025 this->VisitLayer(layer
, &occlusion
);
1027 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1028 occlusion
.occlusion_from_outside_target().ToString());
1029 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1030 occlusion
.occlusion_from_inside_target().ToString());
1032 this->EnterContributingSurface(child
, &occlusion
);
1034 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1035 occlusion
.occlusion_from_outside_target().ToString());
1036 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1037 occlusion
.occlusion_from_inside_target().ToString());
1039 // Occlusion in |child2| should get merged with the |child| surface we are
1041 this->LeaveContributingSurface(child
, &occlusion
);
1042 this->EnterLayer(parent
, &occlusion
);
1044 EXPECT_EQ(gfx::Rect().ToString(),
1045 occlusion
.occlusion_from_outside_target().ToString());
1046 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1048 occlusion
.occlusion_from_inside_target().ToString());
1050 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
1051 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1052 occlusion
.UnoccludedLayerContentRect(
1053 parent
, gfx::Rect(30, 30, 70, 70)));
1055 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
1056 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
1057 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
1058 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
1059 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
1061 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1062 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1063 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1065 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1066 parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1067 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1068 occlusion
.UnoccludedLayerContentRect(
1069 parent
, gfx::Rect(29, 30, 60, 10)));
1070 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1071 occlusion
.UnoccludedLayerContentRect(
1072 parent
, gfx::Rect(30, 29, 60, 10)));
1073 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1074 occlusion
.UnoccludedLayerContentRect(
1075 parent
, gfx::Rect(31, 30, 60, 10)));
1076 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1077 parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1079 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1080 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1081 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1082 occlusion
.UnoccludedLayerContentRect(
1083 parent
, gfx::Rect(29, 40, 70, 60)));
1084 // This rect is mostly occluded by |child2|.
1085 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1086 occlusion
.UnoccludedLayerContentRect(
1087 parent
, gfx::Rect(30, 39, 70, 60)));
1088 // This rect extends past top/right ends of |child2|.
1089 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1090 occlusion
.UnoccludedLayerContentRect(
1091 parent
, gfx::Rect(30, 29, 70, 70)));
1092 // This rect extends past left/right ends of |child2|.
1093 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1094 occlusion
.UnoccludedLayerContentRect(
1095 parent
, gfx::Rect(20, 39, 80, 60)));
1096 EXPECT_RECT_EQ(gfx::Rect(),
1097 occlusion
.UnoccludedLayerContentRect(
1098 parent
, gfx::Rect(31, 40, 70, 60)));
1099 EXPECT_RECT_EQ(gfx::Rect(),
1100 occlusion
.UnoccludedLayerContentRect(
1101 parent
, gfx::Rect(30, 41, 70, 60)));
1103 /* Justification for the above occlusion from |layer|:
1105 +---------------------+
1108 | 30 + ------------+--------------------+
1109 100 | | 10 | | | ==>
1110 | |10+----------|----------------------+
1111 | + ------------+ | | |
1114 +----|--|-------------+ | |
1122 +--|-------------------------------+ |
1124 +---------------------------------+
1128 +---------------------+
1129 | |30 Visible region of |layer|: /////
1130 | 30 60 | |child2|: \\\\\
1131 | 30 +------------+--------------------+
1132 | |\\\\\\\\\\\\| |10 |
1133 | +--|\\\\\\\\\\\\|-----------------+ |
1134 | | +------------+//| 420 | |
1135 | | |///////////////|60 | |
1136 | | |///////////////| | |
1137 +--|--|---------------+ | |
1145 | +------------------------------|--+
1147 +---------------------------------+
1153 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
1155 template <class Types
>
1156 class OcclusionTrackerTestSurfaceRotatedOffAxis
1157 : public OcclusionTrackerTest
<Types
> {
1159 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
1160 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1162 gfx::Transform child_transform
;
1163 child_transform
.Translate(250.0, 250.0);
1164 child_transform
.Rotate(95.0);
1165 child_transform
.Translate(-250.0, -250.0);
1167 gfx::Transform layer_transform
;
1168 layer_transform
.Translate(10.0, 10.0);
1170 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1171 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1172 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1173 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1174 typename
Types::LayerType
* child
= this->CreateLayer(
1175 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1176 child
->SetMasksToBounds(true);
1177 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1178 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
1179 this->CalcDrawEtc(root
);
1181 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1182 typename
Types::RenderSurfaceType
> occlusion(
1183 gfx::Rect(0, 0, 1000, 1000));
1185 gfx::Rect clipped_layer_in_child
= MathUtil::MapClippedRect(
1186 layer_transform
, layer
->visible_content_rect());
1188 this->VisitLayer(layer
, &occlusion
);
1189 this->EnterContributingSurface(child
, &occlusion
);
1191 EXPECT_EQ(gfx::Rect().ToString(),
1192 occlusion
.occlusion_from_outside_target().ToString());
1193 EXPECT_EQ(clipped_layer_in_child
.ToString(),
1194 occlusion
.occlusion_from_inside_target().ToString());
1196 this->LeaveContributingSurface(child
, &occlusion
);
1197 this->EnterLayer(parent
, &occlusion
);
1199 EXPECT_EQ(gfx::Rect().ToString(),
1200 occlusion
.occlusion_from_outside_target().ToString());
1201 EXPECT_EQ(gfx::Rect().ToString(),
1202 occlusion
.occlusion_from_inside_target().ToString());
1204 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
1206 gfx::Rect(75, 55, 1, 1),
1207 occlusion
.UnoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
1211 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
1213 template <class Types
>
1214 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1215 : public OcclusionTrackerTest
<Types
> {
1217 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
1218 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1220 gfx::Transform child_transform
;
1221 child_transform
.Translate(250.0, 250.0);
1222 child_transform
.Rotate(90.0);
1223 child_transform
.Translate(-250.0, -250.0);
1225 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1226 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1227 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1228 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1229 parent
->SetMasksToBounds(true);
1230 typename
Types::ContentLayerType
* child
=
1231 this->CreateDrawingLayer(parent
,
1233 gfx::PointF(30.f
, 30.f
),
1234 gfx::Size(500, 500),
1236 child
->SetMasksToBounds(true);
1237 typename
Types::ContentLayerType
* layer1
=
1238 this->CreateDrawingLayer(child
,
1239 this->identity_matrix
,
1240 gfx::PointF(10.f
, 10.f
),
1241 gfx::Size(500, 500),
1243 typename
Types::ContentLayerType
* layer2
=
1244 this->CreateDrawingLayer(child
,
1245 this->identity_matrix
,
1246 gfx::PointF(10.f
, 450.f
),
1249 this->CalcDrawEtc(root
);
1251 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1252 typename
Types::RenderSurfaceType
> occlusion(
1253 gfx::Rect(0, 0, 1000, 1000));
1255 this->VisitLayer(layer2
, &occlusion
);
1256 this->VisitLayer(layer1
, &occlusion
);
1257 this->VisitLayer(child
, &occlusion
);
1258 this->EnterContributingSurface(child
, &occlusion
);
1260 EXPECT_EQ(gfx::Rect().ToString(),
1261 occlusion
.occlusion_from_outside_target().ToString());
1262 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1263 occlusion
.occlusion_from_inside_target().ToString());
1265 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
1266 EXPECT_FALSE(occlusion
.OccludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
1267 // These rects are occluded except for the part outside the bounds of the
1269 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 429, 60, 70)));
1270 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(11, 430, 60, 70)));
1271 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 431, 60, 70)));
1273 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1274 child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1276 gfx::Rect(9, 430, 1, 70),
1277 occlusion
.UnoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
1278 // These rects are occluded except for the part outside the bounds of the
1280 EXPECT_RECT_EQ(gfx::Rect(),
1281 occlusion
.UnoccludedLayerContentRect(
1282 child
, gfx::Rect(10, 429, 60, 70)));
1283 EXPECT_RECT_EQ(gfx::Rect(),
1284 occlusion
.UnoccludedLayerContentRect(
1285 child
, gfx::Rect(11, 430, 60, 70)));
1286 EXPECT_RECT_EQ(gfx::Rect(),
1287 occlusion
.UnoccludedLayerContentRect(
1288 child
, gfx::Rect(10, 431, 60, 70)));
1290 this->LeaveContributingSurface(child
, &occlusion
);
1291 this->EnterLayer(parent
, &occlusion
);
1293 EXPECT_EQ(gfx::Rect().ToString(),
1294 occlusion
.occlusion_from_outside_target().ToString());
1295 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1296 occlusion
.occlusion_from_inside_target().ToString());
1298 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1299 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1300 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1302 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1303 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1304 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1305 occlusion
.UnoccludedLayerContentRect(
1306 parent
, gfx::Rect(29, 40, 70, 60)));
1307 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1308 occlusion
.UnoccludedLayerContentRect(
1309 parent
, gfx::Rect(30, 39, 70, 60)));
1310 EXPECT_RECT_EQ(gfx::Rect(),
1311 occlusion
.UnoccludedLayerContentRect(
1312 parent
, gfx::Rect(31, 40, 70, 60)));
1313 EXPECT_RECT_EQ(gfx::Rect(),
1314 occlusion
.UnoccludedLayerContentRect(
1315 parent
, gfx::Rect(30, 41, 70, 60)));
1317 /* Justification for the above occlusion from |layer1| and |layer2|:
1319 +---------------------+
1320 | |30 Visible region of |layer1|: /////
1321 | | Visible region of |layer2|: \\\\\
1322 | +---------------------------------+
1324 | +---------------+-----------------+ |
1325 | | |\\\\\\\\\\\\|//| 420 | |
1326 | | |\\\\\\\\\\\\|//|60 | |
1327 | | |\\\\\\\\\\\\|//| | |
1328 +--|--|------------|--+ | |
1336 | +------------|-----------------|--+
1338 +---------------+-----------------+
1344 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1346 template <class Types
>
1347 class OcclusionTrackerTestOverlappingSurfaceSiblings
1348 : public OcclusionTrackerTest
<Types
> {
1350 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
1351 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1353 gfx::Transform child_transform
;
1354 child_transform
.Translate(250.0, 250.0);
1355 child_transform
.Rotate(90.0);
1356 child_transform
.Translate(-250.0, -250.0);
1358 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1359 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1360 parent
->SetMasksToBounds(true);
1361 typename
Types::LayerType
* child1
= this->CreateSurface(
1362 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(10, 10));
1363 typename
Types::LayerType
* child2
= this->CreateSurface(
1364 parent
, child_transform
, gfx::PointF(20.f
, 40.f
), gfx::Size(10, 10));
1365 typename
Types::ContentLayerType
* layer1
=
1366 this->CreateDrawingLayer(child1
,
1367 this->identity_matrix
,
1368 gfx::PointF(-10.f
, -10.f
),
1369 gfx::Size(510, 510),
1371 typename
Types::ContentLayerType
* layer2
=
1372 this->CreateDrawingLayer(child2
,
1373 this->identity_matrix
,
1374 gfx::PointF(-10.f
, -10.f
),
1375 gfx::Size(510, 510),
1377 this->CalcDrawEtc(parent
);
1379 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1380 typename
Types::RenderSurfaceType
> occlusion(
1381 gfx::Rect(0, 0, 1000, 1000));
1383 this->VisitLayer(layer2
, &occlusion
);
1384 this->EnterContributingSurface(child2
, &occlusion
);
1386 EXPECT_EQ(gfx::Rect().ToString(),
1387 occlusion
.occlusion_from_outside_target().ToString());
1388 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1389 occlusion
.occlusion_from_inside_target().ToString());
1391 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1392 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1393 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1394 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1395 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1397 // There is nothing above child2's surface in the z-order.
1398 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1399 occlusion
.UnoccludedContributingSurfaceContentRect(
1400 child2
, false, gfx::Rect(-10, 420, 70, 80), NULL
));
1402 this->LeaveContributingSurface(child2
, &occlusion
);
1403 this->VisitLayer(layer1
, &occlusion
);
1404 this->EnterContributingSurface(child1
, &occlusion
);
1406 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1407 occlusion
.occlusion_from_outside_target().ToString());
1408 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1409 occlusion
.occlusion_from_inside_target().ToString());
1411 // child2's contents will occlude child1 below it.
1412 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1413 occlusion
.UnoccludedContributingSurfaceContentRect(
1414 child1
, false, gfx::Rect(-10, 430, 80, 70), NULL
));
1416 this->LeaveContributingSurface(child1
, &occlusion
);
1417 this->EnterLayer(parent
, &occlusion
);
1419 EXPECT_EQ(gfx::Rect().ToString(),
1420 occlusion
.occlusion_from_outside_target().ToString());
1421 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1423 occlusion
.occlusion_from_inside_target().ToString());
1425 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1427 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1428 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1429 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1431 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1432 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1433 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1435 /* Justification for the above occlusion:
1437 +---------------------+
1439 | 30+ ---------------------------------+
1440 100 | 30| | layer2 |
1441 |20+----------------------------------+ |
1445 +--|-|----------------+ | |
1453 | +--------------------------------|-+
1455 +----------------------------------+
1461 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1463 template <class Types
>
1464 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1465 : public OcclusionTrackerTest
<Types
> {
1467 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1469 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1471 gfx::Transform child1_transform
;
1472 child1_transform
.Translate(250.0, 250.0);
1473 child1_transform
.Rotate(-90.0);
1474 child1_transform
.Translate(-250.0, -250.0);
1476 gfx::Transform child2_transform
;
1477 child2_transform
.Translate(250.0, 250.0);
1478 child2_transform
.Rotate(90.0);
1479 child2_transform
.Translate(-250.0, -250.0);
1481 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1482 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1483 parent
->SetMasksToBounds(true);
1484 typename
Types::LayerType
* child1
= this->CreateSurface(
1485 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1486 typename
Types::LayerType
* child2
=
1487 this->CreateDrawingSurface(parent
,
1489 gfx::PointF(20.f
, 40.f
),
1492 typename
Types::ContentLayerType
* layer1
=
1493 this->CreateDrawingLayer(child1
,
1494 this->identity_matrix
,
1495 gfx::PointF(-10.f
, -20.f
),
1496 gfx::Size(510, 510),
1498 typename
Types::ContentLayerType
* layer2
=
1499 this->CreateDrawingLayer(child2
,
1500 this->identity_matrix
,
1501 gfx::PointF(-10.f
, -10.f
),
1502 gfx::Size(510, 510),
1504 this->CalcDrawEtc(parent
);
1506 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1507 typename
Types::RenderSurfaceType
> occlusion(
1508 gfx::Rect(0, 0, 1000, 1000));
1510 this->VisitLayer(layer2
, &occlusion
);
1511 this->EnterLayer(child2
, &occlusion
);
1513 EXPECT_EQ(gfx::Rect().ToString(),
1514 occlusion
.occlusion_from_outside_target().ToString());
1515 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1516 occlusion
.occlusion_from_inside_target().ToString());
1518 this->LeaveLayer(child2
, &occlusion
);
1519 this->EnterContributingSurface(child2
, &occlusion
);
1521 // There is nothing above child2's surface in the z-order.
1522 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1523 occlusion
.UnoccludedContributingSurfaceContentRect(
1524 child2
, false, gfx::Rect(-10, 420, 70, 80), NULL
));
1526 this->LeaveContributingSurface(child2
, &occlusion
);
1527 this->VisitLayer(layer1
, &occlusion
);
1528 this->EnterContributingSurface(child1
, &occlusion
);
1530 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1531 occlusion
.occlusion_from_outside_target().ToString());
1532 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1533 occlusion
.occlusion_from_inside_target().ToString());
1535 // child2's contents will occlude child1 below it.
1536 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1537 occlusion
.UnoccludedContributingSurfaceContentRect(
1538 child1
, false, gfx::Rect(420, -20, 80, 90), NULL
));
1539 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1540 occlusion
.UnoccludedContributingSurfaceContentRect(
1541 child1
, false, gfx::Rect(420, -10, 80, 90), NULL
));
1542 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1543 occlusion
.UnoccludedContributingSurfaceContentRect(
1544 child1
, false, gfx::Rect(420, -20, 70, 90), NULL
));
1546 this->LeaveContributingSurface(child1
, &occlusion
);
1547 this->EnterLayer(parent
, &occlusion
);
1549 EXPECT_EQ(gfx::Rect().ToString(),
1550 occlusion
.occlusion_from_outside_target().ToString());
1551 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1552 occlusion
.occlusion_from_inside_target().ToString());
1554 /* Justification for the above occlusion:
1556 +---------------------+
1558 10+----------------------------------+
1559 100 || 30 | layer2 |
1560 |20+----------------------------------+
1564 +|-|------------------+ | |
1572 +----------------------------------+ |
1574 +----------------------------------+
1580 ALL_OCCLUSIONTRACKER_TEST(
1581 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1583 template <class Types
>
1584 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1586 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1587 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1589 gfx::Transform layer_transform
;
1590 layer_transform
.Translate(250.0, 250.0);
1591 layer_transform
.Rotate(90.0);
1592 layer_transform
.Translate(-250.0, -250.0);
1594 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1595 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1596 parent
->SetMasksToBounds(true);
1597 typename
Types::ContentLayerType
* blur_layer
=
1598 this->CreateDrawingLayer(parent
,
1600 gfx::PointF(30.f
, 30.f
),
1601 gfx::Size(500, 500),
1603 typename
Types::ContentLayerType
* opaque_layer
=
1604 this->CreateDrawingLayer(parent
,
1606 gfx::PointF(30.f
, 30.f
),
1607 gfx::Size(500, 500),
1609 typename
Types::ContentLayerType
* opacity_layer
=
1610 this->CreateDrawingLayer(parent
,
1612 gfx::PointF(30.f
, 30.f
),
1613 gfx::Size(500, 500),
1616 WebKit::WebFilterOperations filters
;
1617 filters
.append(WebKit::WebFilterOperation::createBlurFilter(10.f
));
1618 blur_layer
->SetFilters(filters
);
1621 filters
.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5f
));
1622 opaque_layer
->SetFilters(filters
);
1625 filters
.append(WebKit::WebFilterOperation::createOpacityFilter(0.5f
));
1626 opacity_layer
->SetFilters(filters
);
1628 this->CalcDrawEtc(parent
);
1630 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1631 typename
Types::RenderSurfaceType
> occlusion(
1632 gfx::Rect(0, 0, 1000, 1000));
1634 // Opacity layer won't contribute to occlusion.
1635 this->VisitLayer(opacity_layer
, &occlusion
);
1636 this->EnterContributingSurface(opacity_layer
, &occlusion
);
1638 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1639 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1641 // And has nothing to contribute to its parent surface.
1642 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1643 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1644 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1646 // Opaque layer will contribute to occlusion.
1647 this->VisitLayer(opaque_layer
, &occlusion
);
1648 this->EnterContributingSurface(opaque_layer
, &occlusion
);
1650 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1651 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1652 occlusion
.occlusion_from_inside_target().ToString());
1654 // And it gets translated to the parent surface.
1655 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1656 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1657 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1658 occlusion
.occlusion_from_inside_target().ToString());
1660 // The blur layer needs to throw away any occlusion from outside its
1662 this->EnterLayer(blur_layer
, &occlusion
);
1663 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1664 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1666 // And it won't contribute to occlusion.
1667 this->LeaveLayer(blur_layer
, &occlusion
);
1668 this->EnterContributingSurface(blur_layer
, &occlusion
);
1669 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1670 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1672 // But the opaque layer's occlusion is preserved on the parent.
1673 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1674 this->EnterLayer(parent
, &occlusion
);
1675 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1676 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1677 occlusion
.occlusion_from_inside_target().ToString());
1681 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1683 template <class Types
>
1684 class OcclusionTrackerTestReplicaDoesOcclude
1685 : public OcclusionTrackerTest
<Types
> {
1687 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1688 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1690 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1691 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1692 typename
Types::LayerType
* surface
=
1693 this->CreateDrawingSurface(parent
,
1694 this->identity_matrix
,
1695 gfx::PointF(0.f
, 100.f
),
1698 this->CreateReplicaLayer(
1699 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1700 this->CalcDrawEtc(parent
);
1702 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1703 typename
Types::RenderSurfaceType
> occlusion(
1704 gfx::Rect(0, 0, 1000, 1000));
1706 this->VisitLayer(surface
, &occlusion
);
1708 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1709 occlusion
.occlusion_from_inside_target().ToString());
1711 this->VisitContributingSurface(surface
, &occlusion
);
1712 this->EnterLayer(parent
, &occlusion
);
1714 // The surface and replica should both be occluding the parent.
1716 UnionRegions(gfx::Rect(0, 100, 50, 50),
1717 gfx::Rect(50, 150, 50, 50)).ToString(),
1718 occlusion
.occlusion_from_inside_target().ToString());
1722 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1724 template <class Types
>
1725 class OcclusionTrackerTestReplicaWithClipping
1726 : public OcclusionTrackerTest
<Types
> {
1728 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1729 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1731 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1732 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1733 parent
->SetMasksToBounds(true);
1734 typename
Types::LayerType
* surface
=
1735 this->CreateDrawingSurface(parent
,
1736 this->identity_matrix
,
1737 gfx::PointF(0.f
, 100.f
),
1740 this->CreateReplicaLayer(
1741 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1742 this->CalcDrawEtc(parent
);
1744 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1745 typename
Types::RenderSurfaceType
> occlusion(
1746 gfx::Rect(0, 0, 1000, 1000));
1748 this->VisitLayer(surface
, &occlusion
);
1750 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1751 occlusion
.occlusion_from_inside_target().ToString());
1753 this->VisitContributingSurface(surface
, &occlusion
);
1754 this->EnterLayer(parent
, &occlusion
);
1756 // The surface and replica should both be occluding the parent.
1758 UnionRegions(gfx::Rect(0, 100, 50, 50),
1759 gfx::Rect(50, 150, 50, 20)).ToString(),
1760 occlusion
.occlusion_from_inside_target().ToString());
1764 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1766 template <class Types
>
1767 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1769 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1770 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1772 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1773 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1774 typename
Types::LayerType
* surface
=
1775 this->CreateDrawingSurface(parent
,
1776 this->identity_matrix
,
1777 gfx::PointF(0.f
, 100.f
),
1780 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1781 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1782 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1783 this->CalcDrawEtc(parent
);
1785 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1786 typename
Types::RenderSurfaceType
> occlusion(
1787 gfx::Rect(0, 0, 1000, 1000));
1789 this->VisitLayer(surface
, &occlusion
);
1791 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1792 occlusion
.occlusion_from_inside_target().ToString());
1794 this->VisitContributingSurface(surface
, &occlusion
);
1795 this->EnterLayer(parent
, &occlusion
);
1797 // The replica should not be occluding the parent, since it has a mask
1799 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1800 occlusion
.occlusion_from_inside_target().ToString());
1804 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1806 template <class Types
>
1807 class OcclusionTrackerTestLayerClipRectOutsideChild
1808 : public OcclusionTrackerTest
<Types
> {
1810 explicit OcclusionTrackerTestLayerClipRectOutsideChild(bool opaque_layers
)
1811 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1813 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1814 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1815 typename
Types::ContentLayerType
* clip
=
1816 this->CreateDrawingLayer(parent
,
1817 this->identity_matrix
,
1818 gfx::PointF(200.f
, 100.f
),
1819 gfx::Size(100, 100),
1821 clip
->SetMasksToBounds(true);
1822 typename
Types::ContentLayerType
* layer
=
1823 this->CreateDrawingLayer(clip
,
1824 this->identity_matrix
,
1825 gfx::PointF(-200.f
, -100.f
),
1826 gfx::Size(200, 200),
1828 this->CalcDrawEtc(parent
);
1830 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1831 typename
Types::RenderSurfaceType
> occlusion(
1832 gfx::Rect(0, 0, 1000, 1000));
1834 this->EnterLayer(layer
, &occlusion
);
1836 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1837 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1838 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1839 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1840 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1842 this->LeaveLayer(layer
, &occlusion
);
1843 this->EnterLayer(clip
, &occlusion
);
1845 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(-100, 0, 100, 100)));
1846 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, -100, 100, 100)));
1847 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 0, 100, 100)));
1848 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 100, 100, 100)));
1849 EXPECT_FALSE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 0, 100, 100)));
1851 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
1852 occlusion
.UnoccludedLayerContentRect(
1853 clip
, gfx::Rect(-100, -100, 300, 300)));
1857 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild
);
1859 template <class Types
>
1860 class OcclusionTrackerTestViewportRectOutsideChild
1861 : public OcclusionTrackerTest
<Types
> {
1863 explicit OcclusionTrackerTestViewportRectOutsideChild(bool opaque_layers
)
1864 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1866 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1867 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1868 typename
Types::ContentLayerType
* layer
=
1869 this->CreateDrawingSurface(parent
,
1870 this->identity_matrix
,
1872 gfx::Size(200, 200),
1874 this->CalcDrawEtc(parent
);
1876 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1877 typename
Types::RenderSurfaceType
> occlusion(
1878 gfx::Rect(200, 100, 100, 100));
1880 this->EnterLayer(layer
, &occlusion
);
1882 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1883 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1884 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1885 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1886 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1888 this->LeaveLayer(layer
, &occlusion
);
1889 this->VisitContributingSurface(layer
, &occlusion
);
1890 this->EnterLayer(parent
, &occlusion
);
1892 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1893 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1894 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1895 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1897 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1898 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1899 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1900 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1901 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1903 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100),
1904 occlusion
.UnoccludedLayerContentRect(
1905 parent
, gfx::Rect(0, 0, 300, 300)));
1909 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild
);
1911 template <class Types
>
1912 class OcclusionTrackerTestLayerClipRectOverChild
1913 : public OcclusionTrackerTest
<Types
> {
1915 explicit OcclusionTrackerTestLayerClipRectOverChild(bool opaque_layers
)
1916 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1918 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1919 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1920 typename
Types::ContentLayerType
* clip
=
1921 this->CreateDrawingLayer(parent
,
1922 this->identity_matrix
,
1923 gfx::PointF(100.f
, 100.f
),
1924 gfx::Size(100, 100),
1926 clip
->SetMasksToBounds(true);
1927 typename
Types::ContentLayerType
* layer
=
1928 this->CreateDrawingSurface(clip
,
1929 this->identity_matrix
,
1930 gfx::PointF(-100.f
, -100.f
),
1931 gfx::Size(200, 200),
1933 this->CalcDrawEtc(parent
);
1935 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1936 typename
Types::RenderSurfaceType
> occlusion(
1937 gfx::Rect(0, 0, 1000, 1000));
1939 this->EnterLayer(layer
, &occlusion
);
1941 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1942 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1943 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1944 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1946 this->LeaveLayer(layer
, &occlusion
);
1947 this->VisitContributingSurface(layer
, &occlusion
);
1949 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1950 occlusion
.occlusion_from_inside_target().ToString());
1952 this->EnterLayer(clip
, &occlusion
);
1954 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 0, 100, 100)));
1955 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 100, 100, 100)));
1956 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 0, 100, 100)));
1957 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 100, 100, 100)));
1958 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 100, 100, 100)));
1959 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 0, 100, 100)));
1960 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 200, 100, 100)));
1961 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 200, 100, 100)));
1962 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 200, 100, 100)));
1964 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1965 clip
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1969 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild
);
1971 template <class Types
>
1972 class OcclusionTrackerTestViewportRectOverChild
1973 : public OcclusionTrackerTest
<Types
> {
1975 explicit OcclusionTrackerTestViewportRectOverChild(bool opaque_layers
)
1976 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1978 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1979 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1980 typename
Types::ContentLayerType
* layer
=
1981 this->CreateDrawingSurface(parent
,
1982 this->identity_matrix
,
1984 gfx::Size(200, 200),
1986 this->CalcDrawEtc(parent
);
1988 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1989 typename
Types::RenderSurfaceType
> occlusion(
1990 gfx::Rect(100, 100, 100, 100));
1992 this->EnterLayer(layer
, &occlusion
);
1994 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1995 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1996 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1997 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1999 this->LeaveLayer(layer
, &occlusion
);
2000 this->VisitContributingSurface(layer
, &occlusion
);
2001 this->EnterLayer(parent
, &occlusion
);
2003 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2004 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2005 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2006 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2007 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2008 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2009 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2010 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2011 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2013 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2014 parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2018 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild
);
2020 template <class Types
>
2021 class OcclusionTrackerTestLayerClipRectPartlyOverChild
2022 : public OcclusionTrackerTest
<Types
> {
2024 explicit OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaque_layers
)
2025 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2027 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2028 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2029 typename
Types::ContentLayerType
* clip
=
2030 this->CreateDrawingLayer(parent
,
2031 this->identity_matrix
,
2032 gfx::PointF(50.f
, 50.f
),
2033 gfx::Size(200, 200),
2035 clip
->SetMasksToBounds(true);
2036 typename
Types::ContentLayerType
* layer
=
2037 this->CreateDrawingSurface(clip
,
2038 this->identity_matrix
,
2039 gfx::PointF(-50.f
, -50.f
),
2040 gfx::Size(200, 200),
2042 this->CalcDrawEtc(parent
);
2044 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2045 typename
Types::RenderSurfaceType
> occlusion(
2046 gfx::Rect(0, 0, 1000, 1000));
2048 this->EnterLayer(layer
, &occlusion
);
2050 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2051 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2052 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2053 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2055 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 50)));
2056 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 50, 100)));
2057 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 50)));
2058 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 50, 100)));
2060 this->LeaveLayer(layer
, &occlusion
);
2061 this->VisitContributingSurface(layer
, &occlusion
);
2062 this->EnterLayer(clip
, &occlusion
);
2064 EXPECT_EQ(gfx::Rect(50, 50, 150, 150).ToString(),
2065 occlusion
.occlusion_from_inside_target().ToString());
2069 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild
);
2071 template <class Types
>
2072 class OcclusionTrackerTestViewportRectPartlyOverChild
2073 : public OcclusionTrackerTest
<Types
> {
2075 explicit OcclusionTrackerTestViewportRectPartlyOverChild(bool opaque_layers
)
2076 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2078 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2079 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2080 typename
Types::ContentLayerType
* layer
=
2081 this->CreateDrawingSurface(parent
,
2082 this->identity_matrix
,
2084 gfx::Size(200, 200),
2086 this->CalcDrawEtc(parent
);
2088 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2089 typename
Types::RenderSurfaceType
> occlusion(
2090 gfx::Rect(50, 50, 200, 200));
2092 this->EnterLayer(layer
, &occlusion
);
2094 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2095 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2096 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2097 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2099 this->LeaveLayer(layer
, &occlusion
);
2100 this->VisitContributingSurface(layer
, &occlusion
);
2101 this->EnterLayer(parent
, &occlusion
);
2103 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2104 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2105 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2106 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2108 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2109 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2110 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2112 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2114 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2116 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200),
2117 occlusion
.UnoccludedLayerContentRect(
2118 parent
, gfx::Rect(0, 0, 300, 300)));
2119 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50),
2120 occlusion
.UnoccludedLayerContentRect(
2121 parent
, gfx::Rect(0, 0, 300, 100)));
2122 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2123 occlusion
.UnoccludedLayerContentRect(
2124 parent
, gfx::Rect(0, 100, 300, 100)));
2125 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2126 occlusion
.UnoccludedLayerContentRect(
2127 parent
, gfx::Rect(200, 100, 100, 100)));
2128 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50),
2129 occlusion
.UnoccludedLayerContentRect(
2130 parent
, gfx::Rect(100, 200, 100, 100)));
2134 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild
);
2136 template <class Types
>
2137 class OcclusionTrackerTestViewportRectOverNothing
2138 : public OcclusionTrackerTest
<Types
> {
2140 explicit OcclusionTrackerTestViewportRectOverNothing(bool opaque_layers
)
2141 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2143 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2144 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2145 typename
Types::ContentLayerType
* layer
=
2146 this->CreateDrawingSurface(parent
,
2147 this->identity_matrix
,
2149 gfx::Size(200, 200),
2151 this->CalcDrawEtc(parent
);
2153 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2154 typename
Types::RenderSurfaceType
> occlusion(
2155 gfx::Rect(500, 500, 100, 100));
2157 this->EnterLayer(layer
, &occlusion
);
2159 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2160 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2161 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2162 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2164 this->LeaveLayer(layer
, &occlusion
);
2165 this->VisitContributingSurface(layer
, &occlusion
);
2166 this->EnterLayer(parent
, &occlusion
);
2168 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2169 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2170 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2171 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2172 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2173 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2174 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2175 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2176 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2178 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2179 parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2180 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2181 parent
, gfx::Rect(0, 0, 300, 100)).IsEmpty());
2182 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2183 parent
, gfx::Rect(0, 100, 300, 100)).IsEmpty());
2184 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2185 parent
, gfx::Rect(200, 100, 100, 100)).IsEmpty());
2186 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2187 parent
, gfx::Rect(100, 200, 100, 100)).IsEmpty());
2191 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing
);
2193 template <class Types
>
2194 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
2195 : public OcclusionTrackerTest
<Types
> {
2197 explicit OcclusionTrackerTestLayerClipRectForLayerOffOrigin(
2199 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2201 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2202 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2203 typename
Types::ContentLayerType
* layer
=
2204 this->CreateDrawingSurface(parent
,
2205 this->identity_matrix
,
2207 gfx::Size(200, 200),
2209 this->CalcDrawEtc(parent
);
2211 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2212 typename
Types::RenderSurfaceType
> occlusion(
2213 gfx::Rect(0, 0, 1000, 1000));
2214 this->EnterLayer(layer
, &occlusion
);
2216 // This layer is translated when drawn into its target. So if the clip rect
2217 // given from the target surface is not in that target space, then after
2218 // translating these query rects into the target, they will fall outside the
2219 // clip and be considered occluded.
2220 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2221 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2222 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2223 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2227 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin
);
2229 template <class Types
>
2230 class OcclusionTrackerTestOpaqueContentsRegionEmpty
2231 : public OcclusionTrackerTest
<Types
> {
2233 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
2234 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2236 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2237 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2238 typename
Types::ContentLayerType
* layer
=
2239 this->CreateDrawingSurface(parent
,
2240 this->identity_matrix
,
2242 gfx::Size(200, 200),
2244 this->CalcDrawEtc(parent
);
2246 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2247 typename
Types::RenderSurfaceType
> occlusion(
2248 gfx::Rect(0, 0, 1000, 1000));
2249 this->EnterLayer(layer
, &occlusion
);
2251 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2252 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2253 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2254 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2256 // Occluded since its outside the surface bounds.
2257 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
2259 this->LeaveLayer(layer
, &occlusion
);
2260 this->VisitContributingSurface(layer
, &occlusion
);
2261 this->EnterLayer(parent
, &occlusion
);
2263 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2267 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
2269 template <class Types
>
2270 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
2271 : public OcclusionTrackerTest
<Types
> {
2273 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
2274 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2276 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2277 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2278 typename
Types::ContentLayerType
* layer
=
2279 this->CreateDrawingLayer(parent
,
2280 this->identity_matrix
,
2281 gfx::PointF(100.f
, 100.f
),
2282 gfx::Size(200, 200),
2284 this->CalcDrawEtc(parent
);
2286 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2287 typename
Types::RenderSurfaceType
> occlusion(
2288 gfx::Rect(0, 0, 1000, 1000));
2289 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
2291 this->ResetLayerIterator();
2292 this->VisitLayer(layer
, &occlusion
);
2293 this->EnterLayer(parent
, &occlusion
);
2295 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
2296 occlusion
.occlusion_from_inside_target().ToString());
2299 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2301 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2303 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2306 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2307 typename
Types::RenderSurfaceType
> occlusion(
2308 gfx::Rect(0, 0, 1000, 1000));
2309 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
2311 this->ResetLayerIterator();
2312 this->VisitLayer(layer
, &occlusion
);
2313 this->EnterLayer(parent
, &occlusion
);
2315 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
2316 occlusion
.occlusion_from_inside_target().ToString());
2319 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2321 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2323 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2326 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2327 typename
Types::RenderSurfaceType
> occlusion(
2328 gfx::Rect(0, 0, 1000, 1000));
2329 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
2331 this->ResetLayerIterator();
2332 this->VisitLayer(layer
, &occlusion
);
2333 this->EnterLayer(parent
, &occlusion
);
2335 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
2336 occlusion
.occlusion_from_inside_target().ToString());
2339 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2341 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2343 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2348 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
2350 template <class Types
>
2351 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
2353 explicit OcclusionTrackerTest3dTransform(bool opaque_layers
)
2354 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2356 gfx::Transform transform
;
2357 transform
.RotateAboutYAxis(30.0);
2359 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2360 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2361 typename
Types::LayerType
* container
= this->CreateLayer(
2362 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2363 typename
Types::ContentLayerType
* layer
=
2364 this->CreateDrawingLayer(container
,
2366 gfx::PointF(100.f
, 100.f
),
2367 gfx::Size(200, 200),
2369 this->CalcDrawEtc(parent
);
2371 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2372 typename
Types::RenderSurfaceType
> occlusion(
2373 gfx::Rect(0, 0, 1000, 1000));
2374 this->EnterLayer(layer
, &occlusion
);
2376 // The layer is rotated in 3d but without preserving 3d, so it only gets
2379 gfx::Rect(0, 0, 200, 200),
2380 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
2384 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
2386 template <class Types
>
2387 class OcclusionTrackerTestUnsorted3dLayers
2388 : public OcclusionTrackerTest
<Types
> {
2390 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
2391 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2393 // Currently, The main thread layer iterator does not iterate over 3d items
2394 // in sorted order, because layer sorting is not performed on the main
2395 // thread. Because of this, the occlusion tracker cannot assume that a 3d
2396 // layer occludes other layers that have not yet been iterated over. For
2397 // now, the expected behavior is that a 3d layer simply does not add any
2398 // occlusion to the occlusion tracker.
2400 gfx::Transform translation_to_front
;
2401 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
2402 gfx::Transform translation_to_back
;
2403 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
2405 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2406 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2407 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
2408 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
2409 typename
Types::ContentLayerType
* child2
=
2410 this->CreateDrawingLayer(parent
,
2411 translation_to_front
,
2412 gfx::PointF(50.f
, 50.f
),
2413 gfx::Size(100, 100),
2415 parent
->SetPreserves3d(true);
2417 this->CalcDrawEtc(parent
);
2419 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2420 typename
Types::RenderSurfaceType
> occlusion(
2421 gfx::Rect(0, 0, 1000, 1000));
2422 this->VisitLayer(child2
, &occlusion
);
2423 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2424 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2426 this->VisitLayer(child1
, &occlusion
);
2427 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2428 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2432 // This test will have different layer ordering on the impl thread; the test
2433 // will only work on the main thread.
2434 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
2436 template <class Types
>
2437 class OcclusionTrackerTestPerspectiveTransform
2438 : public OcclusionTrackerTest
<Types
> {
2440 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers
)
2441 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2443 gfx::Transform transform
;
2444 transform
.Translate(150.0, 150.0);
2445 transform
.ApplyPerspectiveDepth(400.0);
2446 transform
.RotateAboutXAxis(-30.0);
2447 transform
.Translate(-150.0, -150.0);
2449 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2450 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2451 typename
Types::LayerType
* container
= this->CreateLayer(
2452 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2453 typename
Types::ContentLayerType
* layer
=
2454 this->CreateDrawingLayer(container
,
2456 gfx::PointF(100.f
, 100.f
),
2457 gfx::Size(200, 200),
2459 container
->SetPreserves3d(true);
2460 layer
->SetPreserves3d(true);
2461 this->CalcDrawEtc(parent
);
2463 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2464 typename
Types::RenderSurfaceType
> occlusion(
2465 gfx::Rect(0, 0, 1000, 1000));
2466 this->EnterLayer(layer
, &occlusion
);
2469 gfx::Rect(0, 0, 200, 200),
2470 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
2474 // This test requires accumulating occlusion of 3d layers, which are skipped by
2475 // the occlusion tracker on the main thread. So this test should run on the impl
2477 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
2479 template <class Types
>
2480 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2481 : public OcclusionTrackerTest
<Types
> {
2483 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2485 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2487 // This test is based on the platform/chromium/compositing/3d-corners.html
2489 gfx::Transform transform
;
2490 transform
.Translate(250.0, 50.0);
2491 transform
.ApplyPerspectiveDepth(10.0);
2492 transform
.Translate(-250.0, -50.0);
2493 transform
.Translate(250.0, 50.0);
2494 transform
.RotateAboutXAxis(-167.0);
2495 transform
.Translate(-250.0, -50.0);
2497 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2498 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 100));
2499 typename
Types::LayerType
* container
= this->CreateLayer(
2500 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2501 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2502 container
, transform
, gfx::PointF(), gfx::Size(500, 500), true);
2503 container
->SetPreserves3d(true);
2504 layer
->SetPreserves3d(true);
2505 this->CalcDrawEtc(parent
);
2507 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2508 typename
Types::RenderSurfaceType
> occlusion(
2509 gfx::Rect(0, 0, 1000, 1000));
2510 this->EnterLayer(layer
, &occlusion
);
2512 // The bottom 11 pixel rows of this layer remain visible inside the
2513 // container, after translation to the target surface. When translated back,
2514 // this will include many more pixels but must include at least the bottom
2516 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2517 layer
, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
2521 // This test requires accumulating occlusion of 3d layers, which are skipped by
2522 // the occlusion tracker on the main thread. So this test should run on the impl
2524 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
2526 template <class Types
>
2527 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2528 : public OcclusionTrackerTest
<Types
> {
2530 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2532 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2534 gfx::Transform transform
;
2535 transform
.Translate(50.0, 50.0);
2536 transform
.ApplyPerspectiveDepth(100.0);
2537 transform
.Translate3d(0.0, 0.0, 110.0);
2538 transform
.Translate(-50.0, -50.0);
2540 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2541 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2542 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2543 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2544 parent
->SetPreserves3d(true);
2545 layer
->SetPreserves3d(true);
2546 this->CalcDrawEtc(parent
);
2548 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2549 typename
Types::RenderSurfaceType
> occlusion(
2550 gfx::Rect(0, 0, 1000, 1000));
2552 // The |layer| is entirely behind the camera and should not occlude.
2553 this->VisitLayer(layer
, &occlusion
);
2554 this->EnterLayer(parent
, &occlusion
);
2555 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2556 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2560 // This test requires accumulating occlusion of 3d layers, which are skipped by
2561 // the occlusion tracker on the main thread. So this test should run on the impl
2563 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2565 template <class Types
>
2566 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2567 : public OcclusionTrackerTest
<Types
> {
2569 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2571 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2573 gfx::Transform transform
;
2574 transform
.Translate(50.0, 50.0);
2575 transform
.ApplyPerspectiveDepth(100.0);
2576 transform
.Translate3d(0.0, 0.0, 99.0);
2577 transform
.Translate(-50.0, -50.0);
2579 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2580 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2581 parent
->SetMasksToBounds(true);
2582 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2583 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2584 parent
->SetPreserves3d(true);
2585 layer
->SetPreserves3d(true);
2586 this->CalcDrawEtc(parent
);
2588 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2589 typename
Types::RenderSurfaceType
> occlusion(
2590 gfx::Rect(0, 0, 1000, 1000));
2592 // This is very close to the camera, so pixels in its visible_content_rect()
2593 // will actually go outside of the layer's clip rect. Ensure that those
2594 // pixels don't occlude things outside the clip rect.
2595 this->VisitLayer(layer
, &occlusion
);
2596 this->EnterLayer(parent
, &occlusion
);
2597 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2598 occlusion
.occlusion_from_inside_target().ToString());
2599 EXPECT_EQ(gfx::Rect().ToString(),
2600 occlusion
.occlusion_from_outside_target().ToString());
2604 // This test requires accumulating occlusion of 3d layers, which are skipped by
2605 // the occlusion tracker on the main thread. So this test should run on the impl
2607 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2609 template <class Types
>
2610 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2611 : public OcclusionTrackerTest
<Types
> {
2613 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
2614 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2619 // | +--surface_child
2620 // | +--surface_child2
2624 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2625 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2626 typename
Types::ContentLayerType
* layer
=
2627 this->CreateDrawingLayer(parent
,
2628 this->identity_matrix
,
2630 gfx::Size(300, 300),
2632 typename
Types::ContentLayerType
* surface
=
2633 this->CreateDrawingSurface(parent
,
2634 this->identity_matrix
,
2636 gfx::Size(300, 300),
2638 typename
Types::ContentLayerType
* surface_child
=
2639 this->CreateDrawingLayer(surface
,
2640 this->identity_matrix
,
2642 gfx::Size(200, 300),
2644 typename
Types::ContentLayerType
* surface_child2
=
2645 this->CreateDrawingLayer(surface
,
2646 this->identity_matrix
,
2648 gfx::Size(100, 300),
2650 typename
Types::ContentLayerType
* parent2
=
2651 this->CreateDrawingLayer(parent
,
2652 this->identity_matrix
,
2654 gfx::Size(300, 300),
2656 typename
Types::ContentLayerType
* topmost
=
2657 this->CreateDrawingLayer(parent
,
2658 this->identity_matrix
,
2659 gfx::PointF(250.f
, 0.f
),
2663 AddOpacityTransitionToController(
2664 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2665 AddOpacityTransitionToController(
2666 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2667 this->CalcDrawEtc(parent
);
2669 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2670 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2671 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2673 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2674 typename
Types::RenderSurfaceType
> occlusion(
2675 gfx::Rect(0, 0, 1000, 1000));
2677 this->VisitLayer(topmost
, &occlusion
);
2678 this->EnterLayer(parent2
, &occlusion
);
2679 // This occlusion will affect all surfaces.
2680 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2681 occlusion
.occlusion_from_inside_target().ToString());
2682 EXPECT_EQ(gfx::Rect().ToString(),
2683 occlusion
.occlusion_from_outside_target().ToString());
2684 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2685 occlusion
.UnoccludedLayerContentRect(
2686 parent2
, gfx::Rect(0, 0, 300, 300)).ToString());
2687 this->LeaveLayer(parent2
, &occlusion
);
2689 this->VisitLayer(surface_child2
, &occlusion
);
2690 this->EnterLayer(surface_child
, &occlusion
);
2691 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2692 occlusion
.occlusion_from_inside_target().ToString());
2693 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2694 occlusion
.occlusion_from_outside_target().ToString());
2695 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2696 occlusion
.UnoccludedLayerContentRect(
2697 surface_child
, gfx::Rect(0, 0, 200, 300)));
2698 this->LeaveLayer(surface_child
, &occlusion
);
2699 this->EnterLayer(surface
, &occlusion
);
2700 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2701 occlusion
.occlusion_from_inside_target().ToString());
2702 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2703 occlusion
.occlusion_from_outside_target().ToString());
2704 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2705 occlusion
.UnoccludedLayerContentRect(
2706 surface
, gfx::Rect(0, 0, 300, 300)));
2707 this->LeaveLayer(surface
, &occlusion
);
2709 this->EnterContributingSurface(surface
, &occlusion
);
2710 // Occlusion within the surface is lost when leaving the animating surface.
2711 EXPECT_EQ(gfx::Rect().ToString(),
2712 occlusion
.occlusion_from_inside_target().ToString());
2713 EXPECT_EQ(gfx::Rect().ToString(),
2714 occlusion
.occlusion_from_outside_target().ToString());
2715 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2716 occlusion
.UnoccludedContributingSurfaceContentRect(
2717 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
2718 this->LeaveContributingSurface(surface
, &occlusion
);
2720 // Occlusion from outside the animating surface still exists.
2721 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2722 occlusion
.occlusion_from_inside_target().ToString());
2723 EXPECT_EQ(gfx::Rect().ToString(),
2724 occlusion
.occlusion_from_outside_target().ToString());
2726 this->VisitLayer(layer
, &occlusion
);
2727 this->EnterLayer(parent
, &occlusion
);
2729 // Occlusion is not added for the animating |layer|.
2730 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2731 occlusion
.UnoccludedLayerContentRect(
2732 parent
, gfx::Rect(0, 0, 300, 300)));
2736 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2738 template <class Types
>
2739 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2740 : public OcclusionTrackerTest
<Types
> {
2742 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
2743 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2745 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2746 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2747 typename
Types::ContentLayerType
* layer
=
2748 this->CreateDrawingLayer(parent
,
2749 this->identity_matrix
,
2751 gfx::Size(300, 300),
2753 typename
Types::ContentLayerType
* surface
=
2754 this->CreateDrawingSurface(parent
,
2755 this->identity_matrix
,
2757 gfx::Size(300, 300),
2759 typename
Types::ContentLayerType
* surface_child
=
2760 this->CreateDrawingLayer(surface
,
2761 this->identity_matrix
,
2763 gfx::Size(200, 300),
2765 typename
Types::ContentLayerType
* surface_child2
=
2766 this->CreateDrawingLayer(surface
,
2767 this->identity_matrix
,
2769 gfx::Size(100, 300),
2771 typename
Types::ContentLayerType
* parent2
=
2772 this->CreateDrawingLayer(parent
,
2773 this->identity_matrix
,
2775 gfx::Size(300, 300),
2777 typename
Types::ContentLayerType
* topmost
=
2778 this->CreateDrawingLayer(parent
,
2779 this->identity_matrix
,
2780 gfx::PointF(250.f
, 0.f
),
2784 AddOpacityTransitionToController(
2785 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2786 AddOpacityTransitionToController(
2787 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2788 this->CalcDrawEtc(parent
);
2790 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2791 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2792 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2794 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2795 typename
Types::RenderSurfaceType
> occlusion(
2796 gfx::Rect(0, 0, 1000, 1000));
2798 this->VisitLayer(topmost
, &occlusion
);
2799 this->EnterLayer(parent2
, &occlusion
);
2800 // This occlusion will affect all surfaces.
2801 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2802 occlusion
.occlusion_from_inside_target().ToString());
2803 EXPECT_EQ(gfx::Rect().ToString(),
2804 occlusion
.occlusion_from_outside_target().ToString());
2805 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2806 occlusion
.UnoccludedLayerContentRect(
2807 parent
, gfx::Rect(0, 0, 300, 300)));
2808 this->LeaveLayer(parent2
, &occlusion
);
2810 this->VisitLayer(surface_child2
, &occlusion
);
2811 this->EnterLayer(surface_child
, &occlusion
);
2812 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2813 occlusion
.occlusion_from_inside_target().ToString());
2814 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2815 occlusion
.occlusion_from_outside_target().ToString());
2816 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2817 occlusion
.UnoccludedLayerContentRect(
2818 surface_child
, gfx::Rect(0, 0, 200, 300)));
2819 this->LeaveLayer(surface_child
, &occlusion
);
2820 this->EnterLayer(surface
, &occlusion
);
2821 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2822 occlusion
.occlusion_from_inside_target().ToString());
2823 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2824 occlusion
.occlusion_from_outside_target().ToString());
2825 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2826 occlusion
.UnoccludedLayerContentRect(
2827 surface
, gfx::Rect(0, 0, 300, 300)));
2828 this->LeaveLayer(surface
, &occlusion
);
2830 this->EnterContributingSurface(surface
, &occlusion
);
2831 // Occlusion within the surface is lost when leaving the animating surface.
2832 EXPECT_EQ(gfx::Rect().ToString(),
2833 occlusion
.occlusion_from_inside_target().ToString());
2834 EXPECT_EQ(gfx::Rect().ToString(),
2835 occlusion
.occlusion_from_outside_target().ToString());
2836 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2837 occlusion
.UnoccludedContributingSurfaceContentRect(
2838 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
2839 this->LeaveContributingSurface(surface
, &occlusion
);
2841 // Occlusion from outside the animating surface still exists.
2842 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2843 occlusion
.occlusion_from_inside_target().ToString());
2844 EXPECT_EQ(gfx::Rect().ToString(),
2845 occlusion
.occlusion_from_outside_target().ToString());
2847 this->VisitLayer(layer
, &occlusion
);
2848 this->EnterLayer(parent
, &occlusion
);
2850 // Occlusion is not added for the animating |layer|.
2851 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2852 occlusion
.UnoccludedLayerContentRect(
2853 parent
, gfx::Rect(0, 0, 300, 300)));
2857 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2859 template <class Types
>
2860 class OcclusionTrackerTestAnimationTranslateOnMainThread
2861 : public OcclusionTrackerTest
<Types
> {
2863 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2865 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2867 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2868 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2869 typename
Types::ContentLayerType
* layer
=
2870 this->CreateDrawingLayer(parent
,
2871 this->identity_matrix
,
2873 gfx::Size(300, 300),
2875 typename
Types::ContentLayerType
* surface
=
2876 this->CreateDrawingSurface(parent
,
2877 this->identity_matrix
,
2879 gfx::Size(300, 300),
2881 typename
Types::ContentLayerType
* surface_child
=
2882 this->CreateDrawingLayer(surface
,
2883 this->identity_matrix
,
2885 gfx::Size(200, 300),
2887 typename
Types::ContentLayerType
* surface_child2
=
2888 this->CreateDrawingLayer(surface
,
2889 this->identity_matrix
,
2891 gfx::Size(100, 300),
2893 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
2894 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
2896 AddAnimatedTransformToController(
2897 layer
->layer_animation_controller(), 10.0, 30, 0);
2898 AddAnimatedTransformToController(
2899 surface
->layer_animation_controller(), 10.0, 30, 0);
2900 AddAnimatedTransformToController(
2901 surface_child
->layer_animation_controller(), 10.0, 30, 0);
2902 this->CalcDrawEtc(parent
);
2904 EXPECT_TRUE(layer
->draw_transform_is_animating());
2905 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
2907 surface
->render_surface()->target_surface_transforms_are_animating());
2909 surface
->render_surface()->screen_space_transforms_are_animating());
2910 // The surface owning layer doesn't animate against its own surface.
2911 EXPECT_FALSE(surface
->draw_transform_is_animating());
2912 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
2913 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
2914 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
2916 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2917 typename
Types::RenderSurfaceType
> occlusion(
2918 gfx::Rect(0, 0, 1000, 1000));
2920 this->VisitLayer(surface2
, &occlusion
);
2921 this->EnterContributingSurface(surface2
, &occlusion
);
2923 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2924 occlusion
.occlusion_from_inside_target().ToString());
2926 this->LeaveContributingSurface(surface2
, &occlusion
);
2927 this->EnterLayer(surface_child2
, &occlusion
);
2929 // surface_child2 is moving in screen space but not relative to its target,
2930 // so occlusion should happen in its target space only. It also means that
2931 // things occluding from outside the target (e.g. surface2) cannot occlude
2933 EXPECT_EQ(gfx::Rect().ToString(),
2934 occlusion
.occlusion_from_outside_target().ToString());
2936 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2937 occlusion
.UnoccludedLayerContentRect(
2938 surface_child2
, gfx::Rect(0, 0, 100, 300)));
2940 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2942 this->LeaveLayer(surface_child2
, &occlusion
);
2943 this->EnterLayer(surface_child
, &occlusion
);
2945 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 100, 300)));
2946 EXPECT_EQ(gfx::Rect().ToString(),
2947 occlusion
.occlusion_from_outside_target().ToString());
2948 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2949 occlusion
.occlusion_from_inside_target().ToString());
2950 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2951 occlusion
.UnoccludedLayerContentRect(
2952 surface
, gfx::Rect(0, 0, 300, 300)));
2954 // The surface_child is occluded by the surface_child2, but is moving
2955 // relative its target, so it can't be occluded.
2956 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2957 occlusion
.UnoccludedLayerContentRect(
2958 surface_child
, gfx::Rect(0, 0, 200, 300)));
2960 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2962 this->LeaveLayer(surface_child
, &occlusion
);
2963 this->EnterLayer(surface
, &occlusion
);
2964 // The surface_child is moving in screen space but not relative to its
2965 // target, so occlusion should happen from within the target only.
2966 EXPECT_EQ(gfx::Rect().ToString(),
2967 occlusion
.occlusion_from_outside_target().ToString());
2968 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2969 occlusion
.occlusion_from_inside_target().ToString());
2970 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2971 occlusion
.UnoccludedLayerContentRect(
2972 surface
, gfx::Rect(0, 0, 300, 300)));
2974 this->LeaveLayer(surface
, &occlusion
);
2975 // The surface's owning layer is moving in screen space but not relative to
2976 // its target, so occlusion should happen within the target only.
2977 EXPECT_EQ(gfx::Rect().ToString(),
2978 occlusion
.occlusion_from_outside_target().ToString());
2979 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2980 occlusion
.occlusion_from_inside_target().ToString());
2981 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2982 occlusion
.UnoccludedLayerContentRect(
2983 surface
, gfx::Rect(0, 0, 300, 300)));
2985 this->EnterContributingSurface(surface
, &occlusion
);
2986 // The contributing |surface| is animating so it can't be occluded.
2987 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2988 occlusion
.UnoccludedContributingSurfaceContentRect(
2989 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
2990 this->LeaveContributingSurface(surface
, &occlusion
);
2992 this->EnterLayer(layer
, &occlusion
);
2993 // The |surface| is moving in the screen and in its target, so all occlusion
2994 // within the surface is lost when leaving it.
2995 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2996 occlusion
.UnoccludedLayerContentRect(
2997 parent
, gfx::Rect(0, 0, 300, 300)));
2998 this->LeaveLayer(layer
, &occlusion
);
3000 this->EnterLayer(parent
, &occlusion
);
3001 // The |layer| is animating in the screen and in its target, so no occlusion
3003 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3004 occlusion
.UnoccludedLayerContentRect(
3005 parent
, gfx::Rect(0, 0, 300, 300)));
3009 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
3011 template <class Types
>
3012 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
3013 : public OcclusionTrackerTest
<Types
> {
3015 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
3017 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3019 gfx::Transform surface_transform
;
3020 surface_transform
.Translate(300.0, 300.0);
3021 surface_transform
.Scale(2.0, 2.0);
3022 surface_transform
.Translate(-150.0, -150.0);
3024 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3025 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
3026 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
3027 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
3028 typename
Types::ContentLayerType
* surface2
=
3029 this->CreateDrawingSurface(parent
,
3030 this->identity_matrix
,
3031 gfx::PointF(50.f
, 50.f
),
3032 gfx::Size(300, 300),
3034 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3035 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3036 this->CalcDrawEtc(parent
);
3038 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3039 typename
Types::RenderSurfaceType
> occlusion(
3040 gfx::Rect(0, 0, 1000, 1000));
3042 this->VisitLayer(surface2
, &occlusion
);
3043 this->VisitContributingSurface(surface2
, &occlusion
);
3045 EXPECT_EQ(gfx::Rect().ToString(),
3046 occlusion
.occlusion_from_outside_target().ToString());
3047 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
3048 occlusion
.occlusion_from_inside_target().ToString());
3050 // Clear any stored occlusion.
3051 occlusion
.set_occlusion_from_outside_target(Region());
3052 occlusion
.set_occlusion_from_inside_target(Region());
3054 this->VisitLayer(surface
, &occlusion
);
3055 this->VisitContributingSurface(surface
, &occlusion
);
3057 EXPECT_EQ(gfx::Rect().ToString(),
3058 occlusion
.occlusion_from_outside_target().ToString());
3059 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
3060 occlusion
.occlusion_from_inside_target().ToString());
3064 MAIN_AND_IMPL_THREAD_TEST(
3065 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
3067 template <class Types
>
3068 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
3069 : public OcclusionTrackerTest
<Types
> {
3071 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
3073 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3075 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3076 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
3077 parent
->SetMasksToBounds(true);
3078 typename
Types::ContentLayerType
* surface
=
3079 this->CreateDrawingSurface(parent
,
3080 this->identity_matrix
,
3082 gfx::Size(500, 300),
3084 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
3085 this->CalcDrawEtc(parent
);
3087 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3088 typename
Types::RenderSurfaceType
> occlusion(
3089 gfx::Rect(0, 0, 1000, 1000));
3091 this->VisitLayer(surface
, &occlusion
);
3092 this->VisitContributingSurface(surface
, &occlusion
);
3094 EXPECT_EQ(gfx::Rect().ToString(),
3095 occlusion
.occlusion_from_outside_target().ToString());
3096 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
3097 occlusion
.occlusion_from_inside_target().ToString());
3101 MAIN_AND_IMPL_THREAD_TEST(
3102 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
3104 template <class Types
>
3105 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
3107 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers
)
3108 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3110 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3111 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3112 typename
Types::LayerType
* surface
=
3113 this->CreateDrawingSurface(parent
,
3114 this->identity_matrix
,
3116 gfx::Size(100, 100),
3118 this->CreateReplicaLayer(surface
,
3119 this->identity_matrix
,
3120 gfx::PointF(0.f
, 100.f
),
3121 gfx::Size(100, 100));
3122 typename
Types::LayerType
* topmost
=
3123 this->CreateDrawingLayer(parent
,
3124 this->identity_matrix
,
3125 gfx::PointF(0.f
, 100.f
),
3126 gfx::Size(100, 100),
3128 this->CalcDrawEtc(parent
);
3130 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3131 typename
Types::RenderSurfaceType
> occlusion(
3132 gfx::Rect(0, 0, 1000, 1000));
3134 // |topmost| occludes the replica, but not the surface itself.
3135 this->VisitLayer(topmost
, &occlusion
);
3137 EXPECT_EQ(gfx::Rect().ToString(),
3138 occlusion
.occlusion_from_outside_target().ToString());
3139 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3140 occlusion
.occlusion_from_inside_target().ToString());
3142 this->VisitLayer(surface
, &occlusion
);
3144 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3145 occlusion
.occlusion_from_outside_target().ToString());
3146 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3147 occlusion
.occlusion_from_inside_target().ToString());
3149 this->EnterContributingSurface(surface
, &occlusion
);
3151 // Surface is not occluded so it shouldn't think it is.
3152 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3153 occlusion
.UnoccludedContributingSurfaceContentRect(
3154 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3158 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
3160 template <class Types
>
3161 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
3162 : public OcclusionTrackerTest
<Types
> {
3164 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
3165 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3167 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3168 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3169 typename
Types::LayerType
* surface
=
3170 this->CreateDrawingSurface(parent
,
3171 this->identity_matrix
,
3173 gfx::Size(100, 100),
3175 this->CreateReplicaLayer(surface
,
3176 this->identity_matrix
,
3177 gfx::PointF(0.f
, 100.f
),
3178 gfx::Size(100, 100));
3179 typename
Types::LayerType
* topmost
=
3180 this->CreateDrawingLayer(parent
,
3181 this->identity_matrix
,
3183 gfx::Size(100, 110),
3185 this->CalcDrawEtc(parent
);
3187 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3188 typename
Types::RenderSurfaceType
> occlusion(
3189 gfx::Rect(0, 0, 1000, 1000));
3191 // |topmost| occludes the surface, but not the entire surface's replica.
3192 this->VisitLayer(topmost
, &occlusion
);
3194 EXPECT_EQ(gfx::Rect().ToString(),
3195 occlusion
.occlusion_from_outside_target().ToString());
3196 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3197 occlusion
.occlusion_from_inside_target().ToString());
3199 this->VisitLayer(surface
, &occlusion
);
3201 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3202 occlusion
.occlusion_from_outside_target().ToString());
3203 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3204 occlusion
.occlusion_from_inside_target().ToString());
3206 this->EnterContributingSurface(surface
, &occlusion
);
3208 // Surface is occluded, but only the top 10px of the replica.
3209 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3210 occlusion
.UnoccludedContributingSurfaceContentRect(
3211 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3212 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
3213 occlusion
.UnoccludedContributingSurfaceContentRect(
3214 surface
, true, gfx::Rect(0, 0, 100, 100), NULL
));
3218 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
3220 template <class Types
>
3221 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
3222 : public OcclusionTrackerTest
<Types
> {
3224 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
3226 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3228 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3229 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3230 typename
Types::LayerType
* surface
=
3231 this->CreateDrawingSurface(parent
,
3232 this->identity_matrix
,
3234 gfx::Size(100, 100),
3236 this->CreateReplicaLayer(surface
,
3237 this->identity_matrix
,
3238 gfx::PointF(0.f
, 100.f
),
3239 gfx::Size(100, 100));
3240 typename
Types::LayerType
* over_surface
= this->CreateDrawingLayer(
3241 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 100), true);
3242 typename
Types::LayerType
* over_replica
=
3243 this->CreateDrawingLayer(parent
,
3244 this->identity_matrix
,
3245 gfx::PointF(0.f
, 100.f
),
3248 this->CalcDrawEtc(parent
);
3250 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3251 typename
Types::RenderSurfaceType
> occlusion(
3252 gfx::Rect(0, 0, 1000, 1000));
3254 // These occlude the surface and replica differently, so we can test each
3256 this->VisitLayer(over_replica
, &occlusion
);
3257 this->VisitLayer(over_surface
, &occlusion
);
3259 EXPECT_EQ(gfx::Rect().ToString(),
3260 occlusion
.occlusion_from_outside_target().ToString());
3261 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3263 occlusion
.occlusion_from_inside_target().ToString());
3265 this->VisitLayer(surface
, &occlusion
);
3267 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3269 occlusion
.occlusion_from_outside_target().ToString());
3270 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3271 occlusion
.occlusion_from_inside_target().ToString());
3273 this->EnterContributingSurface(surface
, &occlusion
);
3275 // Surface and replica are occluded different amounts.
3276 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
3277 occlusion
.UnoccludedContributingSurfaceContentRect(
3278 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3279 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
3280 occlusion
.UnoccludedContributingSurfaceContentRect(
3281 surface
, true, gfx::Rect(0, 0, 100, 100), NULL
));
3285 ALL_OCCLUSIONTRACKER_TEST(
3286 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
3288 template <class Types
>
3289 class OcclusionTrackerTestSurfaceChildOfSurface
3290 : public OcclusionTrackerTest
<Types
> {
3292 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
3293 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3295 // This test verifies that the surface cliprect does not end up empty and
3296 // clip away the entire unoccluded rect.
3298 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3299 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3300 typename
Types::LayerType
* surface
=
3301 this->CreateDrawingSurface(parent
,
3302 this->identity_matrix
,
3304 gfx::Size(100, 100),
3306 typename
Types::LayerType
* surface_child
=
3307 this->CreateDrawingSurface(surface
,
3308 this->identity_matrix
,
3309 gfx::PointF(0.f
, 10.f
),
3312 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
3313 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
3314 this->CalcDrawEtc(parent
);
3316 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3317 typename
Types::RenderSurfaceType
> occlusion(
3318 gfx::Rect(-100, -100, 1000, 1000));
3320 // |topmost| occludes everything partially so we know occlusion is happening
3322 this->VisitLayer(topmost
, &occlusion
);
3324 EXPECT_EQ(gfx::Rect().ToString(),
3325 occlusion
.occlusion_from_outside_target().ToString());
3326 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3327 occlusion
.occlusion_from_inside_target().ToString());
3329 this->VisitLayer(surface_child
, &occlusion
);
3331 // surface_child increases the occlusion in the screen by a narrow sliver.
3332 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
3333 occlusion
.occlusion_from_outside_target().ToString());
3334 // In its own surface, surface_child is at 0,0 as is its occlusion.
3335 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3336 occlusion
.occlusion_from_inside_target().ToString());
3338 // The root layer always has a clip rect. So the parent of |surface| has a
3339 // clip rect. However, the owning layer for |surface| does not mask to
3340 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3341 // |surface_child| exercises different code paths as its parent does not
3342 // have a clip rect.
3344 this->EnterContributingSurface(surface_child
, &occlusion
);
3345 // The surface_child's parent does not have a clip rect as it owns a render
3346 // surface. Make sure the unoccluded rect does not get clipped away
3348 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
3349 occlusion
.UnoccludedContributingSurfaceContentRect(
3350 surface_child
, false, gfx::Rect(0, 0, 100, 50), NULL
));
3351 this->LeaveContributingSurface(surface_child
, &occlusion
);
3353 // When the surface_child's occlusion is transformed up to its parent, make
3354 // sure it is not clipped away inappropriately also.
3355 this->EnterLayer(surface
, &occlusion
);
3356 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3357 occlusion
.occlusion_from_outside_target().ToString());
3358 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
3359 occlusion
.occlusion_from_inside_target().ToString());
3360 this->LeaveLayer(surface
, &occlusion
);
3362 this->EnterContributingSurface(surface
, &occlusion
);
3363 // The surface's parent does have a clip rect as it is the root layer.
3364 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
3365 occlusion
.UnoccludedContributingSurfaceContentRect(
3366 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3370 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
3372 template <class Types
>
3373 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
3374 : public OcclusionTrackerTest
<Types
> {
3376 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
3378 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3380 // This test verifies that the top-most surface is considered occluded
3381 // outside of its target's clip rect and outside the viewport rect.
3383 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3384 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3385 typename
Types::LayerType
* surface
=
3386 this->CreateDrawingSurface(parent
,
3387 this->identity_matrix
,
3389 gfx::Size(100, 300),
3391 this->CalcDrawEtc(parent
);
3393 // Make a viewport rect that is larger than the root layer.
3394 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3395 typename
Types::RenderSurfaceType
> occlusion(
3396 gfx::Rect(0, 0, 1000, 1000));
3398 this->VisitLayer(surface
, &occlusion
);
3400 // The root layer always has a clip rect. So the parent of |surface| has a
3401 // clip rect giving the surface itself a clip rect.
3402 this->EnterContributingSurface(surface
, &occlusion
);
3403 // Make sure the parent's clip rect clips the unoccluded region of the
3405 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
3406 occlusion
.UnoccludedContributingSurfaceContentRect(
3407 surface
, false, gfx::Rect(0, 0, 100, 300), NULL
));
3409 this->ResetLayerIterator();
3411 // Make a viewport rect that is smaller than the root layer.
3412 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3413 typename
Types::RenderSurfaceType
> occlusion(
3414 gfx::Rect(0, 0, 100, 100));
3416 this->VisitLayer(surface
, &occlusion
);
3418 // The root layer always has a clip rect. So the parent of |surface| has a
3419 // clip rect giving the surface itself a clip rect.
3420 this->EnterContributingSurface(surface
, &occlusion
);
3421 // Make sure the viewport rect clips the unoccluded region of the child
3423 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3424 occlusion
.UnoccludedContributingSurfaceContentRect(
3425 surface
, false, gfx::Rect(0, 0, 100, 300), NULL
));
3430 ALL_OCCLUSIONTRACKER_TEST(
3431 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
);
3433 template <class Types
>
3434 class OcclusionTrackerTestSurfaceChildOfClippingSurface
3435 : public OcclusionTrackerTest
<Types
> {
3437 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers
)
3438 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3440 // This test verifies that the surface cliprect does not end up empty and
3441 // clip away the entire unoccluded rect.
3443 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3444 this->identity_matrix
, gfx::PointF(), gfx::Size(80, 200));
3445 parent
->SetMasksToBounds(true);
3446 typename
Types::LayerType
* surface
=
3447 this->CreateDrawingSurface(parent
,
3448 this->identity_matrix
,
3450 gfx::Size(100, 100),
3452 typename
Types::LayerType
* surface_child
=
3453 this->CreateDrawingSurface(surface
,
3454 this->identity_matrix
,
3456 gfx::Size(100, 100),
3458 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
3459 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
3460 this->CalcDrawEtc(parent
);
3462 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3463 typename
Types::RenderSurfaceType
> occlusion(
3464 gfx::Rect(0, 0, 1000, 1000));
3466 // |topmost| occludes everything partially so we know occlusion is happening
3468 this->VisitLayer(topmost
, &occlusion
);
3470 EXPECT_EQ(gfx::Rect().ToString(),
3471 occlusion
.occlusion_from_outside_target().ToString());
3472 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3473 occlusion
.occlusion_from_inside_target().ToString());
3475 // surface_child is not opaque and does not occlude, so we have a non-empty
3476 // unoccluded area on surface.
3477 this->VisitLayer(surface_child
, &occlusion
);
3479 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3480 occlusion
.occlusion_from_outside_target().ToString());
3481 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3482 occlusion
.occlusion_from_inside_target().ToString());
3484 // The root layer always has a clip rect. So the parent of |surface| has a
3485 // clip rect. However, the owning layer for |surface| does not mask to
3486 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3487 // |surface_child| exercises different code paths as its parent does not
3488 // have a clip rect.
3490 this->EnterContributingSurface(surface_child
, &occlusion
);
3491 // The surface_child's parent does not have a clip rect as it owns a render
3494 gfx::Rect(0, 50, 80, 50).ToString(),
3495 occlusion
.UnoccludedContributingSurfaceContentRect(
3496 surface_child
, false, gfx::Rect(0, 0, 100, 100), NULL
).ToString());
3497 this->LeaveContributingSurface(surface_child
, &occlusion
);
3499 this->VisitLayer(surface
, &occlusion
);
3500 this->EnterContributingSurface(surface
, &occlusion
);
3501 // The surface's parent does have a clip rect as it is the root layer.
3502 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3503 occlusion
.UnoccludedContributingSurfaceContentRect(
3504 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
).ToString());
3508 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface
);
3510 template <class Types
>
3511 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3512 : public OcclusionTrackerTest
<Types
> {
3514 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3516 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3518 gfx::Transform scale_by_half
;
3519 scale_by_half
.Scale(0.5, 0.5);
3521 // Make a surface and its replica, each 50x50, that are completely
3522 // surrounded by opaque layers which are above them in the z-order. The
3523 // surface is scaled to test that the pixel moving is done in the target
3524 // space, where the background filter is applied, but the surface appears at
3525 // 50, 50 and the replica at 200, 50.
3526 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3527 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3528 typename
Types::LayerType
* filtered_surface
=
3529 this->CreateDrawingLayer(parent
,
3531 gfx::PointF(50.f
, 50.f
),
3532 gfx::Size(100, 100),
3534 this->CreateReplicaLayer(filtered_surface
,
3535 this->identity_matrix
,
3536 gfx::PointF(300.f
, 0.f
),
3538 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3539 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 50), true);
3540 typename
Types::LayerType
* occluding_layer2
=
3541 this->CreateDrawingLayer(parent
,
3542 this->identity_matrix
,
3543 gfx::PointF(0.f
, 100.f
),
3546 typename
Types::LayerType
* occluding_layer3
=
3547 this->CreateDrawingLayer(parent
,
3548 this->identity_matrix
,
3549 gfx::PointF(0.f
, 50.f
),
3552 typename
Types::LayerType
* occluding_layer4
=
3553 this->CreateDrawingLayer(parent
,
3554 this->identity_matrix
,
3555 gfx::PointF(100.f
, 50.f
),
3558 typename
Types::LayerType
* occluding_layer5
=
3559 this->CreateDrawingLayer(parent
,
3560 this->identity_matrix
,
3561 gfx::PointF(250.f
, 50.f
),
3565 // Filters make the layer own a surface.
3566 WebKit::WebFilterOperations filters
;
3567 filters
.append(WebKit::WebFilterOperation::createBlurFilter(10.f
));
3568 filtered_surface
->SetBackgroundFilters(filters
);
3570 // Save the distance of influence for the blur effect.
3571 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3572 filters
.getOutsets(outset_top
, outset_right
, outset_bottom
, outset_left
);
3574 this->CalcDrawEtc(parent
);
3576 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3577 typename
Types::RenderSurfaceType
> occlusion(
3578 gfx::Rect(0, 0, 1000, 1000));
3580 // These layers occlude pixels directly beside the filtered_surface. Because
3581 // filtered surface blends pixels in a radius, it will need to see some of
3582 // the pixels (up to radius far) underneath the occluding layers.
3583 this->VisitLayer(occluding_layer5
, &occlusion
);
3584 this->VisitLayer(occluding_layer4
, &occlusion
);
3585 this->VisitLayer(occluding_layer3
, &occlusion
);
3586 this->VisitLayer(occluding_layer2
, &occlusion
);
3587 this->VisitLayer(occluding_layer1
, &occlusion
);
3589 Region expected_occlusion
;
3590 expected_occlusion
.Union(gfx::Rect(0, 0, 300, 50));
3591 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3592 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3593 expected_occlusion
.Union(gfx::Rect(250, 50, 50, 50));
3594 expected_occlusion
.Union(gfx::Rect(0, 100, 300, 50));
3596 EXPECT_EQ(expected_occlusion
.ToString(),
3597 occlusion
.occlusion_from_inside_target().ToString());
3598 EXPECT_EQ(gfx::Rect().ToString(),
3599 occlusion
.occlusion_from_outside_target().ToString());
3601 this->VisitLayer(filtered_surface
, &occlusion
);
3603 // The filtered layer/replica does not occlude.
3604 Region expected_occlusion_outside_surface
;
3605 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 300, 50));
3606 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3607 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3608 expected_occlusion_outside_surface
.Union(gfx::Rect(200, 0, 50, 50));
3609 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 300, 50));
3611 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3612 occlusion
.occlusion_from_outside_target().ToString());
3613 EXPECT_EQ(gfx::Rect().ToString(),
3614 occlusion
.occlusion_from_inside_target().ToString());
3616 // The surface has a background blur, so it needs pixels that are currently
3617 // considered occluded in order to be drawn. So the pixels it needs should
3618 // be removed some the occluded area so that when we get to the parent they
3620 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3622 this->EnterLayer(parent
, &occlusion
);
3624 Region expected_blurred_occlusion
;
3625 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 300, 50 - outset_top
));
3626 expected_blurred_occlusion
.Union(gfx::Rect(
3627 0, 50 - outset_top
, 50 - outset_left
, 50 + outset_top
+ outset_bottom
));
3628 expected_blurred_occlusion
.Union(
3629 gfx::Rect(100 + outset_right
,
3631 100 - outset_right
- outset_left
,
3632 50 + outset_top
+ outset_bottom
));
3633 expected_blurred_occlusion
.Union(
3634 gfx::Rect(250 + outset_right
,
3637 50 + outset_top
+ outset_bottom
));
3638 expected_blurred_occlusion
.Union(
3639 gfx::Rect(0, 100 + outset_bottom
, 300, 50 - outset_bottom
));
3641 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3642 occlusion
.occlusion_from_inside_target().ToString());
3643 EXPECT_EQ(gfx::Rect().ToString(),
3644 occlusion
.occlusion_from_outside_target().ToString());
3646 gfx::Rect outset_rect
;
3647 gfx::Rect test_rect
;
3649 // Nothing in the blur outsets for the filtered_surface is occluded.
3650 outset_rect
= gfx::Rect(50 - outset_left
,
3652 50 + outset_left
+ outset_right
,
3653 50 + outset_top
+ outset_bottom
);
3654 test_rect
= outset_rect
;
3656 outset_rect
.ToString(),
3657 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3659 // Stuff outside the blur outsets is still occluded though.
3660 test_rect
= outset_rect
;
3661 test_rect
.Inset(0, 0, -1, 0);
3663 outset_rect
.ToString(),
3664 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3665 test_rect
= outset_rect
;
3666 test_rect
.Inset(0, 0, 0, -1);
3668 outset_rect
.ToString(),
3669 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3670 test_rect
= outset_rect
;
3671 test_rect
.Inset(-1, 0, 0, 0);
3673 outset_rect
.ToString(),
3674 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3675 test_rect
= outset_rect
;
3676 test_rect
.Inset(0, -1, 0, 0);
3678 outset_rect
.ToString(),
3679 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3681 // Nothing in the blur outsets for the filtered_surface's replica is
3683 outset_rect
= gfx::Rect(200 - outset_left
,
3685 50 + outset_left
+ outset_right
,
3686 50 + outset_top
+ outset_bottom
);
3687 test_rect
= outset_rect
;
3689 outset_rect
.ToString(),
3690 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3692 // Stuff outside the blur outsets is still occluded though.
3693 test_rect
= outset_rect
;
3694 test_rect
.Inset(0, 0, -1, 0);
3696 outset_rect
.ToString(),
3697 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3698 test_rect
= outset_rect
;
3699 test_rect
.Inset(0, 0, 0, -1);
3701 outset_rect
.ToString(),
3702 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3703 test_rect
= outset_rect
;
3704 test_rect
.Inset(-1, 0, 0, 0);
3706 outset_rect
.ToString(),
3707 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3708 test_rect
= outset_rect
;
3709 test_rect
.Inset(0, -1, 0, 0);
3711 outset_rect
.ToString(),
3712 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3716 ALL_OCCLUSIONTRACKER_TEST(
3717 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
3719 template <class Types
>
3720 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3721 : public OcclusionTrackerTest
<Types
> {
3723 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3725 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3727 gfx::Transform scale_by_half
;
3728 scale_by_half
.Scale(0.5, 0.5);
3730 // Makes two surfaces that completely cover |parent|. The occlusion both
3731 // above and below the filters will be reduced by each of them.
3732 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3733 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
3734 typename
Types::LayerType
* parent
= this->CreateSurface(
3735 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
3736 parent
->SetMasksToBounds(true);
3737 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
3738 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3739 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
3740 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3741 typename
Types::LayerType
* occluding_layer_above
=
3742 this->CreateDrawingLayer(parent
,
3743 this->identity_matrix
,
3744 gfx::PointF(100.f
, 100.f
),
3748 // Filters make the layers own surfaces.
3749 WebKit::WebFilterOperations filters
;
3750 filters
.append(WebKit::WebFilterOperation::createBlurFilter(1.f
));
3751 filtered_surface1
->SetBackgroundFilters(filters
);
3752 filtered_surface2
->SetBackgroundFilters(filters
);
3754 // Save the distance of influence for the blur effect.
3755 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3756 filters
.getOutsets(outset_top
, outset_right
, outset_bottom
, outset_left
);
3758 this->CalcDrawEtc(root
);
3760 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3761 typename
Types::RenderSurfaceType
> occlusion(
3762 gfx::Rect(0, 0, 1000, 1000));
3764 this->VisitLayer(occluding_layer_above
, &occlusion
);
3765 EXPECT_EQ(gfx::Rect().ToString(),
3766 occlusion
.occlusion_from_outside_target().ToString());
3767 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3768 occlusion
.occlusion_from_inside_target().ToString());
3770 this->VisitLayer(filtered_surface2
, &occlusion
);
3771 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
3772 this->VisitLayer(filtered_surface1
, &occlusion
);
3773 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
3775 // Test expectations in the target.
3776 gfx::Rect expected_occlusion
=
3777 gfx::Rect(100 / 2 + outset_right
* 2,
3778 100 / 2 + outset_bottom
* 2,
3779 50 / 2 - (outset_left
+ outset_right
) * 2,
3780 50 / 2 - (outset_top
+ outset_bottom
) * 2);
3781 EXPECT_EQ(expected_occlusion
.ToString(),
3782 occlusion
.occlusion_from_inside_target().ToString());
3784 // Test expectations in the screen are the same as in the target, as the
3785 // render surface is 1:1 with the screen.
3786 EXPECT_EQ(expected_occlusion
.ToString(),
3787 occlusion
.occlusion_from_outside_target().ToString());
3791 ALL_OCCLUSIONTRACKER_TEST(
3792 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
3794 template <class Types
>
3795 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
3796 : public OcclusionTrackerTest
<Types
> {
3799 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(
3801 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3803 // Make a surface and its replica, Each 50x50, that are completely
3804 // surrounded by opaque layers which are above them in the z-order.
3805 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3806 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3807 // We stick the filtered surface inside a clipping surface so that we can
3808 // make sure the clip is honored when exposing pixels for
3809 // the background filter.
3810 typename
Types::LayerType
* clipping_surface
=
3811 this->CreateDrawingSurface(parent
,
3812 this->identity_matrix
,
3816 clipping_surface
->SetMasksToBounds(true);
3817 typename
Types::LayerType
* filtered_surface
=
3818 this->CreateDrawingLayer(clipping_surface
,
3819 this->identity_matrix
,
3820 gfx::PointF(50.f
, 50.f
),
3823 this->CreateReplicaLayer(filtered_surface
,
3824 this->identity_matrix
,
3825 gfx::PointF(150.f
, 0.f
),
3827 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3828 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 50), true);
3829 typename
Types::LayerType
* occluding_layer2
=
3830 this->CreateDrawingLayer(parent
,
3831 this->identity_matrix
,
3832 gfx::PointF(0.f
, 100.f
),
3835 typename
Types::LayerType
* occluding_layer3
=
3836 this->CreateDrawingLayer(parent
,
3837 this->identity_matrix
,
3838 gfx::PointF(0.f
, 50.f
),
3841 typename
Types::LayerType
* occluding_layer4
=
3842 this->CreateDrawingLayer(parent
,
3843 this->identity_matrix
,
3844 gfx::PointF(100.f
, 50.f
),
3847 typename
Types::LayerType
* occluding_layer5
=
3848 this->CreateDrawingLayer(parent
,
3849 this->identity_matrix
,
3850 gfx::PointF(250.f
, 50.f
),
3854 // Filters make the layer own a surface. This filter is large enough that it
3855 // goes outside the bottom of the clipping_surface.
3856 WebKit::WebFilterOperations filters
;
3857 filters
.append(WebKit::WebFilterOperation::createBlurFilter(12.f
));
3858 filtered_surface
->SetBackgroundFilters(filters
);
3860 // Save the distance of influence for the blur effect.
3861 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3862 filters
.getOutsets(outset_top
, outset_right
, outset_bottom
, outset_left
);
3864 this->CalcDrawEtc(parent
);
3866 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3867 typename
Types::RenderSurfaceType
> occlusion(
3868 gfx::Rect(0, 0, 1000, 1000));
3870 // These layers occlude pixels directly beside the filtered_surface. Because
3871 // filtered surface blends pixels in a radius, it will need to see some of
3872 // the pixels (up to radius far) underneath the occluding layers.
3873 this->VisitLayer(occluding_layer5
, &occlusion
);
3874 this->VisitLayer(occluding_layer4
, &occlusion
);
3875 this->VisitLayer(occluding_layer3
, &occlusion
);
3876 this->VisitLayer(occluding_layer2
, &occlusion
);
3877 this->VisitLayer(occluding_layer1
, &occlusion
);
3879 Region expected_occlusion
;
3880 expected_occlusion
.Union(gfx::Rect(0, 0, 300, 50));
3881 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3882 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3883 expected_occlusion
.Union(gfx::Rect(250, 50, 50, 50));
3884 expected_occlusion
.Union(gfx::Rect(0, 100, 300, 50));
3886 EXPECT_EQ(expected_occlusion
.ToString(),
3887 occlusion
.occlusion_from_inside_target().ToString());
3888 EXPECT_EQ(gfx::Rect().ToString(),
3889 occlusion
.occlusion_from_outside_target().ToString());
3891 // Everything outside the surface/replica is occluded but the
3892 // surface/replica itself is not.
3893 this->VisitLayer(filtered_surface
, &occlusion
);
3895 // The filtered layer/replica does not occlude.
3896 Region expected_occlusion_outside_surface
;
3897 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 300, 50));
3898 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3899 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3900 expected_occlusion_outside_surface
.Union(gfx::Rect(200, 0, 50, 50));
3901 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 300, 50));
3903 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3904 occlusion
.occlusion_from_outside_target().ToString());
3905 EXPECT_EQ(gfx::Rect().ToString(),
3906 occlusion
.occlusion_from_inside_target().ToString());
3908 // The surface has a background blur, so it needs pixels that are currently
3909 // considered occluded in order to be drawn. So the pixels it needs should
3910 // be removed some the occluded area so that when we get to the parent they
3912 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3914 this->VisitLayer(clipping_surface
, &occlusion
);
3915 this->EnterContributingSurface(clipping_surface
, &occlusion
);
3917 Region expected_blurred_occlusion
;
3918 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 300, 50 - outset_top
));
3919 expected_blurred_occlusion
.Union(gfx::Rect(
3920 0, 50 - outset_top
, 50 - outset_left
, 20 + outset_top
+ outset_bottom
));
3921 expected_blurred_occlusion
.Union(
3922 gfx::Rect(100 + outset_right
,
3924 100 - outset_right
- outset_left
,
3925 20 + outset_top
+ outset_bottom
));
3926 expected_blurred_occlusion
.Union(
3927 gfx::Rect(250 + outset_right
,
3930 20 + outset_top
+ outset_bottom
));
3931 expected_blurred_occlusion
.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
3933 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3934 occlusion
.occlusion_from_outside_target().ToString());
3935 EXPECT_EQ(gfx::Rect().ToString(),
3936 occlusion
.occlusion_from_inside_target().ToString());
3938 gfx::Rect outset_rect
;
3939 gfx::Rect clipped_outset_rect
;
3940 gfx::Rect test_rect
;
3942 // Nothing in the (clipped) blur outsets for the filtered_surface is
3944 outset_rect
= gfx::Rect(50 - outset_left
,
3946 50 + outset_left
+ outset_right
,
3947 50 + outset_top
+ outset_bottom
);
3948 clipped_outset_rect
= outset_rect
;
3949 clipped_outset_rect
.Intersect(gfx::Rect(0 - outset_left
,
3951 300 + outset_left
+ outset_right
,
3952 70 + outset_top
+ outset_bottom
));
3953 clipped_outset_rect
.Intersect(gfx::Rect(0, 0, 300, 70));
3954 test_rect
= outset_rect
;
3956 clipped_outset_rect
,
3957 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3959 // Stuff outside the (clipped) blur outsets is still occluded though.
3960 test_rect
= outset_rect
;
3961 test_rect
.Inset(0, 0, -1, 0);
3963 clipped_outset_rect
,
3964 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3965 test_rect
= outset_rect
;
3966 test_rect
.Inset(0, 0, 0, -1);
3968 clipped_outset_rect
,
3969 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3970 test_rect
= outset_rect
;
3971 test_rect
.Inset(-1, 0, 0, 0);
3973 clipped_outset_rect
,
3974 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3975 test_rect
= outset_rect
;
3976 test_rect
.Inset(0, -1, 0, 0);
3978 clipped_outset_rect
,
3979 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3981 // Nothing in the (clipped) blur outsets for the filtered_surface's replica
3983 outset_rect
= gfx::Rect(200 - outset_left
,
3985 50 + outset_left
+ outset_right
,
3986 50 + outset_top
+ outset_bottom
);
3987 clipped_outset_rect
= outset_rect
;
3988 clipped_outset_rect
.Intersect(gfx::Rect(0 - outset_left
,
3990 300 + outset_left
+ outset_right
,
3991 70 + outset_top
+ outset_bottom
));
3992 clipped_outset_rect
.Intersect(gfx::Rect(0, 0, 300, 70));
3993 test_rect
= outset_rect
;
3995 clipped_outset_rect
,
3996 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3998 // Stuff outside the (clipped) blur outsets is still occluded though.
3999 test_rect
= outset_rect
;
4000 test_rect
.Inset(0, 0, -1, 0);
4002 clipped_outset_rect
,
4003 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4004 test_rect
= outset_rect
;
4005 test_rect
.Inset(0, 0, 0, -1);
4007 clipped_outset_rect
,
4008 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4009 test_rect
= outset_rect
;
4010 test_rect
.Inset(-1, 0, 0, 0);
4012 clipped_outset_rect
,
4013 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4014 test_rect
= outset_rect
;
4015 test_rect
.Inset(0, -1, 0, 0);
4017 clipped_outset_rect
,
4018 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4022 ALL_OCCLUSIONTRACKER_TEST(
4023 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
);
4025 template <class Types
>
4026 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
4027 : public OcclusionTrackerTest
<Types
> {
4029 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
4031 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4033 gfx::Transform scale_by_half
;
4034 scale_by_half
.Scale(0.5, 0.5);
4036 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
4037 // centered below each. The surface is scaled to test that the pixel moving
4038 // is done in the target space, where the background filter is applied, but
4039 // the surface appears at 50, 50 and the replica at 200, 50.
4040 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4041 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4042 typename
Types::LayerType
* behind_surface_layer
=
4043 this->CreateDrawingLayer(parent
,
4044 this->identity_matrix
,
4045 gfx::PointF(60.f
, 60.f
),
4048 typename
Types::LayerType
* behind_replica_layer
=
4049 this->CreateDrawingLayer(parent
,
4050 this->identity_matrix
,
4051 gfx::PointF(210.f
, 60.f
),
4054 typename
Types::LayerType
* filtered_surface
=
4055 this->CreateDrawingLayer(parent
,
4057 gfx::PointF(50.f
, 50.f
),
4058 gfx::Size(100, 100),
4060 this->CreateReplicaLayer(filtered_surface
,
4061 this->identity_matrix
,
4062 gfx::PointF(300.f
, 0.f
),
4065 // Filters make the layer own a surface.
4066 WebKit::WebFilterOperations filters
;
4067 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3.f
));
4068 filtered_surface
->SetBackgroundFilters(filters
);
4070 this->CalcDrawEtc(parent
);
4072 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4073 typename
Types::RenderSurfaceType
> occlusion(
4074 gfx::Rect(0, 0, 1000, 1000));
4076 // The surface has a background blur, so it blurs non-opaque pixels below
4078 this->VisitLayer(filtered_surface
, &occlusion
);
4079 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4081 this->VisitLayer(behind_replica_layer
, &occlusion
);
4082 this->VisitLayer(behind_surface_layer
, &occlusion
);
4084 // The layers behind the surface are not blurred, and their occlusion does
4085 // not change, until we leave the surface. So it should not be modified by
4087 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
4088 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
4090 Region expected_opaque_bounds
=
4091 UnionRegions(occlusion_behind_surface
, occlusion_behind_replica
);
4092 EXPECT_EQ(expected_opaque_bounds
.ToString(),
4093 occlusion
.occlusion_from_inside_target().ToString());
4095 EXPECT_EQ(gfx::Rect().ToString(),
4096 occlusion
.occlusion_from_outside_target().ToString());
4100 ALL_OCCLUSIONTRACKER_TEST(
4101 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
4103 template <class Types
>
4104 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
4105 : public OcclusionTrackerTest
<Types
> {
4107 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
4109 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4111 gfx::Transform scale_by_half
;
4112 scale_by_half
.Scale(0.5, 0.5);
4114 // Make a surface and its replica, each 50x50, that are completely occluded
4115 // by opaque layers which are above them in the z-order. The surface is
4116 // scaled to test that the pixel moving is done in the target space, where
4117 // the background filter is applied, but the surface appears at 50, 50 and
4118 // the replica at 200, 50.
4119 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4120 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4121 typename
Types::LayerType
* filtered_surface
=
4122 this->CreateDrawingLayer(parent
,
4124 gfx::PointF(50.f
, 50.f
),
4125 gfx::Size(100, 100),
4127 this->CreateReplicaLayer(filtered_surface
,
4128 this->identity_matrix
,
4129 gfx::PointF(300.f
, 0.f
),
4131 typename
Types::LayerType
* above_surface_layer
=
4132 this->CreateDrawingLayer(parent
,
4133 this->identity_matrix
,
4134 gfx::PointF(50.f
, 50.f
),
4137 typename
Types::LayerType
* above_replica_layer
=
4138 this->CreateDrawingLayer(parent
,
4139 this->identity_matrix
,
4140 gfx::PointF(200.f
, 50.f
),
4144 // Filters make the layer own a surface.
4145 WebKit::WebFilterOperations filters
;
4146 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3.f
));
4147 filtered_surface
->SetBackgroundFilters(filters
);
4149 this->CalcDrawEtc(parent
);
4151 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4152 typename
Types::RenderSurfaceType
> occlusion(
4153 gfx::Rect(0, 0, 1000, 1000));
4155 this->VisitLayer(above_replica_layer
, &occlusion
);
4156 this->VisitLayer(above_surface_layer
, &occlusion
);
4158 this->VisitLayer(filtered_surface
, &occlusion
);
4160 // The layers above the filtered surface occlude from outside.
4161 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
4162 gfx::Rect occlusion_above_replica
= gfx::Rect(150, 0, 50, 50);
4163 Region expected_opaque_region
=
4164 UnionRegions(occlusion_above_surface
, occlusion_above_replica
);
4166 EXPECT_EQ(gfx::Rect().ToString(),
4167 occlusion
.occlusion_from_inside_target().ToString());
4168 EXPECT_EQ(expected_opaque_region
.ToString(),
4169 occlusion
.occlusion_from_outside_target().ToString());
4172 // The surface has a background blur, so it blurs non-opaque pixels below
4174 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4176 // The filter is completely occluded, so it should not blur anything and
4177 // reduce any occlusion.
4178 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
4179 gfx::Rect occlusion_above_replica
= gfx::Rect(200, 50, 50, 50);
4180 Region expected_opaque_region
=
4181 UnionRegions(occlusion_above_surface
, occlusion_above_replica
);
4183 EXPECT_EQ(expected_opaque_region
.ToString(),
4184 occlusion
.occlusion_from_inside_target().ToString());
4185 EXPECT_EQ(gfx::Rect().ToString(),
4186 occlusion
.occlusion_from_outside_target().ToString());
4191 ALL_OCCLUSIONTRACKER_TEST(
4192 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
4194 template <class Types
>
4195 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
4196 : public OcclusionTrackerTest
<Types
> {
4199 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
4201 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4203 gfx::Transform scale_by_half
;
4204 scale_by_half
.Scale(0.5, 0.5);
4206 // Make a surface and its replica, each 50x50, that are partially occluded
4207 // by opaque layers which are above them in the z-order. The surface is
4208 // scaled to test that the pixel moving is done in the target space, where
4209 // the background filter is applied, but the surface appears at 50, 50 and
4210 // the replica at 200, 50.
4211 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4212 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4213 typename
Types::LayerType
* filtered_surface
=
4214 this->CreateDrawingLayer(parent
,
4216 gfx::PointF(50.f
, 50.f
),
4217 gfx::Size(100, 100),
4219 this->CreateReplicaLayer(filtered_surface
,
4220 this->identity_matrix
,
4221 gfx::PointF(300.f
, 0.f
),
4223 typename
Types::LayerType
* above_surface_layer
=
4224 this->CreateDrawingLayer(parent
,
4225 this->identity_matrix
,
4226 gfx::PointF(70.f
, 50.f
),
4229 typename
Types::LayerType
* above_replica_layer
=
4230 this->CreateDrawingLayer(parent
,
4231 this->identity_matrix
,
4232 gfx::PointF(200.f
, 50.f
),
4235 typename
Types::LayerType
* beside_surface_layer
=
4236 this->CreateDrawingLayer(parent
,
4237 this->identity_matrix
,
4238 gfx::PointF(90.f
, 40.f
),
4241 typename
Types::LayerType
* beside_replica_layer
=
4242 this->CreateDrawingLayer(parent
,
4243 this->identity_matrix
,
4244 gfx::PointF(200.f
, 40.f
),
4248 // Filters make the layer own a surface.
4249 WebKit::WebFilterOperations filters
;
4250 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3.f
));
4251 filtered_surface
->SetBackgroundFilters(filters
);
4253 // Save the distance of influence for the blur effect.
4254 int outset_top
, outset_right
, outset_bottom
, outset_left
;
4255 filters
.getOutsets(outset_top
, outset_right
, outset_bottom
, outset_left
);
4257 this->CalcDrawEtc(parent
);
4259 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4260 typename
Types::RenderSurfaceType
> occlusion(
4261 gfx::Rect(0, 0, 1000, 1000));
4263 this->VisitLayer(beside_replica_layer
, &occlusion
);
4264 this->VisitLayer(beside_surface_layer
, &occlusion
);
4265 this->VisitLayer(above_replica_layer
, &occlusion
);
4266 this->VisitLayer(above_surface_layer
, &occlusion
);
4268 // The surface has a background blur, so it blurs non-opaque pixels below
4270 this->VisitLayer(filtered_surface
, &occlusion
);
4271 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4273 // The filter in the surface and replica are partially unoccluded. Only the
4274 // unoccluded parts should reduce occlusion. This means it will push back
4275 // the occlusion that touches the unoccluded part (occlusion_above___), but
4276 // it will not touch occlusion_beside____ since that is not beside the
4277 // unoccluded part of the surface, even though it is beside the occluded
4278 // part of the surface.
4279 gfx::Rect occlusion_above_surface
=
4280 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
4281 gfx::Rect occlusion_above_replica
=
4282 gfx::Rect(200, 50, 30 - outset_left
, 50);
4283 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
4284 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
4286 Region expected_occlusion
;
4287 expected_occlusion
.Union(occlusion_above_surface
);
4288 expected_occlusion
.Union(occlusion_above_replica
);
4289 expected_occlusion
.Union(occlusion_beside_surface
);
4290 expected_occlusion
.Union(occlusion_beside_replica
);
4292 ASSERT_EQ(expected_occlusion
.ToString(),
4293 occlusion
.occlusion_from_inside_target().ToString());
4294 EXPECT_EQ(gfx::Rect().ToString(),
4295 occlusion
.occlusion_from_outside_target().ToString());
4297 Region::Iterator
expected_rects(expected_occlusion
);
4298 Region::Iterator
target_surface_rects(
4299 occlusion
.occlusion_from_inside_target());
4300 for (; expected_rects
.has_rect();
4301 expected_rects
.next(), target_surface_rects
.next()) {
4302 ASSERT_TRUE(target_surface_rects
.has_rect());
4303 EXPECT_EQ(expected_rects
.rect(), target_surface_rects
.rect());
4308 ALL_OCCLUSIONTRACKER_TEST(
4309 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
4311 template <class Types
>
4312 class OcclusionTrackerTestMinimumTrackingSize
4313 : public OcclusionTrackerTest
<Types
> {
4315 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
4316 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4318 gfx::Size
tracking_size(100, 100);
4319 gfx::Size
below_tracking_size(99, 99);
4321 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4322 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4323 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
4324 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
4325 typename
Types::LayerType
* small
=
4326 this->CreateDrawingLayer(parent
,
4327 this->identity_matrix
,
4329 below_tracking_size
,
4331 this->CalcDrawEtc(parent
);
4333 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4334 typename
Types::RenderSurfaceType
> occlusion(
4335 gfx::Rect(0, 0, 1000, 1000));
4336 occlusion
.set_minimum_tracking_size(tracking_size
);
4338 // The small layer is not tracked because it is too small.
4339 this->VisitLayer(small
, &occlusion
);
4341 EXPECT_EQ(gfx::Rect().ToString(),
4342 occlusion
.occlusion_from_outside_target().ToString());
4343 EXPECT_EQ(gfx::Rect().ToString(),
4344 occlusion
.occlusion_from_inside_target().ToString());
4346 // The large layer is tracked as it is large enough.
4347 this->VisitLayer(large
, &occlusion
);
4349 EXPECT_EQ(gfx::Rect().ToString(),
4350 occlusion
.occlusion_from_outside_target().ToString());
4351 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
4352 occlusion
.occlusion_from_inside_target().ToString());
4356 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
4358 template <class Types
>
4359 class OcclusionTrackerTestViewportClipIsExternalOcclusion
4360 : public OcclusionTrackerTest
<Types
> {
4362 explicit OcclusionTrackerTestViewportClipIsExternalOcclusion(
4364 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4366 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4367 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4368 typename
Types::LayerType
* small
=
4369 this->CreateDrawingSurface(parent
,
4370 this->identity_matrix
,
4372 gfx::Size(200, 200),
4374 typename
Types::LayerType
* large
=
4375 this->CreateDrawingLayer(small
,
4376 this->identity_matrix
,
4378 gfx::Size(400, 400),
4380 small
->SetMasksToBounds(true);
4381 this->CalcDrawEtc(parent
);
4383 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4384 typename
Types::RenderSurfaceType
> occlusion(
4385 gfx::Rect(0, 0, 100, 100));
4387 this->EnterLayer(large
, &occlusion
);
4389 bool has_occlusion_from_outside_target_surface
= false;
4390 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4391 occlusion
.UnoccludedLayerContentRect(
4393 gfx::Rect(0, 0, 400, 400),
4394 &has_occlusion_from_outside_target_surface
));
4395 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4397 has_occlusion_from_outside_target_surface
= false;
4399 occlusion
.OccludedLayer(large
,
4400 gfx::Rect(0, 0, 400, 400),
4401 &has_occlusion_from_outside_target_surface
));
4402 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4404 this->LeaveLayer(large
, &occlusion
);
4405 this->VisitLayer(small
, &occlusion
);
4407 has_occlusion_from_outside_target_surface
= false;
4408 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4409 occlusion
.UnoccludedLayerContentRect(
4411 gfx::Rect(0, 0, 200, 200),
4412 &has_occlusion_from_outside_target_surface
));
4413 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4415 has_occlusion_from_outside_target_surface
= false;
4417 occlusion
.OccludedLayer(small
,
4418 gfx::Rect(0, 0, 200, 200),
4419 &has_occlusion_from_outside_target_surface
));
4420 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4422 this->EnterContributingSurface(small
, &occlusion
);
4424 has_occlusion_from_outside_target_surface
= false;
4425 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4426 occlusion
.UnoccludedContributingSurfaceContentRect(
4429 gfx::Rect(0, 0, 200, 200),
4430 &has_occlusion_from_outside_target_surface
));
4431 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4435 ALL_OCCLUSIONTRACKER_TEST(
4436 OcclusionTrackerTestViewportClipIsExternalOcclusion
)
4438 template <class Types
>
4439 class OcclusionTrackerTestLayerClipIsExternalOcclusion
4440 : public OcclusionTrackerTest
<Types
> {
4442 explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers
)
4443 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4445 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4446 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4447 typename
Types::LayerType
* smallest
= this->CreateDrawingLayer(
4448 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4449 typename
Types::LayerType
* smaller
=
4450 this->CreateDrawingSurface(smallest
,
4451 this->identity_matrix
,
4453 gfx::Size(100, 100),
4455 typename
Types::LayerType
* small
=
4456 this->CreateDrawingSurface(smaller
,
4457 this->identity_matrix
,
4459 gfx::Size(200, 200),
4461 typename
Types::LayerType
* large
=
4462 this->CreateDrawingLayer(small
,
4463 this->identity_matrix
,
4465 gfx::Size(400, 400),
4467 smallest
->SetMasksToBounds(true);
4468 smaller
->SetMasksToBounds(true);
4469 small
->SetMasksToBounds(true);
4470 this->CalcDrawEtc(parent
);
4472 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4473 typename
Types::RenderSurfaceType
> occlusion(
4474 gfx::Rect(0, 0, 1000, 1000));
4476 this->EnterLayer(large
, &occlusion
);
4478 // Clipping from the smaller layer is from outside the target surface.
4479 bool has_occlusion_from_outside_target_surface
= false;
4480 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4481 occlusion
.UnoccludedLayerContentRect(
4483 gfx::Rect(0, 0, 400, 400),
4484 &has_occlusion_from_outside_target_surface
));
4485 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4487 has_occlusion_from_outside_target_surface
= false;
4489 occlusion
.OccludedLayer(large
,
4490 gfx::Rect(0, 0, 400, 400),
4491 &has_occlusion_from_outside_target_surface
));
4492 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4494 this->LeaveLayer(large
, &occlusion
);
4495 this->VisitLayer(small
, &occlusion
);
4497 // Clipping from the smaller layer is from outside the target surface.
4498 has_occlusion_from_outside_target_surface
= false;
4499 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4500 occlusion
.UnoccludedLayerContentRect(
4502 gfx::Rect(0, 0, 200, 200),
4503 &has_occlusion_from_outside_target_surface
));
4504 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4506 has_occlusion_from_outside_target_surface
= false;
4508 occlusion
.OccludedLayer(small
,
4509 gfx::Rect(0, 0, 200, 200),
4510 &has_occlusion_from_outside_target_surface
));
4511 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4513 this->EnterContributingSurface(small
, &occlusion
);
4515 // The |small| surface is clipped from outside its target by |smallest|.
4516 has_occlusion_from_outside_target_surface
= false;
4517 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4518 occlusion
.UnoccludedContributingSurfaceContentRect(
4521 gfx::Rect(0, 0, 200, 200),
4522 &has_occlusion_from_outside_target_surface
));
4523 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4525 this->LeaveContributingSurface(small
, &occlusion
);
4526 this->VisitLayer(smaller
, &occlusion
);
4527 this->EnterContributingSurface(smaller
, &occlusion
);
4529 // The |smaller| surface is clipped from inside its target by |smallest|.
4530 has_occlusion_from_outside_target_surface
= false;
4531 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4532 occlusion
.UnoccludedContributingSurfaceContentRect(
4535 gfx::Rect(0, 0, 100, 100),
4536 &has_occlusion_from_outside_target_surface
));
4537 EXPECT_FALSE(has_occlusion_from_outside_target_surface
);
4541 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion
)