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) {
37 virtual Region
VisibleContentOpaqueRegion() const OVERRIDE
{
38 if (override_opaque_contents_rect_
)
39 return gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect());
40 return Layer::VisibleContentOpaqueRegion();
42 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect
) {
43 override_opaque_contents_rect_
= true;
44 opaque_contents_rect_
= opaque_contents_rect
;
48 virtual ~TestContentLayer() {}
50 bool override_opaque_contents_rect_
;
51 gfx::Rect opaque_contents_rect_
;
54 class TestContentLayerImpl
: public LayerImpl
{
56 TestContentLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
57 : LayerImpl(tree_impl
, id
), override_opaque_contents_rect_(false) {
58 SetDrawsContent(true);
61 virtual Region
VisibleContentOpaqueRegion() const OVERRIDE
{
62 if (override_opaque_contents_rect_
)
63 return gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect());
64 return LayerImpl::VisibleContentOpaqueRegion();
66 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect
) {
67 override_opaque_contents_rect_
= true;
68 opaque_contents_rect_
= opaque_contents_rect
;
72 bool override_opaque_contents_rect_
;
73 gfx::Rect opaque_contents_rect_
;
76 static inline bool LayerImplDrawTransformIsUnknown(const Layer
* layer
) {
77 return layer
->draw_transform_is_animating();
79 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl
* layer
) {
83 template <typename LayerType
, typename RenderSurfaceType
>
84 class TestOcclusionTrackerWithClip
85 : public TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
> {
87 TestOcclusionTrackerWithClip(gfx::Rect viewport_rect
,
88 bool record_metrics_for_frame
)
89 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(
91 record_metrics_for_frame
) {}
92 explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect
)
93 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(viewport_rect
,
96 bool OccludedLayer(const LayerType
* layer
,
97 gfx::Rect content_rect
) const {
98 DCHECK(layer
->visible_content_rect().Contains(content_rect
));
99 return this->Occluded(layer
->render_target(),
101 layer
->draw_transform(),
102 LayerImplDrawTransformIsUnknown(layer
));
105 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
106 // layer. Simple wrapper around UnoccludedContentRect.
107 gfx::Rect
UnoccludedLayerContentRect(const LayerType
* layer
,
108 gfx::Rect content_rect
) const {
109 DCHECK(layer
->visible_content_rect().Contains(content_rect
));
110 return this->UnoccludedContentRect(
111 layer
->render_target(),
113 layer
->draw_transform(),
114 LayerImplDrawTransformIsUnknown(layer
));
118 struct OcclusionTrackerTestMainThreadTypes
{
119 typedef Layer LayerType
;
120 typedef FakeLayerTreeHost HostType
;
121 typedef RenderSurface RenderSurfaceType
;
122 typedef TestContentLayer ContentLayerType
;
123 typedef scoped_refptr
<Layer
> LayerPtrType
;
124 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
125 typedef LayerIterator
<Layer
,
126 RenderSurfaceLayerList
,
128 LayerIteratorActions::FrontToBack
> TestLayerIterator
;
129 typedef OcclusionTracker OcclusionTrackerType
;
131 static LayerPtrType
CreateLayer(HostType
* host
) { return Layer::Create(); }
132 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
133 return make_scoped_refptr(new ContentLayerType());
136 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
137 LayerPtrType
ref(*layer
);
142 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
143 LayerPtrType
ref(*layer
);
148 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
151 struct OcclusionTrackerTestImplThreadTypes
{
152 typedef LayerImpl LayerType
;
153 typedef LayerTreeImpl HostType
;
154 typedef RenderSurfaceImpl RenderSurfaceType
;
155 typedef TestContentLayerImpl ContentLayerType
;
156 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
157 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
158 typedef LayerIterator
<LayerImpl
,
161 LayerIteratorActions::FrontToBack
> TestLayerIterator
;
162 typedef OcclusionTrackerImpl OcclusionTrackerType
;
164 static LayerPtrType
CreateLayer(HostType
* host
) {
165 return LayerImpl::Create(host
, next_layer_impl_id
++);
167 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
168 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
170 static int next_layer_impl_id
;
172 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
173 return layer
->Pass();
176 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
177 return layer
->PassAs
<LayerType
>();
180 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
183 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
185 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
187 explicit OcclusionTrackerTest(bool opaque_layers
)
188 : opaque_layers_(opaque_layers
), host_(FakeLayerTreeHost::Create()) {}
190 virtual void RunMyTest() = 0;
192 virtual void TearDown() {
193 Types::DestroyLayer(&root_
);
194 render_surface_layer_list_
.reset();
195 render_surface_layer_list_impl_
.clear();
196 replica_layers_
.clear();
197 mask_layers_
.clear();
200 typename
Types::HostType
* GetHost();
202 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
203 gfx::PointF position
,
205 typename
Types::ContentLayerPtrType
layer(
206 Types::CreateContentLayer(GetHost()));
207 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
208 SetProperties(layer_ptr
, transform
, position
, bounds
);
210 DCHECK(!root_
.get());
211 root_
= Types::PassLayerPtr(&layer
);
213 SetRootLayerOnMainThread(layer_ptr
);
218 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
219 const gfx::Transform
& transform
,
220 gfx::PointF position
,
222 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
223 typename
Types::LayerType
* layer_ptr
= layer
.get();
224 SetProperties(layer_ptr
, transform
, position
, bounds
);
225 parent
->AddChild(Types::PassLayerPtr(&layer
));
229 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
230 const gfx::Transform
& transform
,
231 gfx::PointF position
,
233 typename
Types::LayerType
* layer
=
234 CreateLayer(parent
, transform
, position
, bounds
);
235 layer
->SetForceRenderSurface(true);
239 typename
Types::ContentLayerType
* CreateDrawingLayer(
240 typename
Types::LayerType
* parent
,
241 const gfx::Transform
& transform
,
242 gfx::PointF position
,
245 typename
Types::ContentLayerPtrType
layer(
246 Types::CreateContentLayer(GetHost()));
247 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
248 SetProperties(layer_ptr
, transform
, position
, bounds
);
250 if (opaque_layers_
) {
251 layer_ptr
->SetContentsOpaque(opaque
);
253 layer_ptr
->SetContentsOpaque(false);
255 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
257 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
260 parent
->AddChild(Types::PassLayerPtr(&layer
));
264 typename
Types::LayerType
* CreateReplicaLayer(
265 typename
Types::LayerType
* owning_layer
,
266 const gfx::Transform
& transform
,
267 gfx::PointF position
,
269 typename
Types::ContentLayerPtrType
layer(
270 Types::CreateContentLayer(GetHost()));
271 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
272 SetProperties(layer_ptr
, transform
, position
, bounds
);
273 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
277 typename
Types::LayerType
* CreateMaskLayer(
278 typename
Types::LayerType
* owning_layer
,
280 typename
Types::ContentLayerPtrType
layer(
281 Types::CreateContentLayer(GetHost()));
282 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
283 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
284 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
288 typename
Types::ContentLayerType
* CreateDrawingSurface(
289 typename
Types::LayerType
* parent
,
290 const gfx::Transform
& transform
,
291 gfx::PointF position
,
294 typename
Types::ContentLayerType
* layer
=
295 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
296 layer
->SetForceRenderSurface(true);
301 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
303 void AddCopyRequest(Layer
* layer
) {
304 layer
->RequestCopyOfOutput(
305 CopyOutputRequest::CreateBitmapRequest(base::Bind(
306 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
307 base::Unretained(this))));
310 void AddCopyRequest(LayerImpl
* layer
) {
311 ScopedPtrVector
<CopyOutputRequest
> requests
;
313 CopyOutputRequest::CreateBitmapRequest(base::Bind(
314 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
315 base::Unretained(this))));
316 layer
->PassCopyRequests(&requests
);
319 void CalcDrawEtc(TestContentLayerImpl
* root
) {
320 DCHECK(root
== root_
.get());
321 DCHECK(!root
->render_surface());
323 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
324 root
, root
->bounds(), &render_surface_layer_list_impl_
);
325 inputs
.can_adjust_raster_scales
= true;
326 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
328 layer_iterator_
= layer_iterator_begin_
=
329 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
332 void CalcDrawEtc(TestContentLayer
* root
) {
333 DCHECK(root
== root_
.get());
334 DCHECK(!root
->render_surface());
336 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
337 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
338 root
, root
->bounds(), render_surface_layer_list_
.get());
339 inputs
.can_adjust_raster_scales
= true;
340 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
342 layer_iterator_
= layer_iterator_begin_
=
343 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
346 void SetDrawsContent(LayerImpl
* layer_impl
, bool draws_content
) {
347 layer_impl
->SetDrawsContent(draws_content
);
350 void SetDrawsContent(Layer
* layer
, bool draws_content
) {
351 layer
->SetIsDrawable(draws_content
);
354 void EnterLayer(typename
Types::LayerType
* layer
,
355 typename
Types::OcclusionTrackerType
* occlusion
,
356 bool prevent_occlusion
) {
357 ASSERT_EQ(layer
, *layer_iterator_
);
358 ASSERT_TRUE(layer_iterator_
.represents_itself());
359 occlusion
->EnterLayer(layer_iterator_
, prevent_occlusion
);
362 void LeaveLayer(typename
Types::LayerType
* layer
,
363 typename
Types::OcclusionTrackerType
* occlusion
) {
364 ASSERT_EQ(layer
, *layer_iterator_
);
365 ASSERT_TRUE(layer_iterator_
.represents_itself());
366 occlusion
->LeaveLayer(layer_iterator_
);
370 void VisitLayer(typename
Types::LayerType
* layer
,
371 typename
Types::OcclusionTrackerType
* occlusion
) {
372 EnterLayer(layer
, occlusion
, false);
373 LeaveLayer(layer
, occlusion
);
376 void EnterContributingSurface(
377 typename
Types::LayerType
* layer
,
378 typename
Types::OcclusionTrackerType
* occlusion
,
379 bool prevent_occlusion
) {
380 ASSERT_EQ(layer
, *layer_iterator_
);
381 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
382 occlusion
->EnterLayer(layer_iterator_
, false);
383 occlusion
->LeaveLayer(layer_iterator_
);
385 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
386 occlusion
->EnterLayer(layer_iterator_
, prevent_occlusion
);
389 void LeaveContributingSurface(
390 typename
Types::LayerType
* layer
,
391 typename
Types::OcclusionTrackerType
* occlusion
) {
392 ASSERT_EQ(layer
, *layer_iterator_
);
393 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
394 occlusion
->LeaveLayer(layer_iterator_
);
398 void VisitContributingSurface(
399 typename
Types::LayerType
* layer
,
400 typename
Types::OcclusionTrackerType
* occlusion
) {
401 EnterContributingSurface(layer
, occlusion
, false);
402 LeaveContributingSurface(layer
, occlusion
);
405 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
407 const gfx::Transform identity_matrix
;
410 void SetRootLayerOnMainThread(Layer
* root
) {
411 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
414 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
416 void SetBaseProperties(typename
Types::LayerType
* layer
,
417 const gfx::Transform
& transform
,
418 gfx::PointF position
,
420 layer
->SetTransform(transform
);
421 layer
->SetSublayerTransform(gfx::Transform());
422 layer
->SetAnchorPoint(gfx::PointF());
423 layer
->SetPosition(position
);
424 layer
->SetBounds(bounds
);
427 void SetProperties(Layer
* layer
,
428 const gfx::Transform
& transform
,
429 gfx::PointF position
,
431 SetBaseProperties(layer
, transform
, position
, bounds
);
434 void SetProperties(LayerImpl
* layer
,
435 const gfx::Transform
& transform
,
436 gfx::PointF position
,
438 SetBaseProperties(layer
, transform
, position
, bounds
);
440 layer
->SetContentBounds(layer
->bounds());
443 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
444 owning_layer
->SetReplicaLayer(layer
.get());
445 replica_layers_
.push_back(layer
);
448 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
449 owning_layer
->SetReplicaLayer(layer
.Pass());
452 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
453 owning_layer
->SetMaskLayer(layer
.get());
454 mask_layers_
.push_back(layer
);
457 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
458 owning_layer
->SetMaskLayer(layer
.Pass());
462 scoped_ptr
<FakeLayerTreeHost
> host_
;
463 // These hold ownership of the layers for the duration of the test.
464 typename
Types::LayerPtrType root_
;
465 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
466 LayerImplList render_surface_layer_list_impl_
;
467 typename
Types::TestLayerIterator layer_iterator_begin_
;
468 typename
Types::TestLayerIterator layer_iterator_
;
469 typename
Types::LayerType
* last_layer_visited_
;
470 LayerList replica_layers_
;
471 LayerList mask_layers_
;
476 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
482 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
483 return host_
->host_impl()->active_tree();
486 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
487 class ClassName##MainThreadOpaqueLayers \
488 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
489 public: /* NOLINT(whitespace/indent) */ \
490 ClassName##MainThreadOpaqueLayers() \
491 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
493 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
494 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
495 class ClassName##MainThreadOpaquePaints \
496 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
497 public: /* NOLINT(whitespace/indent) */ \
498 ClassName##MainThreadOpaquePaints() \
499 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
501 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
503 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
504 class ClassName##ImplThreadOpaqueLayers \
505 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
506 public: /* NOLINT(whitespace/indent) */ \
507 ClassName##ImplThreadOpaqueLayers() \
508 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
510 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
511 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
512 class ClassName##ImplThreadOpaquePaints \
513 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
514 public: /* NOLINT(whitespace/indent) */ \
515 ClassName##ImplThreadOpaquePaints() \
516 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
518 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
520 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
521 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
522 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
523 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
524 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
526 #define MAIN_THREAD_TEST(ClassName) \
527 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
529 #define IMPL_THREAD_TEST(ClassName) \
530 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
532 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
533 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
534 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
536 template <class Types
>
537 class OcclusionTrackerTestIdentityTransforms
538 : public OcclusionTrackerTest
<Types
> {
540 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
541 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
544 typename
Types::ContentLayerType
* root
= this->CreateRoot(
545 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
546 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
547 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
548 typename
Types::ContentLayerType
* layer
=
549 this->CreateDrawingLayer(parent
,
550 this->identity_matrix
,
551 gfx::PointF(30.f
, 30.f
),
554 parent
->SetMasksToBounds(true);
555 this->CalcDrawEtc(root
);
557 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
558 typename
Types::RenderSurfaceType
> occlusion(
559 gfx::Rect(0, 0, 1000, 1000), false);
561 this->VisitLayer(layer
, &occlusion
);
562 this->EnterLayer(parent
, &occlusion
, false);
564 EXPECT_EQ(gfx::Rect().ToString(),
565 occlusion
.occlusion_from_outside_target().ToString());
566 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
567 occlusion
.occlusion_from_inside_target().ToString());
569 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
570 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
571 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
572 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
573 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
575 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
576 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
577 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
578 occlusion
.UnoccludedLayerContentRect(
579 parent
, gfx::Rect(29, 30, 70, 70)));
580 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
581 occlusion
.UnoccludedLayerContentRect(
582 parent
, gfx::Rect(29, 29, 70, 70)));
583 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
584 occlusion
.UnoccludedLayerContentRect(
585 parent
, gfx::Rect(30, 29, 70, 70)));
586 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
587 occlusion
.UnoccludedLayerContentRect(
588 parent
, gfx::Rect(31, 29, 69, 70)));
589 EXPECT_RECT_EQ(gfx::Rect(),
590 occlusion
.UnoccludedLayerContentRect(
591 parent
, gfx::Rect(31, 30, 69, 70)));
592 EXPECT_RECT_EQ(gfx::Rect(),
593 occlusion
.UnoccludedLayerContentRect(
594 parent
, gfx::Rect(31, 31, 69, 69)));
595 EXPECT_RECT_EQ(gfx::Rect(),
596 occlusion
.UnoccludedLayerContentRect(
597 parent
, gfx::Rect(30, 31, 70, 69)));
598 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
599 occlusion
.UnoccludedLayerContentRect(
600 parent
, gfx::Rect(29, 31, 70, 69)));
604 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
606 template <class Types
>
607 class OcclusionTrackerTestQuadsMismatchLayer
608 : public OcclusionTrackerTest
<Types
> {
610 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers
)
611 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
613 gfx::Transform layer_transform
;
614 layer_transform
.Translate(10.0, 10.0);
616 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
617 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(100, 100));
618 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
619 parent
, layer_transform
, gfx::PointF(), gfx::Size(90, 90), true);
620 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
621 layer1
, layer_transform
, gfx::PointF(), gfx::Size(50, 50), true);
622 this->CalcDrawEtc(parent
);
624 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
625 typename
Types::RenderSurfaceType
> occlusion(
626 gfx::Rect(0, 0, 1000, 1000));
628 this->VisitLayer(layer2
, &occlusion
);
629 this->EnterLayer(layer1
, &occlusion
, false);
631 EXPECT_EQ(gfx::Rect().ToString(),
632 occlusion
.occlusion_from_outside_target().ToString());
633 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
634 occlusion
.occlusion_from_inside_target().ToString());
636 // This checks cases where the quads don't match their "containing"
637 // layers, e.g. in terms of transforms or clip rect. This is typical for
638 // DelegatedRendererLayer.
640 gfx::Transform quad_transform
;
641 quad_transform
.Translate(30.0, 30.0);
643 EXPECT_TRUE(occlusion
.UnoccludedContentRect(parent
,
644 gfx::Rect(0, 0, 10, 10),
647 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
648 occlusion
.UnoccludedContentRect(parent
,
649 gfx::Rect(0, 0, 10, 10),
652 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
653 occlusion
.UnoccludedContentRect(parent
,
654 gfx::Rect(40, 40, 10, 10),
657 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
658 occlusion
.UnoccludedContentRect(parent
,
659 gfx::Rect(35, 30, 10, 10),
665 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
667 template <class Types
>
668 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
670 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
671 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
673 gfx::Transform layer_transform
;
674 layer_transform
.Translate(250.0, 250.0);
675 layer_transform
.Rotate(90.0);
676 layer_transform
.Translate(-250.0, -250.0);
678 typename
Types::ContentLayerType
* root
= this->CreateRoot(
679 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
680 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
681 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
682 typename
Types::ContentLayerType
* layer
=
683 this->CreateDrawingLayer(parent
,
685 gfx::PointF(30.f
, 30.f
),
688 parent
->SetMasksToBounds(true);
689 this->CalcDrawEtc(root
);
691 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
692 typename
Types::RenderSurfaceType
> occlusion(
693 gfx::Rect(0, 0, 1000, 1000));
695 this->VisitLayer(layer
, &occlusion
);
696 this->EnterLayer(parent
, &occlusion
, false);
698 EXPECT_EQ(gfx::Rect().ToString(),
699 occlusion
.occlusion_from_outside_target().ToString());
700 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
701 occlusion
.occlusion_from_inside_target().ToString());
703 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
704 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
705 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
706 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
707 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
709 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
710 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
711 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
712 occlusion
.UnoccludedLayerContentRect(
713 parent
, gfx::Rect(29, 30, 69, 70)));
714 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
715 occlusion
.UnoccludedLayerContentRect(
716 parent
, gfx::Rect(29, 29, 70, 70)));
717 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
718 occlusion
.UnoccludedLayerContentRect(
719 parent
, gfx::Rect(30, 29, 70, 70)));
720 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
721 occlusion
.UnoccludedLayerContentRect(
722 parent
, gfx::Rect(31, 29, 69, 70)));
723 EXPECT_RECT_EQ(gfx::Rect(),
724 occlusion
.UnoccludedLayerContentRect(
725 parent
, gfx::Rect(31, 30, 69, 70)));
726 EXPECT_RECT_EQ(gfx::Rect(),
727 occlusion
.UnoccludedLayerContentRect(
728 parent
, gfx::Rect(31, 31, 69, 69)));
729 EXPECT_RECT_EQ(gfx::Rect(),
730 occlusion
.UnoccludedLayerContentRect(
731 parent
, gfx::Rect(30, 31, 70, 69)));
732 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
733 occlusion
.UnoccludedLayerContentRect(
734 parent
, gfx::Rect(29, 31, 70, 69)));
738 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
740 template <class Types
>
741 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
743 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
744 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
746 gfx::Transform layer_transform
;
747 layer_transform
.Translate(20.0, 20.0);
749 typename
Types::ContentLayerType
* root
= this->CreateRoot(
750 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
751 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
752 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
753 typename
Types::ContentLayerType
* layer
=
754 this->CreateDrawingLayer(parent
,
756 gfx::PointF(30.f
, 30.f
),
759 parent
->SetMasksToBounds(true);
760 this->CalcDrawEtc(root
);
762 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
763 typename
Types::RenderSurfaceType
> occlusion(
764 gfx::Rect(0, 0, 1000, 1000));
766 this->VisitLayer(layer
, &occlusion
);
767 this->EnterLayer(parent
, &occlusion
, false);
769 EXPECT_EQ(gfx::Rect().ToString(),
770 occlusion
.occlusion_from_outside_target().ToString());
771 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
772 occlusion
.occlusion_from_inside_target().ToString());
774 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
775 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
776 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
777 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(51, 50, 49, 50)));
778 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 51, 50, 49)));
780 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
781 parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
782 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
783 occlusion
.UnoccludedLayerContentRect(
784 parent
, gfx::Rect(49, 50, 50, 50)));
785 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
786 occlusion
.UnoccludedLayerContentRect(
787 parent
, gfx::Rect(49, 49, 50, 50)));
788 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
789 occlusion
.UnoccludedLayerContentRect(
790 parent
, gfx::Rect(50, 49, 50, 50)));
791 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
792 occlusion
.UnoccludedLayerContentRect(
793 parent
, gfx::Rect(51, 49, 49, 50)));
794 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
795 parent
, gfx::Rect(51, 50, 49, 50)).IsEmpty());
796 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
797 parent
, gfx::Rect(51, 51, 49, 49)).IsEmpty());
798 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
799 parent
, gfx::Rect(50, 51, 50, 49)).IsEmpty());
800 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
801 occlusion
.UnoccludedLayerContentRect(
802 parent
, gfx::Rect(49, 51, 50, 49)));
806 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
808 template <class Types
>
809 class OcclusionTrackerTestChildInRotatedChild
810 : public OcclusionTrackerTest
<Types
> {
812 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
813 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
815 gfx::Transform child_transform
;
816 child_transform
.Translate(250.0, 250.0);
817 child_transform
.Rotate(90.0);
818 child_transform
.Translate(-250.0, -250.0);
820 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
821 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
822 parent
->SetMasksToBounds(true);
823 typename
Types::LayerType
* child
= this->CreateSurface(
824 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
825 child
->SetMasksToBounds(true);
826 typename
Types::ContentLayerType
* layer
=
827 this->CreateDrawingLayer(child
,
828 this->identity_matrix
,
829 gfx::PointF(10.f
, 10.f
),
832 this->CalcDrawEtc(parent
);
834 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
835 typename
Types::RenderSurfaceType
> occlusion(
836 gfx::Rect(0, 0, 1000, 1000));
838 this->VisitLayer(layer
, &occlusion
);
839 this->EnterContributingSurface(child
, &occlusion
, false);
841 EXPECT_EQ(gfx::Rect().ToString(),
842 occlusion
.occlusion_from_outside_target().ToString());
843 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
844 occlusion
.occlusion_from_inside_target().ToString());
846 this->LeaveContributingSurface(child
, &occlusion
);
847 this->EnterLayer(parent
, &occlusion
, false);
849 EXPECT_EQ(gfx::Rect().ToString(),
850 occlusion
.occlusion_from_outside_target().ToString());
851 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
852 occlusion
.occlusion_from_inside_target().ToString());
854 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
855 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
856 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
857 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 40, 69, 60)));
858 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 41, 70, 59)));
860 /* Justification for the above occlusion from |layer|:
862 +---------------------+
865 | 30 + ---------------------------------+
867 | |10+---------------------------------+
871 +----|--|-------------+ | |
879 +--|-------------------------------+ |
881 +---------------------------------+
884 +---------------------+
885 | |30 Visible region of |layer|: /////
887 | +---------------------------------+
889 | +---------------------------------+ |
890 | | |///////////////| 420 | |
891 | | |///////////////|60 | |
892 | | |///////////////| | |
893 +--|--|---------------+ | |
901 | +------------------------------|--+
903 +---------------------------------+
910 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
912 template <class Types
>
913 class OcclusionTrackerTestScaledRenderSurface
914 : public OcclusionTrackerTest
<Types
> {
916 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
917 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
920 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
921 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
923 gfx::Transform layer1_matrix
;
924 layer1_matrix
.Scale(2.0, 2.0);
925 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
926 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
927 layer1
->SetForceRenderSurface(true);
929 gfx::Transform layer2_matrix
;
930 layer2_matrix
.Translate(25.0, 25.0);
931 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
932 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
933 typename
Types::ContentLayerType
* occluder
=
934 this->CreateDrawingLayer(parent
,
935 this->identity_matrix
,
936 gfx::PointF(100.f
, 100.f
),
939 this->CalcDrawEtc(parent
);
941 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
942 typename
Types::RenderSurfaceType
> occlusion(
943 gfx::Rect(0, 0, 1000, 1000));
945 this->VisitLayer(occluder
, &occlusion
);
946 this->EnterLayer(layer2
, &occlusion
, false);
948 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
949 occlusion
.occlusion_from_outside_target().ToString());
950 EXPECT_EQ(gfx::Rect().ToString(),
951 occlusion
.occlusion_from_inside_target().ToString());
954 gfx::Rect(0, 0, 25, 25),
955 occlusion
.UnoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
956 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
957 occlusion
.UnoccludedLayerContentRect(
958 layer2
, gfx::Rect(10, 25, 25, 25)));
959 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
960 occlusion
.UnoccludedLayerContentRect(
961 layer2
, gfx::Rect(25, 10, 25, 25)));
962 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
963 layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
967 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
969 template <class Types
>
970 class OcclusionTrackerTestVisitTargetTwoTimes
971 : public OcclusionTrackerTest
<Types
> {
973 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
974 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
976 gfx::Transform child_transform
;
977 child_transform
.Translate(250.0, 250.0);
978 child_transform
.Rotate(90.0);
979 child_transform
.Translate(-250.0, -250.0);
981 typename
Types::ContentLayerType
* root
= this->CreateRoot(
982 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
983 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
984 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
985 parent
->SetMasksToBounds(true);
986 typename
Types::LayerType
* child
= this->CreateSurface(
987 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
988 child
->SetMasksToBounds(true);
989 typename
Types::ContentLayerType
* layer
=
990 this->CreateDrawingLayer(child
,
991 this->identity_matrix
,
992 gfx::PointF(10.f
, 10.f
),
995 // |child2| makes |parent|'s surface get considered by OcclusionTracker
996 // first, instead of |child|'s. This exercises different code in
997 // LeaveToRenderTarget, as the target surface has already been seen.
998 typename
Types::ContentLayerType
* child2
=
999 this->CreateDrawingLayer(parent
,
1000 this->identity_matrix
,
1001 gfx::PointF(30.f
, 30.f
),
1004 this->CalcDrawEtc(root
);
1006 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1007 typename
Types::RenderSurfaceType
> occlusion(
1008 gfx::Rect(0, 0, 1000, 1000));
1010 this->VisitLayer(child2
, &occlusion
);
1012 EXPECT_EQ(gfx::Rect().ToString(),
1013 occlusion
.occlusion_from_outside_target().ToString());
1014 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1015 occlusion
.occlusion_from_inside_target().ToString());
1017 this->VisitLayer(layer
, &occlusion
);
1019 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1020 occlusion
.occlusion_from_outside_target().ToString());
1021 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1022 occlusion
.occlusion_from_inside_target().ToString());
1024 this->EnterContributingSurface(child
, &occlusion
, false);
1026 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1027 occlusion
.occlusion_from_outside_target().ToString());
1028 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1029 occlusion
.occlusion_from_inside_target().ToString());
1031 // Occlusion in |child2| should get merged with the |child| surface we are
1033 this->LeaveContributingSurface(child
, &occlusion
);
1034 this->EnterLayer(parent
, &occlusion
, false);
1036 EXPECT_EQ(gfx::Rect().ToString(),
1037 occlusion
.occlusion_from_outside_target().ToString());
1038 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1040 occlusion
.occlusion_from_inside_target().ToString());
1042 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
1043 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1044 occlusion
.UnoccludedLayerContentRect(
1045 parent
, gfx::Rect(30, 30, 70, 70)));
1047 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
1048 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
1049 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
1050 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
1051 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
1053 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1054 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1055 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1057 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1058 parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1059 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1060 occlusion
.UnoccludedLayerContentRect(
1061 parent
, gfx::Rect(29, 30, 60, 10)));
1062 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1063 occlusion
.UnoccludedLayerContentRect(
1064 parent
, gfx::Rect(30, 29, 60, 10)));
1065 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1066 occlusion
.UnoccludedLayerContentRect(
1067 parent
, gfx::Rect(31, 30, 60, 10)));
1068 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1069 parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1071 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1072 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1073 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1074 occlusion
.UnoccludedLayerContentRect(
1075 parent
, gfx::Rect(29, 40, 70, 60)));
1076 // This rect is mostly occluded by |child2|.
1077 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1078 occlusion
.UnoccludedLayerContentRect(
1079 parent
, gfx::Rect(30, 39, 70, 60)));
1080 // This rect extends past top/right ends of |child2|.
1081 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1082 occlusion
.UnoccludedLayerContentRect(
1083 parent
, gfx::Rect(30, 29, 70, 70)));
1084 // This rect extends past left/right ends of |child2|.
1085 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1086 occlusion
.UnoccludedLayerContentRect(
1087 parent
, gfx::Rect(20, 39, 80, 60)));
1088 EXPECT_RECT_EQ(gfx::Rect(),
1089 occlusion
.UnoccludedLayerContentRect(
1090 parent
, gfx::Rect(31, 40, 69, 60)));
1091 EXPECT_RECT_EQ(gfx::Rect(),
1092 occlusion
.UnoccludedLayerContentRect(
1093 parent
, gfx::Rect(30, 41, 70, 59)));
1095 /* Justification for the above occlusion from |layer|:
1097 +---------------------+
1100 | 30 + ------------+--------------------+
1101 100 | | 10 | | | ==>
1102 | |10+----------|----------------------+
1103 | + ------------+ | | |
1106 +----|--|-------------+ | |
1114 +--|-------------------------------+ |
1116 +---------------------------------+
1120 +---------------------+
1121 | |30 Visible region of |layer|: /////
1122 | 30 60 | |child2|: \\\\\
1123 | 30 +------------+--------------------+
1124 | |\\\\\\\\\\\\| |10 |
1125 | +--|\\\\\\\\\\\\|-----------------+ |
1126 | | +------------+//| 420 | |
1127 | | |///////////////|60 | |
1128 | | |///////////////| | |
1129 +--|--|---------------+ | |
1137 | +------------------------------|--+
1139 +---------------------------------+
1145 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
1147 template <class Types
>
1148 class OcclusionTrackerTestSurfaceRotatedOffAxis
1149 : public OcclusionTrackerTest
<Types
> {
1151 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
1152 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1154 gfx::Transform child_transform
;
1155 child_transform
.Translate(250.0, 250.0);
1156 child_transform
.Rotate(95.0);
1157 child_transform
.Translate(-250.0, -250.0);
1159 gfx::Transform layer_transform
;
1160 layer_transform
.Translate(10.0, 10.0);
1162 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1163 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1164 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1165 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1166 typename
Types::LayerType
* child
= this->CreateLayer(
1167 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1168 child
->SetMasksToBounds(true);
1169 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1170 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
1171 this->CalcDrawEtc(root
);
1173 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1174 typename
Types::RenderSurfaceType
> occlusion(
1175 gfx::Rect(0, 0, 1000, 1000));
1177 gfx::Rect clipped_layer_in_child
= MathUtil::MapClippedRect(
1178 layer_transform
, layer
->visible_content_rect());
1180 this->VisitLayer(layer
, &occlusion
);
1181 this->EnterContributingSurface(child
, &occlusion
, false);
1183 EXPECT_EQ(gfx::Rect().ToString(),
1184 occlusion
.occlusion_from_outside_target().ToString());
1185 EXPECT_EQ(clipped_layer_in_child
.ToString(),
1186 occlusion
.occlusion_from_inside_target().ToString());
1188 this->LeaveContributingSurface(child
, &occlusion
);
1189 this->EnterLayer(parent
, &occlusion
, false);
1191 EXPECT_EQ(gfx::Rect().ToString(),
1192 occlusion
.occlusion_from_outside_target().ToString());
1193 EXPECT_EQ(gfx::Rect().ToString(),
1194 occlusion
.occlusion_from_inside_target().ToString());
1196 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
1198 gfx::Rect(75, 55, 1, 1),
1199 occlusion
.UnoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
1203 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
1205 template <class Types
>
1206 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1207 : public OcclusionTrackerTest
<Types
> {
1209 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
1210 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1212 gfx::Transform child_transform
;
1213 child_transform
.Translate(250.0, 250.0);
1214 child_transform
.Rotate(90.0);
1215 child_transform
.Translate(-250.0, -250.0);
1217 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1218 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1219 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1220 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1221 parent
->SetMasksToBounds(true);
1222 typename
Types::ContentLayerType
* child
=
1223 this->CreateDrawingSurface(parent
,
1225 gfx::PointF(30.f
, 30.f
),
1226 gfx::Size(500, 500),
1228 child
->SetMasksToBounds(true);
1229 typename
Types::ContentLayerType
* layer1
=
1230 this->CreateDrawingLayer(child
,
1231 this->identity_matrix
,
1232 gfx::PointF(10.f
, 10.f
),
1233 gfx::Size(500, 500),
1235 typename
Types::ContentLayerType
* layer2
=
1236 this->CreateDrawingLayer(child
,
1237 this->identity_matrix
,
1238 gfx::PointF(10.f
, 450.f
),
1241 this->CalcDrawEtc(root
);
1243 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1244 typename
Types::RenderSurfaceType
> occlusion(
1245 gfx::Rect(0, 0, 1000, 1000));
1247 this->VisitLayer(layer2
, &occlusion
);
1248 this->VisitLayer(layer1
, &occlusion
);
1249 this->VisitLayer(child
, &occlusion
);
1250 this->EnterContributingSurface(child
, &occlusion
, false);
1252 EXPECT_EQ(gfx::Rect().ToString(),
1253 occlusion
.occlusion_from_outside_target().ToString());
1254 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1255 occlusion
.occlusion_from_inside_target().ToString());
1257 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
1258 EXPECT_FALSE(occlusion
.OccludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
1259 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(11, 430, 59, 70)));
1260 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 431, 60, 69)));
1262 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1263 child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1265 gfx::Rect(9, 430, 1, 70),
1266 occlusion
.UnoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
1267 EXPECT_RECT_EQ(gfx::Rect(),
1268 occlusion
.UnoccludedLayerContentRect(
1269 child
, gfx::Rect(11, 430, 59, 70)));
1270 EXPECT_RECT_EQ(gfx::Rect(),
1271 occlusion
.UnoccludedLayerContentRect(
1272 child
, gfx::Rect(10, 431, 60, 69)));
1274 this->LeaveContributingSurface(child
, &occlusion
);
1275 this->EnterLayer(parent
, &occlusion
, false);
1277 EXPECT_EQ(gfx::Rect().ToString(),
1278 occlusion
.occlusion_from_outside_target().ToString());
1279 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1280 occlusion
.occlusion_from_inside_target().ToString());
1282 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1283 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1284 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1286 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1287 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1288 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1289 occlusion
.UnoccludedLayerContentRect(
1290 parent
, gfx::Rect(29, 40, 70, 60)));
1291 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1292 occlusion
.UnoccludedLayerContentRect(
1293 parent
, gfx::Rect(30, 39, 70, 60)));
1294 EXPECT_RECT_EQ(gfx::Rect(),
1295 occlusion
.UnoccludedLayerContentRect(
1296 parent
, gfx::Rect(31, 40, 69, 60)));
1297 EXPECT_RECT_EQ(gfx::Rect(),
1298 occlusion
.UnoccludedLayerContentRect(
1299 parent
, gfx::Rect(30, 41, 70, 59)));
1301 /* Justification for the above occlusion from |layer1| and |layer2|:
1303 +---------------------+
1304 | |30 Visible region of |layer1|: /////
1305 | | Visible region of |layer2|: \\\\\
1306 | +---------------------------------+
1308 | +---------------+-----------------+ |
1309 | | |\\\\\\\\\\\\|//| 420 | |
1310 | | |\\\\\\\\\\\\|//|60 | |
1311 | | |\\\\\\\\\\\\|//| | |
1312 +--|--|------------|--+ | |
1320 | +------------|-----------------|--+
1322 +---------------+-----------------+
1328 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1330 template <class Types
>
1331 class OcclusionTrackerTestOverlappingSurfaceSiblings
1332 : public OcclusionTrackerTest
<Types
> {
1334 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
1335 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1337 gfx::Transform child_transform
;
1338 child_transform
.Translate(250.0, 250.0);
1339 child_transform
.Rotate(90.0);
1340 child_transform
.Translate(-250.0, -250.0);
1342 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1343 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1344 parent
->SetMasksToBounds(true);
1345 typename
Types::LayerType
* child1
= this->CreateSurface(
1346 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(10, 10));
1347 typename
Types::LayerType
* child2
= this->CreateSurface(
1348 parent
, child_transform
, gfx::PointF(20.f
, 40.f
), gfx::Size(10, 10));
1349 typename
Types::ContentLayerType
* layer1
=
1350 this->CreateDrawingLayer(child1
,
1351 this->identity_matrix
,
1352 gfx::PointF(-10.f
, -10.f
),
1353 gfx::Size(510, 510),
1355 typename
Types::ContentLayerType
* layer2
=
1356 this->CreateDrawingLayer(child2
,
1357 this->identity_matrix
,
1358 gfx::PointF(-10.f
, -10.f
),
1359 gfx::Size(510, 510),
1361 this->CalcDrawEtc(parent
);
1363 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1364 typename
Types::RenderSurfaceType
> occlusion(
1365 gfx::Rect(0, 0, 1000, 1000));
1367 this->VisitLayer(layer2
, &occlusion
);
1368 this->EnterContributingSurface(child2
, &occlusion
, false);
1370 EXPECT_EQ(gfx::Rect().ToString(),
1371 occlusion
.occlusion_from_outside_target().ToString());
1372 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1373 occlusion
.occlusion_from_inside_target().ToString());
1375 // There is nothing above child2's surface in the z-order.
1376 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1377 occlusion
.UnoccludedContributingSurfaceContentRect(
1378 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1380 this->LeaveContributingSurface(child2
, &occlusion
);
1381 this->VisitLayer(layer1
, &occlusion
);
1382 this->EnterContributingSurface(child1
, &occlusion
, false);
1384 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1385 occlusion
.occlusion_from_outside_target().ToString());
1386 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1387 occlusion
.occlusion_from_inside_target().ToString());
1389 // child2's contents will occlude child1 below it.
1390 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1391 occlusion
.UnoccludedContributingSurfaceContentRect(
1392 child1
, false, gfx::Rect(-10, 430, 80, 70)));
1394 this->LeaveContributingSurface(child1
, &occlusion
);
1395 this->EnterLayer(parent
, &occlusion
, false);
1397 EXPECT_EQ(gfx::Rect().ToString(),
1398 occlusion
.occlusion_from_outside_target().ToString());
1399 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1401 occlusion
.occlusion_from_inside_target().ToString());
1403 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1405 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1406 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1407 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1409 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1410 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1411 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1413 /* Justification for the above occlusion:
1415 +---------------------+
1417 | 30+ ---------------------------------+
1418 100 | 30| | layer2 |
1419 |20+----------------------------------+ |
1423 +--|-|----------------+ | |
1431 | +--------------------------------|-+
1433 +----------------------------------+
1439 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1441 template <class Types
>
1442 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1443 : public OcclusionTrackerTest
<Types
> {
1445 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1447 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1449 gfx::Transform child1_transform
;
1450 child1_transform
.Translate(250.0, 250.0);
1451 child1_transform
.Rotate(-90.0);
1452 child1_transform
.Translate(-250.0, -250.0);
1454 gfx::Transform child2_transform
;
1455 child2_transform
.Translate(250.0, 250.0);
1456 child2_transform
.Rotate(90.0);
1457 child2_transform
.Translate(-250.0, -250.0);
1459 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1460 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1461 parent
->SetMasksToBounds(true);
1462 typename
Types::LayerType
* child1
= this->CreateSurface(
1463 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1464 typename
Types::LayerType
* child2
=
1465 this->CreateDrawingSurface(parent
,
1467 gfx::PointF(20.f
, 40.f
),
1470 typename
Types::ContentLayerType
* layer1
=
1471 this->CreateDrawingLayer(child1
,
1472 this->identity_matrix
,
1473 gfx::PointF(-10.f
, -20.f
),
1474 gfx::Size(510, 510),
1476 typename
Types::ContentLayerType
* layer2
=
1477 this->CreateDrawingLayer(child2
,
1478 this->identity_matrix
,
1479 gfx::PointF(-10.f
, -10.f
),
1480 gfx::Size(510, 510),
1482 this->CalcDrawEtc(parent
);
1484 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1485 typename
Types::RenderSurfaceType
> occlusion(
1486 gfx::Rect(0, 0, 1000, 1000));
1488 this->VisitLayer(layer2
, &occlusion
);
1489 this->EnterLayer(child2
, &occlusion
, false);
1491 EXPECT_EQ(gfx::Rect().ToString(),
1492 occlusion
.occlusion_from_outside_target().ToString());
1493 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1494 occlusion
.occlusion_from_inside_target().ToString());
1496 this->LeaveLayer(child2
, &occlusion
);
1497 this->EnterContributingSurface(child2
, &occlusion
, false);
1499 // There is nothing above child2's surface in the z-order.
1500 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1501 occlusion
.UnoccludedContributingSurfaceContentRect(
1502 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1504 this->LeaveContributingSurface(child2
, &occlusion
);
1505 this->VisitLayer(layer1
, &occlusion
);
1506 this->EnterContributingSurface(child1
, &occlusion
, false);
1508 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1509 occlusion
.occlusion_from_outside_target().ToString());
1510 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1511 occlusion
.occlusion_from_inside_target().ToString());
1513 // child2's contents will occlude child1 below it.
1514 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1515 occlusion
.UnoccludedContributingSurfaceContentRect(
1516 child1
, false, gfx::Rect(420, -20, 80, 90)));
1517 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1518 occlusion
.UnoccludedContributingSurfaceContentRect(
1519 child1
, false, gfx::Rect(420, -10, 80, 90)));
1520 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1521 occlusion
.UnoccludedContributingSurfaceContentRect(
1522 child1
, false, gfx::Rect(420, -20, 70, 90)));
1524 this->LeaveContributingSurface(child1
, &occlusion
);
1525 this->EnterLayer(parent
, &occlusion
, false);
1527 EXPECT_EQ(gfx::Rect().ToString(),
1528 occlusion
.occlusion_from_outside_target().ToString());
1529 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1530 occlusion
.occlusion_from_inside_target().ToString());
1532 /* Justification for the above occlusion:
1534 +---------------------+
1536 10+----------------------------------+
1537 100 || 30 | layer2 |
1538 |20+----------------------------------+
1542 +|-|------------------+ | |
1550 +----------------------------------+ |
1552 +----------------------------------+
1558 ALL_OCCLUSIONTRACKER_TEST(
1559 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1561 template <class Types
>
1562 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1564 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1565 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1567 gfx::Transform layer_transform
;
1568 layer_transform
.Translate(250.0, 250.0);
1569 layer_transform
.Rotate(90.0);
1570 layer_transform
.Translate(-250.0, -250.0);
1572 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1573 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1574 parent
->SetMasksToBounds(true);
1575 typename
Types::ContentLayerType
* blur_layer
=
1576 this->CreateDrawingLayer(parent
,
1578 gfx::PointF(30.f
, 30.f
),
1579 gfx::Size(500, 500),
1581 typename
Types::ContentLayerType
* opaque_layer
=
1582 this->CreateDrawingLayer(parent
,
1584 gfx::PointF(30.f
, 30.f
),
1585 gfx::Size(500, 500),
1587 typename
Types::ContentLayerType
* opacity_layer
=
1588 this->CreateDrawingLayer(parent
,
1590 gfx::PointF(30.f
, 30.f
),
1591 gfx::Size(500, 500),
1594 FilterOperations filters
;
1595 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1596 blur_layer
->SetFilters(filters
);
1599 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1600 opaque_layer
->SetFilters(filters
);
1603 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1604 opacity_layer
->SetFilters(filters
);
1606 this->CalcDrawEtc(parent
);
1608 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1609 typename
Types::RenderSurfaceType
> occlusion(
1610 gfx::Rect(0, 0, 1000, 1000));
1612 // Opacity layer won't contribute to occlusion.
1613 this->VisitLayer(opacity_layer
, &occlusion
);
1614 this->EnterContributingSurface(opacity_layer
, &occlusion
, false);
1616 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1617 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1619 // And has nothing to contribute to its parent surface.
1620 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1621 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1622 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1624 // Opaque layer will contribute to occlusion.
1625 this->VisitLayer(opaque_layer
, &occlusion
);
1626 this->EnterContributingSurface(opaque_layer
, &occlusion
, false);
1628 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1629 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1630 occlusion
.occlusion_from_inside_target().ToString());
1632 // And it gets translated to the parent surface.
1633 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1634 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1635 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1636 occlusion
.occlusion_from_inside_target().ToString());
1638 // The blur layer needs to throw away any occlusion from outside its
1640 this->EnterLayer(blur_layer
, &occlusion
, false);
1641 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1642 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1644 // And it won't contribute to occlusion.
1645 this->LeaveLayer(blur_layer
, &occlusion
);
1646 this->EnterContributingSurface(blur_layer
, &occlusion
, false);
1647 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1648 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1650 // But the opaque layer's occlusion is preserved on the parent.
1651 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1652 this->EnterLayer(parent
, &occlusion
, false);
1653 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1654 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1655 occlusion
.occlusion_from_inside_target().ToString());
1659 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1661 template <class Types
>
1662 class OcclusionTrackerTestReplicaDoesOcclude
1663 : public OcclusionTrackerTest
<Types
> {
1665 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1666 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1668 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1669 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1670 typename
Types::LayerType
* surface
=
1671 this->CreateDrawingSurface(parent
,
1672 this->identity_matrix
,
1673 gfx::PointF(0.f
, 100.f
),
1676 this->CreateReplicaLayer(
1677 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1678 this->CalcDrawEtc(parent
);
1680 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1681 typename
Types::RenderSurfaceType
> occlusion(
1682 gfx::Rect(0, 0, 1000, 1000));
1684 this->VisitLayer(surface
, &occlusion
);
1686 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1687 occlusion
.occlusion_from_inside_target().ToString());
1689 this->VisitContributingSurface(surface
, &occlusion
);
1690 this->EnterLayer(parent
, &occlusion
, false);
1692 // The surface and replica should both be occluding the parent.
1694 UnionRegions(gfx::Rect(0, 100, 50, 50),
1695 gfx::Rect(50, 150, 50, 50)).ToString(),
1696 occlusion
.occlusion_from_inside_target().ToString());
1700 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1702 template <class Types
>
1703 class OcclusionTrackerTestReplicaWithClipping
1704 : public OcclusionTrackerTest
<Types
> {
1706 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1707 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1709 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1710 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1711 parent
->SetMasksToBounds(true);
1712 typename
Types::LayerType
* surface
=
1713 this->CreateDrawingSurface(parent
,
1714 this->identity_matrix
,
1715 gfx::PointF(0.f
, 100.f
),
1718 this->CreateReplicaLayer(
1719 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1720 this->CalcDrawEtc(parent
);
1722 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1723 typename
Types::RenderSurfaceType
> occlusion(
1724 gfx::Rect(0, 0, 1000, 1000));
1726 this->VisitLayer(surface
, &occlusion
);
1728 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1729 occlusion
.occlusion_from_inside_target().ToString());
1731 this->VisitContributingSurface(surface
, &occlusion
);
1732 this->EnterLayer(parent
, &occlusion
, false);
1734 // The surface and replica should both be occluding the parent.
1736 UnionRegions(gfx::Rect(0, 100, 50, 50),
1737 gfx::Rect(50, 150, 50, 20)).ToString(),
1738 occlusion
.occlusion_from_inside_target().ToString());
1742 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1744 template <class Types
>
1745 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1747 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1748 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1750 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1751 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1752 typename
Types::LayerType
* surface
=
1753 this->CreateDrawingSurface(parent
,
1754 this->identity_matrix
,
1755 gfx::PointF(0.f
, 100.f
),
1758 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1759 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1760 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1761 this->CalcDrawEtc(parent
);
1763 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1764 typename
Types::RenderSurfaceType
> occlusion(
1765 gfx::Rect(0, 0, 1000, 1000));
1767 this->VisitLayer(surface
, &occlusion
);
1769 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1770 occlusion
.occlusion_from_inside_target().ToString());
1772 this->VisitContributingSurface(surface
, &occlusion
);
1773 this->EnterLayer(parent
, &occlusion
, false);
1775 // The replica should not be occluding the parent, since it has a mask
1777 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1778 occlusion
.occlusion_from_inside_target().ToString());
1782 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1784 template <class Types
>
1785 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1786 : public OcclusionTrackerTest
<Types
> {
1788 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1789 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1791 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1792 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1793 typename
Types::ContentLayerType
* layer
=
1794 this->CreateDrawingSurface(parent
,
1795 this->identity_matrix
,
1797 gfx::Size(200, 200),
1799 this->CalcDrawEtc(parent
);
1801 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1802 typename
Types::RenderSurfaceType
> occlusion(
1803 gfx::Rect(0, 0, 1000, 1000));
1804 this->EnterLayer(layer
, &occlusion
, false);
1806 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1807 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1808 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1809 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1811 this->LeaveLayer(layer
, &occlusion
);
1812 this->VisitContributingSurface(layer
, &occlusion
);
1813 this->EnterLayer(parent
, &occlusion
, false);
1815 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1819 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1821 template <class Types
>
1822 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1823 : public OcclusionTrackerTest
<Types
> {
1825 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1826 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1828 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1829 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1830 typename
Types::ContentLayerType
* layer
=
1831 this->CreateDrawingLayer(parent
,
1832 this->identity_matrix
,
1833 gfx::PointF(100.f
, 100.f
),
1834 gfx::Size(200, 200),
1836 this->CalcDrawEtc(parent
);
1838 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1839 typename
Types::RenderSurfaceType
> occlusion(
1840 gfx::Rect(0, 0, 1000, 1000));
1841 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1843 this->ResetLayerIterator();
1844 this->VisitLayer(layer
, &occlusion
);
1845 this->EnterLayer(parent
, &occlusion
, false);
1847 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1848 occlusion
.occlusion_from_inside_target().ToString());
1851 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1853 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1855 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1858 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1859 typename
Types::RenderSurfaceType
> occlusion(
1860 gfx::Rect(0, 0, 1000, 1000));
1861 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1863 this->ResetLayerIterator();
1864 this->VisitLayer(layer
, &occlusion
);
1865 this->EnterLayer(parent
, &occlusion
, false);
1867 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1868 occlusion
.occlusion_from_inside_target().ToString());
1871 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1873 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1875 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1878 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1879 typename
Types::RenderSurfaceType
> occlusion(
1880 gfx::Rect(0, 0, 1000, 1000));
1881 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1883 this->ResetLayerIterator();
1884 this->VisitLayer(layer
, &occlusion
);
1885 this->EnterLayer(parent
, &occlusion
, false);
1887 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1888 occlusion
.occlusion_from_inside_target().ToString());
1891 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1893 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1895 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1900 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1902 template <class Types
>
1903 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
1905 explicit OcclusionTrackerTest3dTransform(bool opaque_layers
)
1906 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1908 gfx::Transform transform
;
1909 transform
.RotateAboutYAxis(30.0);
1911 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1912 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1913 typename
Types::LayerType
* container
= this->CreateLayer(
1914 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1915 typename
Types::ContentLayerType
* layer
=
1916 this->CreateDrawingLayer(container
,
1918 gfx::PointF(100.f
, 100.f
),
1919 gfx::Size(200, 200),
1921 this->CalcDrawEtc(parent
);
1923 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1924 typename
Types::RenderSurfaceType
> occlusion(
1925 gfx::Rect(0, 0, 1000, 1000));
1926 this->EnterLayer(layer
, &occlusion
, false);
1928 // The layer is rotated in 3d but without preserving 3d, so it only gets
1931 gfx::Rect(0, 0, 200, 200),
1932 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1936 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
1938 template <class Types
>
1939 class OcclusionTrackerTestUnsorted3dLayers
1940 : public OcclusionTrackerTest
<Types
> {
1942 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
1943 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1945 // Currently, The main thread layer iterator does not iterate over 3d items
1946 // in sorted order, because layer sorting is not performed on the main
1947 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1948 // layer occludes other layers that have not yet been iterated over. For
1949 // now, the expected behavior is that a 3d layer simply does not add any
1950 // occlusion to the occlusion tracker.
1952 gfx::Transform translation_to_front
;
1953 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
1954 gfx::Transform translation_to_back
;
1955 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
1957 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1958 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1959 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
1960 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
1961 typename
Types::ContentLayerType
* child2
=
1962 this->CreateDrawingLayer(parent
,
1963 translation_to_front
,
1964 gfx::PointF(50.f
, 50.f
),
1965 gfx::Size(100, 100),
1967 parent
->SetPreserves3d(true);
1969 this->CalcDrawEtc(parent
);
1971 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1972 typename
Types::RenderSurfaceType
> occlusion(
1973 gfx::Rect(0, 0, 1000, 1000));
1974 this->VisitLayer(child2
, &occlusion
);
1975 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1976 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1978 this->VisitLayer(child1
, &occlusion
);
1979 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1980 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1984 // This test will have different layer ordering on the impl thread; the test
1985 // will only work on the main thread.
1986 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1988 template <class Types
>
1989 class OcclusionTrackerTestPerspectiveTransform
1990 : public OcclusionTrackerTest
<Types
> {
1992 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers
)
1993 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1995 gfx::Transform transform
;
1996 transform
.Translate(150.0, 150.0);
1997 transform
.ApplyPerspectiveDepth(400.0);
1998 transform
.RotateAboutXAxis(-30.0);
1999 transform
.Translate(-150.0, -150.0);
2001 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2002 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2003 typename
Types::LayerType
* container
= this->CreateLayer(
2004 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2005 typename
Types::ContentLayerType
* layer
=
2006 this->CreateDrawingLayer(container
,
2008 gfx::PointF(100.f
, 100.f
),
2009 gfx::Size(200, 200),
2011 container
->SetPreserves3d(true);
2012 layer
->SetPreserves3d(true);
2013 this->CalcDrawEtc(parent
);
2015 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2016 typename
Types::RenderSurfaceType
> occlusion(
2017 gfx::Rect(0, 0, 1000, 1000));
2018 this->EnterLayer(layer
, &occlusion
, false);
2021 gfx::Rect(0, 0, 200, 200),
2022 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
2026 // This test requires accumulating occlusion of 3d layers, which are skipped by
2027 // the occlusion tracker on the main thread. So this test should run on the impl
2029 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
2031 template <class Types
>
2032 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2033 : public OcclusionTrackerTest
<Types
> {
2035 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2037 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2039 // This test is based on the platform/chromium/compositing/3d-corners.html
2041 gfx::Transform transform
;
2042 transform
.Translate(250.0, 50.0);
2043 transform
.ApplyPerspectiveDepth(10.0);
2044 transform
.Translate(-250.0, -50.0);
2045 transform
.Translate(250.0, 50.0);
2046 transform
.RotateAboutXAxis(-167.0);
2047 transform
.Translate(-250.0, -50.0);
2049 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2050 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 100));
2051 typename
Types::LayerType
* container
= this->CreateLayer(
2052 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2053 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2054 container
, transform
, gfx::PointF(), gfx::Size(500, 500), true);
2055 container
->SetPreserves3d(true);
2056 layer
->SetPreserves3d(true);
2057 this->CalcDrawEtc(parent
);
2059 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2060 typename
Types::RenderSurfaceType
> occlusion(
2061 gfx::Rect(0, 0, 1000, 1000));
2062 this->EnterLayer(layer
, &occlusion
, false);
2064 // The bottom 11 pixel rows of this layer remain visible inside the
2065 // container, after translation to the target surface. When translated back,
2066 // this will include many more pixels but must include at least the bottom
2068 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2069 layer
, gfx::Rect(0, 26, 500, 474)).
2070 Contains(gfx::Rect(0, 489, 500, 11)));
2074 // This test requires accumulating occlusion of 3d layers, which are skipped by
2075 // the occlusion tracker on the main thread. So this test should run on the impl
2077 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
2079 template <class Types
>
2080 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2081 : public OcclusionTrackerTest
<Types
> {
2083 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2085 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2087 gfx::Transform transform
;
2088 transform
.Translate(50.0, 50.0);
2089 transform
.ApplyPerspectiveDepth(100.0);
2090 transform
.Translate3d(0.0, 0.0, 110.0);
2091 transform
.Translate(-50.0, -50.0);
2093 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2094 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2095 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2096 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2097 parent
->SetPreserves3d(true);
2098 layer
->SetPreserves3d(true);
2099 this->CalcDrawEtc(parent
);
2101 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2102 typename
Types::RenderSurfaceType
> occlusion(
2103 gfx::Rect(0, 0, 1000, 1000));
2105 // The |layer| is entirely behind the camera and should not occlude.
2106 this->VisitLayer(layer
, &occlusion
);
2107 this->EnterLayer(parent
, &occlusion
, false);
2108 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2109 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2113 // This test requires accumulating occlusion of 3d layers, which are skipped by
2114 // the occlusion tracker on the main thread. So this test should run on the impl
2116 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2118 template <class Types
>
2119 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2120 : public OcclusionTrackerTest
<Types
> {
2122 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2124 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2126 gfx::Transform transform
;
2127 transform
.Translate(50.0, 50.0);
2128 transform
.ApplyPerspectiveDepth(100.0);
2129 transform
.Translate3d(0.0, 0.0, 99.0);
2130 transform
.Translate(-50.0, -50.0);
2132 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2133 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2134 parent
->SetMasksToBounds(true);
2135 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2136 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2137 parent
->SetPreserves3d(true);
2138 layer
->SetPreserves3d(true);
2139 this->CalcDrawEtc(parent
);
2141 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2142 typename
Types::RenderSurfaceType
> occlusion(
2143 gfx::Rect(0, 0, 1000, 1000));
2145 // This is very close to the camera, so pixels in its visible_content_rect()
2146 // will actually go outside of the layer's clip rect. Ensure that those
2147 // pixels don't occlude things outside the clip rect.
2148 this->VisitLayer(layer
, &occlusion
);
2149 this->EnterLayer(parent
, &occlusion
, false);
2150 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2151 occlusion
.occlusion_from_inside_target().ToString());
2152 EXPECT_EQ(gfx::Rect().ToString(),
2153 occlusion
.occlusion_from_outside_target().ToString());
2157 // This test requires accumulating occlusion of 3d layers, which are skipped by
2158 // the occlusion tracker on the main thread. So this test should run on the impl
2160 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2162 template <class Types
>
2163 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2164 : public OcclusionTrackerTest
<Types
> {
2166 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
2167 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2172 // | +--surface_child
2173 // | +--surface_child2
2177 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2178 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2179 typename
Types::ContentLayerType
* layer
=
2180 this->CreateDrawingLayer(parent
,
2181 this->identity_matrix
,
2183 gfx::Size(300, 300),
2185 typename
Types::ContentLayerType
* surface
=
2186 this->CreateDrawingSurface(parent
,
2187 this->identity_matrix
,
2189 gfx::Size(300, 300),
2191 typename
Types::ContentLayerType
* surface_child
=
2192 this->CreateDrawingLayer(surface
,
2193 this->identity_matrix
,
2195 gfx::Size(200, 300),
2197 typename
Types::ContentLayerType
* surface_child2
=
2198 this->CreateDrawingLayer(surface
,
2199 this->identity_matrix
,
2201 gfx::Size(100, 300),
2203 typename
Types::ContentLayerType
* parent2
=
2204 this->CreateDrawingLayer(parent
,
2205 this->identity_matrix
,
2207 gfx::Size(300, 300),
2209 typename
Types::ContentLayerType
* topmost
=
2210 this->CreateDrawingLayer(parent
,
2211 this->identity_matrix
,
2212 gfx::PointF(250.f
, 0.f
),
2216 AddOpacityTransitionToController(
2217 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2218 AddOpacityTransitionToController(
2219 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2220 this->CalcDrawEtc(parent
);
2222 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2223 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2224 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2226 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2227 typename
Types::RenderSurfaceType
> occlusion(
2228 gfx::Rect(0, 0, 1000, 1000));
2230 this->VisitLayer(topmost
, &occlusion
);
2231 this->EnterLayer(parent2
, &occlusion
, false);
2232 // This occlusion will affect all surfaces.
2233 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2234 occlusion
.occlusion_from_inside_target().ToString());
2235 EXPECT_EQ(gfx::Rect().ToString(),
2236 occlusion
.occlusion_from_outside_target().ToString());
2237 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2238 occlusion
.UnoccludedLayerContentRect(
2239 parent2
, gfx::Rect(0, 0, 300, 300)).ToString());
2240 this->LeaveLayer(parent2
, &occlusion
);
2242 this->VisitLayer(surface_child2
, &occlusion
);
2243 this->EnterLayer(surface_child
, &occlusion
, false);
2244 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2245 occlusion
.occlusion_from_inside_target().ToString());
2246 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2247 occlusion
.occlusion_from_outside_target().ToString());
2248 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2249 occlusion
.UnoccludedLayerContentRect(
2250 surface_child
, gfx::Rect(0, 0, 200, 300)));
2251 this->LeaveLayer(surface_child
, &occlusion
);
2252 this->EnterLayer(surface
, &occlusion
, false);
2253 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2254 occlusion
.occlusion_from_inside_target().ToString());
2255 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2256 occlusion
.occlusion_from_outside_target().ToString());
2257 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2258 occlusion
.UnoccludedLayerContentRect(
2259 surface
, gfx::Rect(0, 0, 300, 300)));
2260 this->LeaveLayer(surface
, &occlusion
);
2262 this->EnterContributingSurface(surface
, &occlusion
, false);
2263 // Occlusion within the surface is lost when leaving the animating surface.
2264 EXPECT_EQ(gfx::Rect().ToString(),
2265 occlusion
.occlusion_from_inside_target().ToString());
2266 EXPECT_EQ(gfx::Rect().ToString(),
2267 occlusion
.occlusion_from_outside_target().ToString());
2268 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2269 occlusion
.UnoccludedContributingSurfaceContentRect(
2270 surface
, false, gfx::Rect(0, 0, 300, 300)));
2271 this->LeaveContributingSurface(surface
, &occlusion
);
2273 // Occlusion from outside the animating surface still exists.
2274 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2275 occlusion
.occlusion_from_inside_target().ToString());
2276 EXPECT_EQ(gfx::Rect().ToString(),
2277 occlusion
.occlusion_from_outside_target().ToString());
2279 this->VisitLayer(layer
, &occlusion
);
2280 this->EnterLayer(parent
, &occlusion
, false);
2282 // Occlusion is not added for the animating |layer|.
2283 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2284 occlusion
.UnoccludedLayerContentRect(
2285 parent
, gfx::Rect(0, 0, 300, 300)));
2289 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2291 template <class Types
>
2292 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2293 : public OcclusionTrackerTest
<Types
> {
2295 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
2296 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2298 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2299 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2300 typename
Types::ContentLayerType
* layer
=
2301 this->CreateDrawingLayer(parent
,
2302 this->identity_matrix
,
2304 gfx::Size(300, 300),
2306 typename
Types::ContentLayerType
* surface
=
2307 this->CreateDrawingSurface(parent
,
2308 this->identity_matrix
,
2310 gfx::Size(300, 300),
2312 typename
Types::ContentLayerType
* surface_child
=
2313 this->CreateDrawingLayer(surface
,
2314 this->identity_matrix
,
2316 gfx::Size(200, 300),
2318 typename
Types::ContentLayerType
* surface_child2
=
2319 this->CreateDrawingLayer(surface
,
2320 this->identity_matrix
,
2322 gfx::Size(100, 300),
2324 typename
Types::ContentLayerType
* parent2
=
2325 this->CreateDrawingLayer(parent
,
2326 this->identity_matrix
,
2328 gfx::Size(300, 300),
2330 typename
Types::ContentLayerType
* topmost
=
2331 this->CreateDrawingLayer(parent
,
2332 this->identity_matrix
,
2333 gfx::PointF(250.f
, 0.f
),
2337 AddOpacityTransitionToController(
2338 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2339 AddOpacityTransitionToController(
2340 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2341 this->CalcDrawEtc(parent
);
2343 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2344 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2345 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2347 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2348 typename
Types::RenderSurfaceType
> occlusion(
2349 gfx::Rect(0, 0, 1000, 1000));
2351 this->VisitLayer(topmost
, &occlusion
);
2352 this->EnterLayer(parent2
, &occlusion
, false);
2353 // This occlusion will affect all surfaces.
2354 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2355 occlusion
.occlusion_from_inside_target().ToString());
2356 EXPECT_EQ(gfx::Rect().ToString(),
2357 occlusion
.occlusion_from_outside_target().ToString());
2358 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2359 occlusion
.UnoccludedLayerContentRect(
2360 parent
, gfx::Rect(0, 0, 300, 300)));
2361 this->LeaveLayer(parent2
, &occlusion
);
2363 this->VisitLayer(surface_child2
, &occlusion
);
2364 this->EnterLayer(surface_child
, &occlusion
, false);
2365 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2366 occlusion
.occlusion_from_inside_target().ToString());
2367 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2368 occlusion
.occlusion_from_outside_target().ToString());
2369 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2370 occlusion
.UnoccludedLayerContentRect(
2371 surface_child
, gfx::Rect(0, 0, 200, 300)));
2372 this->LeaveLayer(surface_child
, &occlusion
);
2373 this->EnterLayer(surface
, &occlusion
, false);
2374 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2375 occlusion
.occlusion_from_inside_target().ToString());
2376 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2377 occlusion
.occlusion_from_outside_target().ToString());
2378 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2379 occlusion
.UnoccludedLayerContentRect(
2380 surface
, gfx::Rect(0, 0, 300, 300)));
2381 this->LeaveLayer(surface
, &occlusion
);
2383 this->EnterContributingSurface(surface
, &occlusion
, false);
2384 // Occlusion within the surface is lost when leaving the animating surface.
2385 EXPECT_EQ(gfx::Rect().ToString(),
2386 occlusion
.occlusion_from_inside_target().ToString());
2387 EXPECT_EQ(gfx::Rect().ToString(),
2388 occlusion
.occlusion_from_outside_target().ToString());
2389 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2390 occlusion
.UnoccludedContributingSurfaceContentRect(
2391 surface
, false, gfx::Rect(0, 0, 300, 300)));
2392 this->LeaveContributingSurface(surface
, &occlusion
);
2394 // Occlusion from outside the animating surface still exists.
2395 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2396 occlusion
.occlusion_from_inside_target().ToString());
2397 EXPECT_EQ(gfx::Rect().ToString(),
2398 occlusion
.occlusion_from_outside_target().ToString());
2400 this->VisitLayer(layer
, &occlusion
);
2401 this->EnterLayer(parent
, &occlusion
, false);
2403 // Occlusion is not added for the animating |layer|.
2404 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2405 occlusion
.UnoccludedLayerContentRect(
2406 parent
, gfx::Rect(0, 0, 300, 300)));
2410 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2412 template <class Types
>
2413 class OcclusionTrackerTestAnimationTranslateOnMainThread
2414 : public OcclusionTrackerTest
<Types
> {
2416 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2418 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2420 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2421 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2422 typename
Types::ContentLayerType
* layer
=
2423 this->CreateDrawingLayer(parent
,
2424 this->identity_matrix
,
2426 gfx::Size(300, 300),
2428 typename
Types::ContentLayerType
* surface
=
2429 this->CreateDrawingSurface(parent
,
2430 this->identity_matrix
,
2432 gfx::Size(300, 300),
2434 typename
Types::ContentLayerType
* surface_child
=
2435 this->CreateDrawingLayer(surface
,
2436 this->identity_matrix
,
2438 gfx::Size(200, 300),
2440 typename
Types::ContentLayerType
* surface_child2
=
2441 this->CreateDrawingLayer(surface
,
2442 this->identity_matrix
,
2444 gfx::Size(100, 300),
2446 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
2447 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
2449 AddAnimatedTransformToController(
2450 layer
->layer_animation_controller(), 10.0, 30, 0);
2451 AddAnimatedTransformToController(
2452 surface
->layer_animation_controller(), 10.0, 30, 0);
2453 AddAnimatedTransformToController(
2454 surface_child
->layer_animation_controller(), 10.0, 30, 0);
2455 this->CalcDrawEtc(parent
);
2457 EXPECT_TRUE(layer
->draw_transform_is_animating());
2458 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
2460 surface
->render_surface()->target_surface_transforms_are_animating());
2462 surface
->render_surface()->screen_space_transforms_are_animating());
2463 // The surface owning layer doesn't animate against its own surface.
2464 EXPECT_FALSE(surface
->draw_transform_is_animating());
2465 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
2466 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
2467 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
2469 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2470 typename
Types::RenderSurfaceType
> occlusion(
2471 gfx::Rect(0, 0, 1000, 1000));
2473 this->VisitLayer(surface2
, &occlusion
);
2474 this->EnterContributingSurface(surface2
, &occlusion
, false);
2476 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2477 occlusion
.occlusion_from_inside_target().ToString());
2479 this->LeaveContributingSurface(surface2
, &occlusion
);
2480 this->EnterLayer(surface_child2
, &occlusion
, false);
2482 // surface_child2 is moving in screen space but not relative to its target,
2483 // so occlusion should happen in its target space only. It also means that
2484 // things occluding from outside the target (e.g. surface2) cannot occlude
2486 EXPECT_EQ(gfx::Rect().ToString(),
2487 occlusion
.occlusion_from_outside_target().ToString());
2489 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2490 occlusion
.UnoccludedLayerContentRect(
2491 surface_child2
, gfx::Rect(0, 0, 100, 300)));
2493 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2495 this->LeaveLayer(surface_child2
, &occlusion
);
2496 this->EnterLayer(surface_child
, &occlusion
, false);
2498 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 100, 300)));
2499 EXPECT_EQ(gfx::Rect().ToString(),
2500 occlusion
.occlusion_from_outside_target().ToString());
2501 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2502 occlusion
.occlusion_from_inside_target().ToString());
2503 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2504 occlusion
.UnoccludedLayerContentRect(
2505 surface
, gfx::Rect(0, 0, 300, 300)));
2507 // The surface_child is occluded by the surface_child2, but is moving
2508 // relative its target, so it can't be occluded.
2509 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2510 occlusion
.UnoccludedLayerContentRect(
2511 surface_child
, gfx::Rect(0, 0, 200, 300)));
2513 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2515 this->LeaveLayer(surface_child
, &occlusion
);
2516 this->EnterLayer(surface
, &occlusion
, false);
2517 // The surface_child is moving in screen space but not relative to its
2518 // target, so occlusion should happen from within the target only.
2519 EXPECT_EQ(gfx::Rect().ToString(),
2520 occlusion
.occlusion_from_outside_target().ToString());
2521 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2522 occlusion
.occlusion_from_inside_target().ToString());
2523 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2524 occlusion
.UnoccludedLayerContentRect(
2525 surface
, gfx::Rect(0, 0, 300, 300)));
2527 this->LeaveLayer(surface
, &occlusion
);
2528 // The surface's owning layer is moving in screen space but not relative to
2529 // its target, so occlusion should happen within the target only.
2530 EXPECT_EQ(gfx::Rect().ToString(),
2531 occlusion
.occlusion_from_outside_target().ToString());
2532 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2533 occlusion
.occlusion_from_inside_target().ToString());
2534 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2535 occlusion
.UnoccludedLayerContentRect(
2536 surface
, gfx::Rect(0, 0, 300, 300)));
2538 this->EnterContributingSurface(surface
, &occlusion
, false);
2539 // The contributing |surface| is animating so it can't be occluded.
2540 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2541 occlusion
.UnoccludedContributingSurfaceContentRect(
2542 surface
, false, gfx::Rect(0, 0, 300, 300)));
2543 this->LeaveContributingSurface(surface
, &occlusion
);
2545 this->EnterLayer(layer
, &occlusion
, false);
2546 // The |surface| is moving in the screen and in its target, so all occlusion
2547 // within the surface is lost when leaving it.
2548 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2549 occlusion
.UnoccludedLayerContentRect(
2550 parent
, gfx::Rect(0, 0, 300, 300)));
2551 this->LeaveLayer(layer
, &occlusion
);
2553 this->EnterLayer(parent
, &occlusion
, false);
2554 // The |layer| is animating in the screen and in its target, so no occlusion
2556 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2557 occlusion
.UnoccludedLayerContentRect(
2558 parent
, gfx::Rect(0, 0, 300, 300)));
2562 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
2564 template <class Types
>
2565 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2566 : public OcclusionTrackerTest
<Types
> {
2568 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2570 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2572 gfx::Transform surface_transform
;
2573 surface_transform
.Translate(300.0, 300.0);
2574 surface_transform
.Scale(2.0, 2.0);
2575 surface_transform
.Translate(-150.0, -150.0);
2577 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2578 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2579 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
2580 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
2581 typename
Types::ContentLayerType
* surface2
=
2582 this->CreateDrawingSurface(parent
,
2583 this->identity_matrix
,
2584 gfx::PointF(50.f
, 50.f
),
2585 gfx::Size(300, 300),
2587 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2588 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2589 this->CalcDrawEtc(parent
);
2591 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2592 typename
Types::RenderSurfaceType
> occlusion(
2593 gfx::Rect(0, 0, 1000, 1000));
2595 this->VisitLayer(surface2
, &occlusion
);
2596 this->VisitContributingSurface(surface2
, &occlusion
);
2598 EXPECT_EQ(gfx::Rect().ToString(),
2599 occlusion
.occlusion_from_outside_target().ToString());
2600 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2601 occlusion
.occlusion_from_inside_target().ToString());
2603 // Clear any stored occlusion.
2604 occlusion
.set_occlusion_from_outside_target(Region());
2605 occlusion
.set_occlusion_from_inside_target(Region());
2607 this->VisitLayer(surface
, &occlusion
);
2608 this->VisitContributingSurface(surface
, &occlusion
);
2610 EXPECT_EQ(gfx::Rect().ToString(),
2611 occlusion
.occlusion_from_outside_target().ToString());
2612 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2613 occlusion
.occlusion_from_inside_target().ToString());
2617 MAIN_AND_IMPL_THREAD_TEST(
2618 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
2620 template <class Types
>
2621 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2622 : public OcclusionTrackerTest
<Types
> {
2624 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2626 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2628 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2629 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2630 parent
->SetMasksToBounds(true);
2631 typename
Types::ContentLayerType
* surface
=
2632 this->CreateDrawingSurface(parent
,
2633 this->identity_matrix
,
2635 gfx::Size(500, 300),
2637 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2638 this->CalcDrawEtc(parent
);
2640 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2641 typename
Types::RenderSurfaceType
> occlusion(
2642 gfx::Rect(0, 0, 1000, 1000));
2644 this->VisitLayer(surface
, &occlusion
);
2645 this->VisitContributingSurface(surface
, &occlusion
);
2647 EXPECT_EQ(gfx::Rect().ToString(),
2648 occlusion
.occlusion_from_outside_target().ToString());
2649 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2650 occlusion
.occlusion_from_inside_target().ToString());
2654 MAIN_AND_IMPL_THREAD_TEST(
2655 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2657 template <class Types
>
2658 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
2660 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers
)
2661 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2663 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2664 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2665 typename
Types::LayerType
* surface
=
2666 this->CreateDrawingSurface(parent
,
2667 this->identity_matrix
,
2669 gfx::Size(100, 100),
2671 this->CreateReplicaLayer(surface
,
2672 this->identity_matrix
,
2673 gfx::PointF(0.f
, 100.f
),
2674 gfx::Size(100, 100));
2675 typename
Types::LayerType
* topmost
=
2676 this->CreateDrawingLayer(parent
,
2677 this->identity_matrix
,
2678 gfx::PointF(0.f
, 100.f
),
2679 gfx::Size(100, 100),
2681 this->CalcDrawEtc(parent
);
2683 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2684 typename
Types::RenderSurfaceType
> occlusion(
2685 gfx::Rect(0, 0, 1000, 1000));
2687 // |topmost| occludes the replica, but not the surface itself.
2688 this->VisitLayer(topmost
, &occlusion
);
2690 EXPECT_EQ(gfx::Rect().ToString(),
2691 occlusion
.occlusion_from_outside_target().ToString());
2692 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2693 occlusion
.occlusion_from_inside_target().ToString());
2695 this->VisitLayer(surface
, &occlusion
);
2697 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2698 occlusion
.occlusion_from_outside_target().ToString());
2699 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2700 occlusion
.occlusion_from_inside_target().ToString());
2702 this->EnterContributingSurface(surface
, &occlusion
, false);
2704 // Surface is not occluded so it shouldn't think it is.
2705 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2706 occlusion
.UnoccludedContributingSurfaceContentRect(
2707 surface
, false, gfx::Rect(0, 0, 100, 100)));
2711 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
2713 template <class Types
>
2714 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2715 : public OcclusionTrackerTest
<Types
> {
2717 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
2718 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2720 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2721 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2722 typename
Types::LayerType
* surface
=
2723 this->CreateDrawingSurface(parent
,
2724 this->identity_matrix
,
2726 gfx::Size(100, 100),
2728 this->CreateReplicaLayer(surface
,
2729 this->identity_matrix
,
2730 gfx::PointF(0.f
, 100.f
),
2731 gfx::Size(100, 100));
2732 typename
Types::LayerType
* topmost
=
2733 this->CreateDrawingLayer(parent
,
2734 this->identity_matrix
,
2736 gfx::Size(100, 110),
2738 this->CalcDrawEtc(parent
);
2740 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2741 typename
Types::RenderSurfaceType
> occlusion(
2742 gfx::Rect(0, 0, 1000, 1000));
2744 // |topmost| occludes the surface, but not the entire surface's replica.
2745 this->VisitLayer(topmost
, &occlusion
);
2747 EXPECT_EQ(gfx::Rect().ToString(),
2748 occlusion
.occlusion_from_outside_target().ToString());
2749 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2750 occlusion
.occlusion_from_inside_target().ToString());
2752 this->VisitLayer(surface
, &occlusion
);
2754 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2755 occlusion
.occlusion_from_outside_target().ToString());
2756 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2757 occlusion
.occlusion_from_inside_target().ToString());
2759 this->EnterContributingSurface(surface
, &occlusion
, false);
2761 // Surface is occluded, but only the top 10px of the replica.
2762 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2763 occlusion
.UnoccludedContributingSurfaceContentRect(
2764 surface
, false, gfx::Rect(0, 0, 100, 100)));
2765 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2766 occlusion
.UnoccludedContributingSurfaceContentRect(
2767 surface
, true, gfx::Rect(0, 0, 100, 100)));
2771 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2773 template <class Types
>
2774 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
2775 : public OcclusionTrackerTest
<Types
> {
2777 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
2779 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2781 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2782 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2783 typename
Types::LayerType
* surface
=
2784 this->CreateDrawingSurface(parent
,
2785 this->identity_matrix
,
2787 gfx::Size(100, 100),
2789 this->CreateReplicaLayer(surface
,
2790 this->identity_matrix
,
2791 gfx::PointF(0.f
, 100.f
),
2792 gfx::Size(100, 100));
2793 typename
Types::LayerType
* over_surface
= this->CreateDrawingLayer(
2794 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 100), true);
2795 typename
Types::LayerType
* over_replica
=
2796 this->CreateDrawingLayer(parent
,
2797 this->identity_matrix
,
2798 gfx::PointF(0.f
, 100.f
),
2801 this->CalcDrawEtc(parent
);
2803 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2804 typename
Types::RenderSurfaceType
> occlusion(
2805 gfx::Rect(0, 0, 1000, 1000));
2807 // These occlude the surface and replica differently, so we can test each
2809 this->VisitLayer(over_replica
, &occlusion
);
2810 this->VisitLayer(over_surface
, &occlusion
);
2812 EXPECT_EQ(gfx::Rect().ToString(),
2813 occlusion
.occlusion_from_outside_target().ToString());
2814 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2816 occlusion
.occlusion_from_inside_target().ToString());
2818 this->VisitLayer(surface
, &occlusion
);
2820 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2822 occlusion
.occlusion_from_outside_target().ToString());
2823 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2824 occlusion
.occlusion_from_inside_target().ToString());
2826 this->EnterContributingSurface(surface
, &occlusion
, false);
2828 // Surface and replica are occluded different amounts.
2829 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
2830 occlusion
.UnoccludedContributingSurfaceContentRect(
2831 surface
, false, gfx::Rect(0, 0, 100, 100)));
2832 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2833 occlusion
.UnoccludedContributingSurfaceContentRect(
2834 surface
, true, gfx::Rect(0, 0, 100, 100)));
2838 ALL_OCCLUSIONTRACKER_TEST(
2839 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
2841 template <class Types
>
2842 class OcclusionTrackerTestSurfaceChildOfSurface
2843 : public OcclusionTrackerTest
<Types
> {
2845 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
2846 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2848 // This test verifies that the surface cliprect does not end up empty and
2849 // clip away the entire unoccluded rect.
2851 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2852 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2853 typename
Types::LayerType
* surface
=
2854 this->CreateDrawingSurface(parent
,
2855 this->identity_matrix
,
2857 gfx::Size(100, 100),
2859 typename
Types::LayerType
* surface_child
=
2860 this->CreateDrawingSurface(surface
,
2861 this->identity_matrix
,
2862 gfx::PointF(0.f
, 10.f
),
2865 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
2866 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
2867 this->CalcDrawEtc(parent
);
2869 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2870 typename
Types::RenderSurfaceType
> occlusion(
2871 gfx::Rect(-100, -100, 1000, 1000));
2873 // |topmost| occludes everything partially so we know occlusion is happening
2875 this->VisitLayer(topmost
, &occlusion
);
2877 EXPECT_EQ(gfx::Rect().ToString(),
2878 occlusion
.occlusion_from_outside_target().ToString());
2879 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2880 occlusion
.occlusion_from_inside_target().ToString());
2882 this->VisitLayer(surface_child
, &occlusion
);
2884 // surface_child increases the occlusion in the screen by a narrow sliver.
2885 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2886 occlusion
.occlusion_from_outside_target().ToString());
2887 // In its own surface, surface_child is at 0,0 as is its occlusion.
2888 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2889 occlusion
.occlusion_from_inside_target().ToString());
2891 // The root layer always has a clip rect. So the parent of |surface| has a
2892 // clip rect. However, the owning layer for |surface| does not mask to
2893 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2894 // |surface_child| exercises different code paths as its parent does not
2895 // have a clip rect.
2897 this->EnterContributingSurface(surface_child
, &occlusion
, false);
2898 // The surface_child's parent does not have a clip rect as it owns a render
2899 // surface. Make sure the unoccluded rect does not get clipped away
2901 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
2902 occlusion
.UnoccludedContributingSurfaceContentRect(
2903 surface_child
, false, gfx::Rect(0, 0, 100, 50)));
2904 this->LeaveContributingSurface(surface_child
, &occlusion
);
2906 // When the surface_child's occlusion is transformed up to its parent, make
2907 // sure it is not clipped away inappropriately also.
2908 this->EnterLayer(surface
, &occlusion
, false);
2909 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2910 occlusion
.occlusion_from_outside_target().ToString());
2911 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2912 occlusion
.occlusion_from_inside_target().ToString());
2913 this->LeaveLayer(surface
, &occlusion
);
2915 this->EnterContributingSurface(surface
, &occlusion
, false);
2916 // The surface's parent does have a clip rect as it is the root layer.
2917 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
2918 occlusion
.UnoccludedContributingSurfaceContentRect(
2919 surface
, false, gfx::Rect(0, 0, 100, 100)));
2923 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2925 template <class Types
>
2926 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
2927 : public OcclusionTrackerTest
<Types
> {
2929 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
2931 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2933 // This test verifies that the top-most surface is considered occluded
2934 // outside of its target's clip rect and outside the viewport rect.
2936 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2937 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2938 typename
Types::LayerType
* surface
=
2939 this->CreateDrawingSurface(parent
,
2940 this->identity_matrix
,
2942 gfx::Size(100, 300),
2944 this->CalcDrawEtc(parent
);
2946 // Make a viewport rect that is larger than the root layer.
2947 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2948 typename
Types::RenderSurfaceType
> occlusion(
2949 gfx::Rect(0, 0, 1000, 1000));
2951 this->VisitLayer(surface
, &occlusion
);
2953 // The root layer always has a clip rect. So the parent of |surface| has a
2954 // clip rect giving the surface itself a clip rect.
2955 this->EnterContributingSurface(surface
, &occlusion
, false);
2956 // Make sure the parent's clip rect clips the unoccluded region of the
2958 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
2959 occlusion
.UnoccludedContributingSurfaceContentRect(
2960 surface
, false, gfx::Rect(0, 0, 100, 300)));
2962 this->ResetLayerIterator();
2964 // Make a viewport rect that is smaller than the root layer.
2965 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2966 typename
Types::RenderSurfaceType
> occlusion(
2967 gfx::Rect(0, 0, 100, 100));
2969 this->VisitLayer(surface
, &occlusion
);
2971 // The root layer always has a clip rect. So the parent of |surface| has a
2972 // clip rect giving the surface itself a clip rect.
2973 this->EnterContributingSurface(surface
, &occlusion
, false);
2974 // Make sure the viewport rect clips the unoccluded region of the child
2976 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2977 occlusion
.UnoccludedContributingSurfaceContentRect(
2978 surface
, false, gfx::Rect(0, 0, 100, 300)));
2983 ALL_OCCLUSIONTRACKER_TEST(
2984 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
);
2986 template <class Types
>
2987 class OcclusionTrackerTestSurfaceChildOfClippingSurface
2988 : public OcclusionTrackerTest
<Types
> {
2990 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers
)
2991 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2993 // This test verifies that the surface cliprect does not end up empty and
2994 // clip away the entire unoccluded rect.
2996 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2997 this->identity_matrix
, gfx::PointF(), gfx::Size(80, 200));
2998 parent
->SetMasksToBounds(true);
2999 typename
Types::LayerType
* surface
=
3000 this->CreateDrawingSurface(parent
,
3001 this->identity_matrix
,
3003 gfx::Size(100, 100),
3005 typename
Types::LayerType
* surface_child
=
3006 this->CreateDrawingSurface(surface
,
3007 this->identity_matrix
,
3009 gfx::Size(100, 100),
3011 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
3012 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
3013 this->CalcDrawEtc(parent
);
3015 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3016 typename
Types::RenderSurfaceType
> occlusion(
3017 gfx::Rect(0, 0, 1000, 1000));
3019 // |topmost| occludes everything partially so we know occlusion is happening
3021 this->VisitLayer(topmost
, &occlusion
);
3023 EXPECT_EQ(gfx::Rect().ToString(),
3024 occlusion
.occlusion_from_outside_target().ToString());
3025 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3026 occlusion
.occlusion_from_inside_target().ToString());
3028 // surface_child is not opaque and does not occlude, so we have a non-empty
3029 // unoccluded area on surface.
3030 this->VisitLayer(surface_child
, &occlusion
);
3032 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3033 occlusion
.occlusion_from_outside_target().ToString());
3034 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3035 occlusion
.occlusion_from_inside_target().ToString());
3037 // The root layer always has a clip rect. So the parent of |surface| has a
3038 // clip rect. However, the owning layer for |surface| does not mask to
3039 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3040 // |surface_child| exercises different code paths as its parent does not
3041 // have a clip rect.
3043 this->EnterContributingSurface(surface_child
, &occlusion
, false);
3044 // The surface_child's parent does not have a clip rect as it owns a render
3047 gfx::Rect(0, 50, 80, 50).ToString(),
3048 occlusion
.UnoccludedContributingSurfaceContentRect(
3049 surface_child
, false, gfx::Rect(0, 0, 100, 100)).ToString());
3050 this->LeaveContributingSurface(surface_child
, &occlusion
);
3052 this->VisitLayer(surface
, &occlusion
);
3053 this->EnterContributingSurface(surface
, &occlusion
, false);
3054 // The surface's parent does have a clip rect as it is the root layer.
3055 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3056 occlusion
.UnoccludedContributingSurfaceContentRect(
3057 surface
, false, gfx::Rect(0, 0, 100, 100)).ToString());
3061 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface
);
3063 template <class Types
>
3064 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3065 : public OcclusionTrackerTest
<Types
> {
3067 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3069 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3071 gfx::Transform scale_by_half
;
3072 scale_by_half
.Scale(0.5, 0.5);
3074 // Make a surface and its replica, each 50x50, that are completely
3075 // surrounded by opaque layers which are above them in the z-order. The
3076 // surface is scaled to test that the pixel moving is done in the target
3077 // space, where the background filter is applied, but the surface appears at
3078 // 50, 50 and the replica at 200, 50.
3079 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3080 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3081 typename
Types::LayerType
* filtered_surface
=
3082 this->CreateDrawingLayer(parent
,
3084 gfx::PointF(50.f
, 50.f
),
3085 gfx::Size(100, 100),
3087 this->CreateReplicaLayer(filtered_surface
,
3088 this->identity_matrix
,
3089 gfx::PointF(300.f
, 0.f
),
3091 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3092 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 50), true);
3093 typename
Types::LayerType
* occluding_layer2
=
3094 this->CreateDrawingLayer(parent
,
3095 this->identity_matrix
,
3096 gfx::PointF(0.f
, 100.f
),
3099 typename
Types::LayerType
* occluding_layer3
=
3100 this->CreateDrawingLayer(parent
,
3101 this->identity_matrix
,
3102 gfx::PointF(0.f
, 50.f
),
3105 typename
Types::LayerType
* occluding_layer4
=
3106 this->CreateDrawingLayer(parent
,
3107 this->identity_matrix
,
3108 gfx::PointF(100.f
, 50.f
),
3111 typename
Types::LayerType
* occluding_layer5
=
3112 this->CreateDrawingLayer(parent
,
3113 this->identity_matrix
,
3114 gfx::PointF(250.f
, 50.f
),
3118 // Filters make the layer own a surface.
3119 FilterOperations filters
;
3120 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
3121 filtered_surface
->SetBackgroundFilters(filters
);
3123 // Save the distance of influence for the blur effect.
3124 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3126 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3128 this->CalcDrawEtc(parent
);
3130 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3131 typename
Types::RenderSurfaceType
> occlusion(
3132 gfx::Rect(0, 0, 1000, 1000));
3134 // These layers occlude pixels directly beside the filtered_surface. Because
3135 // filtered surface blends pixels in a radius, it will need to see some of
3136 // the pixels (up to radius far) underneath the occluding layers.
3137 this->VisitLayer(occluding_layer5
, &occlusion
);
3138 this->VisitLayer(occluding_layer4
, &occlusion
);
3139 this->VisitLayer(occluding_layer3
, &occlusion
);
3140 this->VisitLayer(occluding_layer2
, &occlusion
);
3141 this->VisitLayer(occluding_layer1
, &occlusion
);
3143 Region expected_occlusion
;
3144 expected_occlusion
.Union(gfx::Rect(0, 0, 300, 50));
3145 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3146 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3147 expected_occlusion
.Union(gfx::Rect(250, 50, 50, 50));
3148 expected_occlusion
.Union(gfx::Rect(0, 100, 300, 50));
3150 EXPECT_EQ(expected_occlusion
.ToString(),
3151 occlusion
.occlusion_from_inside_target().ToString());
3152 EXPECT_EQ(gfx::Rect().ToString(),
3153 occlusion
.occlusion_from_outside_target().ToString());
3155 this->VisitLayer(filtered_surface
, &occlusion
);
3157 // The filtered layer/replica does not occlude.
3158 Region expected_occlusion_outside_surface
;
3159 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 300, 50));
3160 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3161 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3162 expected_occlusion_outside_surface
.Union(gfx::Rect(200, 0, 50, 50));
3163 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 300, 50));
3165 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3166 occlusion
.occlusion_from_outside_target().ToString());
3167 EXPECT_EQ(gfx::Rect().ToString(),
3168 occlusion
.occlusion_from_inside_target().ToString());
3170 // The surface has a background blur, so it needs pixels that are currently
3171 // considered occluded in order to be drawn. So the pixels it needs should
3172 // be removed some the occluded area so that when we get to the parent they
3174 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3176 this->EnterLayer(parent
, &occlusion
, false);
3178 Region expected_blurred_occlusion
;
3179 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 300, 50 - outset_top
));
3180 expected_blurred_occlusion
.Union(gfx::Rect(
3181 0, 50 - outset_top
, 50 - outset_left
, 50 + outset_top
+ outset_bottom
));
3182 expected_blurred_occlusion
.Union(
3183 gfx::Rect(100 + outset_right
,
3185 100 - outset_right
- outset_left
,
3186 50 + outset_top
+ outset_bottom
));
3187 expected_blurred_occlusion
.Union(
3188 gfx::Rect(250 + outset_right
,
3191 50 + outset_top
+ outset_bottom
));
3192 expected_blurred_occlusion
.Union(
3193 gfx::Rect(0, 100 + outset_bottom
, 300, 50 - outset_bottom
));
3195 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3196 occlusion
.occlusion_from_inside_target().ToString());
3197 EXPECT_EQ(gfx::Rect().ToString(),
3198 occlusion
.occlusion_from_outside_target().ToString());
3200 gfx::Rect outset_rect
;
3201 gfx::Rect test_rect
;
3203 // Nothing in the blur outsets for the filtered_surface is occluded.
3204 outset_rect
= gfx::Rect(50 - outset_left
,
3206 50 + outset_left
+ outset_right
,
3207 50 + outset_top
+ outset_bottom
);
3208 test_rect
= outset_rect
;
3210 outset_rect
.ToString(),
3211 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3213 // Stuff outside the blur outsets is still occluded though.
3214 test_rect
= outset_rect
;
3215 test_rect
.Inset(0, 0, -1, 0);
3217 outset_rect
.ToString(),
3218 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3219 test_rect
= outset_rect
;
3220 test_rect
.Inset(0, 0, 0, -1);
3222 outset_rect
.ToString(),
3223 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3224 test_rect
= outset_rect
;
3225 test_rect
.Inset(-1, 0, 0, 0);
3227 outset_rect
.ToString(),
3228 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3229 test_rect
= outset_rect
;
3230 test_rect
.Inset(0, -1, 0, 0);
3232 outset_rect
.ToString(),
3233 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3235 // Nothing in the blur outsets for the filtered_surface's replica is
3237 outset_rect
= gfx::Rect(200 - outset_left
,
3239 50 + outset_left
+ outset_right
,
3240 50 + outset_top
+ outset_bottom
);
3241 test_rect
= outset_rect
;
3243 outset_rect
.ToString(),
3244 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3246 // Stuff outside the blur outsets is still occluded though.
3247 test_rect
= outset_rect
;
3248 test_rect
.Inset(0, 0, -1, 0);
3250 outset_rect
.ToString(),
3251 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3252 test_rect
= outset_rect
;
3253 test_rect
.Inset(0, 0, 0, -1);
3255 outset_rect
.ToString(),
3256 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3257 test_rect
= outset_rect
;
3258 test_rect
.Inset(-1, 0, 0, 0);
3260 outset_rect
.ToString(),
3261 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3262 test_rect
= outset_rect
;
3263 test_rect
.Inset(0, -1, 0, 0);
3265 outset_rect
.ToString(),
3266 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3270 ALL_OCCLUSIONTRACKER_TEST(
3271 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
3273 template <class Types
>
3274 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3275 : public OcclusionTrackerTest
<Types
> {
3277 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3279 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3281 gfx::Transform scale_by_half
;
3282 scale_by_half
.Scale(0.5, 0.5);
3284 // Makes two surfaces that completely cover |parent|. The occlusion both
3285 // above and below the filters will be reduced by each of them.
3286 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3287 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
3288 typename
Types::LayerType
* parent
= this->CreateSurface(
3289 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
3290 parent
->SetMasksToBounds(true);
3291 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
3292 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3293 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
3294 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3295 typename
Types::LayerType
* occluding_layer_above
=
3296 this->CreateDrawingLayer(parent
,
3297 this->identity_matrix
,
3298 gfx::PointF(100.f
, 100.f
),
3302 // Filters make the layers own surfaces.
3303 FilterOperations filters
;
3304 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
3305 filtered_surface1
->SetBackgroundFilters(filters
);
3306 filtered_surface2
->SetBackgroundFilters(filters
);
3308 // Save the distance of influence for the blur effect.
3309 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3311 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3313 this->CalcDrawEtc(root
);
3315 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3316 typename
Types::RenderSurfaceType
> occlusion(
3317 gfx::Rect(0, 0, 1000, 1000));
3319 this->VisitLayer(occluding_layer_above
, &occlusion
);
3320 EXPECT_EQ(gfx::Rect().ToString(),
3321 occlusion
.occlusion_from_outside_target().ToString());
3322 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3323 occlusion
.occlusion_from_inside_target().ToString());
3325 this->VisitLayer(filtered_surface2
, &occlusion
);
3326 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
3327 this->VisitLayer(filtered_surface1
, &occlusion
);
3328 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
3330 // Test expectations in the target.
3331 gfx::Rect expected_occlusion
=
3332 gfx::Rect(100 / 2 + outset_right
* 2,
3333 100 / 2 + outset_bottom
* 2,
3334 50 / 2 - (outset_left
+ outset_right
) * 2,
3335 50 / 2 - (outset_top
+ outset_bottom
) * 2);
3336 EXPECT_EQ(expected_occlusion
.ToString(),
3337 occlusion
.occlusion_from_inside_target().ToString());
3339 // Test expectations in the screen are the same as in the target, as the
3340 // render surface is 1:1 with the screen.
3341 EXPECT_EQ(expected_occlusion
.ToString(),
3342 occlusion
.occlusion_from_outside_target().ToString());
3346 ALL_OCCLUSIONTRACKER_TEST(
3347 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
3349 template <class Types
>
3350 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3351 : public OcclusionTrackerTest
<Types
> {
3353 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3355 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3357 gfx::Transform scale_by_half
;
3358 scale_by_half
.Scale(0.5, 0.5);
3360 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3361 // centered below each. The surface is scaled to test that the pixel moving
3362 // is done in the target space, where the background filter is applied, but
3363 // the surface appears at 50, 50 and the replica at 200, 50.
3364 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3365 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3366 typename
Types::LayerType
* behind_surface_layer
=
3367 this->CreateDrawingLayer(parent
,
3368 this->identity_matrix
,
3369 gfx::PointF(60.f
, 60.f
),
3372 typename
Types::LayerType
* behind_replica_layer
=
3373 this->CreateDrawingLayer(parent
,
3374 this->identity_matrix
,
3375 gfx::PointF(210.f
, 60.f
),
3378 typename
Types::LayerType
* filtered_surface
=
3379 this->CreateDrawingLayer(parent
,
3381 gfx::PointF(50.f
, 50.f
),
3382 gfx::Size(100, 100),
3384 this->CreateReplicaLayer(filtered_surface
,
3385 this->identity_matrix
,
3386 gfx::PointF(300.f
, 0.f
),
3389 // Filters make the layer own a surface.
3390 FilterOperations filters
;
3391 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3392 filtered_surface
->SetBackgroundFilters(filters
);
3394 this->CalcDrawEtc(parent
);
3396 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3397 typename
Types::RenderSurfaceType
> occlusion(
3398 gfx::Rect(0, 0, 1000, 1000));
3400 // The surface has a background blur, so it blurs non-opaque pixels below
3402 this->VisitLayer(filtered_surface
, &occlusion
);
3403 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3405 this->VisitLayer(behind_replica_layer
, &occlusion
);
3406 this->VisitLayer(behind_surface_layer
, &occlusion
);
3408 // The layers behind the surface are not blurred, and their occlusion does
3409 // not change, until we leave the surface. So it should not be modified by
3411 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
3412 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
3414 Region expected_opaque_bounds
=
3415 UnionRegions(occlusion_behind_surface
, occlusion_behind_replica
);
3416 EXPECT_EQ(expected_opaque_bounds
.ToString(),
3417 occlusion
.occlusion_from_inside_target().ToString());
3419 EXPECT_EQ(gfx::Rect().ToString(),
3420 occlusion
.occlusion_from_outside_target().ToString());
3424 ALL_OCCLUSIONTRACKER_TEST(
3425 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
3427 template <class Types
>
3428 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3429 : public OcclusionTrackerTest
<Types
> {
3431 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3433 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3435 gfx::Transform scale_by_half
;
3436 scale_by_half
.Scale(0.5, 0.5);
3438 // Make a surface and its replica, each 50x50, that are completely occluded
3439 // by opaque layers which are above them in the z-order. The surface is
3440 // scaled to test that the pixel moving is done in the target space, where
3441 // the background filter is applied, but the surface appears at 50, 50 and
3442 // the replica at 200, 50.
3443 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3444 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3445 typename
Types::LayerType
* filtered_surface
=
3446 this->CreateDrawingLayer(parent
,
3448 gfx::PointF(50.f
, 50.f
),
3449 gfx::Size(100, 100),
3451 this->CreateReplicaLayer(filtered_surface
,
3452 this->identity_matrix
,
3453 gfx::PointF(300.f
, 0.f
),
3455 typename
Types::LayerType
* above_surface_layer
=
3456 this->CreateDrawingLayer(parent
,
3457 this->identity_matrix
,
3458 gfx::PointF(50.f
, 50.f
),
3461 typename
Types::LayerType
* above_replica_layer
=
3462 this->CreateDrawingLayer(parent
,
3463 this->identity_matrix
,
3464 gfx::PointF(200.f
, 50.f
),
3468 // Filters make the layer own a surface.
3469 FilterOperations filters
;
3470 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3471 filtered_surface
->SetBackgroundFilters(filters
);
3473 this->CalcDrawEtc(parent
);
3475 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3476 typename
Types::RenderSurfaceType
> occlusion(
3477 gfx::Rect(0, 0, 1000, 1000));
3479 this->VisitLayer(above_replica_layer
, &occlusion
);
3480 this->VisitLayer(above_surface_layer
, &occlusion
);
3482 this->VisitLayer(filtered_surface
, &occlusion
);
3484 // The layers above the filtered surface occlude from outside.
3485 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
3486 gfx::Rect occlusion_above_replica
= gfx::Rect(150, 0, 50, 50);
3487 Region expected_opaque_region
=
3488 UnionRegions(occlusion_above_surface
, occlusion_above_replica
);
3490 EXPECT_EQ(gfx::Rect().ToString(),
3491 occlusion
.occlusion_from_inside_target().ToString());
3492 EXPECT_EQ(expected_opaque_region
.ToString(),
3493 occlusion
.occlusion_from_outside_target().ToString());
3496 // The surface has a background blur, so it blurs non-opaque pixels below
3498 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3500 // The filter is completely occluded, so it should not blur anything and
3501 // reduce any occlusion.
3502 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
3503 gfx::Rect occlusion_above_replica
= gfx::Rect(200, 50, 50, 50);
3504 Region expected_opaque_region
=
3505 UnionRegions(occlusion_above_surface
, occlusion_above_replica
);
3507 EXPECT_EQ(expected_opaque_region
.ToString(),
3508 occlusion
.occlusion_from_inside_target().ToString());
3509 EXPECT_EQ(gfx::Rect().ToString(),
3510 occlusion
.occlusion_from_outside_target().ToString());
3515 ALL_OCCLUSIONTRACKER_TEST(
3516 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
3518 template <class Types
>
3519 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3520 : public OcclusionTrackerTest
<Types
> {
3523 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3525 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3527 gfx::Transform scale_by_half
;
3528 scale_by_half
.Scale(0.5, 0.5);
3530 // Make a surface and its replica, each 50x50, that are partially occluded
3531 // by opaque layers which are above them in the z-order. The surface is
3532 // scaled to test that the pixel moving is done in the target space, where
3533 // the background filter is applied, but the surface appears at 50, 50 and
3534 // the replica at 200, 50.
3535 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3536 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3537 typename
Types::LayerType
* filtered_surface
=
3538 this->CreateDrawingLayer(parent
,
3540 gfx::PointF(50.f
, 50.f
),
3541 gfx::Size(100, 100),
3543 this->CreateReplicaLayer(filtered_surface
,
3544 this->identity_matrix
,
3545 gfx::PointF(300.f
, 0.f
),
3547 typename
Types::LayerType
* above_surface_layer
=
3548 this->CreateDrawingLayer(parent
,
3549 this->identity_matrix
,
3550 gfx::PointF(70.f
, 50.f
),
3553 typename
Types::LayerType
* above_replica_layer
=
3554 this->CreateDrawingLayer(parent
,
3555 this->identity_matrix
,
3556 gfx::PointF(200.f
, 50.f
),
3559 typename
Types::LayerType
* beside_surface_layer
=
3560 this->CreateDrawingLayer(parent
,
3561 this->identity_matrix
,
3562 gfx::PointF(90.f
, 40.f
),
3565 typename
Types::LayerType
* beside_replica_layer
=
3566 this->CreateDrawingLayer(parent
,
3567 this->identity_matrix
,
3568 gfx::PointF(200.f
, 40.f
),
3572 // Filters make the layer own a surface.
3573 FilterOperations filters
;
3574 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3575 filtered_surface
->SetBackgroundFilters(filters
);
3577 // Save the distance of influence for the blur effect.
3578 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3580 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3582 this->CalcDrawEtc(parent
);
3584 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3585 typename
Types::RenderSurfaceType
> occlusion(
3586 gfx::Rect(0, 0, 1000, 1000));
3588 this->VisitLayer(beside_replica_layer
, &occlusion
);
3589 this->VisitLayer(beside_surface_layer
, &occlusion
);
3590 this->VisitLayer(above_replica_layer
, &occlusion
);
3591 this->VisitLayer(above_surface_layer
, &occlusion
);
3593 // The surface has a background blur, so it blurs non-opaque pixels below
3595 this->VisitLayer(filtered_surface
, &occlusion
);
3596 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3598 // The filter in the surface and replica are partially unoccluded. Only the
3599 // unoccluded parts should reduce occlusion. This means it will push back
3600 // the occlusion that touches the unoccluded part (occlusion_above___), but
3601 // it will not touch occlusion_beside____ since that is not beside the
3602 // unoccluded part of the surface, even though it is beside the occluded
3603 // part of the surface.
3604 gfx::Rect occlusion_above_surface
=
3605 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
3606 gfx::Rect occlusion_above_replica
=
3607 gfx::Rect(200, 50, 30 - outset_left
, 50);
3608 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
3609 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
3611 Region expected_occlusion
;
3612 expected_occlusion
.Union(occlusion_above_surface
);
3613 expected_occlusion
.Union(occlusion_above_replica
);
3614 expected_occlusion
.Union(occlusion_beside_surface
);
3615 expected_occlusion
.Union(occlusion_beside_replica
);
3617 ASSERT_EQ(expected_occlusion
.ToString(),
3618 occlusion
.occlusion_from_inside_target().ToString());
3619 EXPECT_EQ(gfx::Rect().ToString(),
3620 occlusion
.occlusion_from_outside_target().ToString());
3622 Region::Iterator
expected_rects(expected_occlusion
);
3623 Region::Iterator
target_surface_rects(
3624 occlusion
.occlusion_from_inside_target());
3625 for (; expected_rects
.has_rect();
3626 expected_rects
.next(), target_surface_rects
.next()) {
3627 ASSERT_TRUE(target_surface_rects
.has_rect());
3628 EXPECT_EQ(expected_rects
.rect(), target_surface_rects
.rect());
3633 ALL_OCCLUSIONTRACKER_TEST(
3634 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
3636 template <class Types
>
3637 class OcclusionTrackerTestMinimumTrackingSize
3638 : public OcclusionTrackerTest
<Types
> {
3640 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
3641 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3643 gfx::Size
tracking_size(100, 100);
3644 gfx::Size
below_tracking_size(99, 99);
3646 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3647 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3648 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
3649 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
3650 typename
Types::LayerType
* small
=
3651 this->CreateDrawingLayer(parent
,
3652 this->identity_matrix
,
3654 below_tracking_size
,
3656 this->CalcDrawEtc(parent
);
3658 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3659 typename
Types::RenderSurfaceType
> occlusion(
3660 gfx::Rect(0, 0, 1000, 1000));
3661 occlusion
.set_minimum_tracking_size(tracking_size
);
3663 // The small layer is not tracked because it is too small.
3664 this->VisitLayer(small
, &occlusion
);
3666 EXPECT_EQ(gfx::Rect().ToString(),
3667 occlusion
.occlusion_from_outside_target().ToString());
3668 EXPECT_EQ(gfx::Rect().ToString(),
3669 occlusion
.occlusion_from_inside_target().ToString());
3671 // The large layer is tracked as it is large enough.
3672 this->VisitLayer(large
, &occlusion
);
3674 EXPECT_EQ(gfx::Rect().ToString(),
3675 occlusion
.occlusion_from_outside_target().ToString());
3676 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
3677 occlusion
.occlusion_from_inside_target().ToString());
3681 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
3683 template <class Types
>
3684 class OcclusionTrackerTestPreventOcclusionOnLayer
3685 : public OcclusionTrackerTest
<Types
> {
3687 explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers
)
3688 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3690 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3691 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3692 typename
Types::LayerType
* unprevented
= this->CreateDrawingLayer(
3693 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
3694 typename
Types::LayerType
* prevented
= this->CreateDrawingLayer(
3695 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
3696 typename
Types::LayerType
* occluding
= this->CreateDrawingLayer(
3697 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
3698 this->CalcDrawEtc(parent
);
3700 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3701 typename
Types::RenderSurfaceType
> occlusion(
3702 gfx::Rect(0, 0, 1000, 1000));
3704 this->VisitLayer(occluding
, &occlusion
);
3705 this->EnterLayer(prevented
, &occlusion
, true);
3707 // This layer is not occluded because it is prevented.
3708 EXPECT_FALSE(occlusion
.OccludedLayer(prevented
,
3709 gfx::Rect(50, 50)));
3711 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3712 occlusion
.UnoccludedLayerContentRect(
3714 gfx::Rect(50, 50)).ToString());
3716 this->LeaveLayer(prevented
, &occlusion
);
3717 this->EnterLayer(unprevented
, &occlusion
, false);
3719 // This layer is fully occluded.
3720 EXPECT_TRUE(occlusion
.OccludedLayer(unprevented
,
3721 gfx::Rect(50, 50)));
3723 EXPECT_EQ(gfx::Rect().ToString(),
3724 occlusion
.UnoccludedLayerContentRect(
3726 gfx::Rect(50, 50)).ToString());
3728 this->LeaveLayer(unprevented
, &occlusion
);
3732 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer
)
3734 template <class Types
>
3735 class OcclusionTrackerTestPreventOcclusionOnContributingSurface
3736 : public OcclusionTrackerTest
<Types
> {
3738 explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface(
3740 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3742 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3743 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3744 typename
Types::LayerType
* unprevented
= this->CreateDrawingSurface(
3745 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
3746 typename
Types::LayerType
* prevented
= this->CreateDrawingSurface(
3747 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), false);
3748 typename
Types::LayerType
* occluding
= this->CreateDrawingLayer(
3749 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
3750 this->CalcDrawEtc(parent
);
3752 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3753 typename
Types::RenderSurfaceType
> occlusion(
3754 gfx::Rect(0, 0, 1000, 1000));
3756 this->VisitLayer(occluding
, &occlusion
);
3757 this->EnterLayer(prevented
, &occlusion
, true);
3759 // This layer is not occluded because it is prevented.
3760 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3761 occlusion
.UnoccludedLayerContentRect(
3763 gfx::Rect(50, 50)).ToString());
3765 this->LeaveLayer(prevented
, &occlusion
);
3766 this->EnterContributingSurface(prevented
, &occlusion
, true);
3768 // This contributing surface is not occluded because it is prevented.
3769 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3770 occlusion
.UnoccludedContributingSurfaceContentRect(
3772 false, // is_replica
3773 gfx::Rect(50, 50)).ToString());
3775 this->LeaveContributingSurface(prevented
, &occlusion
);
3776 this->EnterLayer(unprevented
, &occlusion
, false);
3778 // This layer is fully occluded from outside its surface.
3779 EXPECT_EQ(gfx::Rect().ToString(),
3780 occlusion
.UnoccludedLayerContentRect(
3782 gfx::Rect(50, 50)).ToString());
3784 this->LeaveLayer(unprevented
, &occlusion
);
3785 this->EnterContributingSurface(unprevented
, &occlusion
, false);
3787 // This contributing surface is fully occluded.
3788 EXPECT_EQ(gfx::Rect().ToString(),
3789 occlusion
.UnoccludedContributingSurfaceContentRect(
3791 false, // is_replica
3792 gfx::Rect(50, 50)).ToString());
3794 this->LeaveContributingSurface(unprevented
, &occlusion
);
3798 ALL_OCCLUSIONTRACKER_TEST(
3799 OcclusionTrackerTestPreventOcclusionOnContributingSurface
)
3801 template <class Types
>
3802 class OcclusionTrackerTestScaledLayerIsClipped
3803 : public OcclusionTrackerTest
<Types
> {
3805 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
3806 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3808 gfx::Transform scale_transform
;
3809 scale_transform
.Scale(512.0, 512.0);
3811 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3812 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3813 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3814 this->identity_matrix
,
3815 gfx::PointF(10.f
, 10.f
),
3817 clip
->SetMasksToBounds(true);
3818 typename
Types::LayerType
* scale
= this->CreateLayer(
3819 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3820 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3821 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3822 this->CalcDrawEtc(parent
);
3824 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3825 typename
Types::RenderSurfaceType
> occlusion(
3826 gfx::Rect(0, 0, 1000, 1000));
3828 this->VisitLayer(scaled
, &occlusion
);
3830 EXPECT_EQ(gfx::Rect().ToString(),
3831 occlusion
.occlusion_from_outside_target().ToString());
3832 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3833 occlusion
.occlusion_from_inside_target().ToString());
3837 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
3839 template <class Types
>
3840 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3841 : public OcclusionTrackerTest
<Types
> {
3843 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
3844 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3846 gfx::Transform scale_transform
;
3847 scale_transform
.Scale(512.0, 512.0);
3849 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3850 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3851 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3852 this->identity_matrix
,
3853 gfx::PointF(10.f
, 10.f
),
3855 clip
->SetMasksToBounds(true);
3856 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
3857 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
3858 typename
Types::LayerType
* scale
= this->CreateLayer(
3859 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3860 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3861 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3862 this->CalcDrawEtc(parent
);
3864 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3865 typename
Types::RenderSurfaceType
> occlusion(
3866 gfx::Rect(0, 0, 1000, 1000));
3868 this->VisitLayer(scaled
, &occlusion
);
3869 this->VisitLayer(surface
, &occlusion
);
3870 this->VisitContributingSurface(surface
, &occlusion
);
3872 EXPECT_EQ(gfx::Rect().ToString(),
3873 occlusion
.occlusion_from_outside_target().ToString());
3874 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3875 occlusion
.occlusion_from_inside_target().ToString());
3879 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
3881 template <class Types
>
3882 class OcclusionTrackerTestCopyRequestDoesOcclude
3883 : public OcclusionTrackerTest
<Types
> {
3885 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
3886 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3888 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3889 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3890 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3891 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3892 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
3893 this->identity_matrix
,
3895 gfx::Size(200, 400));
3896 this->AddCopyRequest(copy
);
3897 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3899 this->identity_matrix
,
3901 gfx::Size(200, 400),
3903 this->CalcDrawEtc(root
);
3905 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3906 typename
Types::RenderSurfaceType
> occlusion(
3907 gfx::Rect(0, 0, 1000, 1000));
3909 this->VisitLayer(copy_child
, &occlusion
);
3910 EXPECT_EQ(gfx::Rect().ToString(),
3911 occlusion
.occlusion_from_outside_target().ToString());
3912 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3913 occlusion
.occlusion_from_inside_target().ToString());
3915 // CopyRequests cause the layer to own a surface.
3916 this->VisitContributingSurface(copy
, &occlusion
);
3918 // The occlusion from the copy should be kept.
3919 EXPECT_EQ(gfx::Rect().ToString(),
3920 occlusion
.occlusion_from_outside_target().ToString());
3921 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3922 occlusion
.occlusion_from_inside_target().ToString());
3926 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
3928 template <class Types
>
3929 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3930 : public OcclusionTrackerTest
<Types
> {
3932 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3934 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3936 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3937 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3938 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3939 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3940 typename
Types::LayerType
* hide
= this->CreateLayer(
3941 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
3942 typename
Types::LayerType
* copy
= this->CreateLayer(
3943 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
3944 this->AddCopyRequest(copy
);
3945 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3946 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
3948 // The |copy| layer is hidden but since it is being copied, it will be
3950 hide
->SetHideLayerAndSubtree(true);
3952 this->CalcDrawEtc(root
);
3954 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3955 typename
Types::RenderSurfaceType
> occlusion(
3956 gfx::Rect(0, 0, 1000, 1000));
3958 this->VisitLayer(copy_child
, &occlusion
);
3959 EXPECT_EQ(gfx::Rect().ToString(),
3960 occlusion
.occlusion_from_outside_target().ToString());
3961 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3962 occlusion
.occlusion_from_inside_target().ToString());
3964 // CopyRequests cause the layer to own a surface.
3965 this->VisitContributingSurface(copy
, &occlusion
);
3967 // The occlusion from the copy should be dropped since it is hidden.
3968 EXPECT_EQ(gfx::Rect().ToString(),
3969 occlusion
.occlusion_from_outside_target().ToString());
3970 EXPECT_EQ(gfx::Rect().ToString(),
3971 occlusion
.occlusion_from_inside_target().ToString());
3975 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
3977 template <class Types
>
3978 class OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
3979 : public OcclusionTrackerTest
<Types
> {
3981 explicit OcclusionTrackerTestEmptyEventLayerDoesNotOcclude(
3983 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3985 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3986 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3987 typename
Types::ContentLayerType
* empty_layer
= this->CreateDrawingLayer(
3988 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), true);
3989 this->SetDrawsContent(empty_layer
, false);
3990 empty_layer
->SetTouchEventHandlerRegion(gfx::Rect(10, 10, 10, 10));
3992 this->CalcDrawEtc(root
);
3994 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3995 typename
Types::RenderSurfaceType
> occlusion(
3996 gfx::Rect(0, 0, 1000, 1000), false);
3998 this->VisitLayer(empty_layer
, &occlusion
);
4000 EXPECT_EQ(gfx::Rect().ToString(),
4001 occlusion
.occlusion_from_outside_target().ToString());
4002 EXPECT_EQ(gfx::Rect().ToString(),
4003 occlusion
.occlusion_from_inside_target().ToString());
4007 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
)