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/output/copy_output_request.h"
13 #include "cc/output/copy_output_result.h"
14 #include "cc/output/filter_operation.h"
15 #include "cc/output/filter_operations.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_impl_proxy.h"
18 #include "cc/test/fake_layer_tree_host.h"
19 #include "cc/test/fake_layer_tree_host_impl.h"
20 #include "cc/test/geometry_test_utils.h"
21 #include "cc/test/occlusion_tracker_test_common.h"
22 #include "cc/trees/layer_tree_host_common.h"
23 #include "cc/trees/single_thread_proxy.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/transform.h"
31 class TestContentLayer
: public Layer
{
33 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {}
35 virtual bool DrawsContent() const OVERRIDE
{ return true; }
36 virtual Region
VisibleContentOpaqueRegion() const OVERRIDE
{
37 if (override_opaque_contents_rect_
)
38 return gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect());
39 return Layer::VisibleContentOpaqueRegion();
41 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect
) {
42 override_opaque_contents_rect_
= true;
43 opaque_contents_rect_
= opaque_contents_rect
;
47 virtual ~TestContentLayer() {}
49 bool override_opaque_contents_rect_
;
50 gfx::Rect opaque_contents_rect_
;
53 class TestContentLayerImpl
: public LayerImpl
{
55 TestContentLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
56 : LayerImpl(tree_impl
, id
), override_opaque_contents_rect_(false) {
57 SetDrawsContent(true);
60 virtual Region
VisibleContentOpaqueRegion() const OVERRIDE
{
61 if (override_opaque_contents_rect_
)
62 return gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect());
63 return LayerImpl::VisibleContentOpaqueRegion();
65 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect
) {
66 override_opaque_contents_rect_
= true;
67 opaque_contents_rect_
= opaque_contents_rect
;
71 bool override_opaque_contents_rect_
;
72 gfx::Rect opaque_contents_rect_
;
75 static inline bool LayerImplDrawTransformIsUnknown(const Layer
* layer
) {
76 return layer
->draw_transform_is_animating();
78 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl
* layer
) {
82 template <typename LayerType
, typename RenderSurfaceType
>
83 class TestOcclusionTrackerWithClip
84 : public TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
> {
86 TestOcclusionTrackerWithClip(gfx::Rect viewport_rect
,
87 bool record_metrics_for_frame
)
88 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(
90 record_metrics_for_frame
) {}
91 explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect
)
92 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(viewport_rect
,
95 bool OccludedLayer(const LayerType
* layer
, gfx::Rect content_rect
) {
97 return OccludedLayer(layer
, content_rect
, &temp
);
100 bool OccludedLayer(const LayerType
* layer
,
101 gfx::Rect content_rect
,
102 bool* has_occlusion_from_outside_target_surface
) const {
103 return this->Occluded(layer
->render_target(),
105 layer
->draw_transform(),
106 LayerImplDrawTransformIsUnknown(layer
),
109 has_occlusion_from_outside_target_surface
);
111 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
112 // layer. Simple wrapper around UnoccludedContentRect.
113 gfx::Rect
UnoccludedLayerContentRect(const LayerType
* layer
,
114 gfx::Rect content_rect
) const {
116 return UnoccludedLayerContentRect(layer
, content_rect
, &temp
);
119 gfx::Rect
UnoccludedLayerContentRect(
120 const LayerType
* layer
,
121 gfx::Rect content_rect
,
122 bool* has_occlusion_from_outside_target_surface
) const {
123 return this->UnoccludedContentRect(
124 layer
->render_target(),
126 layer
->draw_transform(),
127 LayerImplDrawTransformIsUnknown(layer
),
130 has_occlusion_from_outside_target_surface
);
134 struct OcclusionTrackerTestMainThreadTypes
{
135 typedef Layer LayerType
;
136 typedef FakeLayerTreeHost HostType
;
137 typedef RenderSurface RenderSurfaceType
;
138 typedef TestContentLayer ContentLayerType
;
139 typedef scoped_refptr
<Layer
> LayerPtrType
;
140 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
141 typedef LayerIterator
<Layer
,
142 RenderSurfaceLayerList
,
144 LayerIteratorActions::FrontToBack
> TestLayerIterator
;
145 typedef OcclusionTracker OcclusionTrackerType
;
147 static LayerPtrType
CreateLayer(HostType
* host
) { return Layer::Create(); }
148 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
149 return make_scoped_refptr(new ContentLayerType());
152 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
153 LayerPtrType
ref(*layer
);
158 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
159 LayerPtrType
ref(*layer
);
164 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
167 struct OcclusionTrackerTestImplThreadTypes
{
168 typedef LayerImpl LayerType
;
169 typedef LayerTreeImpl HostType
;
170 typedef RenderSurfaceImpl RenderSurfaceType
;
171 typedef TestContentLayerImpl ContentLayerType
;
172 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
173 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
174 typedef LayerIterator
<LayerImpl
,
177 LayerIteratorActions::FrontToBack
> TestLayerIterator
;
178 typedef OcclusionTrackerImpl OcclusionTrackerType
;
180 static LayerPtrType
CreateLayer(HostType
* host
) {
181 return LayerImpl::Create(host
, next_layer_impl_id
++);
183 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
184 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
186 static int next_layer_impl_id
;
188 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
189 return layer
->Pass();
192 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
193 return layer
->PassAs
<LayerType
>();
196 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
199 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
201 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
203 explicit OcclusionTrackerTest(bool opaque_layers
)
204 : opaque_layers_(opaque_layers
), host_(FakeLayerTreeHost::Create()) {}
206 virtual void RunMyTest() = 0;
208 virtual void TearDown() {
209 Types::DestroyLayer(&root_
);
210 render_surface_layer_list_
.reset();
211 render_surface_layer_list_impl_
.clear();
212 replica_layers_
.clear();
213 mask_layers_
.clear();
216 typename
Types::HostType
* GetHost();
218 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
219 gfx::PointF position
,
221 typename
Types::ContentLayerPtrType
layer(
222 Types::CreateContentLayer(GetHost()));
223 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
224 SetProperties(layer_ptr
, transform
, position
, bounds
);
226 DCHECK(!root_
.get());
227 root_
= Types::PassLayerPtr(&layer
);
229 SetRootLayerOnMainThread(layer_ptr
);
234 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
235 const gfx::Transform
& transform
,
236 gfx::PointF position
,
238 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
239 typename
Types::LayerType
* layer_ptr
= layer
.get();
240 SetProperties(layer_ptr
, transform
, position
, bounds
);
241 parent
->AddChild(Types::PassLayerPtr(&layer
));
245 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
246 const gfx::Transform
& transform
,
247 gfx::PointF position
,
249 typename
Types::LayerType
* layer
=
250 CreateLayer(parent
, transform
, position
, bounds
);
251 layer
->SetForceRenderSurface(true);
255 typename
Types::ContentLayerType
* CreateDrawingLayer(
256 typename
Types::LayerType
* parent
,
257 const gfx::Transform
& transform
,
258 gfx::PointF position
,
261 typename
Types::ContentLayerPtrType
layer(
262 Types::CreateContentLayer(GetHost()));
263 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
264 SetProperties(layer_ptr
, transform
, position
, bounds
);
266 if (opaque_layers_
) {
267 layer_ptr
->SetContentsOpaque(opaque
);
269 layer_ptr
->SetContentsOpaque(false);
271 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
273 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
276 parent
->AddChild(Types::PassLayerPtr(&layer
));
280 typename
Types::LayerType
* CreateReplicaLayer(
281 typename
Types::LayerType
* owning_layer
,
282 const gfx::Transform
& transform
,
283 gfx::PointF position
,
285 typename
Types::ContentLayerPtrType
layer(
286 Types::CreateContentLayer(GetHost()));
287 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
288 SetProperties(layer_ptr
, transform
, position
, bounds
);
289 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
293 typename
Types::LayerType
* CreateMaskLayer(
294 typename
Types::LayerType
* owning_layer
,
296 typename
Types::ContentLayerPtrType
layer(
297 Types::CreateContentLayer(GetHost()));
298 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
299 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
300 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
304 typename
Types::ContentLayerType
* CreateDrawingSurface(
305 typename
Types::LayerType
* parent
,
306 const gfx::Transform
& transform
,
307 gfx::PointF position
,
310 typename
Types::ContentLayerType
* layer
=
311 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
312 layer
->SetForceRenderSurface(true);
317 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
319 void AddCopyRequest(Layer
* layer
) {
320 layer
->RequestCopyOfOutput(
321 CopyOutputRequest::CreateBitmapRequest(base::Bind(
322 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
323 base::Unretained(this))));
326 void AddCopyRequest(LayerImpl
* layer
) {
327 ScopedPtrVector
<CopyOutputRequest
> requests
;
329 CopyOutputRequest::CreateBitmapRequest(base::Bind(
330 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
331 base::Unretained(this))));
332 layer
->PassCopyRequests(&requests
);
335 void CalcDrawEtc(TestContentLayerImpl
* root
) {
336 DCHECK(root
== root_
.get());
337 DCHECK(!root
->render_surface());
339 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
340 root
, root
->bounds(), &render_surface_layer_list_impl_
);
341 inputs
.can_adjust_raster_scales
= true;
342 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
344 layer_iterator_
= layer_iterator_begin_
=
345 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
348 void CalcDrawEtc(TestContentLayer
* root
) {
349 DCHECK(root
== root_
.get());
350 DCHECK(!root
->render_surface());
352 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
353 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
354 root
, root
->bounds(), render_surface_layer_list_
.get());
355 inputs
.can_adjust_raster_scales
= true;
356 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
358 layer_iterator_
= layer_iterator_begin_
=
359 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
362 void EnterLayer(typename
Types::LayerType
* layer
,
363 typename
Types::OcclusionTrackerType
* occlusion
,
364 bool prevent_occlusion
) {
365 ASSERT_EQ(layer
, *layer_iterator_
);
366 ASSERT_TRUE(layer_iterator_
.represents_itself());
367 occlusion
->EnterLayer(layer_iterator_
, prevent_occlusion
);
370 void LeaveLayer(typename
Types::LayerType
* layer
,
371 typename
Types::OcclusionTrackerType
* occlusion
) {
372 ASSERT_EQ(layer
, *layer_iterator_
);
373 ASSERT_TRUE(layer_iterator_
.represents_itself());
374 occlusion
->LeaveLayer(layer_iterator_
);
378 void VisitLayer(typename
Types::LayerType
* layer
,
379 typename
Types::OcclusionTrackerType
* occlusion
) {
380 EnterLayer(layer
, occlusion
, false);
381 LeaveLayer(layer
, occlusion
);
384 void EnterContributingSurface(
385 typename
Types::LayerType
* layer
,
386 typename
Types::OcclusionTrackerType
* occlusion
,
387 bool prevent_occlusion
) {
388 ASSERT_EQ(layer
, *layer_iterator_
);
389 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
390 occlusion
->EnterLayer(layer_iterator_
, false);
391 occlusion
->LeaveLayer(layer_iterator_
);
393 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
394 occlusion
->EnterLayer(layer_iterator_
, prevent_occlusion
);
397 void LeaveContributingSurface(
398 typename
Types::LayerType
* layer
,
399 typename
Types::OcclusionTrackerType
* occlusion
) {
400 ASSERT_EQ(layer
, *layer_iterator_
);
401 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
402 occlusion
->LeaveLayer(layer_iterator_
);
406 void VisitContributingSurface(
407 typename
Types::LayerType
* layer
,
408 typename
Types::OcclusionTrackerType
* occlusion
) {
409 EnterContributingSurface(layer
, occlusion
, false);
410 LeaveContributingSurface(layer
, occlusion
);
413 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
415 const gfx::Transform identity_matrix
;
418 void SetRootLayerOnMainThread(Layer
* root
) {
419 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
422 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
424 void SetBaseProperties(typename
Types::LayerType
* layer
,
425 const gfx::Transform
& transform
,
426 gfx::PointF position
,
428 layer
->SetTransform(transform
);
429 layer
->SetSublayerTransform(gfx::Transform());
430 layer
->SetAnchorPoint(gfx::PointF());
431 layer
->SetPosition(position
);
432 layer
->SetBounds(bounds
);
435 void SetProperties(Layer
* layer
,
436 const gfx::Transform
& transform
,
437 gfx::PointF position
,
439 SetBaseProperties(layer
, transform
, position
, bounds
);
442 void SetProperties(LayerImpl
* layer
,
443 const gfx::Transform
& transform
,
444 gfx::PointF position
,
446 SetBaseProperties(layer
, transform
, position
, bounds
);
448 layer
->SetContentBounds(layer
->bounds());
451 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
452 owning_layer
->SetReplicaLayer(layer
.get());
453 replica_layers_
.push_back(layer
);
456 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
457 owning_layer
->SetReplicaLayer(layer
.Pass());
460 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
461 owning_layer
->SetMaskLayer(layer
.get());
462 mask_layers_
.push_back(layer
);
465 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
466 owning_layer
->SetMaskLayer(layer
.Pass());
470 scoped_ptr
<FakeLayerTreeHost
> host_
;
471 // These hold ownership of the layers for the duration of the test.
472 typename
Types::LayerPtrType root_
;
473 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
474 LayerImplList render_surface_layer_list_impl_
;
475 typename
Types::TestLayerIterator layer_iterator_begin_
;
476 typename
Types::TestLayerIterator layer_iterator_
;
477 typename
Types::LayerType
* last_layer_visited_
;
478 LayerList replica_layers_
;
479 LayerList mask_layers_
;
484 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
490 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
491 return host_
->host_impl()->active_tree();
494 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
495 class ClassName##MainThreadOpaqueLayers \
496 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
497 public: /* NOLINT(whitespace/indent) */ \
498 ClassName##MainThreadOpaqueLayers() \
499 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
501 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
502 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
503 class ClassName##MainThreadOpaquePaints \
504 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
505 public: /* NOLINT(whitespace/indent) */ \
506 ClassName##MainThreadOpaquePaints() \
507 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
509 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
511 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
512 class ClassName##ImplThreadOpaqueLayers \
513 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
514 public: /* NOLINT(whitespace/indent) */ \
515 ClassName##ImplThreadOpaqueLayers() \
516 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
518 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
519 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
520 class ClassName##ImplThreadOpaquePaints \
521 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
522 public: /* NOLINT(whitespace/indent) */ \
523 ClassName##ImplThreadOpaquePaints() \
524 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
526 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
528 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
529 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
530 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
531 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
532 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
534 #define MAIN_THREAD_TEST(ClassName) \
535 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
537 #define IMPL_THREAD_TEST(ClassName) \
538 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
540 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
541 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
542 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
544 template <class Types
>
545 class OcclusionTrackerTestIdentityTransforms
546 : public OcclusionTrackerTest
<Types
> {
548 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
549 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
552 typename
Types::ContentLayerType
* root
= this->CreateRoot(
553 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
554 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
555 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
556 typename
Types::ContentLayerType
* layer
=
557 this->CreateDrawingLayer(parent
,
558 this->identity_matrix
,
559 gfx::PointF(30.f
, 30.f
),
562 parent
->SetMasksToBounds(true);
563 this->CalcDrawEtc(root
);
565 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
566 typename
Types::RenderSurfaceType
> occlusion(
567 gfx::Rect(0, 0, 1000, 1000), false);
569 this->VisitLayer(layer
, &occlusion
);
570 this->EnterLayer(parent
, &occlusion
, false);
572 EXPECT_EQ(gfx::Rect().ToString(),
573 occlusion
.occlusion_from_outside_target().ToString());
574 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
575 occlusion
.occlusion_from_inside_target().ToString());
577 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
578 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
579 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
580 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
581 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
583 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
584 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
585 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
586 occlusion
.UnoccludedLayerContentRect(
587 parent
, gfx::Rect(29, 30, 70, 70)));
588 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
589 occlusion
.UnoccludedLayerContentRect(
590 parent
, gfx::Rect(29, 29, 70, 70)));
591 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
592 occlusion
.UnoccludedLayerContentRect(
593 parent
, gfx::Rect(30, 29, 70, 70)));
594 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
595 occlusion
.UnoccludedLayerContentRect(
596 parent
, gfx::Rect(31, 29, 70, 70)));
597 EXPECT_RECT_EQ(gfx::Rect(),
598 occlusion
.UnoccludedLayerContentRect(
599 parent
, gfx::Rect(31, 30, 70, 70)));
600 EXPECT_RECT_EQ(gfx::Rect(),
601 occlusion
.UnoccludedLayerContentRect(
602 parent
, gfx::Rect(31, 31, 70, 70)));
603 EXPECT_RECT_EQ(gfx::Rect(),
604 occlusion
.UnoccludedLayerContentRect(
605 parent
, gfx::Rect(30, 31, 70, 70)));
606 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
607 occlusion
.UnoccludedLayerContentRect(
608 parent
, gfx::Rect(29, 31, 70, 70)));
612 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
614 template <class Types
>
615 class OcclusionTrackerTestQuadsMismatchLayer
616 : public OcclusionTrackerTest
<Types
> {
618 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers
)
619 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
621 gfx::Transform layer_transform
;
622 layer_transform
.Translate(10.0, 10.0);
624 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
625 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(100, 100));
626 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
627 parent
, layer_transform
, gfx::PointF(), gfx::Size(90, 90), true);
628 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
629 layer1
, layer_transform
, gfx::PointF(), gfx::Size(50, 50), true);
630 this->CalcDrawEtc(parent
);
632 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
633 typename
Types::RenderSurfaceType
> occlusion(
634 gfx::Rect(0, 0, 1000, 1000));
636 this->VisitLayer(layer2
, &occlusion
);
637 this->EnterLayer(layer1
, &occlusion
, false);
639 EXPECT_EQ(gfx::Rect().ToString(),
640 occlusion
.occlusion_from_outside_target().ToString());
641 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
642 occlusion
.occlusion_from_inside_target().ToString());
644 // This checks cases where the quads don't match their "containing"
645 // layers, e.g. in terms of transforms or clip rect. This is typical for
646 // DelegatedRendererLayer.
648 gfx::Transform quad_transform
;
649 quad_transform
.Translate(30.0, 30.0);
650 gfx::Rect
clip_rect_in_target(0, 0, 100, 100);
652 EXPECT_TRUE(occlusion
.UnoccludedContentRect(parent
,
653 gfx::Rect(0, 0, 10, 10),
659 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
660 occlusion
.UnoccludedContentRect(parent
,
661 gfx::Rect(0, 0, 10, 10),
667 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
668 occlusion
.UnoccludedContentRect(parent
,
669 gfx::Rect(40, 40, 10, 10),
675 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
676 occlusion
.UnoccludedContentRect(parent
,
677 gfx::Rect(35, 30, 10, 10),
683 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5),
684 occlusion
.UnoccludedContentRect(parent
,
685 gfx::Rect(40, 40, 10, 10),
689 gfx::Rect(0, 0, 75, 75),
694 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
696 template <class Types
>
697 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
699 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
700 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
702 gfx::Transform layer_transform
;
703 layer_transform
.Translate(250.0, 250.0);
704 layer_transform
.Rotate(90.0);
705 layer_transform
.Translate(-250.0, -250.0);
707 typename
Types::ContentLayerType
* root
= this->CreateRoot(
708 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
709 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
710 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
711 typename
Types::ContentLayerType
* layer
=
712 this->CreateDrawingLayer(parent
,
714 gfx::PointF(30.f
, 30.f
),
717 parent
->SetMasksToBounds(true);
718 this->CalcDrawEtc(root
);
720 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
721 typename
Types::RenderSurfaceType
> occlusion(
722 gfx::Rect(0, 0, 1000, 1000));
724 this->VisitLayer(layer
, &occlusion
);
725 this->EnterLayer(parent
, &occlusion
, false);
727 EXPECT_EQ(gfx::Rect().ToString(),
728 occlusion
.occlusion_from_outside_target().ToString());
729 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
730 occlusion
.occlusion_from_inside_target().ToString());
732 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
733 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
734 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
735 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
736 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
738 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
739 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
740 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
741 occlusion
.UnoccludedLayerContentRect(
742 parent
, gfx::Rect(29, 30, 70, 70)));
743 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
744 occlusion
.UnoccludedLayerContentRect(
745 parent
, gfx::Rect(29, 29, 70, 70)));
746 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
747 occlusion
.UnoccludedLayerContentRect(
748 parent
, gfx::Rect(30, 29, 70, 70)));
749 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
750 occlusion
.UnoccludedLayerContentRect(
751 parent
, gfx::Rect(31, 29, 70, 70)));
752 EXPECT_RECT_EQ(gfx::Rect(),
753 occlusion
.UnoccludedLayerContentRect(
754 parent
, gfx::Rect(31, 30, 70, 70)));
755 EXPECT_RECT_EQ(gfx::Rect(),
756 occlusion
.UnoccludedLayerContentRect(
757 parent
, gfx::Rect(31, 31, 70, 70)));
758 EXPECT_RECT_EQ(gfx::Rect(),
759 occlusion
.UnoccludedLayerContentRect(
760 parent
, gfx::Rect(30, 31, 70, 70)));
761 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
762 occlusion
.UnoccludedLayerContentRect(
763 parent
, gfx::Rect(29, 31, 70, 70)));
767 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
769 template <class Types
>
770 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
772 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
773 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
775 gfx::Transform layer_transform
;
776 layer_transform
.Translate(20.0, 20.0);
778 typename
Types::ContentLayerType
* root
= this->CreateRoot(
779 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
780 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
781 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
782 typename
Types::ContentLayerType
* layer
=
783 this->CreateDrawingLayer(parent
,
785 gfx::PointF(30.f
, 30.f
),
788 parent
->SetMasksToBounds(true);
789 this->CalcDrawEtc(root
);
791 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
792 typename
Types::RenderSurfaceType
> occlusion(
793 gfx::Rect(0, 0, 1000, 1000));
795 this->VisitLayer(layer
, &occlusion
);
796 this->EnterLayer(parent
, &occlusion
, false);
798 EXPECT_EQ(gfx::Rect().ToString(),
799 occlusion
.occlusion_from_outside_target().ToString());
800 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
801 occlusion
.occlusion_from_inside_target().ToString());
803 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
804 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
805 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
806 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(51, 50, 50, 50)));
807 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 51, 50, 50)));
809 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
810 parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
811 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
812 occlusion
.UnoccludedLayerContentRect(
813 parent
, gfx::Rect(49, 50, 50, 50)));
814 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
815 occlusion
.UnoccludedLayerContentRect(
816 parent
, gfx::Rect(49, 49, 50, 50)));
817 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
818 occlusion
.UnoccludedLayerContentRect(
819 parent
, gfx::Rect(50, 49, 50, 50)));
820 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
821 occlusion
.UnoccludedLayerContentRect(
822 parent
, gfx::Rect(51, 49, 50, 50)));
823 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
824 parent
, gfx::Rect(51, 50, 50, 50)).IsEmpty());
825 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
826 parent
, gfx::Rect(51, 51, 50, 50)).IsEmpty());
827 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
828 parent
, gfx::Rect(50, 51, 50, 50)).IsEmpty());
829 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
830 occlusion
.UnoccludedLayerContentRect(
831 parent
, gfx::Rect(49, 51, 50, 50)));
835 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
837 template <class Types
>
838 class OcclusionTrackerTestChildInRotatedChild
839 : public OcclusionTrackerTest
<Types
> {
841 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
842 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
844 gfx::Transform child_transform
;
845 child_transform
.Translate(250.0, 250.0);
846 child_transform
.Rotate(90.0);
847 child_transform
.Translate(-250.0, -250.0);
849 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
850 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
851 parent
->SetMasksToBounds(true);
852 typename
Types::LayerType
* child
= this->CreateSurface(
853 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
854 child
->SetMasksToBounds(true);
855 typename
Types::ContentLayerType
* layer
=
856 this->CreateDrawingLayer(child
,
857 this->identity_matrix
,
858 gfx::PointF(10.f
, 10.f
),
861 this->CalcDrawEtc(parent
);
863 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
864 typename
Types::RenderSurfaceType
> occlusion(
865 gfx::Rect(0, 0, 1000, 1000));
867 this->VisitLayer(layer
, &occlusion
);
868 this->EnterContributingSurface(child
, &occlusion
, false);
870 EXPECT_EQ(gfx::Rect().ToString(),
871 occlusion
.occlusion_from_outside_target().ToString());
872 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
873 occlusion
.occlusion_from_inside_target().ToString());
875 this->LeaveContributingSurface(child
, &occlusion
);
876 this->EnterLayer(parent
, &occlusion
, false);
878 EXPECT_EQ(gfx::Rect().ToString(),
879 occlusion
.occlusion_from_outside_target().ToString());
880 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
881 occlusion
.occlusion_from_inside_target().ToString());
883 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
884 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
885 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
886 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 40, 70, 60)));
887 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 41, 70, 60)));
889 /* Justification for the above occlusion from |layer|:
891 +---------------------+
894 | 30 + ---------------------------------+
896 | |10+---------------------------------+
900 +----|--|-------------+ | |
908 +--|-------------------------------+ |
910 +---------------------------------+
913 +---------------------+
914 | |30 Visible region of |layer|: /////
916 | +---------------------------------+
918 | +---------------------------------+ |
919 | | |///////////////| 420 | |
920 | | |///////////////|60 | |
921 | | |///////////////| | |
922 +--|--|---------------+ | |
930 | +------------------------------|--+
932 +---------------------------------+
939 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
941 template <class Types
>
942 class OcclusionTrackerTestScaledRenderSurface
943 : public OcclusionTrackerTest
<Types
> {
945 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
946 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
949 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
950 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
952 gfx::Transform layer1_matrix
;
953 layer1_matrix
.Scale(2.0, 2.0);
954 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
955 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
956 layer1
->SetForceRenderSurface(true);
958 gfx::Transform layer2_matrix
;
959 layer2_matrix
.Translate(25.0, 25.0);
960 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
961 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
962 typename
Types::ContentLayerType
* occluder
=
963 this->CreateDrawingLayer(parent
,
964 this->identity_matrix
,
965 gfx::PointF(100.f
, 100.f
),
968 this->CalcDrawEtc(parent
);
970 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
971 typename
Types::RenderSurfaceType
> occlusion(
972 gfx::Rect(0, 0, 1000, 1000));
974 this->VisitLayer(occluder
, &occlusion
);
975 this->EnterLayer(layer2
, &occlusion
, false);
977 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
978 occlusion
.occlusion_from_outside_target().ToString());
979 EXPECT_EQ(gfx::Rect().ToString(),
980 occlusion
.occlusion_from_inside_target().ToString());
983 gfx::Rect(0, 0, 25, 25),
984 occlusion
.UnoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
985 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
986 occlusion
.UnoccludedLayerContentRect(
987 layer2
, gfx::Rect(10, 25, 25, 25)));
988 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
989 occlusion
.UnoccludedLayerContentRect(
990 layer2
, gfx::Rect(25, 10, 25, 25)));
991 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
992 layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
996 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
998 template <class Types
>
999 class OcclusionTrackerTestVisitTargetTwoTimes
1000 : public OcclusionTrackerTest
<Types
> {
1002 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
1003 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1005 gfx::Transform child_transform
;
1006 child_transform
.Translate(250.0, 250.0);
1007 child_transform
.Rotate(90.0);
1008 child_transform
.Translate(-250.0, -250.0);
1010 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1011 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
1012 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1013 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1014 parent
->SetMasksToBounds(true);
1015 typename
Types::LayerType
* child
= this->CreateSurface(
1016 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1017 child
->SetMasksToBounds(true);
1018 typename
Types::ContentLayerType
* layer
=
1019 this->CreateDrawingLayer(child
,
1020 this->identity_matrix
,
1021 gfx::PointF(10.f
, 10.f
),
1022 gfx::Size(500, 500),
1024 // |child2| makes |parent|'s surface get considered by OcclusionTracker
1025 // first, instead of |child|'s. This exercises different code in
1026 // LeaveToRenderTarget, as the target surface has already been seen.
1027 typename
Types::ContentLayerType
* child2
=
1028 this->CreateDrawingLayer(parent
,
1029 this->identity_matrix
,
1030 gfx::PointF(30.f
, 30.f
),
1033 this->CalcDrawEtc(root
);
1035 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1036 typename
Types::RenderSurfaceType
> occlusion(
1037 gfx::Rect(0, 0, 1000, 1000));
1039 this->VisitLayer(child2
, &occlusion
);
1041 EXPECT_EQ(gfx::Rect().ToString(),
1042 occlusion
.occlusion_from_outside_target().ToString());
1043 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1044 occlusion
.occlusion_from_inside_target().ToString());
1046 this->VisitLayer(layer
, &occlusion
);
1048 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1049 occlusion
.occlusion_from_outside_target().ToString());
1050 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1051 occlusion
.occlusion_from_inside_target().ToString());
1053 this->EnterContributingSurface(child
, &occlusion
, false);
1055 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1056 occlusion
.occlusion_from_outside_target().ToString());
1057 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1058 occlusion
.occlusion_from_inside_target().ToString());
1060 // Occlusion in |child2| should get merged with the |child| surface we are
1062 this->LeaveContributingSurface(child
, &occlusion
);
1063 this->EnterLayer(parent
, &occlusion
, false);
1065 EXPECT_EQ(gfx::Rect().ToString(),
1066 occlusion
.occlusion_from_outside_target().ToString());
1067 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1069 occlusion
.occlusion_from_inside_target().ToString());
1071 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
1072 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1073 occlusion
.UnoccludedLayerContentRect(
1074 parent
, gfx::Rect(30, 30, 70, 70)));
1076 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
1077 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
1078 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
1079 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
1080 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
1082 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1083 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1084 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1086 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1087 parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1088 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1089 occlusion
.UnoccludedLayerContentRect(
1090 parent
, gfx::Rect(29, 30, 60, 10)));
1091 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1092 occlusion
.UnoccludedLayerContentRect(
1093 parent
, gfx::Rect(30, 29, 60, 10)));
1094 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1095 occlusion
.UnoccludedLayerContentRect(
1096 parent
, gfx::Rect(31, 30, 60, 10)));
1097 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1098 parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1100 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1101 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1102 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1103 occlusion
.UnoccludedLayerContentRect(
1104 parent
, gfx::Rect(29, 40, 70, 60)));
1105 // This rect is mostly occluded by |child2|.
1106 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1107 occlusion
.UnoccludedLayerContentRect(
1108 parent
, gfx::Rect(30, 39, 70, 60)));
1109 // This rect extends past top/right ends of |child2|.
1110 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1111 occlusion
.UnoccludedLayerContentRect(
1112 parent
, gfx::Rect(30, 29, 70, 70)));
1113 // This rect extends past left/right ends of |child2|.
1114 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1115 occlusion
.UnoccludedLayerContentRect(
1116 parent
, gfx::Rect(20, 39, 80, 60)));
1117 EXPECT_RECT_EQ(gfx::Rect(),
1118 occlusion
.UnoccludedLayerContentRect(
1119 parent
, gfx::Rect(31, 40, 70, 60)));
1120 EXPECT_RECT_EQ(gfx::Rect(),
1121 occlusion
.UnoccludedLayerContentRect(
1122 parent
, gfx::Rect(30, 41, 70, 60)));
1124 /* Justification for the above occlusion from |layer|:
1126 +---------------------+
1129 | 30 + ------------+--------------------+
1130 100 | | 10 | | | ==>
1131 | |10+----------|----------------------+
1132 | + ------------+ | | |
1135 +----|--|-------------+ | |
1143 +--|-------------------------------+ |
1145 +---------------------------------+
1149 +---------------------+
1150 | |30 Visible region of |layer|: /////
1151 | 30 60 | |child2|: \\\\\
1152 | 30 +------------+--------------------+
1153 | |\\\\\\\\\\\\| |10 |
1154 | +--|\\\\\\\\\\\\|-----------------+ |
1155 | | +------------+//| 420 | |
1156 | | |///////////////|60 | |
1157 | | |///////////////| | |
1158 +--|--|---------------+ | |
1166 | +------------------------------|--+
1168 +---------------------------------+
1174 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
1176 template <class Types
>
1177 class OcclusionTrackerTestSurfaceRotatedOffAxis
1178 : public OcclusionTrackerTest
<Types
> {
1180 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
1181 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1183 gfx::Transform child_transform
;
1184 child_transform
.Translate(250.0, 250.0);
1185 child_transform
.Rotate(95.0);
1186 child_transform
.Translate(-250.0, -250.0);
1188 gfx::Transform layer_transform
;
1189 layer_transform
.Translate(10.0, 10.0);
1191 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1192 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1193 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1194 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1195 typename
Types::LayerType
* child
= this->CreateLayer(
1196 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1197 child
->SetMasksToBounds(true);
1198 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1199 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
1200 this->CalcDrawEtc(root
);
1202 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1203 typename
Types::RenderSurfaceType
> occlusion(
1204 gfx::Rect(0, 0, 1000, 1000));
1206 gfx::Rect clipped_layer_in_child
= MathUtil::MapClippedRect(
1207 layer_transform
, layer
->visible_content_rect());
1209 this->VisitLayer(layer
, &occlusion
);
1210 this->EnterContributingSurface(child
, &occlusion
, false);
1212 EXPECT_EQ(gfx::Rect().ToString(),
1213 occlusion
.occlusion_from_outside_target().ToString());
1214 EXPECT_EQ(clipped_layer_in_child
.ToString(),
1215 occlusion
.occlusion_from_inside_target().ToString());
1217 this->LeaveContributingSurface(child
, &occlusion
);
1218 this->EnterLayer(parent
, &occlusion
, false);
1220 EXPECT_EQ(gfx::Rect().ToString(),
1221 occlusion
.occlusion_from_outside_target().ToString());
1222 EXPECT_EQ(gfx::Rect().ToString(),
1223 occlusion
.occlusion_from_inside_target().ToString());
1225 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
1227 gfx::Rect(75, 55, 1, 1),
1228 occlusion
.UnoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
1232 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
1234 template <class Types
>
1235 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1236 : public OcclusionTrackerTest
<Types
> {
1238 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
1239 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1241 gfx::Transform child_transform
;
1242 child_transform
.Translate(250.0, 250.0);
1243 child_transform
.Rotate(90.0);
1244 child_transform
.Translate(-250.0, -250.0);
1246 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1247 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1248 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1249 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1250 parent
->SetMasksToBounds(true);
1251 typename
Types::ContentLayerType
* child
=
1252 this->CreateDrawingSurface(parent
,
1254 gfx::PointF(30.f
, 30.f
),
1255 gfx::Size(500, 500),
1257 child
->SetMasksToBounds(true);
1258 typename
Types::ContentLayerType
* layer1
=
1259 this->CreateDrawingLayer(child
,
1260 this->identity_matrix
,
1261 gfx::PointF(10.f
, 10.f
),
1262 gfx::Size(500, 500),
1264 typename
Types::ContentLayerType
* layer2
=
1265 this->CreateDrawingLayer(child
,
1266 this->identity_matrix
,
1267 gfx::PointF(10.f
, 450.f
),
1270 this->CalcDrawEtc(root
);
1272 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1273 typename
Types::RenderSurfaceType
> occlusion(
1274 gfx::Rect(0, 0, 1000, 1000));
1276 this->VisitLayer(layer2
, &occlusion
);
1277 this->VisitLayer(layer1
, &occlusion
);
1278 this->VisitLayer(child
, &occlusion
);
1279 this->EnterContributingSurface(child
, &occlusion
, false);
1281 EXPECT_EQ(gfx::Rect().ToString(),
1282 occlusion
.occlusion_from_outside_target().ToString());
1283 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1284 occlusion
.occlusion_from_inside_target().ToString());
1286 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
1287 EXPECT_FALSE(occlusion
.OccludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
1288 // These rects are occluded except for the part outside the bounds of the
1290 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 429, 60, 70)));
1291 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(11, 430, 60, 70)));
1292 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 431, 60, 70)));
1294 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1295 child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1297 gfx::Rect(9, 430, 1, 70),
1298 occlusion
.UnoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
1299 // These rects are occluded except for the part outside the bounds of the
1301 EXPECT_RECT_EQ(gfx::Rect(),
1302 occlusion
.UnoccludedLayerContentRect(
1303 child
, gfx::Rect(10, 429, 60, 70)));
1304 EXPECT_RECT_EQ(gfx::Rect(),
1305 occlusion
.UnoccludedLayerContentRect(
1306 child
, gfx::Rect(11, 430, 60, 70)));
1307 EXPECT_RECT_EQ(gfx::Rect(),
1308 occlusion
.UnoccludedLayerContentRect(
1309 child
, gfx::Rect(10, 431, 60, 70)));
1311 this->LeaveContributingSurface(child
, &occlusion
);
1312 this->EnterLayer(parent
, &occlusion
, false);
1314 EXPECT_EQ(gfx::Rect().ToString(),
1315 occlusion
.occlusion_from_outside_target().ToString());
1316 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1317 occlusion
.occlusion_from_inside_target().ToString());
1319 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1320 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1321 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1323 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1324 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1325 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1326 occlusion
.UnoccludedLayerContentRect(
1327 parent
, gfx::Rect(29, 40, 70, 60)));
1328 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1329 occlusion
.UnoccludedLayerContentRect(
1330 parent
, gfx::Rect(30, 39, 70, 60)));
1331 EXPECT_RECT_EQ(gfx::Rect(),
1332 occlusion
.UnoccludedLayerContentRect(
1333 parent
, gfx::Rect(31, 40, 70, 60)));
1334 EXPECT_RECT_EQ(gfx::Rect(),
1335 occlusion
.UnoccludedLayerContentRect(
1336 parent
, gfx::Rect(30, 41, 70, 60)));
1338 /* Justification for the above occlusion from |layer1| and |layer2|:
1340 +---------------------+
1341 | |30 Visible region of |layer1|: /////
1342 | | Visible region of |layer2|: \\\\\
1343 | +---------------------------------+
1345 | +---------------+-----------------+ |
1346 | | |\\\\\\\\\\\\|//| 420 | |
1347 | | |\\\\\\\\\\\\|//|60 | |
1348 | | |\\\\\\\\\\\\|//| | |
1349 +--|--|------------|--+ | |
1357 | +------------|-----------------|--+
1359 +---------------+-----------------+
1365 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1367 template <class Types
>
1368 class OcclusionTrackerTestOverlappingSurfaceSiblings
1369 : public OcclusionTrackerTest
<Types
> {
1371 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
1372 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1374 gfx::Transform child_transform
;
1375 child_transform
.Translate(250.0, 250.0);
1376 child_transform
.Rotate(90.0);
1377 child_transform
.Translate(-250.0, -250.0);
1379 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1380 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1381 parent
->SetMasksToBounds(true);
1382 typename
Types::LayerType
* child1
= this->CreateSurface(
1383 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(10, 10));
1384 typename
Types::LayerType
* child2
= this->CreateSurface(
1385 parent
, child_transform
, gfx::PointF(20.f
, 40.f
), gfx::Size(10, 10));
1386 typename
Types::ContentLayerType
* layer1
=
1387 this->CreateDrawingLayer(child1
,
1388 this->identity_matrix
,
1389 gfx::PointF(-10.f
, -10.f
),
1390 gfx::Size(510, 510),
1392 typename
Types::ContentLayerType
* layer2
=
1393 this->CreateDrawingLayer(child2
,
1394 this->identity_matrix
,
1395 gfx::PointF(-10.f
, -10.f
),
1396 gfx::Size(510, 510),
1398 this->CalcDrawEtc(parent
);
1400 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1401 typename
Types::RenderSurfaceType
> occlusion(
1402 gfx::Rect(0, 0, 1000, 1000));
1404 this->VisitLayer(layer2
, &occlusion
);
1405 this->EnterContributingSurface(child2
, &occlusion
, false);
1407 EXPECT_EQ(gfx::Rect().ToString(),
1408 occlusion
.occlusion_from_outside_target().ToString());
1409 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1410 occlusion
.occlusion_from_inside_target().ToString());
1412 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1413 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1414 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1415 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1416 EXPECT_TRUE(occlusion
.OccludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1418 // There is nothing above child2's surface in the z-order.
1419 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1420 occlusion
.UnoccludedContributingSurfaceContentRect(
1421 child2
, false, gfx::Rect(-10, 420, 70, 80), NULL
));
1423 this->LeaveContributingSurface(child2
, &occlusion
);
1424 this->VisitLayer(layer1
, &occlusion
);
1425 this->EnterContributingSurface(child1
, &occlusion
, false);
1427 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1428 occlusion
.occlusion_from_outside_target().ToString());
1429 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1430 occlusion
.occlusion_from_inside_target().ToString());
1432 // child2's contents will occlude child1 below it.
1433 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1434 occlusion
.UnoccludedContributingSurfaceContentRect(
1435 child1
, false, gfx::Rect(-10, 430, 80, 70), NULL
));
1437 this->LeaveContributingSurface(child1
, &occlusion
);
1438 this->EnterLayer(parent
, &occlusion
, false);
1440 EXPECT_EQ(gfx::Rect().ToString(),
1441 occlusion
.occlusion_from_outside_target().ToString());
1442 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1444 occlusion
.occlusion_from_inside_target().ToString());
1446 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1448 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1449 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1450 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1452 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1453 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1454 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1456 /* Justification for the above occlusion:
1458 +---------------------+
1460 | 30+ ---------------------------------+
1461 100 | 30| | layer2 |
1462 |20+----------------------------------+ |
1466 +--|-|----------------+ | |
1474 | +--------------------------------|-+
1476 +----------------------------------+
1482 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1484 template <class Types
>
1485 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1486 : public OcclusionTrackerTest
<Types
> {
1488 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1490 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1492 gfx::Transform child1_transform
;
1493 child1_transform
.Translate(250.0, 250.0);
1494 child1_transform
.Rotate(-90.0);
1495 child1_transform
.Translate(-250.0, -250.0);
1497 gfx::Transform child2_transform
;
1498 child2_transform
.Translate(250.0, 250.0);
1499 child2_transform
.Rotate(90.0);
1500 child2_transform
.Translate(-250.0, -250.0);
1502 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1503 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1504 parent
->SetMasksToBounds(true);
1505 typename
Types::LayerType
* child1
= this->CreateSurface(
1506 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1507 typename
Types::LayerType
* child2
=
1508 this->CreateDrawingSurface(parent
,
1510 gfx::PointF(20.f
, 40.f
),
1513 typename
Types::ContentLayerType
* layer1
=
1514 this->CreateDrawingLayer(child1
,
1515 this->identity_matrix
,
1516 gfx::PointF(-10.f
, -20.f
),
1517 gfx::Size(510, 510),
1519 typename
Types::ContentLayerType
* layer2
=
1520 this->CreateDrawingLayer(child2
,
1521 this->identity_matrix
,
1522 gfx::PointF(-10.f
, -10.f
),
1523 gfx::Size(510, 510),
1525 this->CalcDrawEtc(parent
);
1527 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1528 typename
Types::RenderSurfaceType
> occlusion(
1529 gfx::Rect(0, 0, 1000, 1000));
1531 this->VisitLayer(layer2
, &occlusion
);
1532 this->EnterLayer(child2
, &occlusion
, false);
1534 EXPECT_EQ(gfx::Rect().ToString(),
1535 occlusion
.occlusion_from_outside_target().ToString());
1536 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1537 occlusion
.occlusion_from_inside_target().ToString());
1539 this->LeaveLayer(child2
, &occlusion
);
1540 this->EnterContributingSurface(child2
, &occlusion
, false);
1542 // There is nothing above child2's surface in the z-order.
1543 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1544 occlusion
.UnoccludedContributingSurfaceContentRect(
1545 child2
, false, gfx::Rect(-10, 420, 70, 80), NULL
));
1547 this->LeaveContributingSurface(child2
, &occlusion
);
1548 this->VisitLayer(layer1
, &occlusion
);
1549 this->EnterContributingSurface(child1
, &occlusion
, false);
1551 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1552 occlusion
.occlusion_from_outside_target().ToString());
1553 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1554 occlusion
.occlusion_from_inside_target().ToString());
1556 // child2's contents will occlude child1 below it.
1557 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1558 occlusion
.UnoccludedContributingSurfaceContentRect(
1559 child1
, false, gfx::Rect(420, -20, 80, 90), NULL
));
1560 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1561 occlusion
.UnoccludedContributingSurfaceContentRect(
1562 child1
, false, gfx::Rect(420, -10, 80, 90), NULL
));
1563 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1564 occlusion
.UnoccludedContributingSurfaceContentRect(
1565 child1
, false, gfx::Rect(420, -20, 70, 90), NULL
));
1567 this->LeaveContributingSurface(child1
, &occlusion
);
1568 this->EnterLayer(parent
, &occlusion
, false);
1570 EXPECT_EQ(gfx::Rect().ToString(),
1571 occlusion
.occlusion_from_outside_target().ToString());
1572 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1573 occlusion
.occlusion_from_inside_target().ToString());
1575 /* Justification for the above occlusion:
1577 +---------------------+
1579 10+----------------------------------+
1580 100 || 30 | layer2 |
1581 |20+----------------------------------+
1585 +|-|------------------+ | |
1593 +----------------------------------+ |
1595 +----------------------------------+
1601 ALL_OCCLUSIONTRACKER_TEST(
1602 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1604 template <class Types
>
1605 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1607 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1608 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1610 gfx::Transform layer_transform
;
1611 layer_transform
.Translate(250.0, 250.0);
1612 layer_transform
.Rotate(90.0);
1613 layer_transform
.Translate(-250.0, -250.0);
1615 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1616 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1617 parent
->SetMasksToBounds(true);
1618 typename
Types::ContentLayerType
* blur_layer
=
1619 this->CreateDrawingLayer(parent
,
1621 gfx::PointF(30.f
, 30.f
),
1622 gfx::Size(500, 500),
1624 typename
Types::ContentLayerType
* opaque_layer
=
1625 this->CreateDrawingLayer(parent
,
1627 gfx::PointF(30.f
, 30.f
),
1628 gfx::Size(500, 500),
1630 typename
Types::ContentLayerType
* opacity_layer
=
1631 this->CreateDrawingLayer(parent
,
1633 gfx::PointF(30.f
, 30.f
),
1634 gfx::Size(500, 500),
1637 FilterOperations filters
;
1638 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1639 blur_layer
->SetFilters(filters
);
1642 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1643 opaque_layer
->SetFilters(filters
);
1646 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1647 opacity_layer
->SetFilters(filters
);
1649 this->CalcDrawEtc(parent
);
1651 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1652 typename
Types::RenderSurfaceType
> occlusion(
1653 gfx::Rect(0, 0, 1000, 1000));
1655 // Opacity layer won't contribute to occlusion.
1656 this->VisitLayer(opacity_layer
, &occlusion
);
1657 this->EnterContributingSurface(opacity_layer
, &occlusion
, false);
1659 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1660 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1662 // And has nothing to contribute to its parent surface.
1663 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1664 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1665 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1667 // Opaque layer will contribute to occlusion.
1668 this->VisitLayer(opaque_layer
, &occlusion
);
1669 this->EnterContributingSurface(opaque_layer
, &occlusion
, false);
1671 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1672 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1673 occlusion
.occlusion_from_inside_target().ToString());
1675 // And it gets translated to the parent surface.
1676 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1677 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1678 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1679 occlusion
.occlusion_from_inside_target().ToString());
1681 // The blur layer needs to throw away any occlusion from outside its
1683 this->EnterLayer(blur_layer
, &occlusion
, false);
1684 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1685 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1687 // And it won't contribute to occlusion.
1688 this->LeaveLayer(blur_layer
, &occlusion
);
1689 this->EnterContributingSurface(blur_layer
, &occlusion
, false);
1690 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1691 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1693 // But the opaque layer's occlusion is preserved on the parent.
1694 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1695 this->EnterLayer(parent
, &occlusion
, false);
1696 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1697 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1698 occlusion
.occlusion_from_inside_target().ToString());
1702 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1704 template <class Types
>
1705 class OcclusionTrackerTestReplicaDoesOcclude
1706 : public OcclusionTrackerTest
<Types
> {
1708 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1709 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1711 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1712 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1713 typename
Types::LayerType
* surface
=
1714 this->CreateDrawingSurface(parent
,
1715 this->identity_matrix
,
1716 gfx::PointF(0.f
, 100.f
),
1719 this->CreateReplicaLayer(
1720 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1721 this->CalcDrawEtc(parent
);
1723 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1724 typename
Types::RenderSurfaceType
> occlusion(
1725 gfx::Rect(0, 0, 1000, 1000));
1727 this->VisitLayer(surface
, &occlusion
);
1729 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1730 occlusion
.occlusion_from_inside_target().ToString());
1732 this->VisitContributingSurface(surface
, &occlusion
);
1733 this->EnterLayer(parent
, &occlusion
, false);
1735 // The surface and replica should both be occluding the parent.
1737 UnionRegions(gfx::Rect(0, 100, 50, 50),
1738 gfx::Rect(50, 150, 50, 50)).ToString(),
1739 occlusion
.occlusion_from_inside_target().ToString());
1743 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1745 template <class Types
>
1746 class OcclusionTrackerTestReplicaWithClipping
1747 : public OcclusionTrackerTest
<Types
> {
1749 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1750 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1752 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1753 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1754 parent
->SetMasksToBounds(true);
1755 typename
Types::LayerType
* surface
=
1756 this->CreateDrawingSurface(parent
,
1757 this->identity_matrix
,
1758 gfx::PointF(0.f
, 100.f
),
1761 this->CreateReplicaLayer(
1762 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1763 this->CalcDrawEtc(parent
);
1765 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1766 typename
Types::RenderSurfaceType
> occlusion(
1767 gfx::Rect(0, 0, 1000, 1000));
1769 this->VisitLayer(surface
, &occlusion
);
1771 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1772 occlusion
.occlusion_from_inside_target().ToString());
1774 this->VisitContributingSurface(surface
, &occlusion
);
1775 this->EnterLayer(parent
, &occlusion
, false);
1777 // The surface and replica should both be occluding the parent.
1779 UnionRegions(gfx::Rect(0, 100, 50, 50),
1780 gfx::Rect(50, 150, 50, 20)).ToString(),
1781 occlusion
.occlusion_from_inside_target().ToString());
1785 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1787 template <class Types
>
1788 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1790 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1791 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1793 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1794 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1795 typename
Types::LayerType
* surface
=
1796 this->CreateDrawingSurface(parent
,
1797 this->identity_matrix
,
1798 gfx::PointF(0.f
, 100.f
),
1801 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1802 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1803 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1804 this->CalcDrawEtc(parent
);
1806 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1807 typename
Types::RenderSurfaceType
> occlusion(
1808 gfx::Rect(0, 0, 1000, 1000));
1810 this->VisitLayer(surface
, &occlusion
);
1812 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1813 occlusion
.occlusion_from_inside_target().ToString());
1815 this->VisitContributingSurface(surface
, &occlusion
);
1816 this->EnterLayer(parent
, &occlusion
, false);
1818 // The replica should not be occluding the parent, since it has a mask
1820 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1821 occlusion
.occlusion_from_inside_target().ToString());
1825 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1827 template <class Types
>
1828 class OcclusionTrackerTestLayerClipRectOutsideChild
1829 : public OcclusionTrackerTest
<Types
> {
1831 explicit OcclusionTrackerTestLayerClipRectOutsideChild(bool opaque_layers
)
1832 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1834 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1835 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1836 typename
Types::ContentLayerType
* clip
=
1837 this->CreateDrawingLayer(parent
,
1838 this->identity_matrix
,
1839 gfx::PointF(200.f
, 100.f
),
1840 gfx::Size(100, 100),
1842 clip
->SetMasksToBounds(true);
1843 typename
Types::ContentLayerType
* layer
=
1844 this->CreateDrawingLayer(clip
,
1845 this->identity_matrix
,
1846 gfx::PointF(-200.f
, -100.f
),
1847 gfx::Size(200, 200),
1849 this->CalcDrawEtc(parent
);
1851 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1852 typename
Types::RenderSurfaceType
> occlusion(
1853 gfx::Rect(0, 0, 1000, 1000));
1855 this->EnterLayer(layer
, &occlusion
, false);
1857 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1858 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1859 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1860 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1861 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1863 this->LeaveLayer(layer
, &occlusion
);
1864 this->EnterLayer(clip
, &occlusion
, false);
1866 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(-100, 0, 100, 100)));
1867 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, -100, 100, 100)));
1868 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 0, 100, 100)));
1869 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 100, 100, 100)));
1870 EXPECT_FALSE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 0, 100, 100)));
1872 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
1873 occlusion
.UnoccludedLayerContentRect(
1874 clip
, gfx::Rect(-100, -100, 300, 300)));
1878 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild
);
1880 template <class Types
>
1881 class OcclusionTrackerTestViewportRectOutsideChild
1882 : public OcclusionTrackerTest
<Types
> {
1884 explicit OcclusionTrackerTestViewportRectOutsideChild(bool opaque_layers
)
1885 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1887 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1888 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1889 typename
Types::ContentLayerType
* layer
=
1890 this->CreateDrawingSurface(parent
,
1891 this->identity_matrix
,
1893 gfx::Size(200, 200),
1895 this->CalcDrawEtc(parent
);
1897 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1898 typename
Types::RenderSurfaceType
> occlusion(
1899 gfx::Rect(200, 100, 100, 100));
1901 this->EnterLayer(layer
, &occlusion
, false);
1903 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1904 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1905 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1906 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1907 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1909 this->LeaveLayer(layer
, &occlusion
);
1910 this->VisitContributingSurface(layer
, &occlusion
);
1911 this->EnterLayer(parent
, &occlusion
, false);
1913 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1914 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1915 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1916 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1918 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1919 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1920 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1921 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1922 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1924 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100),
1925 occlusion
.UnoccludedLayerContentRect(
1926 parent
, gfx::Rect(0, 0, 300, 300)));
1930 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild
);
1932 template <class Types
>
1933 class OcclusionTrackerTestLayerClipRectOverChild
1934 : public OcclusionTrackerTest
<Types
> {
1936 explicit OcclusionTrackerTestLayerClipRectOverChild(bool opaque_layers
)
1937 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1939 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1940 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1941 typename
Types::ContentLayerType
* clip
=
1942 this->CreateDrawingLayer(parent
,
1943 this->identity_matrix
,
1944 gfx::PointF(100.f
, 100.f
),
1945 gfx::Size(100, 100),
1947 clip
->SetMasksToBounds(true);
1948 typename
Types::ContentLayerType
* layer
=
1949 this->CreateDrawingSurface(clip
,
1950 this->identity_matrix
,
1951 gfx::PointF(-100.f
, -100.f
),
1952 gfx::Size(200, 200),
1954 this->CalcDrawEtc(parent
);
1956 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1957 typename
Types::RenderSurfaceType
> occlusion(
1958 gfx::Rect(0, 0, 1000, 1000));
1960 this->EnterLayer(layer
, &occlusion
, false);
1962 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1963 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1964 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1965 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1967 this->LeaveLayer(layer
, &occlusion
);
1968 this->VisitContributingSurface(layer
, &occlusion
);
1970 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1971 occlusion
.occlusion_from_inside_target().ToString());
1973 this->EnterLayer(clip
, &occlusion
, false);
1975 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 0, 100, 100)));
1976 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 100, 100, 100)));
1977 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 0, 100, 100)));
1978 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 100, 100, 100)));
1979 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 100, 100, 100)));
1980 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 0, 100, 100)));
1981 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(0, 200, 100, 100)));
1982 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(100, 200, 100, 100)));
1983 EXPECT_TRUE(occlusion
.OccludedLayer(clip
, gfx::Rect(200, 200, 100, 100)));
1985 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1986 clip
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1990 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild
);
1992 template <class Types
>
1993 class OcclusionTrackerTestViewportRectOverChild
1994 : public OcclusionTrackerTest
<Types
> {
1996 explicit OcclusionTrackerTestViewportRectOverChild(bool opaque_layers
)
1997 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1999 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2000 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2001 typename
Types::ContentLayerType
* layer
=
2002 this->CreateDrawingSurface(parent
,
2003 this->identity_matrix
,
2005 gfx::Size(200, 200),
2007 this->CalcDrawEtc(parent
);
2009 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2010 typename
Types::RenderSurfaceType
> occlusion(
2011 gfx::Rect(100, 100, 100, 100));
2013 this->EnterLayer(layer
, &occlusion
, false);
2015 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2016 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2017 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2018 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2020 this->LeaveLayer(layer
, &occlusion
);
2021 this->VisitContributingSurface(layer
, &occlusion
);
2022 this->EnterLayer(parent
, &occlusion
, false);
2024 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2025 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2026 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2027 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2028 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2029 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2030 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2031 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2032 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2034 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2035 parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2039 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild
);
2041 template <class Types
>
2042 class OcclusionTrackerTestLayerClipRectPartlyOverChild
2043 : public OcclusionTrackerTest
<Types
> {
2045 explicit OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaque_layers
)
2046 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2048 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2049 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2050 typename
Types::ContentLayerType
* clip
=
2051 this->CreateDrawingLayer(parent
,
2052 this->identity_matrix
,
2053 gfx::PointF(50.f
, 50.f
),
2054 gfx::Size(200, 200),
2056 clip
->SetMasksToBounds(true);
2057 typename
Types::ContentLayerType
* layer
=
2058 this->CreateDrawingSurface(clip
,
2059 this->identity_matrix
,
2060 gfx::PointF(-50.f
, -50.f
),
2061 gfx::Size(200, 200),
2063 this->CalcDrawEtc(parent
);
2065 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2066 typename
Types::RenderSurfaceType
> occlusion(
2067 gfx::Rect(0, 0, 1000, 1000));
2069 this->EnterLayer(layer
, &occlusion
, false);
2071 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2072 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2073 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2074 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2076 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 50)));
2077 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 50, 100)));
2078 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 50)));
2079 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 50, 100)));
2081 this->LeaveLayer(layer
, &occlusion
);
2082 this->VisitContributingSurface(layer
, &occlusion
);
2083 this->EnterLayer(clip
, &occlusion
, false);
2085 EXPECT_EQ(gfx::Rect(50, 50, 150, 150).ToString(),
2086 occlusion
.occlusion_from_inside_target().ToString());
2090 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild
);
2092 template <class Types
>
2093 class OcclusionTrackerTestViewportRectPartlyOverChild
2094 : public OcclusionTrackerTest
<Types
> {
2096 explicit OcclusionTrackerTestViewportRectPartlyOverChild(bool opaque_layers
)
2097 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2099 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2100 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2101 typename
Types::ContentLayerType
* layer
=
2102 this->CreateDrawingSurface(parent
,
2103 this->identity_matrix
,
2105 gfx::Size(200, 200),
2107 this->CalcDrawEtc(parent
);
2109 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2110 typename
Types::RenderSurfaceType
> occlusion(
2111 gfx::Rect(50, 50, 200, 200));
2113 this->EnterLayer(layer
, &occlusion
, false);
2115 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2116 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2117 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2118 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2120 this->LeaveLayer(layer
, &occlusion
);
2121 this->VisitContributingSurface(layer
, &occlusion
);
2122 this->EnterLayer(parent
, &occlusion
, false);
2124 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2125 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2126 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2127 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2129 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2130 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2131 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2133 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2135 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2137 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200),
2138 occlusion
.UnoccludedLayerContentRect(
2139 parent
, gfx::Rect(0, 0, 300, 300)));
2140 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50),
2141 occlusion
.UnoccludedLayerContentRect(
2142 parent
, gfx::Rect(0, 0, 300, 100)));
2143 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2144 occlusion
.UnoccludedLayerContentRect(
2145 parent
, gfx::Rect(0, 100, 300, 100)));
2146 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2147 occlusion
.UnoccludedLayerContentRect(
2148 parent
, gfx::Rect(200, 100, 100, 100)));
2149 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50),
2150 occlusion
.UnoccludedLayerContentRect(
2151 parent
, gfx::Rect(100, 200, 100, 100)));
2155 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild
);
2157 template <class Types
>
2158 class OcclusionTrackerTestViewportRectOverNothing
2159 : public OcclusionTrackerTest
<Types
> {
2161 explicit OcclusionTrackerTestViewportRectOverNothing(bool opaque_layers
)
2162 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2164 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2165 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2166 typename
Types::ContentLayerType
* layer
=
2167 this->CreateDrawingSurface(parent
,
2168 this->identity_matrix
,
2170 gfx::Size(200, 200),
2172 this->CalcDrawEtc(parent
);
2174 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2175 typename
Types::RenderSurfaceType
> occlusion(
2176 gfx::Rect(500, 500, 100, 100));
2178 this->EnterLayer(layer
, &occlusion
, false);
2180 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2181 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2182 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2183 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2185 this->LeaveLayer(layer
, &occlusion
);
2186 this->VisitContributingSurface(layer
, &occlusion
);
2187 this->EnterLayer(parent
, &occlusion
, false);
2189 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
2190 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2191 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
2192 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2193 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
2194 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
2195 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
2196 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
2197 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2199 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2200 parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2201 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2202 parent
, gfx::Rect(0, 0, 300, 100)).IsEmpty());
2203 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2204 parent
, gfx::Rect(0, 100, 300, 100)).IsEmpty());
2205 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2206 parent
, gfx::Rect(200, 100, 100, 100)).IsEmpty());
2207 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2208 parent
, gfx::Rect(100, 200, 100, 100)).IsEmpty());
2212 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing
);
2214 template <class Types
>
2215 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
2216 : public OcclusionTrackerTest
<Types
> {
2218 explicit OcclusionTrackerTestLayerClipRectForLayerOffOrigin(
2220 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2222 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2223 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2224 typename
Types::ContentLayerType
* layer
=
2225 this->CreateDrawingSurface(parent
,
2226 this->identity_matrix
,
2228 gfx::Size(200, 200),
2230 this->CalcDrawEtc(parent
);
2232 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2233 typename
Types::RenderSurfaceType
> occlusion(
2234 gfx::Rect(0, 0, 1000, 1000));
2235 this->EnterLayer(layer
, &occlusion
, false);
2237 // This layer is translated when drawn into its target. So if the clip rect
2238 // given from the target surface is not in that target space, then after
2239 // translating these query rects into the target, they will fall outside the
2240 // clip and be considered occluded.
2241 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2242 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2243 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2244 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2248 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin
);
2250 template <class Types
>
2251 class OcclusionTrackerTestOpaqueContentsRegionEmpty
2252 : public OcclusionTrackerTest
<Types
> {
2254 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
2255 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2257 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2258 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2259 typename
Types::ContentLayerType
* layer
=
2260 this->CreateDrawingSurface(parent
,
2261 this->identity_matrix
,
2263 gfx::Size(200, 200),
2265 this->CalcDrawEtc(parent
);
2267 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2268 typename
Types::RenderSurfaceType
> occlusion(
2269 gfx::Rect(0, 0, 1000, 1000));
2270 this->EnterLayer(layer
, &occlusion
, false);
2272 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2273 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
2274 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
2275 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
2277 // Occluded since its outside the surface bounds.
2278 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
2280 this->LeaveLayer(layer
, &occlusion
);
2281 this->VisitContributingSurface(layer
, &occlusion
);
2282 this->EnterLayer(parent
, &occlusion
, false);
2284 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2288 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
2290 template <class Types
>
2291 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
2292 : public OcclusionTrackerTest
<Types
> {
2294 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
2295 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2297 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2298 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2299 typename
Types::ContentLayerType
* layer
=
2300 this->CreateDrawingLayer(parent
,
2301 this->identity_matrix
,
2302 gfx::PointF(100.f
, 100.f
),
2303 gfx::Size(200, 200),
2305 this->CalcDrawEtc(parent
);
2307 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2308 typename
Types::RenderSurfaceType
> occlusion(
2309 gfx::Rect(0, 0, 1000, 1000));
2310 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
2312 this->ResetLayerIterator();
2313 this->VisitLayer(layer
, &occlusion
);
2314 this->EnterLayer(parent
, &occlusion
, false);
2316 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
2317 occlusion
.occlusion_from_inside_target().ToString());
2320 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2322 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2324 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2327 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2328 typename
Types::RenderSurfaceType
> occlusion(
2329 gfx::Rect(0, 0, 1000, 1000));
2330 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
2332 this->ResetLayerIterator();
2333 this->VisitLayer(layer
, &occlusion
);
2334 this->EnterLayer(parent
, &occlusion
, false);
2336 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
2337 occlusion
.occlusion_from_inside_target().ToString());
2340 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2342 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2344 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2347 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2348 typename
Types::RenderSurfaceType
> occlusion(
2349 gfx::Rect(0, 0, 1000, 1000));
2350 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
2352 this->ResetLayerIterator();
2353 this->VisitLayer(layer
, &occlusion
);
2354 this->EnterLayer(parent
, &occlusion
, false);
2356 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
2357 occlusion
.occlusion_from_inside_target().ToString());
2360 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
2362 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
2364 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
2369 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
2371 template <class Types
>
2372 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
2374 explicit OcclusionTrackerTest3dTransform(bool opaque_layers
)
2375 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2377 gfx::Transform transform
;
2378 transform
.RotateAboutYAxis(30.0);
2380 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2381 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2382 typename
Types::LayerType
* container
= this->CreateLayer(
2383 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2384 typename
Types::ContentLayerType
* layer
=
2385 this->CreateDrawingLayer(container
,
2387 gfx::PointF(100.f
, 100.f
),
2388 gfx::Size(200, 200),
2390 this->CalcDrawEtc(parent
);
2392 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2393 typename
Types::RenderSurfaceType
> occlusion(
2394 gfx::Rect(0, 0, 1000, 1000));
2395 this->EnterLayer(layer
, &occlusion
, false);
2397 // The layer is rotated in 3d but without preserving 3d, so it only gets
2400 gfx::Rect(0, 0, 200, 200),
2401 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
2405 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
2407 template <class Types
>
2408 class OcclusionTrackerTestUnsorted3dLayers
2409 : public OcclusionTrackerTest
<Types
> {
2411 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
2412 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2414 // Currently, The main thread layer iterator does not iterate over 3d items
2415 // in sorted order, because layer sorting is not performed on the main
2416 // thread. Because of this, the occlusion tracker cannot assume that a 3d
2417 // layer occludes other layers that have not yet been iterated over. For
2418 // now, the expected behavior is that a 3d layer simply does not add any
2419 // occlusion to the occlusion tracker.
2421 gfx::Transform translation_to_front
;
2422 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
2423 gfx::Transform translation_to_back
;
2424 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
2426 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2427 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2428 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
2429 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
2430 typename
Types::ContentLayerType
* child2
=
2431 this->CreateDrawingLayer(parent
,
2432 translation_to_front
,
2433 gfx::PointF(50.f
, 50.f
),
2434 gfx::Size(100, 100),
2436 parent
->SetPreserves3d(true);
2438 this->CalcDrawEtc(parent
);
2440 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2441 typename
Types::RenderSurfaceType
> occlusion(
2442 gfx::Rect(0, 0, 1000, 1000));
2443 this->VisitLayer(child2
, &occlusion
);
2444 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2445 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2447 this->VisitLayer(child1
, &occlusion
);
2448 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2449 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2453 // This test will have different layer ordering on the impl thread; the test
2454 // will only work on the main thread.
2455 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
2457 template <class Types
>
2458 class OcclusionTrackerTestPerspectiveTransform
2459 : public OcclusionTrackerTest
<Types
> {
2461 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers
)
2462 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2464 gfx::Transform transform
;
2465 transform
.Translate(150.0, 150.0);
2466 transform
.ApplyPerspectiveDepth(400.0);
2467 transform
.RotateAboutXAxis(-30.0);
2468 transform
.Translate(-150.0, -150.0);
2470 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2471 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2472 typename
Types::LayerType
* container
= this->CreateLayer(
2473 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2474 typename
Types::ContentLayerType
* layer
=
2475 this->CreateDrawingLayer(container
,
2477 gfx::PointF(100.f
, 100.f
),
2478 gfx::Size(200, 200),
2480 container
->SetPreserves3d(true);
2481 layer
->SetPreserves3d(true);
2482 this->CalcDrawEtc(parent
);
2484 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2485 typename
Types::RenderSurfaceType
> occlusion(
2486 gfx::Rect(0, 0, 1000, 1000));
2487 this->EnterLayer(layer
, &occlusion
, false);
2490 gfx::Rect(0, 0, 200, 200),
2491 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
2495 // This test requires accumulating occlusion of 3d layers, which are skipped by
2496 // the occlusion tracker on the main thread. So this test should run on the impl
2498 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
2500 template <class Types
>
2501 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2502 : public OcclusionTrackerTest
<Types
> {
2504 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2506 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2508 // This test is based on the platform/chromium/compositing/3d-corners.html
2510 gfx::Transform transform
;
2511 transform
.Translate(250.0, 50.0);
2512 transform
.ApplyPerspectiveDepth(10.0);
2513 transform
.Translate(-250.0, -50.0);
2514 transform
.Translate(250.0, 50.0);
2515 transform
.RotateAboutXAxis(-167.0);
2516 transform
.Translate(-250.0, -50.0);
2518 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2519 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 100));
2520 typename
Types::LayerType
* container
= this->CreateLayer(
2521 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2522 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2523 container
, transform
, gfx::PointF(), gfx::Size(500, 500), true);
2524 container
->SetPreserves3d(true);
2525 layer
->SetPreserves3d(true);
2526 this->CalcDrawEtc(parent
);
2528 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2529 typename
Types::RenderSurfaceType
> occlusion(
2530 gfx::Rect(0, 0, 1000, 1000));
2531 this->EnterLayer(layer
, &occlusion
, false);
2533 // The bottom 11 pixel rows of this layer remain visible inside the
2534 // container, after translation to the target surface. When translated back,
2535 // this will include many more pixels but must include at least the bottom
2537 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2538 layer
, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
2542 // This test requires accumulating occlusion of 3d layers, which are skipped by
2543 // the occlusion tracker on the main thread. So this test should run on the impl
2545 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
2547 template <class Types
>
2548 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2549 : public OcclusionTrackerTest
<Types
> {
2551 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2553 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2555 gfx::Transform transform
;
2556 transform
.Translate(50.0, 50.0);
2557 transform
.ApplyPerspectiveDepth(100.0);
2558 transform
.Translate3d(0.0, 0.0, 110.0);
2559 transform
.Translate(-50.0, -50.0);
2561 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2562 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2563 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2564 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2565 parent
->SetPreserves3d(true);
2566 layer
->SetPreserves3d(true);
2567 this->CalcDrawEtc(parent
);
2569 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2570 typename
Types::RenderSurfaceType
> occlusion(
2571 gfx::Rect(0, 0, 1000, 1000));
2573 // The |layer| is entirely behind the camera and should not occlude.
2574 this->VisitLayer(layer
, &occlusion
);
2575 this->EnterLayer(parent
, &occlusion
, false);
2576 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2577 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2581 // This test requires accumulating occlusion of 3d layers, which are skipped by
2582 // the occlusion tracker on the main thread. So this test should run on the impl
2584 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2586 template <class Types
>
2587 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2588 : public OcclusionTrackerTest
<Types
> {
2590 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2592 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2594 gfx::Transform transform
;
2595 transform
.Translate(50.0, 50.0);
2596 transform
.ApplyPerspectiveDepth(100.0);
2597 transform
.Translate3d(0.0, 0.0, 99.0);
2598 transform
.Translate(-50.0, -50.0);
2600 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2601 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2602 parent
->SetMasksToBounds(true);
2603 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2604 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2605 parent
->SetPreserves3d(true);
2606 layer
->SetPreserves3d(true);
2607 this->CalcDrawEtc(parent
);
2609 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2610 typename
Types::RenderSurfaceType
> occlusion(
2611 gfx::Rect(0, 0, 1000, 1000));
2613 // This is very close to the camera, so pixels in its visible_content_rect()
2614 // will actually go outside of the layer's clip rect. Ensure that those
2615 // pixels don't occlude things outside the clip rect.
2616 this->VisitLayer(layer
, &occlusion
);
2617 this->EnterLayer(parent
, &occlusion
, false);
2618 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2619 occlusion
.occlusion_from_inside_target().ToString());
2620 EXPECT_EQ(gfx::Rect().ToString(),
2621 occlusion
.occlusion_from_outside_target().ToString());
2625 // This test requires accumulating occlusion of 3d layers, which are skipped by
2626 // the occlusion tracker on the main thread. So this test should run on the impl
2628 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2630 template <class Types
>
2631 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2632 : public OcclusionTrackerTest
<Types
> {
2634 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
2635 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2640 // | +--surface_child
2641 // | +--surface_child2
2645 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2646 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2647 typename
Types::ContentLayerType
* layer
=
2648 this->CreateDrawingLayer(parent
,
2649 this->identity_matrix
,
2651 gfx::Size(300, 300),
2653 typename
Types::ContentLayerType
* surface
=
2654 this->CreateDrawingSurface(parent
,
2655 this->identity_matrix
,
2657 gfx::Size(300, 300),
2659 typename
Types::ContentLayerType
* surface_child
=
2660 this->CreateDrawingLayer(surface
,
2661 this->identity_matrix
,
2663 gfx::Size(200, 300),
2665 typename
Types::ContentLayerType
* surface_child2
=
2666 this->CreateDrawingLayer(surface
,
2667 this->identity_matrix
,
2669 gfx::Size(100, 300),
2671 typename
Types::ContentLayerType
* parent2
=
2672 this->CreateDrawingLayer(parent
,
2673 this->identity_matrix
,
2675 gfx::Size(300, 300),
2677 typename
Types::ContentLayerType
* topmost
=
2678 this->CreateDrawingLayer(parent
,
2679 this->identity_matrix
,
2680 gfx::PointF(250.f
, 0.f
),
2684 AddOpacityTransitionToController(
2685 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2686 AddOpacityTransitionToController(
2687 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2688 this->CalcDrawEtc(parent
);
2690 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2691 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2692 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2694 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2695 typename
Types::RenderSurfaceType
> occlusion(
2696 gfx::Rect(0, 0, 1000, 1000));
2698 this->VisitLayer(topmost
, &occlusion
);
2699 this->EnterLayer(parent2
, &occlusion
, false);
2700 // This occlusion will affect all surfaces.
2701 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2702 occlusion
.occlusion_from_inside_target().ToString());
2703 EXPECT_EQ(gfx::Rect().ToString(),
2704 occlusion
.occlusion_from_outside_target().ToString());
2705 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2706 occlusion
.UnoccludedLayerContentRect(
2707 parent2
, gfx::Rect(0, 0, 300, 300)).ToString());
2708 this->LeaveLayer(parent2
, &occlusion
);
2710 this->VisitLayer(surface_child2
, &occlusion
);
2711 this->EnterLayer(surface_child
, &occlusion
, false);
2712 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2713 occlusion
.occlusion_from_inside_target().ToString());
2714 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2715 occlusion
.occlusion_from_outside_target().ToString());
2716 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2717 occlusion
.UnoccludedLayerContentRect(
2718 surface_child
, gfx::Rect(0, 0, 200, 300)));
2719 this->LeaveLayer(surface_child
, &occlusion
);
2720 this->EnterLayer(surface
, &occlusion
, false);
2721 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2722 occlusion
.occlusion_from_inside_target().ToString());
2723 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2724 occlusion
.occlusion_from_outside_target().ToString());
2725 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2726 occlusion
.UnoccludedLayerContentRect(
2727 surface
, gfx::Rect(0, 0, 300, 300)));
2728 this->LeaveLayer(surface
, &occlusion
);
2730 this->EnterContributingSurface(surface
, &occlusion
, false);
2731 // Occlusion within the surface is lost when leaving the animating surface.
2732 EXPECT_EQ(gfx::Rect().ToString(),
2733 occlusion
.occlusion_from_inside_target().ToString());
2734 EXPECT_EQ(gfx::Rect().ToString(),
2735 occlusion
.occlusion_from_outside_target().ToString());
2736 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2737 occlusion
.UnoccludedContributingSurfaceContentRect(
2738 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
2739 this->LeaveContributingSurface(surface
, &occlusion
);
2741 // Occlusion from outside the animating surface still exists.
2742 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2743 occlusion
.occlusion_from_inside_target().ToString());
2744 EXPECT_EQ(gfx::Rect().ToString(),
2745 occlusion
.occlusion_from_outside_target().ToString());
2747 this->VisitLayer(layer
, &occlusion
);
2748 this->EnterLayer(parent
, &occlusion
, false);
2750 // Occlusion is not added for the animating |layer|.
2751 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2752 occlusion
.UnoccludedLayerContentRect(
2753 parent
, gfx::Rect(0, 0, 300, 300)));
2757 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2759 template <class Types
>
2760 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2761 : public OcclusionTrackerTest
<Types
> {
2763 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
2764 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2766 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2767 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2768 typename
Types::ContentLayerType
* layer
=
2769 this->CreateDrawingLayer(parent
,
2770 this->identity_matrix
,
2772 gfx::Size(300, 300),
2774 typename
Types::ContentLayerType
* surface
=
2775 this->CreateDrawingSurface(parent
,
2776 this->identity_matrix
,
2778 gfx::Size(300, 300),
2780 typename
Types::ContentLayerType
* surface_child
=
2781 this->CreateDrawingLayer(surface
,
2782 this->identity_matrix
,
2784 gfx::Size(200, 300),
2786 typename
Types::ContentLayerType
* surface_child2
=
2787 this->CreateDrawingLayer(surface
,
2788 this->identity_matrix
,
2790 gfx::Size(100, 300),
2792 typename
Types::ContentLayerType
* parent2
=
2793 this->CreateDrawingLayer(parent
,
2794 this->identity_matrix
,
2796 gfx::Size(300, 300),
2798 typename
Types::ContentLayerType
* topmost
=
2799 this->CreateDrawingLayer(parent
,
2800 this->identity_matrix
,
2801 gfx::PointF(250.f
, 0.f
),
2805 AddOpacityTransitionToController(
2806 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2807 AddOpacityTransitionToController(
2808 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2809 this->CalcDrawEtc(parent
);
2811 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2812 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2813 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2815 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2816 typename
Types::RenderSurfaceType
> occlusion(
2817 gfx::Rect(0, 0, 1000, 1000));
2819 this->VisitLayer(topmost
, &occlusion
);
2820 this->EnterLayer(parent2
, &occlusion
, false);
2821 // This occlusion will affect all surfaces.
2822 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2823 occlusion
.occlusion_from_inside_target().ToString());
2824 EXPECT_EQ(gfx::Rect().ToString(),
2825 occlusion
.occlusion_from_outside_target().ToString());
2826 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2827 occlusion
.UnoccludedLayerContentRect(
2828 parent
, gfx::Rect(0, 0, 300, 300)));
2829 this->LeaveLayer(parent2
, &occlusion
);
2831 this->VisitLayer(surface_child2
, &occlusion
);
2832 this->EnterLayer(surface_child
, &occlusion
, false);
2833 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2834 occlusion
.occlusion_from_inside_target().ToString());
2835 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2836 occlusion
.occlusion_from_outside_target().ToString());
2837 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2838 occlusion
.UnoccludedLayerContentRect(
2839 surface_child
, gfx::Rect(0, 0, 200, 300)));
2840 this->LeaveLayer(surface_child
, &occlusion
);
2841 this->EnterLayer(surface
, &occlusion
, false);
2842 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2843 occlusion
.occlusion_from_inside_target().ToString());
2844 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2845 occlusion
.occlusion_from_outside_target().ToString());
2846 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2847 occlusion
.UnoccludedLayerContentRect(
2848 surface
, gfx::Rect(0, 0, 300, 300)));
2849 this->LeaveLayer(surface
, &occlusion
);
2851 this->EnterContributingSurface(surface
, &occlusion
, false);
2852 // Occlusion within the surface is lost when leaving the animating surface.
2853 EXPECT_EQ(gfx::Rect().ToString(),
2854 occlusion
.occlusion_from_inside_target().ToString());
2855 EXPECT_EQ(gfx::Rect().ToString(),
2856 occlusion
.occlusion_from_outside_target().ToString());
2857 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2858 occlusion
.UnoccludedContributingSurfaceContentRect(
2859 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
2860 this->LeaveContributingSurface(surface
, &occlusion
);
2862 // Occlusion from outside the animating surface still exists.
2863 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2864 occlusion
.occlusion_from_inside_target().ToString());
2865 EXPECT_EQ(gfx::Rect().ToString(),
2866 occlusion
.occlusion_from_outside_target().ToString());
2868 this->VisitLayer(layer
, &occlusion
);
2869 this->EnterLayer(parent
, &occlusion
, false);
2871 // Occlusion is not added for the animating |layer|.
2872 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2873 occlusion
.UnoccludedLayerContentRect(
2874 parent
, gfx::Rect(0, 0, 300, 300)));
2878 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2880 template <class Types
>
2881 class OcclusionTrackerTestAnimationTranslateOnMainThread
2882 : public OcclusionTrackerTest
<Types
> {
2884 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2886 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2888 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2889 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2890 typename
Types::ContentLayerType
* layer
=
2891 this->CreateDrawingLayer(parent
,
2892 this->identity_matrix
,
2894 gfx::Size(300, 300),
2896 typename
Types::ContentLayerType
* surface
=
2897 this->CreateDrawingSurface(parent
,
2898 this->identity_matrix
,
2900 gfx::Size(300, 300),
2902 typename
Types::ContentLayerType
* surface_child
=
2903 this->CreateDrawingLayer(surface
,
2904 this->identity_matrix
,
2906 gfx::Size(200, 300),
2908 typename
Types::ContentLayerType
* surface_child2
=
2909 this->CreateDrawingLayer(surface
,
2910 this->identity_matrix
,
2912 gfx::Size(100, 300),
2914 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
2915 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
2917 AddAnimatedTransformToController(
2918 layer
->layer_animation_controller(), 10.0, 30, 0);
2919 AddAnimatedTransformToController(
2920 surface
->layer_animation_controller(), 10.0, 30, 0);
2921 AddAnimatedTransformToController(
2922 surface_child
->layer_animation_controller(), 10.0, 30, 0);
2923 this->CalcDrawEtc(parent
);
2925 EXPECT_TRUE(layer
->draw_transform_is_animating());
2926 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
2928 surface
->render_surface()->target_surface_transforms_are_animating());
2930 surface
->render_surface()->screen_space_transforms_are_animating());
2931 // The surface owning layer doesn't animate against its own surface.
2932 EXPECT_FALSE(surface
->draw_transform_is_animating());
2933 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
2934 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
2935 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
2937 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2938 typename
Types::RenderSurfaceType
> occlusion(
2939 gfx::Rect(0, 0, 1000, 1000));
2941 this->VisitLayer(surface2
, &occlusion
);
2942 this->EnterContributingSurface(surface2
, &occlusion
, false);
2944 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2945 occlusion
.occlusion_from_inside_target().ToString());
2947 this->LeaveContributingSurface(surface2
, &occlusion
);
2948 this->EnterLayer(surface_child2
, &occlusion
, false);
2950 // surface_child2 is moving in screen space but not relative to its target,
2951 // so occlusion should happen in its target space only. It also means that
2952 // things occluding from outside the target (e.g. surface2) cannot occlude
2954 EXPECT_EQ(gfx::Rect().ToString(),
2955 occlusion
.occlusion_from_outside_target().ToString());
2957 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2958 occlusion
.UnoccludedLayerContentRect(
2959 surface_child2
, gfx::Rect(0, 0, 100, 300)));
2961 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2963 this->LeaveLayer(surface_child2
, &occlusion
);
2964 this->EnterLayer(surface_child
, &occlusion
, false);
2966 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 100, 300)));
2967 EXPECT_EQ(gfx::Rect().ToString(),
2968 occlusion
.occlusion_from_outside_target().ToString());
2969 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2970 occlusion
.occlusion_from_inside_target().ToString());
2971 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2972 occlusion
.UnoccludedLayerContentRect(
2973 surface
, gfx::Rect(0, 0, 300, 300)));
2975 // The surface_child is occluded by the surface_child2, but is moving
2976 // relative its target, so it can't be occluded.
2977 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2978 occlusion
.UnoccludedLayerContentRect(
2979 surface_child
, gfx::Rect(0, 0, 200, 300)));
2981 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2983 this->LeaveLayer(surface_child
, &occlusion
);
2984 this->EnterLayer(surface
, &occlusion
, false);
2985 // The surface_child is moving in screen space but not relative to its
2986 // target, so occlusion should happen from within the target only.
2987 EXPECT_EQ(gfx::Rect().ToString(),
2988 occlusion
.occlusion_from_outside_target().ToString());
2989 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2990 occlusion
.occlusion_from_inside_target().ToString());
2991 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2992 occlusion
.UnoccludedLayerContentRect(
2993 surface
, gfx::Rect(0, 0, 300, 300)));
2995 this->LeaveLayer(surface
, &occlusion
);
2996 // The surface's owning layer is moving in screen space but not relative to
2997 // its target, so occlusion should happen within the target only.
2998 EXPECT_EQ(gfx::Rect().ToString(),
2999 occlusion
.occlusion_from_outside_target().ToString());
3000 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
3001 occlusion
.occlusion_from_inside_target().ToString());
3002 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3003 occlusion
.UnoccludedLayerContentRect(
3004 surface
, gfx::Rect(0, 0, 300, 300)));
3006 this->EnterContributingSurface(surface
, &occlusion
, false);
3007 // The contributing |surface| is animating so it can't be occluded.
3008 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
3009 occlusion
.UnoccludedContributingSurfaceContentRect(
3010 surface
, false, gfx::Rect(0, 0, 300, 300), NULL
));
3011 this->LeaveContributingSurface(surface
, &occlusion
);
3013 this->EnterLayer(layer
, &occlusion
, false);
3014 // The |surface| is moving in the screen and in its target, so all occlusion
3015 // within the surface is lost when leaving it.
3016 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3017 occlusion
.UnoccludedLayerContentRect(
3018 parent
, gfx::Rect(0, 0, 300, 300)));
3019 this->LeaveLayer(layer
, &occlusion
);
3021 this->EnterLayer(parent
, &occlusion
, false);
3022 // The |layer| is animating in the screen and in its target, so no occlusion
3024 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3025 occlusion
.UnoccludedLayerContentRect(
3026 parent
, gfx::Rect(0, 0, 300, 300)));
3030 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
3032 template <class Types
>
3033 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
3034 : public OcclusionTrackerTest
<Types
> {
3036 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
3038 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3040 gfx::Transform surface_transform
;
3041 surface_transform
.Translate(300.0, 300.0);
3042 surface_transform
.Scale(2.0, 2.0);
3043 surface_transform
.Translate(-150.0, -150.0);
3045 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3046 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
3047 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
3048 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
3049 typename
Types::ContentLayerType
* surface2
=
3050 this->CreateDrawingSurface(parent
,
3051 this->identity_matrix
,
3052 gfx::PointF(50.f
, 50.f
),
3053 gfx::Size(300, 300),
3055 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3056 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3057 this->CalcDrawEtc(parent
);
3059 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3060 typename
Types::RenderSurfaceType
> occlusion(
3061 gfx::Rect(0, 0, 1000, 1000));
3063 this->VisitLayer(surface2
, &occlusion
);
3064 this->VisitContributingSurface(surface2
, &occlusion
);
3066 EXPECT_EQ(gfx::Rect().ToString(),
3067 occlusion
.occlusion_from_outside_target().ToString());
3068 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
3069 occlusion
.occlusion_from_inside_target().ToString());
3071 // Clear any stored occlusion.
3072 occlusion
.set_occlusion_from_outside_target(Region());
3073 occlusion
.set_occlusion_from_inside_target(Region());
3075 this->VisitLayer(surface
, &occlusion
);
3076 this->VisitContributingSurface(surface
, &occlusion
);
3078 EXPECT_EQ(gfx::Rect().ToString(),
3079 occlusion
.occlusion_from_outside_target().ToString());
3080 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
3081 occlusion
.occlusion_from_inside_target().ToString());
3085 MAIN_AND_IMPL_THREAD_TEST(
3086 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
3088 template <class Types
>
3089 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
3090 : public OcclusionTrackerTest
<Types
> {
3092 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
3094 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3096 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3097 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
3098 parent
->SetMasksToBounds(true);
3099 typename
Types::ContentLayerType
* surface
=
3100 this->CreateDrawingSurface(parent
,
3101 this->identity_matrix
,
3103 gfx::Size(500, 300),
3105 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
3106 this->CalcDrawEtc(parent
);
3108 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3109 typename
Types::RenderSurfaceType
> occlusion(
3110 gfx::Rect(0, 0, 1000, 1000));
3112 this->VisitLayer(surface
, &occlusion
);
3113 this->VisitContributingSurface(surface
, &occlusion
);
3115 EXPECT_EQ(gfx::Rect().ToString(),
3116 occlusion
.occlusion_from_outside_target().ToString());
3117 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
3118 occlusion
.occlusion_from_inside_target().ToString());
3122 MAIN_AND_IMPL_THREAD_TEST(
3123 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
3125 template <class Types
>
3126 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
3128 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers
)
3129 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3131 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3132 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3133 typename
Types::LayerType
* surface
=
3134 this->CreateDrawingSurface(parent
,
3135 this->identity_matrix
,
3137 gfx::Size(100, 100),
3139 this->CreateReplicaLayer(surface
,
3140 this->identity_matrix
,
3141 gfx::PointF(0.f
, 100.f
),
3142 gfx::Size(100, 100));
3143 typename
Types::LayerType
* topmost
=
3144 this->CreateDrawingLayer(parent
,
3145 this->identity_matrix
,
3146 gfx::PointF(0.f
, 100.f
),
3147 gfx::Size(100, 100),
3149 this->CalcDrawEtc(parent
);
3151 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3152 typename
Types::RenderSurfaceType
> occlusion(
3153 gfx::Rect(0, 0, 1000, 1000));
3155 // |topmost| occludes the replica, but not the surface itself.
3156 this->VisitLayer(topmost
, &occlusion
);
3158 EXPECT_EQ(gfx::Rect().ToString(),
3159 occlusion
.occlusion_from_outside_target().ToString());
3160 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3161 occlusion
.occlusion_from_inside_target().ToString());
3163 this->VisitLayer(surface
, &occlusion
);
3165 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3166 occlusion
.occlusion_from_outside_target().ToString());
3167 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3168 occlusion
.occlusion_from_inside_target().ToString());
3170 this->EnterContributingSurface(surface
, &occlusion
, false);
3172 // Surface is not occluded so it shouldn't think it is.
3173 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3174 occlusion
.UnoccludedContributingSurfaceContentRect(
3175 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3179 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
3181 template <class Types
>
3182 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
3183 : public OcclusionTrackerTest
<Types
> {
3185 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
3186 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3188 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3189 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3190 typename
Types::LayerType
* surface
=
3191 this->CreateDrawingSurface(parent
,
3192 this->identity_matrix
,
3194 gfx::Size(100, 100),
3196 this->CreateReplicaLayer(surface
,
3197 this->identity_matrix
,
3198 gfx::PointF(0.f
, 100.f
),
3199 gfx::Size(100, 100));
3200 typename
Types::LayerType
* topmost
=
3201 this->CreateDrawingLayer(parent
,
3202 this->identity_matrix
,
3204 gfx::Size(100, 110),
3206 this->CalcDrawEtc(parent
);
3208 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3209 typename
Types::RenderSurfaceType
> occlusion(
3210 gfx::Rect(0, 0, 1000, 1000));
3212 // |topmost| occludes the surface, but not the entire surface's replica.
3213 this->VisitLayer(topmost
, &occlusion
);
3215 EXPECT_EQ(gfx::Rect().ToString(),
3216 occlusion
.occlusion_from_outside_target().ToString());
3217 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3218 occlusion
.occlusion_from_inside_target().ToString());
3220 this->VisitLayer(surface
, &occlusion
);
3222 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3223 occlusion
.occlusion_from_outside_target().ToString());
3224 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3225 occlusion
.occlusion_from_inside_target().ToString());
3227 this->EnterContributingSurface(surface
, &occlusion
, false);
3229 // Surface is occluded, but only the top 10px of the replica.
3230 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3231 occlusion
.UnoccludedContributingSurfaceContentRect(
3232 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3233 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
3234 occlusion
.UnoccludedContributingSurfaceContentRect(
3235 surface
, true, gfx::Rect(0, 0, 100, 100), NULL
));
3239 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
3241 template <class Types
>
3242 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
3243 : public OcclusionTrackerTest
<Types
> {
3245 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
3247 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3249 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3250 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3251 typename
Types::LayerType
* surface
=
3252 this->CreateDrawingSurface(parent
,
3253 this->identity_matrix
,
3255 gfx::Size(100, 100),
3257 this->CreateReplicaLayer(surface
,
3258 this->identity_matrix
,
3259 gfx::PointF(0.f
, 100.f
),
3260 gfx::Size(100, 100));
3261 typename
Types::LayerType
* over_surface
= this->CreateDrawingLayer(
3262 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 100), true);
3263 typename
Types::LayerType
* over_replica
=
3264 this->CreateDrawingLayer(parent
,
3265 this->identity_matrix
,
3266 gfx::PointF(0.f
, 100.f
),
3269 this->CalcDrawEtc(parent
);
3271 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3272 typename
Types::RenderSurfaceType
> occlusion(
3273 gfx::Rect(0, 0, 1000, 1000));
3275 // These occlude the surface and replica differently, so we can test each
3277 this->VisitLayer(over_replica
, &occlusion
);
3278 this->VisitLayer(over_surface
, &occlusion
);
3280 EXPECT_EQ(gfx::Rect().ToString(),
3281 occlusion
.occlusion_from_outside_target().ToString());
3282 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3284 occlusion
.occlusion_from_inside_target().ToString());
3286 this->VisitLayer(surface
, &occlusion
);
3288 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3290 occlusion
.occlusion_from_outside_target().ToString());
3291 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3292 occlusion
.occlusion_from_inside_target().ToString());
3294 this->EnterContributingSurface(surface
, &occlusion
, false);
3296 // Surface and replica are occluded different amounts.
3297 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
3298 occlusion
.UnoccludedContributingSurfaceContentRect(
3299 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3300 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
3301 occlusion
.UnoccludedContributingSurfaceContentRect(
3302 surface
, true, gfx::Rect(0, 0, 100, 100), NULL
));
3306 ALL_OCCLUSIONTRACKER_TEST(
3307 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
3309 template <class Types
>
3310 class OcclusionTrackerTestSurfaceChildOfSurface
3311 : public OcclusionTrackerTest
<Types
> {
3313 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
3314 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3316 // This test verifies that the surface cliprect does not end up empty and
3317 // clip away the entire unoccluded rect.
3319 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3320 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3321 typename
Types::LayerType
* surface
=
3322 this->CreateDrawingSurface(parent
,
3323 this->identity_matrix
,
3325 gfx::Size(100, 100),
3327 typename
Types::LayerType
* surface_child
=
3328 this->CreateDrawingSurface(surface
,
3329 this->identity_matrix
,
3330 gfx::PointF(0.f
, 10.f
),
3333 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
3334 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
3335 this->CalcDrawEtc(parent
);
3337 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3338 typename
Types::RenderSurfaceType
> occlusion(
3339 gfx::Rect(-100, -100, 1000, 1000));
3341 // |topmost| occludes everything partially so we know occlusion is happening
3343 this->VisitLayer(topmost
, &occlusion
);
3345 EXPECT_EQ(gfx::Rect().ToString(),
3346 occlusion
.occlusion_from_outside_target().ToString());
3347 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3348 occlusion
.occlusion_from_inside_target().ToString());
3350 this->VisitLayer(surface_child
, &occlusion
);
3352 // surface_child increases the occlusion in the screen by a narrow sliver.
3353 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
3354 occlusion
.occlusion_from_outside_target().ToString());
3355 // In its own surface, surface_child is at 0,0 as is its occlusion.
3356 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3357 occlusion
.occlusion_from_inside_target().ToString());
3359 // The root layer always has a clip rect. So the parent of |surface| has a
3360 // clip rect. However, the owning layer for |surface| does not mask to
3361 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3362 // |surface_child| exercises different code paths as its parent does not
3363 // have a clip rect.
3365 this->EnterContributingSurface(surface_child
, &occlusion
, false);
3366 // The surface_child's parent does not have a clip rect as it owns a render
3367 // surface. Make sure the unoccluded rect does not get clipped away
3369 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
3370 occlusion
.UnoccludedContributingSurfaceContentRect(
3371 surface_child
, false, gfx::Rect(0, 0, 100, 50), NULL
));
3372 this->LeaveContributingSurface(surface_child
, &occlusion
);
3374 // When the surface_child's occlusion is transformed up to its parent, make
3375 // sure it is not clipped away inappropriately also.
3376 this->EnterLayer(surface
, &occlusion
, false);
3377 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3378 occlusion
.occlusion_from_outside_target().ToString());
3379 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
3380 occlusion
.occlusion_from_inside_target().ToString());
3381 this->LeaveLayer(surface
, &occlusion
);
3383 this->EnterContributingSurface(surface
, &occlusion
, false);
3384 // The surface's parent does have a clip rect as it is the root layer.
3385 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
3386 occlusion
.UnoccludedContributingSurfaceContentRect(
3387 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
));
3391 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
3393 template <class Types
>
3394 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
3395 : public OcclusionTrackerTest
<Types
> {
3397 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
3399 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3401 // This test verifies that the top-most surface is considered occluded
3402 // outside of its target's clip rect and outside the viewport rect.
3404 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3405 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
3406 typename
Types::LayerType
* surface
=
3407 this->CreateDrawingSurface(parent
,
3408 this->identity_matrix
,
3410 gfx::Size(100, 300),
3412 this->CalcDrawEtc(parent
);
3414 // Make a viewport rect that is larger than the root layer.
3415 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3416 typename
Types::RenderSurfaceType
> occlusion(
3417 gfx::Rect(0, 0, 1000, 1000));
3419 this->VisitLayer(surface
, &occlusion
);
3421 // The root layer always has a clip rect. So the parent of |surface| has a
3422 // clip rect giving the surface itself a clip rect.
3423 this->EnterContributingSurface(surface
, &occlusion
, false);
3424 // Make sure the parent's clip rect clips the unoccluded region of the
3426 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
3427 occlusion
.UnoccludedContributingSurfaceContentRect(
3428 surface
, false, gfx::Rect(0, 0, 100, 300), NULL
));
3430 this->ResetLayerIterator();
3432 // Make a viewport rect that is smaller than the root layer.
3433 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3434 typename
Types::RenderSurfaceType
> occlusion(
3435 gfx::Rect(0, 0, 100, 100));
3437 this->VisitLayer(surface
, &occlusion
);
3439 // The root layer always has a clip rect. So the parent of |surface| has a
3440 // clip rect giving the surface itself a clip rect.
3441 this->EnterContributingSurface(surface
, &occlusion
, false);
3442 // Make sure the viewport rect clips the unoccluded region of the child
3444 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3445 occlusion
.UnoccludedContributingSurfaceContentRect(
3446 surface
, false, gfx::Rect(0, 0, 100, 300), NULL
));
3451 ALL_OCCLUSIONTRACKER_TEST(
3452 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
);
3454 template <class Types
>
3455 class OcclusionTrackerTestSurfaceChildOfClippingSurface
3456 : public OcclusionTrackerTest
<Types
> {
3458 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers
)
3459 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3461 // This test verifies that the surface cliprect does not end up empty and
3462 // clip away the entire unoccluded rect.
3464 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3465 this->identity_matrix
, gfx::PointF(), gfx::Size(80, 200));
3466 parent
->SetMasksToBounds(true);
3467 typename
Types::LayerType
* surface
=
3468 this->CreateDrawingSurface(parent
,
3469 this->identity_matrix
,
3471 gfx::Size(100, 100),
3473 typename
Types::LayerType
* surface_child
=
3474 this->CreateDrawingSurface(surface
,
3475 this->identity_matrix
,
3477 gfx::Size(100, 100),
3479 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
3480 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
3481 this->CalcDrawEtc(parent
);
3483 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3484 typename
Types::RenderSurfaceType
> occlusion(
3485 gfx::Rect(0, 0, 1000, 1000));
3487 // |topmost| occludes everything partially so we know occlusion is happening
3489 this->VisitLayer(topmost
, &occlusion
);
3491 EXPECT_EQ(gfx::Rect().ToString(),
3492 occlusion
.occlusion_from_outside_target().ToString());
3493 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3494 occlusion
.occlusion_from_inside_target().ToString());
3496 // surface_child is not opaque and does not occlude, so we have a non-empty
3497 // unoccluded area on surface.
3498 this->VisitLayer(surface_child
, &occlusion
);
3500 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3501 occlusion
.occlusion_from_outside_target().ToString());
3502 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3503 occlusion
.occlusion_from_inside_target().ToString());
3505 // The root layer always has a clip rect. So the parent of |surface| has a
3506 // clip rect. However, the owning layer for |surface| does not mask to
3507 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3508 // |surface_child| exercises different code paths as its parent does not
3509 // have a clip rect.
3511 this->EnterContributingSurface(surface_child
, &occlusion
, false);
3512 // The surface_child's parent does not have a clip rect as it owns a render
3515 gfx::Rect(0, 50, 80, 50).ToString(),
3516 occlusion
.UnoccludedContributingSurfaceContentRect(
3517 surface_child
, false, gfx::Rect(0, 0, 100, 100), NULL
).ToString());
3518 this->LeaveContributingSurface(surface_child
, &occlusion
);
3520 this->VisitLayer(surface
, &occlusion
);
3521 this->EnterContributingSurface(surface
, &occlusion
, false);
3522 // The surface's parent does have a clip rect as it is the root layer.
3523 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3524 occlusion
.UnoccludedContributingSurfaceContentRect(
3525 surface
, false, gfx::Rect(0, 0, 100, 100), NULL
).ToString());
3529 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface
);
3531 template <class Types
>
3532 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3533 : public OcclusionTrackerTest
<Types
> {
3535 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3537 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3539 gfx::Transform scale_by_half
;
3540 scale_by_half
.Scale(0.5, 0.5);
3542 // Make a surface and its replica, each 50x50, that are completely
3543 // surrounded by opaque layers which are above them in the z-order. The
3544 // surface is scaled to test that the pixel moving is done in the target
3545 // space, where the background filter is applied, but the surface appears at
3546 // 50, 50 and the replica at 200, 50.
3547 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3548 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3549 typename
Types::LayerType
* filtered_surface
=
3550 this->CreateDrawingLayer(parent
,
3552 gfx::PointF(50.f
, 50.f
),
3553 gfx::Size(100, 100),
3555 this->CreateReplicaLayer(filtered_surface
,
3556 this->identity_matrix
,
3557 gfx::PointF(300.f
, 0.f
),
3559 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3560 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 50), true);
3561 typename
Types::LayerType
* occluding_layer2
=
3562 this->CreateDrawingLayer(parent
,
3563 this->identity_matrix
,
3564 gfx::PointF(0.f
, 100.f
),
3567 typename
Types::LayerType
* occluding_layer3
=
3568 this->CreateDrawingLayer(parent
,
3569 this->identity_matrix
,
3570 gfx::PointF(0.f
, 50.f
),
3573 typename
Types::LayerType
* occluding_layer4
=
3574 this->CreateDrawingLayer(parent
,
3575 this->identity_matrix
,
3576 gfx::PointF(100.f
, 50.f
),
3579 typename
Types::LayerType
* occluding_layer5
=
3580 this->CreateDrawingLayer(parent
,
3581 this->identity_matrix
,
3582 gfx::PointF(250.f
, 50.f
),
3586 // Filters make the layer own a surface.
3587 FilterOperations filters
;
3588 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
3589 filtered_surface
->SetBackgroundFilters(filters
);
3591 // Save the distance of influence for the blur effect.
3592 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3594 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3596 this->CalcDrawEtc(parent
);
3598 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3599 typename
Types::RenderSurfaceType
> occlusion(
3600 gfx::Rect(0, 0, 1000, 1000));
3602 // These layers occlude pixels directly beside the filtered_surface. Because
3603 // filtered surface blends pixels in a radius, it will need to see some of
3604 // the pixels (up to radius far) underneath the occluding layers.
3605 this->VisitLayer(occluding_layer5
, &occlusion
);
3606 this->VisitLayer(occluding_layer4
, &occlusion
);
3607 this->VisitLayer(occluding_layer3
, &occlusion
);
3608 this->VisitLayer(occluding_layer2
, &occlusion
);
3609 this->VisitLayer(occluding_layer1
, &occlusion
);
3611 Region expected_occlusion
;
3612 expected_occlusion
.Union(gfx::Rect(0, 0, 300, 50));
3613 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3614 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3615 expected_occlusion
.Union(gfx::Rect(250, 50, 50, 50));
3616 expected_occlusion
.Union(gfx::Rect(0, 100, 300, 50));
3618 EXPECT_EQ(expected_occlusion
.ToString(),
3619 occlusion
.occlusion_from_inside_target().ToString());
3620 EXPECT_EQ(gfx::Rect().ToString(),
3621 occlusion
.occlusion_from_outside_target().ToString());
3623 this->VisitLayer(filtered_surface
, &occlusion
);
3625 // The filtered layer/replica does not occlude.
3626 Region expected_occlusion_outside_surface
;
3627 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 300, 50));
3628 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3629 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3630 expected_occlusion_outside_surface
.Union(gfx::Rect(200, 0, 50, 50));
3631 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 300, 50));
3633 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3634 occlusion
.occlusion_from_outside_target().ToString());
3635 EXPECT_EQ(gfx::Rect().ToString(),
3636 occlusion
.occlusion_from_inside_target().ToString());
3638 // The surface has a background blur, so it needs pixels that are currently
3639 // considered occluded in order to be drawn. So the pixels it needs should
3640 // be removed some the occluded area so that when we get to the parent they
3642 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3644 this->EnterLayer(parent
, &occlusion
, false);
3646 Region expected_blurred_occlusion
;
3647 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 300, 50 - outset_top
));
3648 expected_blurred_occlusion
.Union(gfx::Rect(
3649 0, 50 - outset_top
, 50 - outset_left
, 50 + outset_top
+ outset_bottom
));
3650 expected_blurred_occlusion
.Union(
3651 gfx::Rect(100 + outset_right
,
3653 100 - outset_right
- outset_left
,
3654 50 + outset_top
+ outset_bottom
));
3655 expected_blurred_occlusion
.Union(
3656 gfx::Rect(250 + outset_right
,
3659 50 + outset_top
+ outset_bottom
));
3660 expected_blurred_occlusion
.Union(
3661 gfx::Rect(0, 100 + outset_bottom
, 300, 50 - outset_bottom
));
3663 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3664 occlusion
.occlusion_from_inside_target().ToString());
3665 EXPECT_EQ(gfx::Rect().ToString(),
3666 occlusion
.occlusion_from_outside_target().ToString());
3668 gfx::Rect outset_rect
;
3669 gfx::Rect test_rect
;
3671 // Nothing in the blur outsets for the filtered_surface is occluded.
3672 outset_rect
= gfx::Rect(50 - outset_left
,
3674 50 + outset_left
+ outset_right
,
3675 50 + outset_top
+ outset_bottom
);
3676 test_rect
= outset_rect
;
3678 outset_rect
.ToString(),
3679 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3681 // Stuff outside the blur outsets is still occluded though.
3682 test_rect
= outset_rect
;
3683 test_rect
.Inset(0, 0, -1, 0);
3685 outset_rect
.ToString(),
3686 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3687 test_rect
= outset_rect
;
3688 test_rect
.Inset(0, 0, 0, -1);
3690 outset_rect
.ToString(),
3691 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3692 test_rect
= outset_rect
;
3693 test_rect
.Inset(-1, 0, 0, 0);
3695 outset_rect
.ToString(),
3696 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3697 test_rect
= outset_rect
;
3698 test_rect
.Inset(0, -1, 0, 0);
3700 outset_rect
.ToString(),
3701 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3703 // Nothing in the blur outsets for the filtered_surface's replica is
3705 outset_rect
= gfx::Rect(200 - outset_left
,
3707 50 + outset_left
+ outset_right
,
3708 50 + outset_top
+ outset_bottom
);
3709 test_rect
= outset_rect
;
3711 outset_rect
.ToString(),
3712 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3714 // Stuff outside the blur outsets is still occluded though.
3715 test_rect
= outset_rect
;
3716 test_rect
.Inset(0, 0, -1, 0);
3718 outset_rect
.ToString(),
3719 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3720 test_rect
= outset_rect
;
3721 test_rect
.Inset(0, 0, 0, -1);
3723 outset_rect
.ToString(),
3724 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3725 test_rect
= outset_rect
;
3726 test_rect
.Inset(-1, 0, 0, 0);
3728 outset_rect
.ToString(),
3729 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3730 test_rect
= outset_rect
;
3731 test_rect
.Inset(0, -1, 0, 0);
3733 outset_rect
.ToString(),
3734 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3738 ALL_OCCLUSIONTRACKER_TEST(
3739 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
3741 template <class Types
>
3742 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3743 : public OcclusionTrackerTest
<Types
> {
3745 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3747 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3749 gfx::Transform scale_by_half
;
3750 scale_by_half
.Scale(0.5, 0.5);
3752 // Makes two surfaces that completely cover |parent|. The occlusion both
3753 // above and below the filters will be reduced by each of them.
3754 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3755 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
3756 typename
Types::LayerType
* parent
= this->CreateSurface(
3757 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
3758 parent
->SetMasksToBounds(true);
3759 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
3760 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3761 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
3762 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3763 typename
Types::LayerType
* occluding_layer_above
=
3764 this->CreateDrawingLayer(parent
,
3765 this->identity_matrix
,
3766 gfx::PointF(100.f
, 100.f
),
3770 // Filters make the layers own surfaces.
3771 FilterOperations filters
;
3772 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
3773 filtered_surface1
->SetBackgroundFilters(filters
);
3774 filtered_surface2
->SetBackgroundFilters(filters
);
3776 // Save the distance of influence for the blur effect.
3777 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3779 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3781 this->CalcDrawEtc(root
);
3783 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3784 typename
Types::RenderSurfaceType
> occlusion(
3785 gfx::Rect(0, 0, 1000, 1000));
3787 this->VisitLayer(occluding_layer_above
, &occlusion
);
3788 EXPECT_EQ(gfx::Rect().ToString(),
3789 occlusion
.occlusion_from_outside_target().ToString());
3790 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3791 occlusion
.occlusion_from_inside_target().ToString());
3793 this->VisitLayer(filtered_surface2
, &occlusion
);
3794 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
3795 this->VisitLayer(filtered_surface1
, &occlusion
);
3796 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
3798 // Test expectations in the target.
3799 gfx::Rect expected_occlusion
=
3800 gfx::Rect(100 / 2 + outset_right
* 2,
3801 100 / 2 + outset_bottom
* 2,
3802 50 / 2 - (outset_left
+ outset_right
) * 2,
3803 50 / 2 - (outset_top
+ outset_bottom
) * 2);
3804 EXPECT_EQ(expected_occlusion
.ToString(),
3805 occlusion
.occlusion_from_inside_target().ToString());
3807 // Test expectations in the screen are the same as in the target, as the
3808 // render surface is 1:1 with the screen.
3809 EXPECT_EQ(expected_occlusion
.ToString(),
3810 occlusion
.occlusion_from_outside_target().ToString());
3814 ALL_OCCLUSIONTRACKER_TEST(
3815 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
3817 template <class Types
>
3818 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
3819 : public OcclusionTrackerTest
<Types
> {
3822 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(
3824 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3826 // Make a surface and its replica, Each 50x50, that are completely
3827 // surrounded by opaque layers which are above them in the z-order.
3828 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3829 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3830 // We stick the filtered surface inside a clipping surface so that we can
3831 // make sure the clip is honored when exposing pixels for
3832 // the background filter.
3833 typename
Types::LayerType
* clipping_surface
=
3834 this->CreateDrawingSurface(parent
,
3835 this->identity_matrix
,
3839 clipping_surface
->SetMasksToBounds(true);
3840 typename
Types::LayerType
* filtered_surface
=
3841 this->CreateDrawingLayer(clipping_surface
,
3842 this->identity_matrix
,
3843 gfx::PointF(50.f
, 50.f
),
3846 this->CreateReplicaLayer(filtered_surface
,
3847 this->identity_matrix
,
3848 gfx::PointF(150.f
, 0.f
),
3850 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3851 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 50), true);
3852 typename
Types::LayerType
* occluding_layer2
=
3853 this->CreateDrawingLayer(parent
,
3854 this->identity_matrix
,
3855 gfx::PointF(0.f
, 100.f
),
3858 typename
Types::LayerType
* occluding_layer3
=
3859 this->CreateDrawingLayer(parent
,
3860 this->identity_matrix
,
3861 gfx::PointF(0.f
, 50.f
),
3864 typename
Types::LayerType
* occluding_layer4
=
3865 this->CreateDrawingLayer(parent
,
3866 this->identity_matrix
,
3867 gfx::PointF(100.f
, 50.f
),
3870 typename
Types::LayerType
* occluding_layer5
=
3871 this->CreateDrawingLayer(parent
,
3872 this->identity_matrix
,
3873 gfx::PointF(250.f
, 50.f
),
3877 // Filters make the layer own a surface. This filter is large enough that it
3878 // goes outside the bottom of the clipping_surface.
3879 FilterOperations filters
;
3880 filters
.Append(FilterOperation::CreateBlurFilter(12.f
));
3881 filtered_surface
->SetBackgroundFilters(filters
);
3883 // Save the distance of influence for the blur effect.
3884 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3886 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3888 this->CalcDrawEtc(parent
);
3890 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3891 typename
Types::RenderSurfaceType
> occlusion(
3892 gfx::Rect(0, 0, 1000, 1000));
3894 // These layers occlude pixels directly beside the filtered_surface. Because
3895 // filtered surface blends pixels in a radius, it will need to see some of
3896 // the pixels (up to radius far) underneath the occluding layers.
3897 this->VisitLayer(occluding_layer5
, &occlusion
);
3898 this->VisitLayer(occluding_layer4
, &occlusion
);
3899 this->VisitLayer(occluding_layer3
, &occlusion
);
3900 this->VisitLayer(occluding_layer2
, &occlusion
);
3901 this->VisitLayer(occluding_layer1
, &occlusion
);
3903 Region expected_occlusion
;
3904 expected_occlusion
.Union(gfx::Rect(0, 0, 300, 50));
3905 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3906 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3907 expected_occlusion
.Union(gfx::Rect(250, 50, 50, 50));
3908 expected_occlusion
.Union(gfx::Rect(0, 100, 300, 50));
3910 EXPECT_EQ(expected_occlusion
.ToString(),
3911 occlusion
.occlusion_from_inside_target().ToString());
3912 EXPECT_EQ(gfx::Rect().ToString(),
3913 occlusion
.occlusion_from_outside_target().ToString());
3915 // Everything outside the surface/replica is occluded but the
3916 // surface/replica itself is not.
3917 this->VisitLayer(filtered_surface
, &occlusion
);
3919 // The filtered layer/replica does not occlude.
3920 Region expected_occlusion_outside_surface
;
3921 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 300, 50));
3922 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3923 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3924 expected_occlusion_outside_surface
.Union(gfx::Rect(200, 0, 50, 50));
3925 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 300, 50));
3927 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3928 occlusion
.occlusion_from_outside_target().ToString());
3929 EXPECT_EQ(gfx::Rect().ToString(),
3930 occlusion
.occlusion_from_inside_target().ToString());
3932 // The surface has a background blur, so it needs pixels that are currently
3933 // considered occluded in order to be drawn. So the pixels it needs should
3934 // be removed some the occluded area so that when we get to the parent they
3936 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3938 this->VisitLayer(clipping_surface
, &occlusion
);
3939 this->EnterContributingSurface(clipping_surface
, &occlusion
, false);
3941 Region expected_blurred_occlusion
;
3942 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 300, 50 - outset_top
));
3943 expected_blurred_occlusion
.Union(gfx::Rect(
3944 0, 50 - outset_top
, 50 - outset_left
, 20 + outset_top
+ outset_bottom
));
3945 expected_blurred_occlusion
.Union(
3946 gfx::Rect(100 + outset_right
,
3948 100 - outset_right
- outset_left
,
3949 20 + outset_top
+ outset_bottom
));
3950 expected_blurred_occlusion
.Union(
3951 gfx::Rect(250 + outset_right
,
3954 20 + outset_top
+ outset_bottom
));
3955 expected_blurred_occlusion
.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
3957 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3958 occlusion
.occlusion_from_outside_target().ToString());
3959 EXPECT_EQ(gfx::Rect().ToString(),
3960 occlusion
.occlusion_from_inside_target().ToString());
3962 gfx::Rect outset_rect
;
3963 gfx::Rect clipped_outset_rect
;
3964 gfx::Rect test_rect
;
3966 // Nothing in the (clipped) blur outsets for the filtered_surface is
3968 outset_rect
= gfx::Rect(50 - outset_left
,
3970 50 + outset_left
+ outset_right
,
3971 50 + outset_top
+ outset_bottom
);
3972 clipped_outset_rect
= outset_rect
;
3973 clipped_outset_rect
.Intersect(gfx::Rect(0 - outset_left
,
3975 300 + outset_left
+ outset_right
,
3976 70 + outset_top
+ outset_bottom
));
3977 clipped_outset_rect
.Intersect(gfx::Rect(0, 0, 300, 70));
3978 test_rect
= outset_rect
;
3980 clipped_outset_rect
,
3981 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3983 // Stuff outside the (clipped) blur outsets is still occluded though.
3984 test_rect
= outset_rect
;
3985 test_rect
.Inset(0, 0, -1, 0);
3987 clipped_outset_rect
,
3988 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3989 test_rect
= outset_rect
;
3990 test_rect
.Inset(0, 0, 0, -1);
3992 clipped_outset_rect
,
3993 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3994 test_rect
= outset_rect
;
3995 test_rect
.Inset(-1, 0, 0, 0);
3997 clipped_outset_rect
,
3998 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
3999 test_rect
= outset_rect
;
4000 test_rect
.Inset(0, -1, 0, 0);
4002 clipped_outset_rect
,
4003 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4005 // Nothing in the (clipped) blur outsets for the filtered_surface's replica
4007 outset_rect
= gfx::Rect(200 - outset_left
,
4009 50 + outset_left
+ outset_right
,
4010 50 + outset_top
+ outset_bottom
);
4011 clipped_outset_rect
= outset_rect
;
4012 clipped_outset_rect
.Intersect(gfx::Rect(0 - outset_left
,
4014 300 + outset_left
+ outset_right
,
4015 70 + outset_top
+ outset_bottom
));
4016 clipped_outset_rect
.Intersect(gfx::Rect(0, 0, 300, 70));
4017 test_rect
= outset_rect
;
4019 clipped_outset_rect
,
4020 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4022 // Stuff outside the (clipped) blur outsets is still occluded though.
4023 test_rect
= outset_rect
;
4024 test_rect
.Inset(0, 0, -1, 0);
4026 clipped_outset_rect
,
4027 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4028 test_rect
= outset_rect
;
4029 test_rect
.Inset(0, 0, 0, -1);
4031 clipped_outset_rect
,
4032 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4033 test_rect
= outset_rect
;
4034 test_rect
.Inset(-1, 0, 0, 0);
4036 clipped_outset_rect
,
4037 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4038 test_rect
= outset_rect
;
4039 test_rect
.Inset(0, -1, 0, 0);
4041 clipped_outset_rect
,
4042 occlusion
.UnoccludedLayerContentRect(clipping_surface
, test_rect
));
4046 ALL_OCCLUSIONTRACKER_TEST(
4047 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
);
4049 template <class Types
>
4050 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
4051 : public OcclusionTrackerTest
<Types
> {
4053 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
4055 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4057 gfx::Transform scale_by_half
;
4058 scale_by_half
.Scale(0.5, 0.5);
4060 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
4061 // centered below each. The surface is scaled to test that the pixel moving
4062 // is done in the target space, where the background filter is applied, but
4063 // the surface appears at 50, 50 and the replica at 200, 50.
4064 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4065 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4066 typename
Types::LayerType
* behind_surface_layer
=
4067 this->CreateDrawingLayer(parent
,
4068 this->identity_matrix
,
4069 gfx::PointF(60.f
, 60.f
),
4072 typename
Types::LayerType
* behind_replica_layer
=
4073 this->CreateDrawingLayer(parent
,
4074 this->identity_matrix
,
4075 gfx::PointF(210.f
, 60.f
),
4078 typename
Types::LayerType
* filtered_surface
=
4079 this->CreateDrawingLayer(parent
,
4081 gfx::PointF(50.f
, 50.f
),
4082 gfx::Size(100, 100),
4084 this->CreateReplicaLayer(filtered_surface
,
4085 this->identity_matrix
,
4086 gfx::PointF(300.f
, 0.f
),
4089 // Filters make the layer own a surface.
4090 FilterOperations filters
;
4091 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
4092 filtered_surface
->SetBackgroundFilters(filters
);
4094 this->CalcDrawEtc(parent
);
4096 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4097 typename
Types::RenderSurfaceType
> occlusion(
4098 gfx::Rect(0, 0, 1000, 1000));
4100 // The surface has a background blur, so it blurs non-opaque pixels below
4102 this->VisitLayer(filtered_surface
, &occlusion
);
4103 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4105 this->VisitLayer(behind_replica_layer
, &occlusion
);
4106 this->VisitLayer(behind_surface_layer
, &occlusion
);
4108 // The layers behind the surface are not blurred, and their occlusion does
4109 // not change, until we leave the surface. So it should not be modified by
4111 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
4112 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
4114 Region expected_opaque_bounds
=
4115 UnionRegions(occlusion_behind_surface
, occlusion_behind_replica
);
4116 EXPECT_EQ(expected_opaque_bounds
.ToString(),
4117 occlusion
.occlusion_from_inside_target().ToString());
4119 EXPECT_EQ(gfx::Rect().ToString(),
4120 occlusion
.occlusion_from_outside_target().ToString());
4124 ALL_OCCLUSIONTRACKER_TEST(
4125 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
4127 template <class Types
>
4128 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
4129 : public OcclusionTrackerTest
<Types
> {
4131 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
4133 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4135 gfx::Transform scale_by_half
;
4136 scale_by_half
.Scale(0.5, 0.5);
4138 // Make a surface and its replica, each 50x50, that are completely occluded
4139 // by opaque layers which are above them in the z-order. The surface is
4140 // scaled to test that the pixel moving is done in the target space, where
4141 // the background filter is applied, but the surface appears at 50, 50 and
4142 // the replica at 200, 50.
4143 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4144 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4145 typename
Types::LayerType
* filtered_surface
=
4146 this->CreateDrawingLayer(parent
,
4148 gfx::PointF(50.f
, 50.f
),
4149 gfx::Size(100, 100),
4151 this->CreateReplicaLayer(filtered_surface
,
4152 this->identity_matrix
,
4153 gfx::PointF(300.f
, 0.f
),
4155 typename
Types::LayerType
* above_surface_layer
=
4156 this->CreateDrawingLayer(parent
,
4157 this->identity_matrix
,
4158 gfx::PointF(50.f
, 50.f
),
4161 typename
Types::LayerType
* above_replica_layer
=
4162 this->CreateDrawingLayer(parent
,
4163 this->identity_matrix
,
4164 gfx::PointF(200.f
, 50.f
),
4168 // Filters make the layer own a surface.
4169 FilterOperations filters
;
4170 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
4171 filtered_surface
->SetBackgroundFilters(filters
);
4173 this->CalcDrawEtc(parent
);
4175 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4176 typename
Types::RenderSurfaceType
> occlusion(
4177 gfx::Rect(0, 0, 1000, 1000));
4179 this->VisitLayer(above_replica_layer
, &occlusion
);
4180 this->VisitLayer(above_surface_layer
, &occlusion
);
4182 this->VisitLayer(filtered_surface
, &occlusion
);
4184 // The layers above the filtered surface occlude from outside.
4185 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
4186 gfx::Rect occlusion_above_replica
= gfx::Rect(150, 0, 50, 50);
4187 Region expected_opaque_region
=
4188 UnionRegions(occlusion_above_surface
, occlusion_above_replica
);
4190 EXPECT_EQ(gfx::Rect().ToString(),
4191 occlusion
.occlusion_from_inside_target().ToString());
4192 EXPECT_EQ(expected_opaque_region
.ToString(),
4193 occlusion
.occlusion_from_outside_target().ToString());
4196 // The surface has a background blur, so it blurs non-opaque pixels below
4198 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4200 // The filter is completely occluded, so it should not blur anything and
4201 // reduce any occlusion.
4202 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
4203 gfx::Rect occlusion_above_replica
= gfx::Rect(200, 50, 50, 50);
4204 Region expected_opaque_region
=
4205 UnionRegions(occlusion_above_surface
, occlusion_above_replica
);
4207 EXPECT_EQ(expected_opaque_region
.ToString(),
4208 occlusion
.occlusion_from_inside_target().ToString());
4209 EXPECT_EQ(gfx::Rect().ToString(),
4210 occlusion
.occlusion_from_outside_target().ToString());
4215 ALL_OCCLUSIONTRACKER_TEST(
4216 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
4218 template <class Types
>
4219 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
4220 : public OcclusionTrackerTest
<Types
> {
4223 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
4225 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4227 gfx::Transform scale_by_half
;
4228 scale_by_half
.Scale(0.5, 0.5);
4230 // Make a surface and its replica, each 50x50, that are partially occluded
4231 // by opaque layers which are above them in the z-order. The surface is
4232 // scaled to test that the pixel moving is done in the target space, where
4233 // the background filter is applied, but the surface appears at 50, 50 and
4234 // the replica at 200, 50.
4235 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4236 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
4237 typename
Types::LayerType
* filtered_surface
=
4238 this->CreateDrawingLayer(parent
,
4240 gfx::PointF(50.f
, 50.f
),
4241 gfx::Size(100, 100),
4243 this->CreateReplicaLayer(filtered_surface
,
4244 this->identity_matrix
,
4245 gfx::PointF(300.f
, 0.f
),
4247 typename
Types::LayerType
* above_surface_layer
=
4248 this->CreateDrawingLayer(parent
,
4249 this->identity_matrix
,
4250 gfx::PointF(70.f
, 50.f
),
4253 typename
Types::LayerType
* above_replica_layer
=
4254 this->CreateDrawingLayer(parent
,
4255 this->identity_matrix
,
4256 gfx::PointF(200.f
, 50.f
),
4259 typename
Types::LayerType
* beside_surface_layer
=
4260 this->CreateDrawingLayer(parent
,
4261 this->identity_matrix
,
4262 gfx::PointF(90.f
, 40.f
),
4265 typename
Types::LayerType
* beside_replica_layer
=
4266 this->CreateDrawingLayer(parent
,
4267 this->identity_matrix
,
4268 gfx::PointF(200.f
, 40.f
),
4272 // Filters make the layer own a surface.
4273 FilterOperations filters
;
4274 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
4275 filtered_surface
->SetBackgroundFilters(filters
);
4277 // Save the distance of influence for the blur effect.
4278 int outset_top
, outset_right
, outset_bottom
, outset_left
;
4280 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
4282 this->CalcDrawEtc(parent
);
4284 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4285 typename
Types::RenderSurfaceType
> occlusion(
4286 gfx::Rect(0, 0, 1000, 1000));
4288 this->VisitLayer(beside_replica_layer
, &occlusion
);
4289 this->VisitLayer(beside_surface_layer
, &occlusion
);
4290 this->VisitLayer(above_replica_layer
, &occlusion
);
4291 this->VisitLayer(above_surface_layer
, &occlusion
);
4293 // The surface has a background blur, so it blurs non-opaque pixels below
4295 this->VisitLayer(filtered_surface
, &occlusion
);
4296 this->VisitContributingSurface(filtered_surface
, &occlusion
);
4298 // The filter in the surface and replica are partially unoccluded. Only the
4299 // unoccluded parts should reduce occlusion. This means it will push back
4300 // the occlusion that touches the unoccluded part (occlusion_above___), but
4301 // it will not touch occlusion_beside____ since that is not beside the
4302 // unoccluded part of the surface, even though it is beside the occluded
4303 // part of the surface.
4304 gfx::Rect occlusion_above_surface
=
4305 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
4306 gfx::Rect occlusion_above_replica
=
4307 gfx::Rect(200, 50, 30 - outset_left
, 50);
4308 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
4309 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
4311 Region expected_occlusion
;
4312 expected_occlusion
.Union(occlusion_above_surface
);
4313 expected_occlusion
.Union(occlusion_above_replica
);
4314 expected_occlusion
.Union(occlusion_beside_surface
);
4315 expected_occlusion
.Union(occlusion_beside_replica
);
4317 ASSERT_EQ(expected_occlusion
.ToString(),
4318 occlusion
.occlusion_from_inside_target().ToString());
4319 EXPECT_EQ(gfx::Rect().ToString(),
4320 occlusion
.occlusion_from_outside_target().ToString());
4322 Region::Iterator
expected_rects(expected_occlusion
);
4323 Region::Iterator
target_surface_rects(
4324 occlusion
.occlusion_from_inside_target());
4325 for (; expected_rects
.has_rect();
4326 expected_rects
.next(), target_surface_rects
.next()) {
4327 ASSERT_TRUE(target_surface_rects
.has_rect());
4328 EXPECT_EQ(expected_rects
.rect(), target_surface_rects
.rect());
4333 ALL_OCCLUSIONTRACKER_TEST(
4334 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
4336 template <class Types
>
4337 class OcclusionTrackerTestMinimumTrackingSize
4338 : public OcclusionTrackerTest
<Types
> {
4340 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
4341 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4343 gfx::Size
tracking_size(100, 100);
4344 gfx::Size
below_tracking_size(99, 99);
4346 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4347 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4348 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
4349 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
4350 typename
Types::LayerType
* small
=
4351 this->CreateDrawingLayer(parent
,
4352 this->identity_matrix
,
4354 below_tracking_size
,
4356 this->CalcDrawEtc(parent
);
4358 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4359 typename
Types::RenderSurfaceType
> occlusion(
4360 gfx::Rect(0, 0, 1000, 1000));
4361 occlusion
.set_minimum_tracking_size(tracking_size
);
4363 // The small layer is not tracked because it is too small.
4364 this->VisitLayer(small
, &occlusion
);
4366 EXPECT_EQ(gfx::Rect().ToString(),
4367 occlusion
.occlusion_from_outside_target().ToString());
4368 EXPECT_EQ(gfx::Rect().ToString(),
4369 occlusion
.occlusion_from_inside_target().ToString());
4371 // The large layer is tracked as it is large enough.
4372 this->VisitLayer(large
, &occlusion
);
4374 EXPECT_EQ(gfx::Rect().ToString(),
4375 occlusion
.occlusion_from_outside_target().ToString());
4376 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
4377 occlusion
.occlusion_from_inside_target().ToString());
4381 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
4383 template <class Types
>
4384 class OcclusionTrackerTestViewportClipIsExternalOcclusion
4385 : public OcclusionTrackerTest
<Types
> {
4387 explicit OcclusionTrackerTestViewportClipIsExternalOcclusion(
4389 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4391 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4392 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4393 typename
Types::LayerType
* small
=
4394 this->CreateDrawingSurface(parent
,
4395 this->identity_matrix
,
4397 gfx::Size(200, 200),
4399 typename
Types::LayerType
* large
=
4400 this->CreateDrawingLayer(small
,
4401 this->identity_matrix
,
4403 gfx::Size(400, 400),
4405 small
->SetMasksToBounds(true);
4406 this->CalcDrawEtc(parent
);
4408 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4409 typename
Types::RenderSurfaceType
> occlusion(
4410 gfx::Rect(0, 0, 100, 100));
4412 this->EnterLayer(large
, &occlusion
, false);
4414 bool has_occlusion_from_outside_target_surface
= false;
4415 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4416 occlusion
.UnoccludedLayerContentRect(
4418 gfx::Rect(0, 0, 400, 400),
4419 &has_occlusion_from_outside_target_surface
));
4420 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4422 has_occlusion_from_outside_target_surface
= false;
4424 occlusion
.OccludedLayer(large
,
4425 gfx::Rect(0, 0, 400, 400),
4426 &has_occlusion_from_outside_target_surface
));
4427 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4429 this->LeaveLayer(large
, &occlusion
);
4430 this->VisitLayer(small
, &occlusion
);
4432 has_occlusion_from_outside_target_surface
= false;
4433 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4434 occlusion
.UnoccludedLayerContentRect(
4436 gfx::Rect(0, 0, 200, 200),
4437 &has_occlusion_from_outside_target_surface
));
4438 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4440 has_occlusion_from_outside_target_surface
= false;
4442 occlusion
.OccludedLayer(small
,
4443 gfx::Rect(0, 0, 200, 200),
4444 &has_occlusion_from_outside_target_surface
));
4445 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4447 this->EnterContributingSurface(small
, &occlusion
, false);
4449 has_occlusion_from_outside_target_surface
= false;
4450 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4451 occlusion
.UnoccludedContributingSurfaceContentRect(
4454 gfx::Rect(0, 0, 200, 200),
4455 &has_occlusion_from_outside_target_surface
));
4456 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4460 ALL_OCCLUSIONTRACKER_TEST(
4461 OcclusionTrackerTestViewportClipIsExternalOcclusion
)
4463 template <class Types
>
4464 class OcclusionTrackerTestLayerClipIsExternalOcclusion
4465 : public OcclusionTrackerTest
<Types
> {
4467 explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers
)
4468 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4470 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4471 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4472 typename
Types::LayerType
* smallest
= this->CreateDrawingLayer(
4473 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4474 typename
Types::LayerType
* smaller
=
4475 this->CreateDrawingSurface(smallest
,
4476 this->identity_matrix
,
4478 gfx::Size(100, 100),
4480 typename
Types::LayerType
* small
=
4481 this->CreateDrawingSurface(smaller
,
4482 this->identity_matrix
,
4484 gfx::Size(200, 200),
4486 typename
Types::LayerType
* large
=
4487 this->CreateDrawingLayer(small
,
4488 this->identity_matrix
,
4490 gfx::Size(400, 400),
4492 smallest
->SetMasksToBounds(true);
4493 smaller
->SetMasksToBounds(true);
4494 small
->SetMasksToBounds(true);
4495 this->CalcDrawEtc(parent
);
4497 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4498 typename
Types::RenderSurfaceType
> occlusion(
4499 gfx::Rect(0, 0, 1000, 1000));
4501 this->EnterLayer(large
, &occlusion
, false);
4503 // Clipping from the smaller layer is from outside the target surface.
4504 bool has_occlusion_from_outside_target_surface
= false;
4505 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4506 occlusion
.UnoccludedLayerContentRect(
4508 gfx::Rect(0, 0, 400, 400),
4509 &has_occlusion_from_outside_target_surface
));
4510 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4512 has_occlusion_from_outside_target_surface
= false;
4514 occlusion
.OccludedLayer(large
,
4515 gfx::Rect(0, 0, 400, 400),
4516 &has_occlusion_from_outside_target_surface
));
4517 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4519 this->LeaveLayer(large
, &occlusion
);
4520 this->VisitLayer(small
, &occlusion
);
4522 // Clipping from the smaller layer is from outside the target surface.
4523 has_occlusion_from_outside_target_surface
= false;
4524 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4525 occlusion
.UnoccludedLayerContentRect(
4527 gfx::Rect(0, 0, 200, 200),
4528 &has_occlusion_from_outside_target_surface
));
4529 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4531 has_occlusion_from_outside_target_surface
= false;
4533 occlusion
.OccludedLayer(small
,
4534 gfx::Rect(0, 0, 200, 200),
4535 &has_occlusion_from_outside_target_surface
));
4536 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4538 this->EnterContributingSurface(small
, &occlusion
, false);
4540 // The |small| surface is clipped from outside its target by |smallest|.
4541 has_occlusion_from_outside_target_surface
= false;
4542 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4543 occlusion
.UnoccludedContributingSurfaceContentRect(
4546 gfx::Rect(0, 0, 200, 200),
4547 &has_occlusion_from_outside_target_surface
));
4548 EXPECT_TRUE(has_occlusion_from_outside_target_surface
);
4550 this->LeaveContributingSurface(small
, &occlusion
);
4551 this->VisitLayer(smaller
, &occlusion
);
4552 this->EnterContributingSurface(smaller
, &occlusion
, false);
4554 // The |smaller| surface is clipped from inside its target by |smallest|.
4555 has_occlusion_from_outside_target_surface
= false;
4556 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4557 occlusion
.UnoccludedContributingSurfaceContentRect(
4560 gfx::Rect(0, 0, 100, 100),
4561 &has_occlusion_from_outside_target_surface
));
4562 EXPECT_FALSE(has_occlusion_from_outside_target_surface
);
4566 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion
)
4568 template <class Types
>
4569 class OcclusionTrackerTestPreventOcclusionOnLayer
4570 : public OcclusionTrackerTest
<Types
> {
4572 explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers
)
4573 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4575 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4576 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4577 typename
Types::LayerType
* unprevented
= this->CreateDrawingLayer(
4578 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4579 typename
Types::LayerType
* prevented
= this->CreateDrawingLayer(
4580 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4581 typename
Types::LayerType
* occluding
= this->CreateDrawingLayer(
4582 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
4583 this->CalcDrawEtc(parent
);
4585 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4586 typename
Types::RenderSurfaceType
> occlusion(
4587 gfx::Rect(0, 0, 1000, 1000));
4588 bool external_occlusion
= false;
4590 this->VisitLayer(occluding
, &occlusion
);
4591 this->EnterLayer(prevented
, &occlusion
, true);
4593 // This layer is not occluded because it is prevented.
4594 EXPECT_FALSE(occlusion
.OccludedLayer(prevented
,
4596 &external_occlusion
));
4597 EXPECT_FALSE(external_occlusion
);
4599 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4600 occlusion
.UnoccludedLayerContentRect(
4603 &external_occlusion
).ToString());
4604 EXPECT_FALSE(external_occlusion
);
4606 this->LeaveLayer(prevented
, &occlusion
);
4607 this->EnterLayer(unprevented
, &occlusion
, false);
4609 // This layer is fully occluded.
4610 EXPECT_TRUE(occlusion
.OccludedLayer(unprevented
,
4612 &external_occlusion
));
4613 EXPECT_FALSE(external_occlusion
);
4615 EXPECT_EQ(gfx::Rect().ToString(),
4616 occlusion
.UnoccludedLayerContentRect(
4619 &external_occlusion
).ToString());
4620 EXPECT_FALSE(external_occlusion
);
4622 this->LeaveLayer(unprevented
, &occlusion
);
4626 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer
)
4628 template <class Types
>
4629 class OcclusionTrackerTestPreventOcclusionOnContributingSurface
4630 : public OcclusionTrackerTest
<Types
> {
4632 explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface(
4634 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4636 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4637 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4638 typename
Types::LayerType
* unprevented
= this->CreateDrawingSurface(
4639 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4640 typename
Types::LayerType
* prevented
= this->CreateDrawingSurface(
4641 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4642 typename
Types::LayerType
* occluding
= this->CreateDrawingLayer(
4643 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
4644 this->CalcDrawEtc(parent
);
4646 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4647 typename
Types::RenderSurfaceType
> occlusion(
4648 gfx::Rect(0, 0, 1000, 1000));
4649 bool external_occlusion
= false;
4651 this->VisitLayer(occluding
, &occlusion
);
4652 this->EnterLayer(prevented
, &occlusion
, true);
4654 // This layer is not occluded because it is prevented.
4655 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4656 occlusion
.UnoccludedLayerContentRect(
4659 &external_occlusion
).ToString());
4660 EXPECT_FALSE(external_occlusion
);
4662 this->LeaveLayer(prevented
, &occlusion
);
4663 this->EnterContributingSurface(prevented
, &occlusion
, true);
4665 // This contributing surface is not occluded because it is prevented.
4666 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4667 occlusion
.UnoccludedContributingSurfaceContentRect(
4669 false, // is_replica
4671 &external_occlusion
).ToString());
4672 EXPECT_FALSE(external_occlusion
);
4674 this->LeaveContributingSurface(prevented
, &occlusion
);
4675 this->EnterLayer(unprevented
, &occlusion
, false);
4677 // This layer is fully occluded from outside its surface.
4678 EXPECT_EQ(gfx::Rect().ToString(),
4679 occlusion
.UnoccludedLayerContentRect(
4682 &external_occlusion
).ToString());
4683 EXPECT_TRUE(external_occlusion
);
4685 this->LeaveLayer(unprevented
, &occlusion
);
4686 this->EnterContributingSurface(unprevented
, &occlusion
, false);
4688 // This contributing surface is fully occluded.
4689 EXPECT_EQ(gfx::Rect().ToString(),
4690 occlusion
.UnoccludedContributingSurfaceContentRect(
4692 false, // is_replica
4694 &external_occlusion
).ToString());
4695 EXPECT_FALSE(external_occlusion
);
4697 this->LeaveContributingSurface(unprevented
, &occlusion
);
4701 ALL_OCCLUSIONTRACKER_TEST(
4702 OcclusionTrackerTestPreventOcclusionOnContributingSurface
)
4704 template <class Types
>
4705 class OcclusionTrackerTestPreventOcclusionByClipping
4706 : public OcclusionTrackerTest
<Types
> {
4708 explicit OcclusionTrackerTestPreventOcclusionByClipping(bool opaque_layers
)
4709 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4711 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4712 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4713 typename
Types::LayerType
* unprevented
= this->CreateDrawingLayer(
4714 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4715 typename
Types::LayerType
* prevented
= this->CreateDrawingLayer(
4716 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
4717 this->CalcDrawEtc(parent
);
4719 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4720 typename
Types::RenderSurfaceType
> occlusion(
4721 gfx::Rect(0, 0, 10, 10));
4722 bool external_occlusion
= false;
4724 this->EnterLayer(prevented
, &occlusion
, true);
4726 // This layer is not occluded because it is prevented.
4727 EXPECT_FALSE(occlusion
.OccludedLayer(prevented
,
4729 &external_occlusion
));
4730 EXPECT_FALSE(external_occlusion
);
4732 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4733 occlusion
.UnoccludedLayerContentRect(
4736 &external_occlusion
).ToString());
4737 EXPECT_FALSE(external_occlusion
);
4739 this->LeaveLayer(prevented
, &occlusion
);
4740 this->EnterLayer(unprevented
, &occlusion
, false);
4742 // This layer is clipped by the screen space clip rect.
4743 EXPECT_EQ(gfx::Rect(10, 10).ToString(),
4744 occlusion
.UnoccludedLayerContentRect(
4747 &external_occlusion
).ToString());
4748 EXPECT_TRUE(external_occlusion
);
4750 this->LeaveLayer(unprevented
, &occlusion
);
4754 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionByClipping
)
4756 template <class Types
>
4757 class OcclusionTrackerTestScaledLayerIsClipped
4758 : public OcclusionTrackerTest
<Types
> {
4760 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
4761 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4763 gfx::Transform scale_transform
;
4764 scale_transform
.Scale(512.0, 512.0);
4766 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4767 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4768 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
4769 this->identity_matrix
,
4770 gfx::PointF(10.f
, 10.f
),
4772 clip
->SetMasksToBounds(true);
4773 typename
Types::LayerType
* scale
= this->CreateLayer(
4774 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
4775 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
4776 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
4777 this->CalcDrawEtc(parent
);
4779 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4780 typename
Types::RenderSurfaceType
> occlusion(
4781 gfx::Rect(0, 0, 1000, 1000));
4783 this->VisitLayer(scaled
, &occlusion
);
4785 EXPECT_EQ(gfx::Rect().ToString(),
4786 occlusion
.occlusion_from_outside_target().ToString());
4787 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
4788 occlusion
.occlusion_from_inside_target().ToString());
4792 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
4794 template <class Types
>
4795 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
4796 : public OcclusionTrackerTest
<Types
> {
4798 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
4799 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4801 gfx::Transform scale_transform
;
4802 scale_transform
.Scale(512.0, 512.0);
4804 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
4805 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
4806 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
4807 this->identity_matrix
,
4808 gfx::PointF(10.f
, 10.f
),
4810 clip
->SetMasksToBounds(true);
4811 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
4812 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
4813 typename
Types::LayerType
* scale
= this->CreateLayer(
4814 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
4815 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
4816 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
4817 this->CalcDrawEtc(parent
);
4819 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4820 typename
Types::RenderSurfaceType
> occlusion(
4821 gfx::Rect(0, 0, 1000, 1000));
4823 this->VisitLayer(scaled
, &occlusion
);
4824 this->VisitLayer(surface
, &occlusion
);
4825 this->VisitContributingSurface(surface
, &occlusion
);
4827 EXPECT_EQ(gfx::Rect().ToString(),
4828 occlusion
.occlusion_from_outside_target().ToString());
4829 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
4830 occlusion
.occlusion_from_inside_target().ToString());
4834 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
4836 template <class Types
>
4837 class OcclusionTrackerTestCopyRequestDoesOcclude
4838 : public OcclusionTrackerTest
<Types
> {
4840 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
4841 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4843 typename
Types::ContentLayerType
* root
= this->CreateRoot(
4844 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
4845 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
4846 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
4847 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
4848 this->identity_matrix
,
4850 gfx::Size(200, 400));
4851 this->AddCopyRequest(copy
);
4852 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
4854 this->identity_matrix
,
4856 gfx::Size(200, 400),
4858 this->CalcDrawEtc(root
);
4860 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4861 typename
Types::RenderSurfaceType
> occlusion(
4862 gfx::Rect(0, 0, 1000, 1000));
4864 this->VisitLayer(copy_child
, &occlusion
);
4865 EXPECT_EQ(gfx::Rect().ToString(),
4866 occlusion
.occlusion_from_outside_target().ToString());
4867 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
4868 occlusion
.occlusion_from_inside_target().ToString());
4870 // CopyRequests cause the layer to own a surface.
4871 this->VisitContributingSurface(copy
, &occlusion
);
4873 // The occlusion from the copy should be kept.
4874 EXPECT_EQ(gfx::Rect().ToString(),
4875 occlusion
.occlusion_from_outside_target().ToString());
4876 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
4877 occlusion
.occlusion_from_inside_target().ToString());
4881 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
4883 template <class Types
>
4884 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
4885 : public OcclusionTrackerTest
<Types
> {
4887 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
4889 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
4891 typename
Types::ContentLayerType
* root
= this->CreateRoot(
4892 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
4893 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
4894 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
4895 typename
Types::LayerType
* hide
= this->CreateLayer(
4896 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
4897 typename
Types::LayerType
* copy
= this->CreateLayer(
4898 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
4899 this->AddCopyRequest(copy
);
4900 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
4901 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
4903 // The |copy| layer is hidden but since it is being copied, it will be
4905 hide
->SetHideLayerAndSubtree(true);
4907 this->CalcDrawEtc(root
);
4909 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
4910 typename
Types::RenderSurfaceType
> occlusion(
4911 gfx::Rect(0, 0, 1000, 1000));
4913 this->VisitLayer(copy_child
, &occlusion
);
4914 EXPECT_EQ(gfx::Rect().ToString(),
4915 occlusion
.occlusion_from_outside_target().ToString());
4916 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
4917 occlusion
.occlusion_from_inside_target().ToString());
4919 // CopyRequests cause the layer to own a surface.
4920 this->VisitContributingSurface(copy
, &occlusion
);
4922 // The occlusion from the copy should be dropped since it is hidden.
4923 EXPECT_EQ(gfx::Rect().ToString(),
4924 occlusion
.occlusion_from_outside_target().ToString());
4925 EXPECT_EQ(gfx::Rect().ToString(),
4926 occlusion
.occlusion_from_inside_target().ToString());
4930 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)