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(const 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(const 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(const gfx::Rect
& viewport_rect
,
88 bool record_metrics_for_frame
)
89 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(
91 record_metrics_for_frame
) {}
92 explicit TestOcclusionTrackerWithClip(const gfx::Rect
& viewport_rect
)
93 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(viewport_rect
,
96 bool OccludedLayer(const LayerType
* layer
,
97 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 ASSERT_EQ(layer
, *layer_iterator_
);
357 ASSERT_TRUE(layer_iterator_
.represents_itself());
358 occlusion
->EnterLayer(layer_iterator_
);
361 void LeaveLayer(typename
Types::LayerType
* layer
,
362 typename
Types::OcclusionTrackerType
* occlusion
) {
363 ASSERT_EQ(layer
, *layer_iterator_
);
364 ASSERT_TRUE(layer_iterator_
.represents_itself());
365 occlusion
->LeaveLayer(layer_iterator_
);
369 void VisitLayer(typename
Types::LayerType
* layer
,
370 typename
Types::OcclusionTrackerType
* occlusion
) {
371 EnterLayer(layer
, occlusion
);
372 LeaveLayer(layer
, occlusion
);
375 void EnterContributingSurface(
376 typename
Types::LayerType
* layer
,
377 typename
Types::OcclusionTrackerType
* occlusion
) {
378 ASSERT_EQ(layer
, *layer_iterator_
);
379 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
380 occlusion
->EnterLayer(layer_iterator_
);
381 occlusion
->LeaveLayer(layer_iterator_
);
383 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
384 occlusion
->EnterLayer(layer_iterator_
);
387 void LeaveContributingSurface(
388 typename
Types::LayerType
* layer
,
389 typename
Types::OcclusionTrackerType
* occlusion
) {
390 ASSERT_EQ(layer
, *layer_iterator_
);
391 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
392 occlusion
->LeaveLayer(layer_iterator_
);
396 void VisitContributingSurface(
397 typename
Types::LayerType
* layer
,
398 typename
Types::OcclusionTrackerType
* occlusion
) {
399 EnterContributingSurface(layer
, occlusion
);
400 LeaveContributingSurface(layer
, occlusion
);
403 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
405 const gfx::Transform identity_matrix
;
408 void SetRootLayerOnMainThread(Layer
* root
) {
409 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
412 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
414 void SetBaseProperties(typename
Types::LayerType
* layer
,
415 const gfx::Transform
& transform
,
416 const gfx::PointF
& position
,
418 layer
->SetTransform(transform
);
419 layer
->SetSublayerTransform(gfx::Transform());
420 layer
->SetAnchorPoint(gfx::PointF());
421 layer
->SetPosition(position
);
422 layer
->SetBounds(bounds
);
425 void SetProperties(Layer
* layer
,
426 const gfx::Transform
& transform
,
427 const gfx::PointF
& position
,
429 SetBaseProperties(layer
, transform
, position
, bounds
);
432 void SetProperties(LayerImpl
* layer
,
433 const gfx::Transform
& transform
,
434 const gfx::PointF
& position
,
436 SetBaseProperties(layer
, transform
, position
, bounds
);
438 layer
->SetContentBounds(layer
->bounds());
441 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
442 owning_layer
->SetReplicaLayer(layer
.get());
443 replica_layers_
.push_back(layer
);
446 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
447 owning_layer
->SetReplicaLayer(layer
.Pass());
450 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
451 owning_layer
->SetMaskLayer(layer
.get());
452 mask_layers_
.push_back(layer
);
455 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
456 owning_layer
->SetMaskLayer(layer
.Pass());
460 scoped_ptr
<FakeLayerTreeHost
> host_
;
461 // These hold ownership of the layers for the duration of the test.
462 typename
Types::LayerPtrType root_
;
463 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
464 LayerImplList render_surface_layer_list_impl_
;
465 typename
Types::TestLayerIterator layer_iterator_begin_
;
466 typename
Types::TestLayerIterator layer_iterator_
;
467 typename
Types::LayerType
* last_layer_visited_
;
468 LayerList replica_layers_
;
469 LayerList mask_layers_
;
474 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
480 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
481 return host_
->host_impl()->active_tree();
484 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
485 class ClassName##MainThreadOpaqueLayers \
486 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
487 public: /* NOLINT(whitespace/indent) */ \
488 ClassName##MainThreadOpaqueLayers() \
489 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
491 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
492 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
493 class ClassName##MainThreadOpaquePaints \
494 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
495 public: /* NOLINT(whitespace/indent) */ \
496 ClassName##MainThreadOpaquePaints() \
497 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
499 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
501 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
502 class ClassName##ImplThreadOpaqueLayers \
503 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
504 public: /* NOLINT(whitespace/indent) */ \
505 ClassName##ImplThreadOpaqueLayers() \
506 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
508 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
509 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
510 class ClassName##ImplThreadOpaquePaints \
511 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
512 public: /* NOLINT(whitespace/indent) */ \
513 ClassName##ImplThreadOpaquePaints() \
514 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
516 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
518 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
519 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
520 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
521 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
522 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
524 #define MAIN_THREAD_TEST(ClassName) \
525 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
527 #define IMPL_THREAD_TEST(ClassName) \
528 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
530 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
531 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
532 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
534 template <class Types
>
535 class OcclusionTrackerTestIdentityTransforms
536 : public OcclusionTrackerTest
<Types
> {
538 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
539 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
542 typename
Types::ContentLayerType
* root
= this->CreateRoot(
543 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
544 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
545 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
546 typename
Types::ContentLayerType
* layer
=
547 this->CreateDrawingLayer(parent
,
548 this->identity_matrix
,
549 gfx::PointF(30.f
, 30.f
),
552 parent
->SetMasksToBounds(true);
553 this->CalcDrawEtc(root
);
555 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
556 typename
Types::RenderSurfaceType
> occlusion(
557 gfx::Rect(0, 0, 1000, 1000), false);
559 this->VisitLayer(layer
, &occlusion
);
560 this->EnterLayer(parent
, &occlusion
);
562 EXPECT_EQ(gfx::Rect().ToString(),
563 occlusion
.occlusion_from_outside_target().ToString());
564 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
565 occlusion
.occlusion_from_inside_target().ToString());
567 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
568 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
569 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
570 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
571 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
573 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
574 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
575 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
576 occlusion
.UnoccludedLayerContentRect(
577 parent
, gfx::Rect(29, 30, 70, 70)));
578 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
579 occlusion
.UnoccludedLayerContentRect(
580 parent
, gfx::Rect(29, 29, 70, 70)));
581 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
582 occlusion
.UnoccludedLayerContentRect(
583 parent
, gfx::Rect(30, 29, 70, 70)));
584 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
585 occlusion
.UnoccludedLayerContentRect(
586 parent
, gfx::Rect(31, 29, 69, 70)));
587 EXPECT_RECT_EQ(gfx::Rect(),
588 occlusion
.UnoccludedLayerContentRect(
589 parent
, gfx::Rect(31, 30, 69, 70)));
590 EXPECT_RECT_EQ(gfx::Rect(),
591 occlusion
.UnoccludedLayerContentRect(
592 parent
, gfx::Rect(31, 31, 69, 69)));
593 EXPECT_RECT_EQ(gfx::Rect(),
594 occlusion
.UnoccludedLayerContentRect(
595 parent
, gfx::Rect(30, 31, 70, 69)));
596 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
597 occlusion
.UnoccludedLayerContentRect(
598 parent
, gfx::Rect(29, 31, 70, 69)));
602 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
604 template <class Types
>
605 class OcclusionTrackerTestQuadsMismatchLayer
606 : public OcclusionTrackerTest
<Types
> {
608 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers
)
609 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
611 gfx::Transform layer_transform
;
612 layer_transform
.Translate(10.0, 10.0);
614 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
615 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(100, 100));
616 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
617 parent
, layer_transform
, gfx::PointF(), gfx::Size(90, 90), true);
618 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
619 layer1
, layer_transform
, gfx::PointF(), gfx::Size(50, 50), true);
620 this->CalcDrawEtc(parent
);
622 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
623 typename
Types::RenderSurfaceType
> occlusion(
624 gfx::Rect(0, 0, 1000, 1000));
626 this->VisitLayer(layer2
, &occlusion
);
627 this->EnterLayer(layer1
, &occlusion
);
629 EXPECT_EQ(gfx::Rect().ToString(),
630 occlusion
.occlusion_from_outside_target().ToString());
631 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
632 occlusion
.occlusion_from_inside_target().ToString());
634 // This checks cases where the quads don't match their "containing"
635 // layers, e.g. in terms of transforms or clip rect. This is typical for
636 // DelegatedRendererLayer.
638 gfx::Transform quad_transform
;
639 quad_transform
.Translate(30.0, 30.0);
641 EXPECT_TRUE(occlusion
.UnoccludedContentRect(parent
,
642 gfx::Rect(0, 0, 10, 10),
645 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
646 occlusion
.UnoccludedContentRect(parent
,
647 gfx::Rect(0, 0, 10, 10),
650 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
651 occlusion
.UnoccludedContentRect(parent
,
652 gfx::Rect(40, 40, 10, 10),
655 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
656 occlusion
.UnoccludedContentRect(parent
,
657 gfx::Rect(35, 30, 10, 10),
663 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
665 template <class Types
>
666 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
668 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
669 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
671 gfx::Transform layer_transform
;
672 layer_transform
.Translate(250.0, 250.0);
673 layer_transform
.Rotate(90.0);
674 layer_transform
.Translate(-250.0, -250.0);
676 typename
Types::ContentLayerType
* root
= this->CreateRoot(
677 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
678 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
679 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
680 typename
Types::ContentLayerType
* layer
=
681 this->CreateDrawingLayer(parent
,
683 gfx::PointF(30.f
, 30.f
),
686 parent
->SetMasksToBounds(true);
687 this->CalcDrawEtc(root
);
689 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
690 typename
Types::RenderSurfaceType
> occlusion(
691 gfx::Rect(0, 0, 1000, 1000));
693 this->VisitLayer(layer
, &occlusion
);
694 this->EnterLayer(parent
, &occlusion
);
696 EXPECT_EQ(gfx::Rect().ToString(),
697 occlusion
.occlusion_from_outside_target().ToString());
698 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
699 occlusion
.occlusion_from_inside_target().ToString());
701 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
702 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
703 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
704 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
705 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
707 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
708 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
709 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
710 occlusion
.UnoccludedLayerContentRect(
711 parent
, gfx::Rect(29, 30, 69, 70)));
712 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
713 occlusion
.UnoccludedLayerContentRect(
714 parent
, gfx::Rect(29, 29, 70, 70)));
715 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
716 occlusion
.UnoccludedLayerContentRect(
717 parent
, gfx::Rect(30, 29, 70, 70)));
718 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
719 occlusion
.UnoccludedLayerContentRect(
720 parent
, gfx::Rect(31, 29, 69, 70)));
721 EXPECT_RECT_EQ(gfx::Rect(),
722 occlusion
.UnoccludedLayerContentRect(
723 parent
, gfx::Rect(31, 30, 69, 70)));
724 EXPECT_RECT_EQ(gfx::Rect(),
725 occlusion
.UnoccludedLayerContentRect(
726 parent
, gfx::Rect(31, 31, 69, 69)));
727 EXPECT_RECT_EQ(gfx::Rect(),
728 occlusion
.UnoccludedLayerContentRect(
729 parent
, gfx::Rect(30, 31, 70, 69)));
730 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
731 occlusion
.UnoccludedLayerContentRect(
732 parent
, gfx::Rect(29, 31, 70, 69)));
736 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
738 template <class Types
>
739 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
741 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
742 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
744 gfx::Transform layer_transform
;
745 layer_transform
.Translate(20.0, 20.0);
747 typename
Types::ContentLayerType
* root
= this->CreateRoot(
748 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
749 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
750 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
751 typename
Types::ContentLayerType
* layer
=
752 this->CreateDrawingLayer(parent
,
754 gfx::PointF(30.f
, 30.f
),
757 parent
->SetMasksToBounds(true);
758 this->CalcDrawEtc(root
);
760 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
761 typename
Types::RenderSurfaceType
> occlusion(
762 gfx::Rect(0, 0, 1000, 1000));
764 this->VisitLayer(layer
, &occlusion
);
765 this->EnterLayer(parent
, &occlusion
);
767 EXPECT_EQ(gfx::Rect().ToString(),
768 occlusion
.occlusion_from_outside_target().ToString());
769 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
770 occlusion
.occlusion_from_inside_target().ToString());
772 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
773 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
774 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
775 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(51, 50, 49, 50)));
776 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 51, 50, 49)));
778 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
779 parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
780 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
781 occlusion
.UnoccludedLayerContentRect(
782 parent
, gfx::Rect(49, 50, 50, 50)));
783 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
784 occlusion
.UnoccludedLayerContentRect(
785 parent
, gfx::Rect(49, 49, 50, 50)));
786 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
787 occlusion
.UnoccludedLayerContentRect(
788 parent
, gfx::Rect(50, 49, 50, 50)));
789 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
790 occlusion
.UnoccludedLayerContentRect(
791 parent
, gfx::Rect(51, 49, 49, 50)));
792 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
793 parent
, gfx::Rect(51, 50, 49, 50)).IsEmpty());
794 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
795 parent
, gfx::Rect(51, 51, 49, 49)).IsEmpty());
796 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
797 parent
, gfx::Rect(50, 51, 50, 49)).IsEmpty());
798 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
799 occlusion
.UnoccludedLayerContentRect(
800 parent
, gfx::Rect(49, 51, 50, 49)));
804 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
806 template <class Types
>
807 class OcclusionTrackerTestChildInRotatedChild
808 : public OcclusionTrackerTest
<Types
> {
810 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
811 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
813 gfx::Transform child_transform
;
814 child_transform
.Translate(250.0, 250.0);
815 child_transform
.Rotate(90.0);
816 child_transform
.Translate(-250.0, -250.0);
818 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
819 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
820 parent
->SetMasksToBounds(true);
821 typename
Types::LayerType
* child
= this->CreateSurface(
822 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
823 child
->SetMasksToBounds(true);
824 typename
Types::ContentLayerType
* layer
=
825 this->CreateDrawingLayer(child
,
826 this->identity_matrix
,
827 gfx::PointF(10.f
, 10.f
),
830 this->CalcDrawEtc(parent
);
832 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
833 typename
Types::RenderSurfaceType
> occlusion(
834 gfx::Rect(0, 0, 1000, 1000));
836 this->VisitLayer(layer
, &occlusion
);
837 this->EnterContributingSurface(child
, &occlusion
);
839 EXPECT_EQ(gfx::Rect().ToString(),
840 occlusion
.occlusion_from_outside_target().ToString());
841 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
842 occlusion
.occlusion_from_inside_target().ToString());
844 this->LeaveContributingSurface(child
, &occlusion
);
845 this->EnterLayer(parent
, &occlusion
);
847 EXPECT_EQ(gfx::Rect().ToString(),
848 occlusion
.occlusion_from_outside_target().ToString());
849 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
850 occlusion
.occlusion_from_inside_target().ToString());
852 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
853 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
854 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
855 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 40, 69, 60)));
856 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 41, 70, 59)));
858 /* Justification for the above occlusion from |layer|:
860 +---------------------+
863 | 30 + ---------------------------------+
865 | |10+---------------------------------+
869 +----|--|-------------+ | |
877 +--|-------------------------------+ |
879 +---------------------------------+
882 +---------------------+
883 | |30 Visible region of |layer|: /////
885 | +---------------------------------+
887 | +---------------------------------+ |
888 | | |///////////////| 420 | |
889 | | |///////////////|60 | |
890 | | |///////////////| | |
891 +--|--|---------------+ | |
899 | +------------------------------|--+
901 +---------------------------------+
908 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
910 template <class Types
>
911 class OcclusionTrackerTestScaledRenderSurface
912 : public OcclusionTrackerTest
<Types
> {
914 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
915 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
918 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
919 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
921 gfx::Transform layer1_matrix
;
922 layer1_matrix
.Scale(2.0, 2.0);
923 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
924 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
925 layer1
->SetForceRenderSurface(true);
927 gfx::Transform layer2_matrix
;
928 layer2_matrix
.Translate(25.0, 25.0);
929 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
930 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
931 typename
Types::ContentLayerType
* occluder
=
932 this->CreateDrawingLayer(parent
,
933 this->identity_matrix
,
934 gfx::PointF(100.f
, 100.f
),
937 this->CalcDrawEtc(parent
);
939 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
940 typename
Types::RenderSurfaceType
> occlusion(
941 gfx::Rect(0, 0, 1000, 1000));
943 this->VisitLayer(occluder
, &occlusion
);
944 this->EnterLayer(layer2
, &occlusion
);
946 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
947 occlusion
.occlusion_from_outside_target().ToString());
948 EXPECT_EQ(gfx::Rect().ToString(),
949 occlusion
.occlusion_from_inside_target().ToString());
952 gfx::Rect(0, 0, 25, 25),
953 occlusion
.UnoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
954 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
955 occlusion
.UnoccludedLayerContentRect(
956 layer2
, gfx::Rect(10, 25, 25, 25)));
957 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
958 occlusion
.UnoccludedLayerContentRect(
959 layer2
, gfx::Rect(25, 10, 25, 25)));
960 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
961 layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
965 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
967 template <class Types
>
968 class OcclusionTrackerTestVisitTargetTwoTimes
969 : public OcclusionTrackerTest
<Types
> {
971 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
972 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
974 gfx::Transform child_transform
;
975 child_transform
.Translate(250.0, 250.0);
976 child_transform
.Rotate(90.0);
977 child_transform
.Translate(-250.0, -250.0);
979 typename
Types::ContentLayerType
* root
= this->CreateRoot(
980 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
981 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
982 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
983 parent
->SetMasksToBounds(true);
984 typename
Types::LayerType
* child
= this->CreateSurface(
985 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
986 child
->SetMasksToBounds(true);
987 typename
Types::ContentLayerType
* layer
=
988 this->CreateDrawingLayer(child
,
989 this->identity_matrix
,
990 gfx::PointF(10.f
, 10.f
),
993 // |child2| makes |parent|'s surface get considered by OcclusionTracker
994 // first, instead of |child|'s. This exercises different code in
995 // LeaveToRenderTarget, as the target surface has already been seen.
996 typename
Types::ContentLayerType
* child2
=
997 this->CreateDrawingLayer(parent
,
998 this->identity_matrix
,
999 gfx::PointF(30.f
, 30.f
),
1002 this->CalcDrawEtc(root
);
1004 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1005 typename
Types::RenderSurfaceType
> occlusion(
1006 gfx::Rect(0, 0, 1000, 1000));
1008 this->VisitLayer(child2
, &occlusion
);
1010 EXPECT_EQ(gfx::Rect().ToString(),
1011 occlusion
.occlusion_from_outside_target().ToString());
1012 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1013 occlusion
.occlusion_from_inside_target().ToString());
1015 this->VisitLayer(layer
, &occlusion
);
1017 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1018 occlusion
.occlusion_from_outside_target().ToString());
1019 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1020 occlusion
.occlusion_from_inside_target().ToString());
1022 this->EnterContributingSurface(child
, &occlusion
);
1024 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1025 occlusion
.occlusion_from_outside_target().ToString());
1026 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1027 occlusion
.occlusion_from_inside_target().ToString());
1029 // Occlusion in |child2| should get merged with the |child| surface we are
1031 this->LeaveContributingSurface(child
, &occlusion
);
1032 this->EnterLayer(parent
, &occlusion
);
1034 EXPECT_EQ(gfx::Rect().ToString(),
1035 occlusion
.occlusion_from_outside_target().ToString());
1036 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1038 occlusion
.occlusion_from_inside_target().ToString());
1040 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
1041 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1042 occlusion
.UnoccludedLayerContentRect(
1043 parent
, gfx::Rect(30, 30, 70, 70)));
1045 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
1046 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
1047 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
1048 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
1049 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
1051 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1052 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1053 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1055 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1056 parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1057 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1058 occlusion
.UnoccludedLayerContentRect(
1059 parent
, gfx::Rect(29, 30, 60, 10)));
1060 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1061 occlusion
.UnoccludedLayerContentRect(
1062 parent
, gfx::Rect(30, 29, 60, 10)));
1063 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1064 occlusion
.UnoccludedLayerContentRect(
1065 parent
, gfx::Rect(31, 30, 60, 10)));
1066 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1067 parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1069 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1070 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1071 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1072 occlusion
.UnoccludedLayerContentRect(
1073 parent
, gfx::Rect(29, 40, 70, 60)));
1074 // This rect is mostly occluded by |child2|.
1075 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1076 occlusion
.UnoccludedLayerContentRect(
1077 parent
, gfx::Rect(30, 39, 70, 60)));
1078 // This rect extends past top/right ends of |child2|.
1079 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1080 occlusion
.UnoccludedLayerContentRect(
1081 parent
, gfx::Rect(30, 29, 70, 70)));
1082 // This rect extends past left/right ends of |child2|.
1083 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1084 occlusion
.UnoccludedLayerContentRect(
1085 parent
, gfx::Rect(20, 39, 80, 60)));
1086 EXPECT_RECT_EQ(gfx::Rect(),
1087 occlusion
.UnoccludedLayerContentRect(
1088 parent
, gfx::Rect(31, 40, 69, 60)));
1089 EXPECT_RECT_EQ(gfx::Rect(),
1090 occlusion
.UnoccludedLayerContentRect(
1091 parent
, gfx::Rect(30, 41, 70, 59)));
1093 /* Justification for the above occlusion from |layer|:
1095 +---------------------+
1098 | 30 + ------------+--------------------+
1099 100 | | 10 | | | ==>
1100 | |10+----------|----------------------+
1101 | + ------------+ | | |
1104 +----|--|-------------+ | |
1112 +--|-------------------------------+ |
1114 +---------------------------------+
1118 +---------------------+
1119 | |30 Visible region of |layer|: /////
1120 | 30 60 | |child2|: \\\\\
1121 | 30 +------------+--------------------+
1122 | |\\\\\\\\\\\\| |10 |
1123 | +--|\\\\\\\\\\\\|-----------------+ |
1124 | | +------------+//| 420 | |
1125 | | |///////////////|60 | |
1126 | | |///////////////| | |
1127 +--|--|---------------+ | |
1135 | +------------------------------|--+
1137 +---------------------------------+
1143 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
1145 template <class Types
>
1146 class OcclusionTrackerTestSurfaceRotatedOffAxis
1147 : public OcclusionTrackerTest
<Types
> {
1149 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
1150 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1152 gfx::Transform child_transform
;
1153 child_transform
.Translate(250.0, 250.0);
1154 child_transform
.Rotate(95.0);
1155 child_transform
.Translate(-250.0, -250.0);
1157 gfx::Transform layer_transform
;
1158 layer_transform
.Translate(10.0, 10.0);
1160 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1161 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1162 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1163 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1164 typename
Types::LayerType
* child
= this->CreateLayer(
1165 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1166 child
->SetMasksToBounds(true);
1167 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1168 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
1169 this->CalcDrawEtc(root
);
1171 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1172 typename
Types::RenderSurfaceType
> occlusion(
1173 gfx::Rect(0, 0, 1000, 1000));
1175 gfx::Rect clipped_layer_in_child
= MathUtil::MapClippedRect(
1176 layer_transform
, layer
->visible_content_rect());
1178 this->VisitLayer(layer
, &occlusion
);
1179 this->EnterContributingSurface(child
, &occlusion
);
1181 EXPECT_EQ(gfx::Rect().ToString(),
1182 occlusion
.occlusion_from_outside_target().ToString());
1183 EXPECT_EQ(clipped_layer_in_child
.ToString(),
1184 occlusion
.occlusion_from_inside_target().ToString());
1186 this->LeaveContributingSurface(child
, &occlusion
);
1187 this->EnterLayer(parent
, &occlusion
);
1189 EXPECT_EQ(gfx::Rect().ToString(),
1190 occlusion
.occlusion_from_outside_target().ToString());
1191 EXPECT_EQ(gfx::Rect().ToString(),
1192 occlusion
.occlusion_from_inside_target().ToString());
1194 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
1196 gfx::Rect(75, 55, 1, 1),
1197 occlusion
.UnoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
1201 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
1203 template <class Types
>
1204 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1205 : public OcclusionTrackerTest
<Types
> {
1207 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
1208 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1210 gfx::Transform child_transform
;
1211 child_transform
.Translate(250.0, 250.0);
1212 child_transform
.Rotate(90.0);
1213 child_transform
.Translate(-250.0, -250.0);
1215 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1216 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1217 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1218 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1219 parent
->SetMasksToBounds(true);
1220 typename
Types::ContentLayerType
* child
=
1221 this->CreateDrawingSurface(parent
,
1223 gfx::PointF(30.f
, 30.f
),
1224 gfx::Size(500, 500),
1226 child
->SetMasksToBounds(true);
1227 typename
Types::ContentLayerType
* layer1
=
1228 this->CreateDrawingLayer(child
,
1229 this->identity_matrix
,
1230 gfx::PointF(10.f
, 10.f
),
1231 gfx::Size(500, 500),
1233 typename
Types::ContentLayerType
* layer2
=
1234 this->CreateDrawingLayer(child
,
1235 this->identity_matrix
,
1236 gfx::PointF(10.f
, 450.f
),
1239 this->CalcDrawEtc(root
);
1241 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1242 typename
Types::RenderSurfaceType
> occlusion(
1243 gfx::Rect(0, 0, 1000, 1000));
1245 this->VisitLayer(layer2
, &occlusion
);
1246 this->VisitLayer(layer1
, &occlusion
);
1247 this->VisitLayer(child
, &occlusion
);
1248 this->EnterContributingSurface(child
, &occlusion
);
1250 EXPECT_EQ(gfx::Rect().ToString(),
1251 occlusion
.occlusion_from_outside_target().ToString());
1252 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1253 occlusion
.occlusion_from_inside_target().ToString());
1255 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
1256 EXPECT_FALSE(occlusion
.OccludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
1257 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(11, 430, 59, 70)));
1258 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 431, 60, 69)));
1260 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1261 child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1263 gfx::Rect(9, 430, 1, 70),
1264 occlusion
.UnoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
1265 EXPECT_RECT_EQ(gfx::Rect(),
1266 occlusion
.UnoccludedLayerContentRect(
1267 child
, gfx::Rect(11, 430, 59, 70)));
1268 EXPECT_RECT_EQ(gfx::Rect(),
1269 occlusion
.UnoccludedLayerContentRect(
1270 child
, gfx::Rect(10, 431, 60, 69)));
1272 this->LeaveContributingSurface(child
, &occlusion
);
1273 this->EnterLayer(parent
, &occlusion
);
1275 EXPECT_EQ(gfx::Rect().ToString(),
1276 occlusion
.occlusion_from_outside_target().ToString());
1277 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1278 occlusion
.occlusion_from_inside_target().ToString());
1280 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1281 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1282 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1284 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1285 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1286 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1287 occlusion
.UnoccludedLayerContentRect(
1288 parent
, gfx::Rect(29, 40, 70, 60)));
1289 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1290 occlusion
.UnoccludedLayerContentRect(
1291 parent
, gfx::Rect(30, 39, 70, 60)));
1292 EXPECT_RECT_EQ(gfx::Rect(),
1293 occlusion
.UnoccludedLayerContentRect(
1294 parent
, gfx::Rect(31, 40, 69, 60)));
1295 EXPECT_RECT_EQ(gfx::Rect(),
1296 occlusion
.UnoccludedLayerContentRect(
1297 parent
, gfx::Rect(30, 41, 70, 59)));
1299 /* Justification for the above occlusion from |layer1| and |layer2|:
1301 +---------------------+
1302 | |30 Visible region of |layer1|: /////
1303 | | Visible region of |layer2|: \\\\\
1304 | +---------------------------------+
1306 | +---------------+-----------------+ |
1307 | | |\\\\\\\\\\\\|//| 420 | |
1308 | | |\\\\\\\\\\\\|//|60 | |
1309 | | |\\\\\\\\\\\\|//| | |
1310 +--|--|------------|--+ | |
1318 | +------------|-----------------|--+
1320 +---------------+-----------------+
1326 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1328 template <class Types
>
1329 class OcclusionTrackerTestOverlappingSurfaceSiblings
1330 : public OcclusionTrackerTest
<Types
> {
1332 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
1333 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1335 gfx::Transform child_transform
;
1336 child_transform
.Translate(250.0, 250.0);
1337 child_transform
.Rotate(90.0);
1338 child_transform
.Translate(-250.0, -250.0);
1340 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1341 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1342 parent
->SetMasksToBounds(true);
1343 typename
Types::LayerType
* child1
= this->CreateSurface(
1344 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(10, 10));
1345 typename
Types::LayerType
* child2
= this->CreateSurface(
1346 parent
, child_transform
, gfx::PointF(20.f
, 40.f
), gfx::Size(10, 10));
1347 typename
Types::ContentLayerType
* layer1
=
1348 this->CreateDrawingLayer(child1
,
1349 this->identity_matrix
,
1350 gfx::PointF(-10.f
, -10.f
),
1351 gfx::Size(510, 510),
1353 typename
Types::ContentLayerType
* layer2
=
1354 this->CreateDrawingLayer(child2
,
1355 this->identity_matrix
,
1356 gfx::PointF(-10.f
, -10.f
),
1357 gfx::Size(510, 510),
1359 this->CalcDrawEtc(parent
);
1361 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1362 typename
Types::RenderSurfaceType
> occlusion(
1363 gfx::Rect(0, 0, 1000, 1000));
1365 this->VisitLayer(layer2
, &occlusion
);
1366 this->EnterContributingSurface(child2
, &occlusion
);
1368 EXPECT_EQ(gfx::Rect().ToString(),
1369 occlusion
.occlusion_from_outside_target().ToString());
1370 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1371 occlusion
.occlusion_from_inside_target().ToString());
1373 // There is nothing above child2's surface in the z-order.
1374 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1375 occlusion
.UnoccludedContributingSurfaceContentRect(
1376 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1378 this->LeaveContributingSurface(child2
, &occlusion
);
1379 this->VisitLayer(layer1
, &occlusion
);
1380 this->EnterContributingSurface(child1
, &occlusion
);
1382 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1383 occlusion
.occlusion_from_outside_target().ToString());
1384 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1385 occlusion
.occlusion_from_inside_target().ToString());
1387 // child2's contents will occlude child1 below it.
1388 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1389 occlusion
.UnoccludedContributingSurfaceContentRect(
1390 child1
, false, gfx::Rect(-10, 430, 80, 70)));
1392 this->LeaveContributingSurface(child1
, &occlusion
);
1393 this->EnterLayer(parent
, &occlusion
);
1395 EXPECT_EQ(gfx::Rect().ToString(),
1396 occlusion
.occlusion_from_outside_target().ToString());
1397 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1399 occlusion
.occlusion_from_inside_target().ToString());
1401 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1403 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1404 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1405 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1407 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1408 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1409 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1411 /* Justification for the above occlusion:
1413 +---------------------+
1415 | 30+ ---------------------------------+
1416 100 | 30| | layer2 |
1417 |20+----------------------------------+ |
1421 +--|-|----------------+ | |
1429 | +--------------------------------|-+
1431 +----------------------------------+
1437 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1439 template <class Types
>
1440 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1441 : public OcclusionTrackerTest
<Types
> {
1443 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1445 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1447 gfx::Transform child1_transform
;
1448 child1_transform
.Translate(250.0, 250.0);
1449 child1_transform
.Rotate(-90.0);
1450 child1_transform
.Translate(-250.0, -250.0);
1452 gfx::Transform child2_transform
;
1453 child2_transform
.Translate(250.0, 250.0);
1454 child2_transform
.Rotate(90.0);
1455 child2_transform
.Translate(-250.0, -250.0);
1457 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1458 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1459 parent
->SetMasksToBounds(true);
1460 typename
Types::LayerType
* child1
= this->CreateSurface(
1461 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1462 typename
Types::LayerType
* child2
=
1463 this->CreateDrawingSurface(parent
,
1465 gfx::PointF(20.f
, 40.f
),
1468 typename
Types::ContentLayerType
* layer1
=
1469 this->CreateDrawingLayer(child1
,
1470 this->identity_matrix
,
1471 gfx::PointF(-10.f
, -20.f
),
1472 gfx::Size(510, 510),
1474 typename
Types::ContentLayerType
* layer2
=
1475 this->CreateDrawingLayer(child2
,
1476 this->identity_matrix
,
1477 gfx::PointF(-10.f
, -10.f
),
1478 gfx::Size(510, 510),
1480 this->CalcDrawEtc(parent
);
1482 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1483 typename
Types::RenderSurfaceType
> occlusion(
1484 gfx::Rect(0, 0, 1000, 1000));
1486 this->VisitLayer(layer2
, &occlusion
);
1487 this->EnterLayer(child2
, &occlusion
);
1489 EXPECT_EQ(gfx::Rect().ToString(),
1490 occlusion
.occlusion_from_outside_target().ToString());
1491 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1492 occlusion
.occlusion_from_inside_target().ToString());
1494 this->LeaveLayer(child2
, &occlusion
);
1495 this->EnterContributingSurface(child2
, &occlusion
);
1497 // There is nothing above child2's surface in the z-order.
1498 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1499 occlusion
.UnoccludedContributingSurfaceContentRect(
1500 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1502 this->LeaveContributingSurface(child2
, &occlusion
);
1503 this->VisitLayer(layer1
, &occlusion
);
1504 this->EnterContributingSurface(child1
, &occlusion
);
1506 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1507 occlusion
.occlusion_from_outside_target().ToString());
1508 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1509 occlusion
.occlusion_from_inside_target().ToString());
1511 // child2's contents will occlude child1 below it.
1512 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1513 occlusion
.UnoccludedContributingSurfaceContentRect(
1514 child1
, false, gfx::Rect(420, -20, 80, 90)));
1515 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1516 occlusion
.UnoccludedContributingSurfaceContentRect(
1517 child1
, false, gfx::Rect(420, -10, 80, 90)));
1518 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1519 occlusion
.UnoccludedContributingSurfaceContentRect(
1520 child1
, false, gfx::Rect(420, -20, 70, 90)));
1522 this->LeaveContributingSurface(child1
, &occlusion
);
1523 this->EnterLayer(parent
, &occlusion
);
1525 EXPECT_EQ(gfx::Rect().ToString(),
1526 occlusion
.occlusion_from_outside_target().ToString());
1527 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1528 occlusion
.occlusion_from_inside_target().ToString());
1530 /* Justification for the above occlusion:
1532 +---------------------+
1534 10+----------------------------------+
1535 100 || 30 | layer2 |
1536 |20+----------------------------------+
1540 +|-|------------------+ | |
1548 +----------------------------------+ |
1550 +----------------------------------+
1556 ALL_OCCLUSIONTRACKER_TEST(
1557 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1559 template <class Types
>
1560 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1562 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1563 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1565 gfx::Transform layer_transform
;
1566 layer_transform
.Translate(250.0, 250.0);
1567 layer_transform
.Rotate(90.0);
1568 layer_transform
.Translate(-250.0, -250.0);
1570 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1571 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1572 parent
->SetMasksToBounds(true);
1573 typename
Types::ContentLayerType
* blur_layer
=
1574 this->CreateDrawingLayer(parent
,
1576 gfx::PointF(30.f
, 30.f
),
1577 gfx::Size(500, 500),
1579 typename
Types::ContentLayerType
* opaque_layer
=
1580 this->CreateDrawingLayer(parent
,
1582 gfx::PointF(30.f
, 30.f
),
1583 gfx::Size(500, 500),
1585 typename
Types::ContentLayerType
* opacity_layer
=
1586 this->CreateDrawingLayer(parent
,
1588 gfx::PointF(30.f
, 30.f
),
1589 gfx::Size(500, 500),
1592 FilterOperations filters
;
1593 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1594 blur_layer
->SetFilters(filters
);
1597 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1598 opaque_layer
->SetFilters(filters
);
1601 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1602 opacity_layer
->SetFilters(filters
);
1604 this->CalcDrawEtc(parent
);
1606 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1607 typename
Types::RenderSurfaceType
> occlusion(
1608 gfx::Rect(0, 0, 1000, 1000));
1610 // Opacity layer won't contribute to occlusion.
1611 this->VisitLayer(opacity_layer
, &occlusion
);
1612 this->EnterContributingSurface(opacity_layer
, &occlusion
);
1614 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1615 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1617 // And has nothing to contribute to its parent surface.
1618 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1619 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1620 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1622 // Opaque layer will contribute to occlusion.
1623 this->VisitLayer(opaque_layer
, &occlusion
);
1624 this->EnterContributingSurface(opaque_layer
, &occlusion
);
1626 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1627 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1628 occlusion
.occlusion_from_inside_target().ToString());
1630 // And it gets translated to the parent surface.
1631 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1632 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1633 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1634 occlusion
.occlusion_from_inside_target().ToString());
1636 // The blur layer needs to throw away any occlusion from outside its
1638 this->EnterLayer(blur_layer
, &occlusion
);
1639 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1640 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1642 // And it won't contribute to occlusion.
1643 this->LeaveLayer(blur_layer
, &occlusion
);
1644 this->EnterContributingSurface(blur_layer
, &occlusion
);
1645 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1646 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1648 // But the opaque layer's occlusion is preserved on the parent.
1649 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1650 this->EnterLayer(parent
, &occlusion
);
1651 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1652 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1653 occlusion
.occlusion_from_inside_target().ToString());
1657 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1659 template <class Types
>
1660 class OcclusionTrackerTestReplicaDoesOcclude
1661 : public OcclusionTrackerTest
<Types
> {
1663 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1664 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1666 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1667 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1668 typename
Types::LayerType
* surface
=
1669 this->CreateDrawingSurface(parent
,
1670 this->identity_matrix
,
1671 gfx::PointF(0.f
, 100.f
),
1674 this->CreateReplicaLayer(
1675 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1676 this->CalcDrawEtc(parent
);
1678 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1679 typename
Types::RenderSurfaceType
> occlusion(
1680 gfx::Rect(0, 0, 1000, 1000));
1682 this->VisitLayer(surface
, &occlusion
);
1684 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1685 occlusion
.occlusion_from_inside_target().ToString());
1687 this->VisitContributingSurface(surface
, &occlusion
);
1688 this->EnterLayer(parent
, &occlusion
);
1690 // The surface and replica should both be occluding the parent.
1692 UnionRegions(gfx::Rect(0, 100, 50, 50),
1693 gfx::Rect(50, 150, 50, 50)).ToString(),
1694 occlusion
.occlusion_from_inside_target().ToString());
1698 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1700 template <class Types
>
1701 class OcclusionTrackerTestReplicaWithClipping
1702 : public OcclusionTrackerTest
<Types
> {
1704 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1705 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1707 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1708 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1709 parent
->SetMasksToBounds(true);
1710 typename
Types::LayerType
* surface
=
1711 this->CreateDrawingSurface(parent
,
1712 this->identity_matrix
,
1713 gfx::PointF(0.f
, 100.f
),
1716 this->CreateReplicaLayer(
1717 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1718 this->CalcDrawEtc(parent
);
1720 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1721 typename
Types::RenderSurfaceType
> occlusion(
1722 gfx::Rect(0, 0, 1000, 1000));
1724 this->VisitLayer(surface
, &occlusion
);
1726 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1727 occlusion
.occlusion_from_inside_target().ToString());
1729 this->VisitContributingSurface(surface
, &occlusion
);
1730 this->EnterLayer(parent
, &occlusion
);
1732 // The surface and replica should both be occluding the parent.
1734 UnionRegions(gfx::Rect(0, 100, 50, 50),
1735 gfx::Rect(50, 150, 50, 20)).ToString(),
1736 occlusion
.occlusion_from_inside_target().ToString());
1740 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1742 template <class Types
>
1743 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1745 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1746 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1748 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1749 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1750 typename
Types::LayerType
* surface
=
1751 this->CreateDrawingSurface(parent
,
1752 this->identity_matrix
,
1753 gfx::PointF(0.f
, 100.f
),
1756 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1757 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1758 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1759 this->CalcDrawEtc(parent
);
1761 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1762 typename
Types::RenderSurfaceType
> occlusion(
1763 gfx::Rect(0, 0, 1000, 1000));
1765 this->VisitLayer(surface
, &occlusion
);
1767 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1768 occlusion
.occlusion_from_inside_target().ToString());
1770 this->VisitContributingSurface(surface
, &occlusion
);
1771 this->EnterLayer(parent
, &occlusion
);
1773 // The replica should not be occluding the parent, since it has a mask
1775 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1776 occlusion
.occlusion_from_inside_target().ToString());
1780 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1782 template <class Types
>
1783 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1784 : public OcclusionTrackerTest
<Types
> {
1786 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1787 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1789 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1790 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1791 typename
Types::ContentLayerType
* layer
=
1792 this->CreateDrawingSurface(parent
,
1793 this->identity_matrix
,
1795 gfx::Size(200, 200),
1797 this->CalcDrawEtc(parent
);
1799 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1800 typename
Types::RenderSurfaceType
> occlusion(
1801 gfx::Rect(0, 0, 1000, 1000));
1802 this->EnterLayer(layer
, &occlusion
);
1804 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1805 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1806 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1807 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1809 this->LeaveLayer(layer
, &occlusion
);
1810 this->VisitContributingSurface(layer
, &occlusion
);
1811 this->EnterLayer(parent
, &occlusion
);
1813 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1817 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1819 template <class Types
>
1820 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1821 : public OcclusionTrackerTest
<Types
> {
1823 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1824 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1826 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1827 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1828 typename
Types::ContentLayerType
* layer
=
1829 this->CreateDrawingLayer(parent
,
1830 this->identity_matrix
,
1831 gfx::PointF(100.f
, 100.f
),
1832 gfx::Size(200, 200),
1834 this->CalcDrawEtc(parent
);
1836 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1837 typename
Types::RenderSurfaceType
> occlusion(
1838 gfx::Rect(0, 0, 1000, 1000));
1839 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1841 this->ResetLayerIterator();
1842 this->VisitLayer(layer
, &occlusion
);
1843 this->EnterLayer(parent
, &occlusion
);
1845 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1846 occlusion
.occlusion_from_inside_target().ToString());
1849 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1851 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1853 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1856 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1857 typename
Types::RenderSurfaceType
> occlusion(
1858 gfx::Rect(0, 0, 1000, 1000));
1859 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1861 this->ResetLayerIterator();
1862 this->VisitLayer(layer
, &occlusion
);
1863 this->EnterLayer(parent
, &occlusion
);
1865 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1866 occlusion
.occlusion_from_inside_target().ToString());
1869 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1871 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1873 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1876 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1877 typename
Types::RenderSurfaceType
> occlusion(
1878 gfx::Rect(0, 0, 1000, 1000));
1879 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1881 this->ResetLayerIterator();
1882 this->VisitLayer(layer
, &occlusion
);
1883 this->EnterLayer(parent
, &occlusion
);
1885 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1886 occlusion
.occlusion_from_inside_target().ToString());
1889 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1891 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1893 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1898 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1900 template <class Types
>
1901 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
1903 explicit OcclusionTrackerTest3dTransform(bool opaque_layers
)
1904 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1906 gfx::Transform transform
;
1907 transform
.RotateAboutYAxis(30.0);
1909 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1910 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1911 typename
Types::LayerType
* container
= this->CreateLayer(
1912 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1913 typename
Types::ContentLayerType
* layer
=
1914 this->CreateDrawingLayer(container
,
1916 gfx::PointF(100.f
, 100.f
),
1917 gfx::Size(200, 200),
1919 this->CalcDrawEtc(parent
);
1921 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1922 typename
Types::RenderSurfaceType
> occlusion(
1923 gfx::Rect(0, 0, 1000, 1000));
1924 this->EnterLayer(layer
, &occlusion
);
1926 // The layer is rotated in 3d but without preserving 3d, so it only gets
1929 gfx::Rect(0, 0, 200, 200),
1930 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1934 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
1936 template <class Types
>
1937 class OcclusionTrackerTestUnsorted3dLayers
1938 : public OcclusionTrackerTest
<Types
> {
1940 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
1941 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1943 // Currently, The main thread layer iterator does not iterate over 3d items
1944 // in sorted order, because layer sorting is not performed on the main
1945 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1946 // layer occludes other layers that have not yet been iterated over. For
1947 // now, the expected behavior is that a 3d layer simply does not add any
1948 // occlusion to the occlusion tracker.
1950 gfx::Transform translation_to_front
;
1951 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
1952 gfx::Transform translation_to_back
;
1953 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
1955 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1956 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1957 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
1958 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
1959 typename
Types::ContentLayerType
* child2
=
1960 this->CreateDrawingLayer(parent
,
1961 translation_to_front
,
1962 gfx::PointF(50.f
, 50.f
),
1963 gfx::Size(100, 100),
1965 parent
->SetPreserves3d(true);
1967 this->CalcDrawEtc(parent
);
1969 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
1970 typename
Types::RenderSurfaceType
> occlusion(
1971 gfx::Rect(0, 0, 1000, 1000));
1972 this->VisitLayer(child2
, &occlusion
);
1973 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1974 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1976 this->VisitLayer(child1
, &occlusion
);
1977 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1978 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1982 // This test will have different layer ordering on the impl thread; the test
1983 // will only work on the main thread.
1984 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1986 template <class Types
>
1987 class OcclusionTrackerTestPerspectiveTransform
1988 : public OcclusionTrackerTest
<Types
> {
1990 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers
)
1991 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1993 gfx::Transform transform
;
1994 transform
.Translate(150.0, 150.0);
1995 transform
.ApplyPerspectiveDepth(400.0);
1996 transform
.RotateAboutXAxis(-30.0);
1997 transform
.Translate(-150.0, -150.0);
1999 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2000 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2001 typename
Types::LayerType
* container
= this->CreateLayer(
2002 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2003 typename
Types::ContentLayerType
* layer
=
2004 this->CreateDrawingLayer(container
,
2006 gfx::PointF(100.f
, 100.f
),
2007 gfx::Size(200, 200),
2009 container
->SetPreserves3d(true);
2010 layer
->SetPreserves3d(true);
2011 this->CalcDrawEtc(parent
);
2013 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2014 typename
Types::RenderSurfaceType
> occlusion(
2015 gfx::Rect(0, 0, 1000, 1000));
2016 this->EnterLayer(layer
, &occlusion
);
2019 gfx::Rect(0, 0, 200, 200),
2020 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
2024 // This test requires accumulating occlusion of 3d layers, which are skipped by
2025 // the occlusion tracker on the main thread. So this test should run on the impl
2027 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
2029 template <class Types
>
2030 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2031 : public OcclusionTrackerTest
<Types
> {
2033 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2035 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2037 // This test is based on the platform/chromium/compositing/3d-corners.html
2039 gfx::Transform transform
;
2040 transform
.Translate(250.0, 50.0);
2041 transform
.ApplyPerspectiveDepth(10.0);
2042 transform
.Translate(-250.0, -50.0);
2043 transform
.Translate(250.0, 50.0);
2044 transform
.RotateAboutXAxis(-167.0);
2045 transform
.Translate(-250.0, -50.0);
2047 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2048 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 100));
2049 typename
Types::LayerType
* container
= this->CreateLayer(
2050 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2051 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2052 container
, transform
, gfx::PointF(), gfx::Size(500, 500), true);
2053 container
->SetPreserves3d(true);
2054 layer
->SetPreserves3d(true);
2055 this->CalcDrawEtc(parent
);
2057 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2058 typename
Types::RenderSurfaceType
> occlusion(
2059 gfx::Rect(0, 0, 1000, 1000));
2060 this->EnterLayer(layer
, &occlusion
);
2062 // The bottom 11 pixel rows of this layer remain visible inside the
2063 // container, after translation to the target surface. When translated back,
2064 // this will include many more pixels but must include at least the bottom
2066 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2067 layer
, gfx::Rect(0, 26, 500, 474)).
2068 Contains(gfx::Rect(0, 489, 500, 11)));
2072 // This test requires accumulating occlusion of 3d layers, which are skipped by
2073 // the occlusion tracker on the main thread. So this test should run on the impl
2075 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
2077 template <class Types
>
2078 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2079 : public OcclusionTrackerTest
<Types
> {
2081 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2083 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2085 gfx::Transform transform
;
2086 transform
.Translate(50.0, 50.0);
2087 transform
.ApplyPerspectiveDepth(100.0);
2088 transform
.Translate3d(0.0, 0.0, 110.0);
2089 transform
.Translate(-50.0, -50.0);
2091 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2092 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2093 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2094 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2095 parent
->SetPreserves3d(true);
2096 layer
->SetPreserves3d(true);
2097 this->CalcDrawEtc(parent
);
2099 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2100 typename
Types::RenderSurfaceType
> occlusion(
2101 gfx::Rect(0, 0, 1000, 1000));
2103 // The |layer| is entirely behind the camera and should not occlude.
2104 this->VisitLayer(layer
, &occlusion
);
2105 this->EnterLayer(parent
, &occlusion
);
2106 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2107 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2111 // This test requires accumulating occlusion of 3d layers, which are skipped by
2112 // the occlusion tracker on the main thread. So this test should run on the impl
2114 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2116 template <class Types
>
2117 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2118 : public OcclusionTrackerTest
<Types
> {
2120 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2122 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2124 gfx::Transform transform
;
2125 transform
.Translate(50.0, 50.0);
2126 transform
.ApplyPerspectiveDepth(100.0);
2127 transform
.Translate3d(0.0, 0.0, 99.0);
2128 transform
.Translate(-50.0, -50.0);
2130 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2131 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2132 parent
->SetMasksToBounds(true);
2133 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2134 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2135 parent
->SetPreserves3d(true);
2136 layer
->SetPreserves3d(true);
2137 this->CalcDrawEtc(parent
);
2139 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2140 typename
Types::RenderSurfaceType
> occlusion(
2141 gfx::Rect(0, 0, 1000, 1000));
2143 // This is very close to the camera, so pixels in its visible_content_rect()
2144 // will actually go outside of the layer's clip rect. Ensure that those
2145 // pixels don't occlude things outside the clip rect.
2146 this->VisitLayer(layer
, &occlusion
);
2147 this->EnterLayer(parent
, &occlusion
);
2148 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2149 occlusion
.occlusion_from_inside_target().ToString());
2150 EXPECT_EQ(gfx::Rect().ToString(),
2151 occlusion
.occlusion_from_outside_target().ToString());
2155 // This test requires accumulating occlusion of 3d layers, which are skipped by
2156 // the occlusion tracker on the main thread. So this test should run on the impl
2158 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2160 template <class Types
>
2161 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2162 : public OcclusionTrackerTest
<Types
> {
2164 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
2165 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2170 // | +--surface_child
2171 // | +--surface_child2
2175 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2176 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2177 typename
Types::ContentLayerType
* layer
=
2178 this->CreateDrawingLayer(parent
,
2179 this->identity_matrix
,
2181 gfx::Size(300, 300),
2183 typename
Types::ContentLayerType
* surface
=
2184 this->CreateDrawingSurface(parent
,
2185 this->identity_matrix
,
2187 gfx::Size(300, 300),
2189 typename
Types::ContentLayerType
* surface_child
=
2190 this->CreateDrawingLayer(surface
,
2191 this->identity_matrix
,
2193 gfx::Size(200, 300),
2195 typename
Types::ContentLayerType
* surface_child2
=
2196 this->CreateDrawingLayer(surface
,
2197 this->identity_matrix
,
2199 gfx::Size(100, 300),
2201 typename
Types::ContentLayerType
* parent2
=
2202 this->CreateDrawingLayer(parent
,
2203 this->identity_matrix
,
2205 gfx::Size(300, 300),
2207 typename
Types::ContentLayerType
* topmost
=
2208 this->CreateDrawingLayer(parent
,
2209 this->identity_matrix
,
2210 gfx::PointF(250.f
, 0.f
),
2214 AddOpacityTransitionToController(
2215 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2216 AddOpacityTransitionToController(
2217 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2218 this->CalcDrawEtc(parent
);
2220 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2221 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2222 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2224 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2225 typename
Types::RenderSurfaceType
> occlusion(
2226 gfx::Rect(0, 0, 1000, 1000));
2228 this->VisitLayer(topmost
, &occlusion
);
2229 this->EnterLayer(parent2
, &occlusion
);
2230 // This occlusion will affect all surfaces.
2231 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2232 occlusion
.occlusion_from_inside_target().ToString());
2233 EXPECT_EQ(gfx::Rect().ToString(),
2234 occlusion
.occlusion_from_outside_target().ToString());
2235 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2236 occlusion
.UnoccludedLayerContentRect(
2237 parent2
, gfx::Rect(0, 0, 300, 300)).ToString());
2238 this->LeaveLayer(parent2
, &occlusion
);
2240 this->VisitLayer(surface_child2
, &occlusion
);
2241 this->EnterLayer(surface_child
, &occlusion
);
2242 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2243 occlusion
.occlusion_from_inside_target().ToString());
2244 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2245 occlusion
.occlusion_from_outside_target().ToString());
2246 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2247 occlusion
.UnoccludedLayerContentRect(
2248 surface_child
, gfx::Rect(0, 0, 200, 300)));
2249 this->LeaveLayer(surface_child
, &occlusion
);
2250 this->EnterLayer(surface
, &occlusion
);
2251 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2252 occlusion
.occlusion_from_inside_target().ToString());
2253 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2254 occlusion
.occlusion_from_outside_target().ToString());
2255 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2256 occlusion
.UnoccludedLayerContentRect(
2257 surface
, gfx::Rect(0, 0, 300, 300)));
2258 this->LeaveLayer(surface
, &occlusion
);
2260 this->EnterContributingSurface(surface
, &occlusion
);
2261 // Occlusion within the surface is lost when leaving the animating surface.
2262 EXPECT_EQ(gfx::Rect().ToString(),
2263 occlusion
.occlusion_from_inside_target().ToString());
2264 EXPECT_EQ(gfx::Rect().ToString(),
2265 occlusion
.occlusion_from_outside_target().ToString());
2266 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2267 occlusion
.UnoccludedContributingSurfaceContentRect(
2268 surface
, false, gfx::Rect(0, 0, 300, 300)));
2269 this->LeaveContributingSurface(surface
, &occlusion
);
2271 // Occlusion from outside the animating surface still exists.
2272 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2273 occlusion
.occlusion_from_inside_target().ToString());
2274 EXPECT_EQ(gfx::Rect().ToString(),
2275 occlusion
.occlusion_from_outside_target().ToString());
2277 this->VisitLayer(layer
, &occlusion
);
2278 this->EnterLayer(parent
, &occlusion
);
2280 // Occlusion is not added for the animating |layer|.
2281 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2282 occlusion
.UnoccludedLayerContentRect(
2283 parent
, gfx::Rect(0, 0, 300, 300)));
2287 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2289 template <class Types
>
2290 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2291 : public OcclusionTrackerTest
<Types
> {
2293 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
2294 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2296 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2297 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2298 typename
Types::ContentLayerType
* layer
=
2299 this->CreateDrawingLayer(parent
,
2300 this->identity_matrix
,
2302 gfx::Size(300, 300),
2304 typename
Types::ContentLayerType
* surface
=
2305 this->CreateDrawingSurface(parent
,
2306 this->identity_matrix
,
2308 gfx::Size(300, 300),
2310 typename
Types::ContentLayerType
* surface_child
=
2311 this->CreateDrawingLayer(surface
,
2312 this->identity_matrix
,
2314 gfx::Size(200, 300),
2316 typename
Types::ContentLayerType
* surface_child2
=
2317 this->CreateDrawingLayer(surface
,
2318 this->identity_matrix
,
2320 gfx::Size(100, 300),
2322 typename
Types::ContentLayerType
* parent2
=
2323 this->CreateDrawingLayer(parent
,
2324 this->identity_matrix
,
2326 gfx::Size(300, 300),
2328 typename
Types::ContentLayerType
* topmost
=
2329 this->CreateDrawingLayer(parent
,
2330 this->identity_matrix
,
2331 gfx::PointF(250.f
, 0.f
),
2335 AddOpacityTransitionToController(
2336 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2337 AddOpacityTransitionToController(
2338 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2339 this->CalcDrawEtc(parent
);
2341 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2342 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2343 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2345 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2346 typename
Types::RenderSurfaceType
> occlusion(
2347 gfx::Rect(0, 0, 1000, 1000));
2349 this->VisitLayer(topmost
, &occlusion
);
2350 this->EnterLayer(parent2
, &occlusion
);
2351 // This occlusion will affect all surfaces.
2352 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2353 occlusion
.occlusion_from_inside_target().ToString());
2354 EXPECT_EQ(gfx::Rect().ToString(),
2355 occlusion
.occlusion_from_outside_target().ToString());
2356 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2357 occlusion
.UnoccludedLayerContentRect(
2358 parent
, gfx::Rect(0, 0, 300, 300)));
2359 this->LeaveLayer(parent2
, &occlusion
);
2361 this->VisitLayer(surface_child2
, &occlusion
);
2362 this->EnterLayer(surface_child
, &occlusion
);
2363 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2364 occlusion
.occlusion_from_inside_target().ToString());
2365 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2366 occlusion
.occlusion_from_outside_target().ToString());
2367 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2368 occlusion
.UnoccludedLayerContentRect(
2369 surface_child
, gfx::Rect(0, 0, 200, 300)));
2370 this->LeaveLayer(surface_child
, &occlusion
);
2371 this->EnterLayer(surface
, &occlusion
);
2372 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2373 occlusion
.occlusion_from_inside_target().ToString());
2374 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2375 occlusion
.occlusion_from_outside_target().ToString());
2376 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2377 occlusion
.UnoccludedLayerContentRect(
2378 surface
, gfx::Rect(0, 0, 300, 300)));
2379 this->LeaveLayer(surface
, &occlusion
);
2381 this->EnterContributingSurface(surface
, &occlusion
);
2382 // Occlusion within the surface is lost when leaving the animating surface.
2383 EXPECT_EQ(gfx::Rect().ToString(),
2384 occlusion
.occlusion_from_inside_target().ToString());
2385 EXPECT_EQ(gfx::Rect().ToString(),
2386 occlusion
.occlusion_from_outside_target().ToString());
2387 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2388 occlusion
.UnoccludedContributingSurfaceContentRect(
2389 surface
, false, gfx::Rect(0, 0, 300, 300)));
2390 this->LeaveContributingSurface(surface
, &occlusion
);
2392 // Occlusion from outside the animating surface still exists.
2393 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2394 occlusion
.occlusion_from_inside_target().ToString());
2395 EXPECT_EQ(gfx::Rect().ToString(),
2396 occlusion
.occlusion_from_outside_target().ToString());
2398 this->VisitLayer(layer
, &occlusion
);
2399 this->EnterLayer(parent
, &occlusion
);
2401 // Occlusion is not added for the animating |layer|.
2402 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2403 occlusion
.UnoccludedLayerContentRect(
2404 parent
, gfx::Rect(0, 0, 300, 300)));
2408 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2410 template <class Types
>
2411 class OcclusionTrackerTestAnimationTranslateOnMainThread
2412 : public OcclusionTrackerTest
<Types
> {
2414 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2416 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2418 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2419 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2420 typename
Types::ContentLayerType
* layer
=
2421 this->CreateDrawingLayer(parent
,
2422 this->identity_matrix
,
2424 gfx::Size(300, 300),
2426 typename
Types::ContentLayerType
* surface
=
2427 this->CreateDrawingSurface(parent
,
2428 this->identity_matrix
,
2430 gfx::Size(300, 300),
2432 typename
Types::ContentLayerType
* surface_child
=
2433 this->CreateDrawingLayer(surface
,
2434 this->identity_matrix
,
2436 gfx::Size(200, 300),
2438 typename
Types::ContentLayerType
* surface_child2
=
2439 this->CreateDrawingLayer(surface
,
2440 this->identity_matrix
,
2442 gfx::Size(100, 300),
2444 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
2445 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
2447 AddAnimatedTransformToController(
2448 layer
->layer_animation_controller(), 10.0, 30, 0);
2449 AddAnimatedTransformToController(
2450 surface
->layer_animation_controller(), 10.0, 30, 0);
2451 AddAnimatedTransformToController(
2452 surface_child
->layer_animation_controller(), 10.0, 30, 0);
2453 this->CalcDrawEtc(parent
);
2455 EXPECT_TRUE(layer
->draw_transform_is_animating());
2456 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
2458 surface
->render_surface()->target_surface_transforms_are_animating());
2460 surface
->render_surface()->screen_space_transforms_are_animating());
2461 // The surface owning layer doesn't animate against its own surface.
2462 EXPECT_FALSE(surface
->draw_transform_is_animating());
2463 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
2464 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
2465 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
2467 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2468 typename
Types::RenderSurfaceType
> occlusion(
2469 gfx::Rect(0, 0, 1000, 1000));
2471 this->VisitLayer(surface2
, &occlusion
);
2472 this->EnterContributingSurface(surface2
, &occlusion
);
2474 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2475 occlusion
.occlusion_from_inside_target().ToString());
2477 this->LeaveContributingSurface(surface2
, &occlusion
);
2478 this->EnterLayer(surface_child2
, &occlusion
);
2480 // surface_child2 is moving in screen space but not relative to its target,
2481 // so occlusion should happen in its target space only. It also means that
2482 // things occluding from outside the target (e.g. surface2) cannot occlude
2484 EXPECT_EQ(gfx::Rect().ToString(),
2485 occlusion
.occlusion_from_outside_target().ToString());
2487 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2488 occlusion
.UnoccludedLayerContentRect(
2489 surface_child2
, gfx::Rect(0, 0, 100, 300)));
2491 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2493 this->LeaveLayer(surface_child2
, &occlusion
);
2494 this->EnterLayer(surface_child
, &occlusion
);
2496 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 100, 300)));
2497 EXPECT_EQ(gfx::Rect().ToString(),
2498 occlusion
.occlusion_from_outside_target().ToString());
2499 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2500 occlusion
.occlusion_from_inside_target().ToString());
2501 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2502 occlusion
.UnoccludedLayerContentRect(
2503 surface
, gfx::Rect(0, 0, 300, 300)));
2505 // The surface_child is occluded by the surface_child2, but is moving
2506 // relative its target, so it can't be occluded.
2507 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2508 occlusion
.UnoccludedLayerContentRect(
2509 surface_child
, gfx::Rect(0, 0, 200, 300)));
2511 occlusion
.OccludedLayer(surface_child
, gfx::Rect(0, 0, 50, 300)));
2513 this->LeaveLayer(surface_child
, &occlusion
);
2514 this->EnterLayer(surface
, &occlusion
);
2515 // The surface_child is moving in screen space but not relative to its
2516 // target, so occlusion should happen from within the target only.
2517 EXPECT_EQ(gfx::Rect().ToString(),
2518 occlusion
.occlusion_from_outside_target().ToString());
2519 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2520 occlusion
.occlusion_from_inside_target().ToString());
2521 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2522 occlusion
.UnoccludedLayerContentRect(
2523 surface
, gfx::Rect(0, 0, 300, 300)));
2525 this->LeaveLayer(surface
, &occlusion
);
2526 // The surface's owning layer is moving in screen space but not relative to
2527 // its target, so occlusion should happen within the target only.
2528 EXPECT_EQ(gfx::Rect().ToString(),
2529 occlusion
.occlusion_from_outside_target().ToString());
2530 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2531 occlusion
.occlusion_from_inside_target().ToString());
2532 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2533 occlusion
.UnoccludedLayerContentRect(
2534 surface
, gfx::Rect(0, 0, 300, 300)));
2536 this->EnterContributingSurface(surface
, &occlusion
);
2537 // The contributing |surface| is animating so it can't be occluded.
2538 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2539 occlusion
.UnoccludedContributingSurfaceContentRect(
2540 surface
, false, gfx::Rect(0, 0, 300, 300)));
2541 this->LeaveContributingSurface(surface
, &occlusion
);
2543 this->EnterLayer(layer
, &occlusion
);
2544 // The |surface| is moving in the screen and in its target, so all occlusion
2545 // within the surface is lost when leaving it.
2546 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2547 occlusion
.UnoccludedLayerContentRect(
2548 parent
, gfx::Rect(0, 0, 300, 300)));
2549 this->LeaveLayer(layer
, &occlusion
);
2551 this->EnterLayer(parent
, &occlusion
);
2552 // The |layer| is animating in the screen and in its target, so no occlusion
2554 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2555 occlusion
.UnoccludedLayerContentRect(
2556 parent
, gfx::Rect(0, 0, 300, 300)));
2560 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
2562 template <class Types
>
2563 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2564 : public OcclusionTrackerTest
<Types
> {
2566 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2568 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2570 gfx::Transform surface_transform
;
2571 surface_transform
.Translate(300.0, 300.0);
2572 surface_transform
.Scale(2.0, 2.0);
2573 surface_transform
.Translate(-150.0, -150.0);
2575 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2576 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2577 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
2578 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
2579 typename
Types::ContentLayerType
* surface2
=
2580 this->CreateDrawingSurface(parent
,
2581 this->identity_matrix
,
2582 gfx::PointF(50.f
, 50.f
),
2583 gfx::Size(300, 300),
2585 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2586 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2587 this->CalcDrawEtc(parent
);
2589 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2590 typename
Types::RenderSurfaceType
> occlusion(
2591 gfx::Rect(0, 0, 1000, 1000));
2593 this->VisitLayer(surface2
, &occlusion
);
2594 this->VisitContributingSurface(surface2
, &occlusion
);
2596 EXPECT_EQ(gfx::Rect().ToString(),
2597 occlusion
.occlusion_from_outside_target().ToString());
2598 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2599 occlusion
.occlusion_from_inside_target().ToString());
2601 // Clear any stored occlusion.
2602 occlusion
.set_occlusion_from_outside_target(Region());
2603 occlusion
.set_occlusion_from_inside_target(Region());
2605 this->VisitLayer(surface
, &occlusion
);
2606 this->VisitContributingSurface(surface
, &occlusion
);
2608 EXPECT_EQ(gfx::Rect().ToString(),
2609 occlusion
.occlusion_from_outside_target().ToString());
2610 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2611 occlusion
.occlusion_from_inside_target().ToString());
2615 MAIN_AND_IMPL_THREAD_TEST(
2616 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
2618 template <class Types
>
2619 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2620 : public OcclusionTrackerTest
<Types
> {
2622 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2624 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2626 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2627 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2628 parent
->SetMasksToBounds(true);
2629 typename
Types::ContentLayerType
* surface
=
2630 this->CreateDrawingSurface(parent
,
2631 this->identity_matrix
,
2633 gfx::Size(500, 300),
2635 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2636 this->CalcDrawEtc(parent
);
2638 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2639 typename
Types::RenderSurfaceType
> occlusion(
2640 gfx::Rect(0, 0, 1000, 1000));
2642 this->VisitLayer(surface
, &occlusion
);
2643 this->VisitContributingSurface(surface
, &occlusion
);
2645 EXPECT_EQ(gfx::Rect().ToString(),
2646 occlusion
.occlusion_from_outside_target().ToString());
2647 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2648 occlusion
.occlusion_from_inside_target().ToString());
2652 MAIN_AND_IMPL_THREAD_TEST(
2653 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2655 template <class Types
>
2656 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
2658 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers
)
2659 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2661 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2662 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2663 typename
Types::LayerType
* surface
=
2664 this->CreateDrawingSurface(parent
,
2665 this->identity_matrix
,
2667 gfx::Size(100, 100),
2669 this->CreateReplicaLayer(surface
,
2670 this->identity_matrix
,
2671 gfx::PointF(0.f
, 100.f
),
2672 gfx::Size(100, 100));
2673 typename
Types::LayerType
* topmost
=
2674 this->CreateDrawingLayer(parent
,
2675 this->identity_matrix
,
2676 gfx::PointF(0.f
, 100.f
),
2677 gfx::Size(100, 100),
2679 this->CalcDrawEtc(parent
);
2681 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2682 typename
Types::RenderSurfaceType
> occlusion(
2683 gfx::Rect(0, 0, 1000, 1000));
2685 // |topmost| occludes the replica, but not the surface itself.
2686 this->VisitLayer(topmost
, &occlusion
);
2688 EXPECT_EQ(gfx::Rect().ToString(),
2689 occlusion
.occlusion_from_outside_target().ToString());
2690 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2691 occlusion
.occlusion_from_inside_target().ToString());
2693 this->VisitLayer(surface
, &occlusion
);
2695 // Render target with replica ignores occlusion from outside.
2696 EXPECT_EQ(gfx::Rect().ToString(),
2697 occlusion
.occlusion_from_outside_target().ToString());
2698 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2699 occlusion
.occlusion_from_inside_target().ToString());
2701 this->EnterContributingSurface(surface
, &occlusion
);
2703 // Surface is not occluded so it shouldn't think it is.
2704 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2705 occlusion
.UnoccludedContributingSurfaceContentRect(
2706 surface
, false, gfx::Rect(0, 0, 100, 100)));
2710 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
2712 template <class Types
>
2713 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2714 : public OcclusionTrackerTest
<Types
> {
2716 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
2717 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2719 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2720 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2721 typename
Types::LayerType
* surface
=
2722 this->CreateDrawingSurface(parent
,
2723 this->identity_matrix
,
2725 gfx::Size(100, 100),
2727 this->CreateReplicaLayer(surface
,
2728 this->identity_matrix
,
2729 gfx::PointF(0.f
, 100.f
),
2730 gfx::Size(100, 100));
2731 typename
Types::LayerType
* topmost
=
2732 this->CreateDrawingLayer(parent
,
2733 this->identity_matrix
,
2735 gfx::Size(100, 110),
2737 this->CalcDrawEtc(parent
);
2739 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
2740 typename
Types::RenderSurfaceType
> occlusion(
2741 gfx::Rect(0, 0, 1000, 1000));
2743 // |topmost| occludes the surface, but not the entire surface's replica.
2744 this->VisitLayer(topmost
, &occlusion
);
2746 EXPECT_EQ(gfx::Rect().ToString(),
2747 occlusion
.occlusion_from_outside_target().ToString());
2748 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2749 occlusion
.occlusion_from_inside_target().ToString());
2751 this->VisitLayer(surface
, &occlusion
);
2753 // Render target with replica ignores occlusion from outside.
2754 EXPECT_EQ(gfx::Rect().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
);
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 // Render target with replica ignores occlusion from outside.
2821 EXPECT_EQ(gfx::Rect().ToString(),
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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 50x50 filtered surface that is completely surrounded by opaque
3075 // layers which are above it in the z-order. The surface is scaled to test
3076 // that the pixel moving is done in the target space, where the background
3077 // filter is applied.
3078 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3079 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
3080 typename
Types::LayerType
* filtered_surface
=
3081 this->CreateDrawingLayer(parent
,
3083 gfx::PointF(50.f
, 50.f
),
3084 gfx::Size(100, 100),
3086 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3087 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 50), true);
3088 typename
Types::LayerType
* occluding_layer2
=
3089 this->CreateDrawingLayer(parent
,
3090 this->identity_matrix
,
3091 gfx::PointF(0.f
, 100.f
),
3094 typename
Types::LayerType
* occluding_layer3
=
3095 this->CreateDrawingLayer(parent
,
3096 this->identity_matrix
,
3097 gfx::PointF(0.f
, 50.f
),
3100 typename
Types::LayerType
* occluding_layer4
=
3101 this->CreateDrawingLayer(parent
,
3102 this->identity_matrix
,
3103 gfx::PointF(100.f
, 50.f
),
3107 // Filters make the layer own a surface.
3108 FilterOperations filters
;
3109 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
3110 filtered_surface
->SetBackgroundFilters(filters
);
3112 // Save the distance of influence for the blur effect.
3113 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3115 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3117 this->CalcDrawEtc(parent
);
3119 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3120 typename
Types::RenderSurfaceType
> occlusion(
3121 gfx::Rect(0, 0, 1000, 1000));
3123 // These layers occlude pixels directly beside the filtered_surface. Because
3124 // filtered surface blends pixels in a radius, it will need to see some of
3125 // the pixels (up to radius far) underneath the occluding layers.
3126 this->VisitLayer(occluding_layer4
, &occlusion
);
3127 this->VisitLayer(occluding_layer3
, &occlusion
);
3128 this->VisitLayer(occluding_layer2
, &occlusion
);
3129 this->VisitLayer(occluding_layer1
, &occlusion
);
3131 Region expected_occlusion
;
3132 expected_occlusion
.Union(gfx::Rect(0, 0, 200, 50));
3133 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3134 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3135 expected_occlusion
.Union(gfx::Rect(0, 100, 200, 50));
3137 EXPECT_EQ(expected_occlusion
.ToString(),
3138 occlusion
.occlusion_from_inside_target().ToString());
3139 EXPECT_EQ(gfx::Rect().ToString(),
3140 occlusion
.occlusion_from_outside_target().ToString());
3142 this->VisitLayer(filtered_surface
, &occlusion
);
3144 // The filtered layer does not occlude.
3145 Region expected_occlusion_outside_surface
;
3146 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 200, 50));
3147 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3148 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3149 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 200, 50));
3151 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3152 occlusion
.occlusion_from_outside_target().ToString());
3153 EXPECT_EQ(gfx::Rect().ToString(),
3154 occlusion
.occlusion_from_inside_target().ToString());
3156 // The surface has a background blur, so it needs pixels that are currently
3157 // considered occluded in order to be drawn. So the pixels it needs should
3158 // be removed some the occluded area so that when we get to the parent they
3160 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3162 this->EnterLayer(parent
, &occlusion
);
3164 Region expected_blurred_occlusion
;
3165 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 200, 50 - outset_top
));
3166 expected_blurred_occlusion
.Union(gfx::Rect(
3167 0, 50 - outset_top
, 50 - outset_left
, 50 + outset_top
+ outset_bottom
));
3168 expected_blurred_occlusion
.Union(
3169 gfx::Rect(100 + outset_right
,
3172 50 + outset_top
+ outset_bottom
));
3173 expected_blurred_occlusion
.Union(
3174 gfx::Rect(0, 100 + outset_bottom
, 200, 50 - outset_bottom
));
3176 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3177 occlusion
.occlusion_from_inside_target().ToString());
3178 EXPECT_EQ(gfx::Rect().ToString(),
3179 occlusion
.occlusion_from_outside_target().ToString());
3181 gfx::Rect outset_rect
;
3182 gfx::Rect test_rect
;
3184 // Nothing in the blur outsets for the filtered_surface is occluded.
3185 outset_rect
= gfx::Rect(50 - outset_left
,
3187 50 + outset_left
+ outset_right
,
3188 50 + outset_top
+ outset_bottom
);
3189 test_rect
= outset_rect
;
3191 outset_rect
.ToString(),
3192 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3194 // Stuff outside the blur outsets is still occluded though.
3195 test_rect
= outset_rect
;
3196 test_rect
.Inset(0, 0, -1, 0);
3198 outset_rect
.ToString(),
3199 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3200 test_rect
= outset_rect
;
3201 test_rect
.Inset(0, 0, 0, -1);
3203 outset_rect
.ToString(),
3204 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3205 test_rect
= outset_rect
;
3206 test_rect
.Inset(-1, 0, 0, 0);
3208 outset_rect
.ToString(),
3209 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3210 test_rect
= outset_rect
;
3211 test_rect
.Inset(0, -1, 0, 0);
3213 outset_rect
.ToString(),
3214 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3218 ALL_OCCLUSIONTRACKER_TEST(
3219 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
3221 template <class Types
>
3222 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3223 : public OcclusionTrackerTest
<Types
> {
3225 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3227 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3229 gfx::Transform scale_by_half
;
3230 scale_by_half
.Scale(0.5, 0.5);
3232 // Makes two surfaces that completely cover |parent|. The occlusion both
3233 // above and below the filters will be reduced by each of them.
3234 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3235 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
3236 typename
Types::LayerType
* parent
= this->CreateSurface(
3237 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
3238 parent
->SetMasksToBounds(true);
3239 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
3240 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3241 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
3242 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3243 typename
Types::LayerType
* occluding_layer_above
=
3244 this->CreateDrawingLayer(parent
,
3245 this->identity_matrix
,
3246 gfx::PointF(100.f
, 100.f
),
3250 // Filters make the layers own surfaces.
3251 FilterOperations filters
;
3252 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
3253 filtered_surface1
->SetBackgroundFilters(filters
);
3254 filtered_surface2
->SetBackgroundFilters(filters
);
3256 // Save the distance of influence for the blur effect.
3257 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3259 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3261 this->CalcDrawEtc(root
);
3263 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3264 typename
Types::RenderSurfaceType
> occlusion(
3265 gfx::Rect(0, 0, 1000, 1000));
3267 this->VisitLayer(occluding_layer_above
, &occlusion
);
3268 EXPECT_EQ(gfx::Rect().ToString(),
3269 occlusion
.occlusion_from_outside_target().ToString());
3270 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3271 occlusion
.occlusion_from_inside_target().ToString());
3273 this->VisitLayer(filtered_surface2
, &occlusion
);
3274 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
3275 this->VisitLayer(filtered_surface1
, &occlusion
);
3276 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
3278 // Test expectations in the target.
3279 gfx::Rect expected_occlusion
=
3280 gfx::Rect(100 / 2 + outset_right
* 2,
3281 100 / 2 + outset_bottom
* 2,
3282 50 / 2 - (outset_left
+ outset_right
) * 2,
3283 50 / 2 - (outset_top
+ outset_bottom
) * 2);
3284 EXPECT_EQ(expected_occlusion
.ToString(),
3285 occlusion
.occlusion_from_inside_target().ToString());
3287 // Test expectations in the screen are the same as in the target, as the
3288 // render surface is 1:1 with the screen.
3289 EXPECT_EQ(expected_occlusion
.ToString(),
3290 occlusion
.occlusion_from_outside_target().ToString());
3294 ALL_OCCLUSIONTRACKER_TEST(
3295 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
3297 template <class Types
>
3298 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3299 : public OcclusionTrackerTest
<Types
> {
3301 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3303 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3305 gfx::Transform scale_by_half
;
3306 scale_by_half
.Scale(0.5, 0.5);
3308 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3309 // centered below each. The surface is scaled to test that the pixel moving
3310 // is done in the target space, where the background filter is applied, but
3311 // the surface appears at 50, 50 and the replica at 200, 50.
3312 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3313 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3314 typename
Types::LayerType
* behind_surface_layer
=
3315 this->CreateDrawingLayer(parent
,
3316 this->identity_matrix
,
3317 gfx::PointF(60.f
, 60.f
),
3320 typename
Types::LayerType
* behind_replica_layer
=
3321 this->CreateDrawingLayer(parent
,
3322 this->identity_matrix
,
3323 gfx::PointF(210.f
, 60.f
),
3326 typename
Types::LayerType
* filtered_surface
=
3327 this->CreateDrawingLayer(parent
,
3329 gfx::PointF(50.f
, 50.f
),
3330 gfx::Size(100, 100),
3332 this->CreateReplicaLayer(filtered_surface
,
3333 this->identity_matrix
,
3334 gfx::PointF(300.f
, 0.f
),
3337 // Filters make the layer own a surface.
3338 FilterOperations filters
;
3339 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3340 filtered_surface
->SetBackgroundFilters(filters
);
3342 this->CalcDrawEtc(parent
);
3344 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3345 typename
Types::RenderSurfaceType
> occlusion(
3346 gfx::Rect(0, 0, 1000, 1000));
3348 // The surface has a background blur, so it blurs non-opaque pixels below
3350 this->VisitLayer(filtered_surface
, &occlusion
);
3351 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3353 this->VisitLayer(behind_replica_layer
, &occlusion
);
3354 this->VisitLayer(behind_surface_layer
, &occlusion
);
3356 // The layers behind the surface are not blurred, and their occlusion does
3357 // not change, until we leave the surface. So it should not be modified by
3359 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
3360 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
3362 Region expected_opaque_bounds
=
3363 UnionRegions(occlusion_behind_surface
, occlusion_behind_replica
);
3364 EXPECT_EQ(expected_opaque_bounds
.ToString(),
3365 occlusion
.occlusion_from_inside_target().ToString());
3367 EXPECT_EQ(gfx::Rect().ToString(),
3368 occlusion
.occlusion_from_outside_target().ToString());
3372 ALL_OCCLUSIONTRACKER_TEST(
3373 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
3375 template <class Types
>
3376 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3377 : public OcclusionTrackerTest
<Types
> {
3379 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3381 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3383 gfx::Transform scale_by_half
;
3384 scale_by_half
.Scale(0.5, 0.5);
3386 // Make a 50x50 filtered surface that is completely occluded by an opaque
3387 // layer which is above it in the z-order. The surface is
3388 // scaled to test that the pixel moving is done in the target space, where
3389 // the background filter is applied, but the surface appears at 50, 50.
3390 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3391 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
3392 typename
Types::LayerType
* filtered_surface
=
3393 this->CreateDrawingLayer(parent
,
3395 gfx::PointF(50.f
, 50.f
),
3396 gfx::Size(100, 100),
3398 typename
Types::LayerType
* occluding_layer
=
3399 this->CreateDrawingLayer(parent
,
3400 this->identity_matrix
,
3401 gfx::PointF(50.f
, 50.f
),
3405 // Filters make the layer own a surface.
3406 FilterOperations filters
;
3407 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3408 filtered_surface
->SetBackgroundFilters(filters
);
3410 this->CalcDrawEtc(parent
);
3412 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3413 typename
Types::RenderSurfaceType
> occlusion(
3414 gfx::Rect(0, 0, 1000, 1000));
3416 this->VisitLayer(occluding_layer
, &occlusion
);
3418 this->VisitLayer(filtered_surface
, &occlusion
);
3420 // The layers above the filtered surface occlude from outside.
3421 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
3423 EXPECT_EQ(gfx::Rect().ToString(),
3424 occlusion
.occlusion_from_inside_target().ToString());
3425 EXPECT_EQ(occlusion_above_surface
.ToString(),
3426 occlusion
.occlusion_from_outside_target().ToString());
3429 // The surface has a background blur, so it blurs non-opaque pixels below
3431 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3433 // The filter is completely occluded, so it should not blur anything and
3434 // reduce any occlusion.
3435 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
3437 EXPECT_EQ(occlusion_above_surface
.ToString(),
3438 occlusion
.occlusion_from_inside_target().ToString());
3439 EXPECT_EQ(gfx::Rect().ToString(),
3440 occlusion
.occlusion_from_outside_target().ToString());
3445 ALL_OCCLUSIONTRACKER_TEST(
3446 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
3448 template <class Types
>
3449 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3450 : public OcclusionTrackerTest
<Types
> {
3453 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3455 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3457 gfx::Transform scale_by_half
;
3458 scale_by_half
.Scale(0.5, 0.5);
3460 // Make a surface and its replica, each 50x50, that are partially occluded
3461 // by opaque layers which are above them in the z-order. The surface is
3462 // scaled to test that the pixel moving is done in the target space, where
3463 // the background filter is applied, but the surface appears at 50, 50 and
3464 // the replica at 200, 50.
3465 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3466 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3467 typename
Types::LayerType
* filtered_surface
=
3468 this->CreateDrawingLayer(parent
,
3470 gfx::PointF(50.f
, 50.f
),
3471 gfx::Size(100, 100),
3473 this->CreateReplicaLayer(filtered_surface
,
3474 this->identity_matrix
,
3475 gfx::PointF(300.f
, 0.f
),
3477 typename
Types::LayerType
* above_surface_layer
=
3478 this->CreateDrawingLayer(parent
,
3479 this->identity_matrix
,
3480 gfx::PointF(70.f
, 50.f
),
3483 typename
Types::LayerType
* above_replica_layer
=
3484 this->CreateDrawingLayer(parent
,
3485 this->identity_matrix
,
3486 gfx::PointF(200.f
, 50.f
),
3489 typename
Types::LayerType
* beside_surface_layer
=
3490 this->CreateDrawingLayer(parent
,
3491 this->identity_matrix
,
3492 gfx::PointF(90.f
, 40.f
),
3495 typename
Types::LayerType
* beside_replica_layer
=
3496 this->CreateDrawingLayer(parent
,
3497 this->identity_matrix
,
3498 gfx::PointF(200.f
, 40.f
),
3502 // Filters make the layer own a surface.
3503 FilterOperations filters
;
3504 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3505 filtered_surface
->SetBackgroundFilters(filters
);
3507 // Save the distance of influence for the blur effect.
3508 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3510 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3512 this->CalcDrawEtc(parent
);
3514 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3515 typename
Types::RenderSurfaceType
> occlusion(
3516 gfx::Rect(0, 0, 1000, 1000));
3518 this->VisitLayer(beside_replica_layer
, &occlusion
);
3519 this->VisitLayer(beside_surface_layer
, &occlusion
);
3520 this->VisitLayer(above_replica_layer
, &occlusion
);
3521 this->VisitLayer(above_surface_layer
, &occlusion
);
3523 // The surface has a background blur, so it blurs non-opaque pixels below
3525 this->VisitLayer(filtered_surface
, &occlusion
);
3526 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3528 // The filter in the surface and replica are partially unoccluded. Only the
3529 // unoccluded parts should reduce occlusion. This means it will push back
3530 // the occlusion that touches the unoccluded part (occlusion_above___), but
3531 // it will not touch occlusion_beside____ since that is not beside the
3532 // unoccluded part of the surface, even though it is beside the occluded
3533 // part of the surface.
3534 gfx::Rect occlusion_above_surface
=
3535 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
3536 gfx::Rect occlusion_above_replica
=
3537 gfx::Rect(200, 50, 30 - outset_left
, 50);
3538 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
3539 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
3541 Region expected_occlusion
;
3542 expected_occlusion
.Union(occlusion_above_surface
);
3543 expected_occlusion
.Union(occlusion_above_replica
);
3544 expected_occlusion
.Union(occlusion_beside_surface
);
3545 expected_occlusion
.Union(occlusion_beside_replica
);
3547 ASSERT_EQ(expected_occlusion
.ToString(),
3548 occlusion
.occlusion_from_inside_target().ToString());
3549 EXPECT_EQ(gfx::Rect().ToString(),
3550 occlusion
.occlusion_from_outside_target().ToString());
3552 Region::Iterator
expected_rects(expected_occlusion
);
3553 Region::Iterator
target_surface_rects(
3554 occlusion
.occlusion_from_inside_target());
3555 for (; expected_rects
.has_rect();
3556 expected_rects
.next(), target_surface_rects
.next()) {
3557 ASSERT_TRUE(target_surface_rects
.has_rect());
3558 EXPECT_EQ(expected_rects
.rect(), target_surface_rects
.rect());
3563 ALL_OCCLUSIONTRACKER_TEST(
3564 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
3566 template <class Types
>
3567 class OcclusionTrackerTestMinimumTrackingSize
3568 : public OcclusionTrackerTest
<Types
> {
3570 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
3571 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3573 gfx::Size
tracking_size(100, 100);
3574 gfx::Size
below_tracking_size(99, 99);
3576 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3577 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3578 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
3579 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
3580 typename
Types::LayerType
* small
=
3581 this->CreateDrawingLayer(parent
,
3582 this->identity_matrix
,
3584 below_tracking_size
,
3586 this->CalcDrawEtc(parent
);
3588 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3589 typename
Types::RenderSurfaceType
> occlusion(
3590 gfx::Rect(0, 0, 1000, 1000));
3591 occlusion
.set_minimum_tracking_size(tracking_size
);
3593 // The small layer is not tracked because it is too small.
3594 this->VisitLayer(small
, &occlusion
);
3596 EXPECT_EQ(gfx::Rect().ToString(),
3597 occlusion
.occlusion_from_outside_target().ToString());
3598 EXPECT_EQ(gfx::Rect().ToString(),
3599 occlusion
.occlusion_from_inside_target().ToString());
3601 // The large layer is tracked as it is large enough.
3602 this->VisitLayer(large
, &occlusion
);
3604 EXPECT_EQ(gfx::Rect().ToString(),
3605 occlusion
.occlusion_from_outside_target().ToString());
3606 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
3607 occlusion
.occlusion_from_inside_target().ToString());
3611 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
3613 template <class Types
>
3614 class OcclusionTrackerTestScaledLayerIsClipped
3615 : public OcclusionTrackerTest
<Types
> {
3617 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
3618 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3620 gfx::Transform scale_transform
;
3621 scale_transform
.Scale(512.0, 512.0);
3623 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3624 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3625 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3626 this->identity_matrix
,
3627 gfx::PointF(10.f
, 10.f
),
3629 clip
->SetMasksToBounds(true);
3630 typename
Types::LayerType
* scale
= this->CreateLayer(
3631 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3632 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3633 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3634 this->CalcDrawEtc(parent
);
3636 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3637 typename
Types::RenderSurfaceType
> occlusion(
3638 gfx::Rect(0, 0, 1000, 1000));
3640 this->VisitLayer(scaled
, &occlusion
);
3642 EXPECT_EQ(gfx::Rect().ToString(),
3643 occlusion
.occlusion_from_outside_target().ToString());
3644 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3645 occlusion
.occlusion_from_inside_target().ToString());
3649 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
3651 template <class Types
>
3652 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3653 : public OcclusionTrackerTest
<Types
> {
3655 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
3656 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3658 gfx::Transform scale_transform
;
3659 scale_transform
.Scale(512.0, 512.0);
3661 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3662 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3663 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3664 this->identity_matrix
,
3665 gfx::PointF(10.f
, 10.f
),
3667 clip
->SetMasksToBounds(true);
3668 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
3669 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
3670 typename
Types::LayerType
* scale
= this->CreateLayer(
3671 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3672 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3673 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3674 this->CalcDrawEtc(parent
);
3676 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3677 typename
Types::RenderSurfaceType
> occlusion(
3678 gfx::Rect(0, 0, 1000, 1000));
3680 this->VisitLayer(scaled
, &occlusion
);
3681 this->VisitLayer(surface
, &occlusion
);
3682 this->VisitContributingSurface(surface
, &occlusion
);
3684 EXPECT_EQ(gfx::Rect().ToString(),
3685 occlusion
.occlusion_from_outside_target().ToString());
3686 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3687 occlusion
.occlusion_from_inside_target().ToString());
3691 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
3693 template <class Types
>
3694 class OcclusionTrackerTestCopyRequestDoesOcclude
3695 : public OcclusionTrackerTest
<Types
> {
3697 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
3698 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3700 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3701 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3702 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3703 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3704 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
3705 this->identity_matrix
,
3707 gfx::Size(200, 400));
3708 this->AddCopyRequest(copy
);
3709 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3711 this->identity_matrix
,
3713 gfx::Size(200, 400),
3715 this->CalcDrawEtc(root
);
3717 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3718 typename
Types::RenderSurfaceType
> occlusion(
3719 gfx::Rect(0, 0, 1000, 1000));
3721 this->VisitLayer(copy_child
, &occlusion
);
3722 EXPECT_EQ(gfx::Rect().ToString(),
3723 occlusion
.occlusion_from_outside_target().ToString());
3724 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3725 occlusion
.occlusion_from_inside_target().ToString());
3727 // CopyRequests cause the layer to own a surface.
3728 this->VisitContributingSurface(copy
, &occlusion
);
3730 // The occlusion from the copy should be kept.
3731 EXPECT_EQ(gfx::Rect().ToString(),
3732 occlusion
.occlusion_from_outside_target().ToString());
3733 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3734 occlusion
.occlusion_from_inside_target().ToString());
3738 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
3740 template <class Types
>
3741 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3742 : public OcclusionTrackerTest
<Types
> {
3744 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3746 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3748 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3749 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3750 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3751 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3752 typename
Types::LayerType
* hide
= this->CreateLayer(
3753 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
3754 typename
Types::LayerType
* copy
= this->CreateLayer(
3755 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
3756 this->AddCopyRequest(copy
);
3757 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3758 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
3760 // The |copy| layer is hidden but since it is being copied, it will be
3762 hide
->SetHideLayerAndSubtree(true);
3764 this->CalcDrawEtc(root
);
3766 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3767 typename
Types::RenderSurfaceType
> occlusion(
3768 gfx::Rect(0, 0, 1000, 1000));
3770 this->VisitLayer(copy_child
, &occlusion
);
3771 EXPECT_EQ(gfx::Rect().ToString(),
3772 occlusion
.occlusion_from_outside_target().ToString());
3773 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3774 occlusion
.occlusion_from_inside_target().ToString());
3776 // CopyRequests cause the layer to own a surface.
3777 this->VisitContributingSurface(copy
, &occlusion
);
3779 // The occlusion from the copy should be dropped since it is hidden.
3780 EXPECT_EQ(gfx::Rect().ToString(),
3781 occlusion
.occlusion_from_outside_target().ToString());
3782 EXPECT_EQ(gfx::Rect().ToString(),
3783 occlusion
.occlusion_from_inside_target().ToString());
3787 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
3789 template <class Types
>
3790 class OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
3791 : public OcclusionTrackerTest
<Types
> {
3793 explicit OcclusionTrackerTestEmptyEventLayerDoesNotOcclude(
3795 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3797 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3798 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3799 typename
Types::ContentLayerType
* empty_layer
= this->CreateDrawingLayer(
3800 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), true);
3801 this->SetDrawsContent(empty_layer
, false);
3802 empty_layer
->SetTouchEventHandlerRegion(gfx::Rect(10, 10, 10, 10));
3804 this->CalcDrawEtc(root
);
3806 TestOcclusionTrackerWithClip
<typename
Types::LayerType
,
3807 typename
Types::RenderSurfaceType
> occlusion(
3808 gfx::Rect(0, 0, 1000, 1000), false);
3810 this->VisitLayer(empty_layer
, &occlusion
);
3812 EXPECT_EQ(gfx::Rect().ToString(),
3813 occlusion
.occlusion_from_outside_target().ToString());
3814 EXPECT_EQ(gfx::Rect().ToString(),
3815 occlusion
.occlusion_from_inside_target().ToString());
3819 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
)