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/layers/layer.h"
10 #include "cc/layers/layer_impl.h"
11 #include "cc/output/copy_output_request.h"
12 #include "cc/output/copy_output_result.h"
13 #include "cc/output/filter_operation.h"
14 #include "cc/output/filter_operations.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_impl_proxy.h"
17 #include "cc/test/fake_layer_tree_host.h"
18 #include "cc/test/fake_layer_tree_host_impl.h"
19 #include "cc/test/geometry_test_utils.h"
20 #include "cc/test/test_occlusion_tracker.h"
21 #include "cc/test/test_task_graph_runner.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 TestContentLayerImpl
: public LayerImpl
{
33 TestContentLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
34 : LayerImpl(tree_impl
, id
), override_opaque_contents_rect_(false) {
35 SetDrawsContent(true);
38 SimpleEnclosedRegion
VisibleOpaqueRegion() const override
{
39 if (override_opaque_contents_rect_
) {
40 return SimpleEnclosedRegion(
41 gfx::IntersectRects(opaque_contents_rect_
, visible_layer_rect()));
43 return LayerImpl::VisibleOpaqueRegion();
45 void SetOpaqueContentsRect(const gfx::Rect
& opaque_contents_rect
) {
46 override_opaque_contents_rect_
= true;
47 opaque_contents_rect_
= opaque_contents_rect
;
51 bool override_opaque_contents_rect_
;
52 gfx::Rect opaque_contents_rect_
;
55 class TestOcclusionTrackerWithClip
: public TestOcclusionTracker
{
57 explicit TestOcclusionTrackerWithClip(const gfx::Rect
& viewport_rect
)
58 : TestOcclusionTracker(viewport_rect
) {}
60 bool OccludedLayer(const LayerImpl
* layer
,
61 const gfx::Rect
& content_rect
) const {
62 DCHECK(layer
->visible_layer_rect().Contains(content_rect
));
63 return this->GetCurrentOcclusionForLayer(layer
->draw_transform())
64 .IsOccluded(content_rect
);
67 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
68 // layer. Simple wrapper around GetUnoccludedContentRect.
69 gfx::Rect
UnoccludedLayerContentRect(const LayerImpl
* layer
,
70 const gfx::Rect
& content_rect
) const {
71 DCHECK(layer
->visible_layer_rect().Contains(content_rect
));
72 return this->GetCurrentOcclusionForLayer(layer
->draw_transform())
73 .GetUnoccludedContentRect(content_rect
);
76 gfx::Rect
UnoccludedSurfaceContentRect(const LayerImpl
* layer
,
77 const gfx::Rect
& content_rect
) const {
78 RenderSurfaceImpl
* surface
= layer
->render_surface();
79 return this->GetCurrentOcclusionForContributingSurface(
80 surface
->draw_transform())
81 .GetUnoccludedContentRect(content_rect
);
85 class OcclusionTrackerTest
: public testing::Test
{
87 explicit OcclusionTrackerTest(bool opaque_layers
)
88 : opaque_layers_(opaque_layers
),
89 client_(FakeLayerTreeHostClient::DIRECT_3D
),
90 host_(FakeLayerTreeHost::Create(&client_
, &task_graph_runner_
)),
91 next_layer_impl_id_(1) {}
93 virtual void RunMyTest() = 0;
95 void TearDown() override
{ DestroyLayers(); }
97 TestContentLayerImpl
* CreateRoot(const gfx::Transform
& transform
,
98 const gfx::PointF
& position
,
99 const gfx::Size
& bounds
) {
100 LayerTreeImpl
* tree
= host_
->host_impl()->active_tree();
101 int id
= next_layer_impl_id_
++;
102 scoped_ptr
<TestContentLayerImpl
> layer(new TestContentLayerImpl(tree
, id
));
103 TestContentLayerImpl
* layer_ptr
= layer
.get();
104 SetProperties(layer_ptr
, transform
, position
, bounds
);
106 DCHECK(!root_
.get());
107 root_
= layer
.Pass();
109 layer_ptr
->SetHasRenderSurface(true);
110 SetRootLayerOnMainThread(layer_ptr
);
115 LayerImpl
* CreateLayer(LayerImpl
* parent
,
116 const gfx::Transform
& transform
,
117 const gfx::PointF
& position
,
118 const gfx::Size
& bounds
) {
119 LayerTreeImpl
* tree
= host_
->host_impl()->active_tree();
120 int id
= next_layer_impl_id_
++;
121 scoped_ptr
<LayerImpl
> layer
= LayerImpl::Create(tree
, id
);
122 LayerImpl
* layer_ptr
= layer
.get();
123 SetProperties(layer_ptr
, transform
, position
, bounds
);
124 parent
->AddChild(layer
.Pass());
128 LayerImpl
* CreateSurface(LayerImpl
* parent
,
129 const gfx::Transform
& transform
,
130 const gfx::PointF
& position
,
131 const gfx::Size
& bounds
) {
132 LayerImpl
* layer
= CreateLayer(parent
, transform
, position
, bounds
);
133 layer
->SetHasRenderSurface(true);
137 TestContentLayerImpl
* CreateDrawingLayer(LayerImpl
* parent
,
138 const gfx::Transform
& transform
,
139 const gfx::PointF
& position
,
140 const gfx::Size
& bounds
,
142 LayerTreeImpl
* tree
= host_
->host_impl()->active_tree();
143 int id
= next_layer_impl_id_
++;
144 scoped_ptr
<TestContentLayerImpl
> layer(new TestContentLayerImpl(tree
, id
));
145 TestContentLayerImpl
* layer_ptr
= layer
.get();
146 SetProperties(layer_ptr
, transform
, position
, bounds
);
148 if (opaque_layers_
) {
149 layer_ptr
->SetContentsOpaque(opaque
);
151 layer_ptr
->SetContentsOpaque(false);
153 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
155 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
158 parent
->AddChild(layer
.Pass());
162 LayerImpl
* CreateReplicaLayer(LayerImpl
* owning_layer
,
163 const gfx::Transform
& transform
,
164 const gfx::PointF
& position
,
165 const gfx::Size
& bounds
) {
166 LayerTreeImpl
* tree
= host_
->host_impl()->active_tree();
167 int id
= next_layer_impl_id_
++;
168 scoped_ptr
<TestContentLayerImpl
> layer(new TestContentLayerImpl(tree
, id
));
169 TestContentLayerImpl
* layer_ptr
= layer
.get();
170 SetProperties(layer_ptr
, transform
, position
, bounds
);
171 SetReplica(owning_layer
, layer
.Pass());
175 LayerImpl
* CreateMaskLayer(LayerImpl
* owning_layer
, const gfx::Size
& bounds
) {
176 LayerTreeImpl
* tree
= host_
->host_impl()->active_tree();
177 int id
= next_layer_impl_id_
++;
178 scoped_ptr
<TestContentLayerImpl
> layer(new TestContentLayerImpl(tree
, id
));
179 TestContentLayerImpl
* layer_ptr
= layer
.get();
180 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
181 SetMask(owning_layer
, layer
.Pass());
185 TestContentLayerImpl
* CreateDrawingSurface(LayerImpl
* parent
,
186 const gfx::Transform
& transform
,
187 const gfx::PointF
& position
,
188 const gfx::Size
& bounds
,
190 TestContentLayerImpl
* layer
=
191 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
192 layer
->SetHasRenderSurface(true);
196 void DestroyLayers() {
198 render_surface_layer_list_
= nullptr;
199 render_surface_layer_list_impl_
.clear();
200 replica_layers_
.clear();
201 mask_layers_
.clear();
202 ResetLayerIterator();
205 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
207 void AddCopyRequest(Layer
* layer
) {
208 layer
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
209 base::Bind(&OcclusionTrackerTest::CopyOutputCallback
,
210 base::Unretained(this))));
213 void AddCopyRequest(LayerImpl
* layer
) {
214 ScopedPtrVector
<CopyOutputRequest
> requests
;
215 requests
.push_back(CopyOutputRequest::CreateBitmapRequest(base::Bind(
216 &OcclusionTrackerTest::CopyOutputCallback
, base::Unretained(this))));
217 layer
->SetHasRenderSurface(true);
218 layer
->PassCopyRequests(&requests
);
221 void CalcDrawEtc(TestContentLayerImpl
* root
) {
222 DCHECK(root
== root_
.get());
224 // These occlusion tests attach and detach layers in multiple
225 // iterations, so rebuild property trees every time.
226 root
->layer_tree_impl()->property_trees()->needs_rebuild
= true;
228 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root
);
230 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
231 root
, root
->bounds(), &render_surface_layer_list_impl_
);
232 inputs
.can_adjust_raster_scales
= true;
233 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
235 layer_iterator_
= layer_iterator_begin_
=
236 LayerIterator::Begin(&render_surface_layer_list_impl_
);
239 void EnterLayer(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
240 ASSERT_EQ(*layer_iterator_
, layer
);
241 ASSERT_TRUE(layer_iterator_
.represents_itself());
242 occlusion
->EnterLayer(layer_iterator_
);
245 void LeaveLayer(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
246 ASSERT_EQ(*layer_iterator_
, layer
);
247 ASSERT_TRUE(layer_iterator_
.represents_itself());
248 occlusion
->LeaveLayer(layer_iterator_
);
252 void VisitLayer(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
253 EnterLayer(layer
, occlusion
);
254 LeaveLayer(layer
, occlusion
);
257 void EnterContributingSurface(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
258 ASSERT_EQ(*layer_iterator_
, layer
);
259 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
260 occlusion
->EnterLayer(layer_iterator_
);
261 occlusion
->LeaveLayer(layer_iterator_
);
263 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
264 occlusion
->EnterLayer(layer_iterator_
);
267 void LeaveContributingSurface(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
268 ASSERT_EQ(*layer_iterator_
, layer
);
269 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
270 occlusion
->LeaveLayer(layer_iterator_
);
274 void VisitContributingSurface(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
275 EnterContributingSurface(layer
, occlusion
);
276 LeaveContributingSurface(layer
, occlusion
);
279 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
281 const gfx::Transform identity_matrix
;
284 void SetRootLayerOnMainThread(Layer
* root
) {
285 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
288 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
290 void SetProperties(LayerImpl
* layer
,
291 const gfx::Transform
& transform
,
292 const gfx::PointF
& position
,
293 const gfx::Size
& bounds
) {
294 layer
->SetTransform(transform
);
295 layer
->SetPosition(position
);
296 layer
->SetBounds(bounds
);
299 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
300 owning_layer
->SetReplicaLayer(layer
.Pass());
303 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
304 owning_layer
->SetMaskLayer(layer
.Pass());
308 FakeLayerTreeHostClient client_
;
309 TestTaskGraphRunner task_graph_runner_
;
310 scoped_ptr
<FakeLayerTreeHost
> host_
;
311 // These hold ownership of the layers for the duration of the test.
312 scoped_ptr
<LayerImpl
> root_
;
313 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
314 LayerImplList render_surface_layer_list_impl_
;
315 LayerIterator layer_iterator_begin_
;
316 LayerIterator layer_iterator_
;
317 LayerList replica_layers_
;
318 LayerList mask_layers_
;
319 int next_layer_impl_id_
;
322 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
323 class ClassName##ImplThreadOpaqueLayers : public ClassName { \
324 public: /* NOLINT(whitespace/indent) */ \
325 ClassName##ImplThreadOpaqueLayers() : ClassName(true) {} \
327 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
328 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
329 class ClassName##ImplThreadOpaquePaints : public ClassName { \
330 public: /* NOLINT(whitespace/indent) */ \
331 ClassName##ImplThreadOpaquePaints() : ClassName(false) {} \
333 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
335 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
336 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
337 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
339 class OcclusionTrackerTestIdentityTransforms
: public OcclusionTrackerTest
{
341 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
342 : OcclusionTrackerTest(opaque_layers
) {}
344 void RunMyTest() override
{
345 TestContentLayerImpl
* root
= this->CreateRoot(
346 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
347 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
348 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
349 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
350 parent
, this->identity_matrix
, gfx::PointF(30.f
, 30.f
),
351 gfx::Size(500, 500), true);
352 parent
->SetMasksToBounds(true);
353 this->CalcDrawEtc(root
);
355 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
357 this->VisitLayer(layer
, &occlusion
);
358 this->EnterLayer(parent
, &occlusion
);
360 EXPECT_EQ(gfx::Rect().ToString(),
361 occlusion
.occlusion_from_outside_target().ToString());
362 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
363 occlusion
.occlusion_from_inside_target().ToString());
367 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
369 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
{
371 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
372 : OcclusionTrackerTest(opaque_layers
) {}
373 void RunMyTest() override
{
374 gfx::Transform layer_transform
;
375 layer_transform
.Translate(250.0, 250.0);
376 layer_transform
.Rotate(90.0);
377 layer_transform
.Translate(-250.0, -250.0);
379 TestContentLayerImpl
* root
= this->CreateRoot(
380 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
381 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
382 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
383 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
384 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
386 parent
->SetMasksToBounds(true);
387 this->CalcDrawEtc(root
);
389 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
391 this->VisitLayer(layer
, &occlusion
);
392 this->EnterLayer(parent
, &occlusion
);
394 EXPECT_EQ(gfx::Rect().ToString(),
395 occlusion
.occlusion_from_outside_target().ToString());
396 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
397 occlusion
.occlusion_from_inside_target().ToString());
401 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
403 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
{
405 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
406 : OcclusionTrackerTest(opaque_layers
) {}
407 void RunMyTest() override
{
408 gfx::Transform layer_transform
;
409 layer_transform
.Translate(20.0, 20.0);
411 TestContentLayerImpl
* root
= this->CreateRoot(
412 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
413 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
414 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
415 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
416 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
418 parent
->SetMasksToBounds(true);
419 this->CalcDrawEtc(root
);
421 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
423 this->VisitLayer(layer
, &occlusion
);
424 this->EnterLayer(parent
, &occlusion
);
426 EXPECT_EQ(gfx::Rect().ToString(),
427 occlusion
.occlusion_from_outside_target().ToString());
428 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
429 occlusion
.occlusion_from_inside_target().ToString());
433 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
435 class OcclusionTrackerTestChildInRotatedChild
: public OcclusionTrackerTest
{
437 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
438 : OcclusionTrackerTest(opaque_layers
) {}
439 void RunMyTest() override
{
440 gfx::Transform child_transform
;
441 child_transform
.Translate(250.0, 250.0);
442 child_transform
.Rotate(90.0);
443 child_transform
.Translate(-250.0, -250.0);
445 TestContentLayerImpl
* parent
= this->CreateRoot(
446 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
447 parent
->SetMasksToBounds(true);
448 LayerImpl
* child
= this->CreateSurface(
449 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
450 child
->SetMasksToBounds(true);
451 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
452 child
, this->identity_matrix
, gfx::PointF(10.f
, 10.f
),
453 gfx::Size(500, 500), true);
454 this->CalcDrawEtc(parent
);
456 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
458 this->VisitLayer(layer
, &occlusion
);
459 this->EnterContributingSurface(child
, &occlusion
);
461 EXPECT_EQ(gfx::Rect().ToString(),
462 occlusion
.occlusion_from_outside_target().ToString());
463 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
464 occlusion
.occlusion_from_inside_target().ToString());
466 this->LeaveContributingSurface(child
, &occlusion
);
467 this->EnterLayer(parent
, &occlusion
);
469 EXPECT_EQ(gfx::Rect().ToString(),
470 occlusion
.occlusion_from_outside_target().ToString());
471 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
472 occlusion
.occlusion_from_inside_target().ToString());
474 /* Justification for the above occlusion from |layer|:
476 +---------------------+
479 | 30 + ---------------------------------+
481 | |10+---------------------------------+
485 +----|--|-------------+ | |
493 +--|-------------------------------+ |
495 +---------------------------------+
498 +---------------------+
499 | |30 Visible region of |layer|: /////
501 | +---------------------------------+
503 | +---------------------------------+ |
504 | | |///////////////| 420 | |
505 | | |///////////////|60 | |
506 | | |///////////////| | |
507 +--|--|---------------+ | |
515 | +------------------------------|--+
517 +---------------------------------+
524 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
526 class OcclusionTrackerTestScaledRenderSurface
: public OcclusionTrackerTest
{
528 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
529 : OcclusionTrackerTest(opaque_layers
) {}
531 void RunMyTest() override
{
532 TestContentLayerImpl
* parent
= this->CreateRoot(
533 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
535 gfx::Transform layer1_matrix
;
536 layer1_matrix
.Scale(2.0, 2.0);
537 TestContentLayerImpl
* layer1
= this->CreateDrawingLayer(
538 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
539 layer1
->SetHasRenderSurface(true);
541 gfx::Transform layer2_matrix
;
542 layer2_matrix
.Translate(25.0, 25.0);
543 TestContentLayerImpl
* layer2
= this->CreateDrawingLayer(
544 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
545 TestContentLayerImpl
* occluder
= this->CreateDrawingLayer(
546 parent
, this->identity_matrix
, gfx::PointF(100.f
, 100.f
),
547 gfx::Size(500, 500), true);
548 this->CalcDrawEtc(parent
);
550 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
552 this->VisitLayer(occluder
, &occlusion
);
553 this->EnterLayer(layer2
, &occlusion
);
555 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
556 occlusion
.occlusion_from_outside_target().ToString());
557 EXPECT_EQ(gfx::Rect().ToString(),
558 occlusion
.occlusion_from_inside_target().ToString());
562 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
564 class OcclusionTrackerTestVisitTargetTwoTimes
: public OcclusionTrackerTest
{
566 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
567 : OcclusionTrackerTest(opaque_layers
) {}
568 void RunMyTest() override
{
569 TestContentLayerImpl
* root
= this->CreateRoot(
570 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
571 LayerImpl
* surface
= this->CreateSurface(
572 root
, this->identity_matrix
, gfx::PointF(30.f
, 30.f
), gfx::Size());
573 TestContentLayerImpl
* surface_child
= this->CreateDrawingLayer(
574 surface
, this->identity_matrix
, gfx::PointF(10.f
, 10.f
),
575 gfx::Size(50, 50), true);
576 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
577 // first, instead of |surface|'s. This exercises different code in
578 // LeaveToRenderTarget, as the target surface has already been seen when
579 // leaving |surface| later.
580 TestContentLayerImpl
* top_layer
= this->CreateDrawingLayer(
581 root
, this->identity_matrix
, gfx::PointF(40.f
, 90.f
), gfx::Size(50, 20),
583 this->CalcDrawEtc(root
);
585 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
587 this->VisitLayer(top_layer
, &occlusion
);
589 EXPECT_EQ(gfx::Rect().ToString(),
590 occlusion
.occlusion_from_outside_target().ToString());
591 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
592 occlusion
.occlusion_from_inside_target().ToString());
594 this->VisitLayer(surface_child
, &occlusion
);
596 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
597 occlusion
.occlusion_from_outside_target().ToString());
598 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
599 occlusion
.occlusion_from_inside_target().ToString());
601 this->EnterContributingSurface(surface
, &occlusion
);
603 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
604 occlusion
.occlusion_from_outside_target().ToString());
605 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
606 occlusion
.occlusion_from_inside_target().ToString());
608 // Occlusion from |top_layer| already in the root target should get merged
609 // with the occlusion from the |surface| we are leaving now.
610 this->LeaveContributingSurface(surface
, &occlusion
);
611 this->EnterLayer(root
, &occlusion
);
613 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
614 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
615 occlusion
.occlusion_from_inside_target().ToString());
619 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
621 class OcclusionTrackerTestSurfaceRotatedOffAxis
: public OcclusionTrackerTest
{
623 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
624 : OcclusionTrackerTest(opaque_layers
) {}
625 void RunMyTest() override
{
626 gfx::Transform child_transform
;
627 child_transform
.Translate(250.0, 250.0);
628 child_transform
.Rotate(95.0);
629 child_transform
.Translate(-250.0, -250.0);
631 gfx::Transform layer_transform
;
632 layer_transform
.Translate(10.0, 10.0);
634 TestContentLayerImpl
* root
= this->CreateRoot(
635 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
636 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
637 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
638 LayerImpl
* child
= this->CreateSurface(
639 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
640 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
641 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
642 this->CalcDrawEtc(root
);
644 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
646 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
647 layer_transform
, layer
->visible_layer_rect());
649 this->VisitLayer(layer
, &occlusion
);
650 this->EnterContributingSurface(child
, &occlusion
);
652 EXPECT_EQ(gfx::Rect().ToString(),
653 occlusion
.occlusion_from_outside_target().ToString());
654 EXPECT_EQ(clipped_layer_in_child
.ToString(),
655 occlusion
.occlusion_from_inside_target().ToString());
657 this->LeaveContributingSurface(child
, &occlusion
);
658 this->EnterLayer(parent
, &occlusion
);
660 EXPECT_EQ(gfx::Rect().ToString(),
661 occlusion
.occlusion_from_outside_target().ToString());
662 EXPECT_EQ(gfx::Rect().ToString(),
663 occlusion
.occlusion_from_inside_target().ToString());
667 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
669 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
670 : public OcclusionTrackerTest
{
672 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
673 : OcclusionTrackerTest(opaque_layers
) {}
674 void RunMyTest() override
{
675 gfx::Transform child_transform
;
676 child_transform
.Translate(250.0, 250.0);
677 child_transform
.Rotate(90.0);
678 child_transform
.Translate(-250.0, -250.0);
680 TestContentLayerImpl
* root
= this->CreateRoot(
681 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
682 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
683 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
684 parent
->SetMasksToBounds(true);
685 TestContentLayerImpl
* child
= this->CreateDrawingSurface(
686 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
688 child
->SetMasksToBounds(true);
689 TestContentLayerImpl
* layer1
= this->CreateDrawingLayer(
690 child
, this->identity_matrix
, gfx::PointF(10.f
, 10.f
),
691 gfx::Size(500, 500), true);
692 TestContentLayerImpl
* layer2
= this->CreateDrawingLayer(
693 child
, this->identity_matrix
, gfx::PointF(10.f
, 450.f
),
694 gfx::Size(500, 60), true);
695 this->CalcDrawEtc(root
);
697 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
699 this->VisitLayer(layer2
, &occlusion
);
700 this->VisitLayer(layer1
, &occlusion
);
701 this->VisitLayer(child
, &occlusion
);
702 this->EnterContributingSurface(child
, &occlusion
);
704 EXPECT_EQ(gfx::Rect().ToString(),
705 occlusion
.occlusion_from_outside_target().ToString());
706 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
707 occlusion
.occlusion_from_inside_target().ToString());
709 this->LeaveContributingSurface(child
, &occlusion
);
710 this->EnterLayer(parent
, &occlusion
);
712 EXPECT_EQ(gfx::Rect().ToString(),
713 occlusion
.occlusion_from_outside_target().ToString());
714 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
715 occlusion
.occlusion_from_inside_target().ToString());
717 /* Justification for the above occlusion from |layer1| and |layer2|:
719 +---------------------+
720 | |30 Visible region of |layer1|: /////
721 | | Visible region of |layer2|: \\\\\
722 | +---------------------------------+
724 | +---------------+-----------------+ |
725 | | |\\\\\\\\\\\\|//| 420 | |
726 | | |\\\\\\\\\\\\|//|60 | |
727 | | |\\\\\\\\\\\\|//| | |
728 +--|--|------------|--+ | |
736 | +------------|-----------------|--+
738 +---------------+-----------------+
744 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
746 class OcclusionTrackerTestOverlappingSurfaceSiblings
747 : public OcclusionTrackerTest
{
749 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
750 : OcclusionTrackerTest(opaque_layers
) {}
751 void RunMyTest() override
{
752 TestContentLayerImpl
* parent
= this->CreateRoot(
753 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
754 parent
->SetMasksToBounds(true);
755 LayerImpl
* child1
= this->CreateSurface(
756 parent
, this->identity_matrix
, gfx::PointF(10.f
, 0.f
), gfx::Size());
757 LayerImpl
* child2
= this->CreateSurface(
758 parent
, this->identity_matrix
, gfx::PointF(30.f
, 0.f
), gfx::Size());
759 TestContentLayerImpl
* layer1
= this->CreateDrawingLayer(
760 child1
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 50), true);
761 TestContentLayerImpl
* layer2
= this->CreateDrawingLayer(
762 child2
, this->identity_matrix
, gfx::PointF(10.f
, 0.f
),
763 gfx::Size(40, 50), true);
764 this->CalcDrawEtc(parent
);
766 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
768 this->VisitLayer(layer2
, &occlusion
);
769 this->EnterContributingSurface(child2
, &occlusion
);
771 // layer2's occlusion.
772 EXPECT_EQ(gfx::Rect().ToString(),
773 occlusion
.occlusion_from_outside_target().ToString());
774 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
775 occlusion
.occlusion_from_inside_target().ToString());
777 this->LeaveContributingSurface(child2
, &occlusion
);
778 this->VisitLayer(layer1
, &occlusion
);
779 this->EnterContributingSurface(child1
, &occlusion
);
781 // layer2's occlusion in the target space of layer1.
782 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
783 occlusion
.occlusion_from_outside_target().ToString());
784 // layer1's occlusion.
785 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
786 occlusion
.occlusion_from_inside_target().ToString());
788 this->LeaveContributingSurface(child1
, &occlusion
);
789 this->EnterLayer(parent
, &occlusion
);
791 // The occlusion from from layer1 and layer2 is merged.
792 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
793 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
794 occlusion
.occlusion_from_inside_target().ToString());
798 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
800 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
801 : public OcclusionTrackerTest
{
803 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
805 : OcclusionTrackerTest(opaque_layers
) {}
806 void RunMyTest() override
{
807 gfx::Transform child1_transform
;
808 child1_transform
.Translate(250.0, 250.0);
809 child1_transform
.Rotate(-90.0);
810 child1_transform
.Translate(-250.0, -250.0);
812 gfx::Transform child2_transform
;
813 child2_transform
.Translate(250.0, 250.0);
814 child2_transform
.Rotate(90.0);
815 child2_transform
.Translate(-250.0, -250.0);
817 TestContentLayerImpl
* parent
= this->CreateRoot(
818 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
819 parent
->SetMasksToBounds(true);
820 LayerImpl
* child1
= this->CreateSurface(
821 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
822 LayerImpl
* child2
= this->CreateDrawingSurface(parent
, child2_transform
,
823 gfx::PointF(20.f
, 40.f
),
824 gfx::Size(10, 10), false);
825 TestContentLayerImpl
* layer1
= this->CreateDrawingLayer(
826 child1
, this->identity_matrix
, gfx::PointF(-10.f
, -20.f
),
827 gfx::Size(510, 510), true);
828 TestContentLayerImpl
* layer2
= this->CreateDrawingLayer(
829 child2
, this->identity_matrix
, gfx::PointF(-10.f
, -10.f
),
830 gfx::Size(510, 510), true);
831 this->CalcDrawEtc(parent
);
833 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
835 this->VisitLayer(layer2
, &occlusion
);
836 this->EnterLayer(child2
, &occlusion
);
838 EXPECT_EQ(gfx::Rect().ToString(),
839 occlusion
.occlusion_from_outside_target().ToString());
840 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
841 occlusion
.occlusion_from_inside_target().ToString());
843 this->LeaveLayer(child2
, &occlusion
);
844 this->EnterContributingSurface(child2
, &occlusion
);
846 EXPECT_EQ(gfx::Rect().ToString(),
847 occlusion
.occlusion_from_outside_target().ToString());
848 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
849 occlusion
.occlusion_from_inside_target().ToString());
851 this->LeaveContributingSurface(child2
, &occlusion
);
852 this->VisitLayer(layer1
, &occlusion
);
853 this->EnterContributingSurface(child1
, &occlusion
);
855 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
856 occlusion
.occlusion_from_outside_target().ToString());
857 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
858 occlusion
.occlusion_from_inside_target().ToString());
860 this->LeaveContributingSurface(child1
, &occlusion
);
861 this->EnterLayer(parent
, &occlusion
);
863 EXPECT_EQ(gfx::Rect().ToString(),
864 occlusion
.occlusion_from_outside_target().ToString());
865 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
866 occlusion
.occlusion_from_inside_target().ToString());
868 /* Justification for the above occlusion:
870 +---------------------+
872 10+----------------------------------+
874 |20+----------------------------------+
878 +|-|------------------+ | |
886 +----------------------------------+ |
888 +----------------------------------+
894 ALL_OCCLUSIONTRACKER_TEST(
895 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
897 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
{
899 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
900 : OcclusionTrackerTest(opaque_layers
) {}
901 void RunMyTest() override
{
902 gfx::Transform layer_transform
;
903 layer_transform
.Translate(250.0, 250.0);
904 layer_transform
.Rotate(90.0);
905 layer_transform
.Translate(-250.0, -250.0);
907 TestContentLayerImpl
* parent
= this->CreateRoot(
908 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
909 parent
->SetMasksToBounds(true);
910 TestContentLayerImpl
* blur_layer
= this->CreateDrawingLayer(
911 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
913 TestContentLayerImpl
* opaque_layer
= this->CreateDrawingLayer(
914 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
916 TestContentLayerImpl
* opacity_layer
= this->CreateDrawingLayer(
917 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
920 blur_layer
->SetHasRenderSurface(true);
921 FilterOperations filters
;
922 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
923 blur_layer
->SetFilters(filters
);
925 opaque_layer
->SetHasRenderSurface(true);
927 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
928 opaque_layer
->SetFilters(filters
);
930 opacity_layer
->SetHasRenderSurface(true);
932 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
933 opacity_layer
->SetFilters(filters
);
935 this->CalcDrawEtc(parent
);
937 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
939 // Opacity layer won't contribute to occlusion.
940 this->VisitLayer(opacity_layer
, &occlusion
);
941 this->EnterContributingSurface(opacity_layer
, &occlusion
);
943 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
944 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
946 // And has nothing to contribute to its parent surface.
947 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
948 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
949 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
951 // Opaque layer will contribute to occlusion.
952 this->VisitLayer(opaque_layer
, &occlusion
);
953 this->EnterContributingSurface(opaque_layer
, &occlusion
);
955 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
956 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
957 occlusion
.occlusion_from_inside_target().ToString());
959 // And it gets translated to the parent surface.
960 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
961 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
962 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
963 occlusion
.occlusion_from_inside_target().ToString());
965 // The blur layer needs to throw away any occlusion from outside its
967 this->EnterLayer(blur_layer
, &occlusion
);
968 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
969 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
971 // And it won't contribute to occlusion.
972 this->LeaveLayer(blur_layer
, &occlusion
);
973 this->EnterContributingSurface(blur_layer
, &occlusion
);
974 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
975 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
977 // But the opaque layer's occlusion is preserved on the parent.
978 this->LeaveContributingSurface(blur_layer
, &occlusion
);
979 this->EnterLayer(parent
, &occlusion
);
980 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
981 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
982 occlusion
.occlusion_from_inside_target().ToString());
986 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
988 class OcclusionTrackerTestReplicaDoesOcclude
: public OcclusionTrackerTest
{
990 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
991 : OcclusionTrackerTest(opaque_layers
) {}
992 void RunMyTest() override
{
993 TestContentLayerImpl
* parent
= this->CreateRoot(
994 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
995 LayerImpl
* surface
= this->CreateDrawingSurface(
996 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
997 this->CreateReplicaLayer(
998 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
999 this->CalcDrawEtc(parent
);
1001 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1003 this->VisitLayer(surface
, &occlusion
);
1005 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1006 occlusion
.occlusion_from_inside_target().ToString());
1008 this->VisitContributingSurface(surface
, &occlusion
);
1009 this->EnterLayer(parent
, &occlusion
);
1011 // The surface and replica should both be occluding the parent.
1012 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1013 occlusion
.occlusion_from_inside_target().ToString());
1017 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1019 class OcclusionTrackerTestReplicaWithClipping
: public OcclusionTrackerTest
{
1021 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1022 : OcclusionTrackerTest(opaque_layers
) {}
1023 void RunMyTest() override
{
1024 TestContentLayerImpl
* parent
= this->CreateRoot(
1025 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1026 parent
->SetMasksToBounds(true);
1027 LayerImpl
* surface
= this->CreateDrawingSurface(
1028 parent
, this->identity_matrix
, gfx::PointF(0.f
, 100.f
),
1029 gfx::Size(50, 50), true);
1030 this->CreateReplicaLayer(
1031 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1032 this->CalcDrawEtc(parent
);
1034 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1036 this->VisitLayer(surface
, &occlusion
);
1038 // The surface layer's occlusion in its own space.
1039 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1040 occlusion
.occlusion_from_inside_target().ToString());
1041 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1043 this->VisitContributingSurface(surface
, &occlusion
);
1044 this->EnterLayer(parent
, &occlusion
);
1046 // The surface and replica should both be occluding the parent, the
1047 // replica's occlusion is clipped by the parent.
1048 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1049 occlusion
.occlusion_from_inside_target().ToString());
1050 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1054 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1056 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
{
1058 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1059 : OcclusionTrackerTest(opaque_layers
) {}
1060 void RunMyTest() override
{
1061 TestContentLayerImpl
* parent
= this->CreateRoot(
1062 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1063 LayerImpl
* surface
= this->CreateDrawingSurface(
1064 parent
, this->identity_matrix
, gfx::PointF(0.f
, 100.f
),
1065 gfx::Size(50, 50), true);
1066 LayerImpl
* replica
= this->CreateReplicaLayer(
1067 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1068 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1069 this->CalcDrawEtc(parent
);
1071 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1073 this->VisitLayer(surface
, &occlusion
);
1075 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1076 occlusion
.occlusion_from_inside_target().ToString());
1078 this->VisitContributingSurface(surface
, &occlusion
);
1079 this->EnterLayer(parent
, &occlusion
);
1081 // The replica should not be occluding the parent, since it has a mask
1083 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1084 occlusion
.occlusion_from_inside_target().ToString());
1088 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1090 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1091 : public OcclusionTrackerTest
{
1093 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1094 : OcclusionTrackerTest(opaque_layers
) {}
1095 void RunMyTest() override
{
1096 TestContentLayerImpl
* parent
= this->CreateRoot(
1097 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1098 TestContentLayerImpl
* layer
=
1099 this->CreateDrawingSurface(parent
, this->identity_matrix
, gfx::PointF(),
1100 gfx::Size(200, 200), false);
1101 this->CalcDrawEtc(parent
);
1103 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1104 this->EnterLayer(layer
, &occlusion
);
1106 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1107 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1109 this->LeaveLayer(layer
, &occlusion
);
1110 this->VisitContributingSurface(layer
, &occlusion
);
1111 this->EnterLayer(parent
, &occlusion
);
1113 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1114 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1118 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1120 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1121 : public OcclusionTrackerTest
{
1123 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1124 : OcclusionTrackerTest(opaque_layers
) {}
1125 void RunMyTest() override
{
1126 TestContentLayerImpl
* parent
= this->CreateRoot(
1127 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1128 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
1129 parent
, this->identity_matrix
, gfx::PointF(100.f
, 100.f
),
1130 gfx::Size(200, 200), false);
1131 this->CalcDrawEtc(parent
);
1133 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1134 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1136 this->ResetLayerIterator();
1137 this->VisitLayer(layer
, &occlusion
);
1138 this->EnterLayer(parent
, &occlusion
);
1140 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1141 occlusion
.occlusion_from_inside_target().ToString());
1144 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1145 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1147 this->ResetLayerIterator();
1148 this->VisitLayer(layer
, &occlusion
);
1149 this->EnterLayer(parent
, &occlusion
);
1151 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1152 occlusion
.occlusion_from_inside_target().ToString());
1155 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1156 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1158 this->ResetLayerIterator();
1159 this->VisitLayer(layer
, &occlusion
);
1160 this->EnterLayer(parent
, &occlusion
);
1162 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1163 occlusion
.occlusion_from_inside_target().ToString());
1168 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1170 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1171 : public OcclusionTrackerTest
{
1173 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1175 : OcclusionTrackerTest(opaque_layers
) {}
1176 void RunMyTest() override
{
1177 gfx::Transform transform
;
1178 transform
.Translate(50.0, 50.0);
1179 transform
.ApplyPerspectiveDepth(100.0);
1180 transform
.Translate3d(0.0, 0.0, 110.0);
1181 transform
.Translate(-50.0, -50.0);
1183 TestContentLayerImpl
* parent
= this->CreateRoot(
1184 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1185 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
1186 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
1187 parent
->SetShouldFlattenTransform(false);
1188 parent
->Set3dSortingContextId(1);
1189 layer
->SetShouldFlattenTransform(false);
1190 layer
->Set3dSortingContextId(1);
1191 this->CalcDrawEtc(parent
);
1193 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1195 // The |layer| is entirely behind the camera and should not occlude.
1196 this->VisitLayer(layer
, &occlusion
);
1197 this->EnterLayer(parent
, &occlusion
);
1198 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1199 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1203 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1204 : public OcclusionTrackerTest
{
1206 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1208 : OcclusionTrackerTest(opaque_layers
) {}
1209 void RunMyTest() override
{
1210 gfx::Transform surface_transform
;
1211 surface_transform
.Translate(300.0, 300.0);
1212 surface_transform
.Scale(2.0, 2.0);
1213 surface_transform
.Translate(-150.0, -150.0);
1215 TestContentLayerImpl
* parent
= this->CreateRoot(
1216 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
1217 TestContentLayerImpl
* surface
= this->CreateDrawingSurface(
1218 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
1219 TestContentLayerImpl
* surface2
= this->CreateDrawingSurface(
1220 parent
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
),
1221 gfx::Size(300, 300), false);
1222 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1223 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1224 this->CalcDrawEtc(parent
);
1226 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1228 this->VisitLayer(surface2
, &occlusion
);
1229 this->VisitContributingSurface(surface2
, &occlusion
);
1231 EXPECT_EQ(gfx::Rect().ToString(),
1232 occlusion
.occlusion_from_outside_target().ToString());
1233 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1234 occlusion
.occlusion_from_inside_target().ToString());
1236 // Clear any stored occlusion.
1237 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1238 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1240 this->VisitLayer(surface
, &occlusion
);
1241 this->VisitContributingSurface(surface
, &occlusion
);
1243 EXPECT_EQ(gfx::Rect().ToString(),
1244 occlusion
.occlusion_from_outside_target().ToString());
1245 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1246 occlusion
.occlusion_from_inside_target().ToString());
1250 ALL_OCCLUSIONTRACKER_TEST(
1251 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
1253 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1254 : public OcclusionTrackerTest
{
1256 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
1258 : OcclusionTrackerTest(opaque_layers
) {}
1259 void RunMyTest() override
{
1260 TestContentLayerImpl
* parent
= this->CreateRoot(
1261 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1262 parent
->SetMasksToBounds(true);
1263 TestContentLayerImpl
* surface
=
1264 this->CreateDrawingSurface(parent
, this->identity_matrix
, gfx::PointF(),
1265 gfx::Size(500, 300), false);
1266 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
1267 this->CalcDrawEtc(parent
);
1269 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1271 this->VisitLayer(surface
, &occlusion
);
1272 this->VisitContributingSurface(surface
, &occlusion
);
1274 EXPECT_EQ(gfx::Rect().ToString(),
1275 occlusion
.occlusion_from_outside_target().ToString());
1276 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
1277 occlusion
.occlusion_from_inside_target().ToString());
1281 ALL_OCCLUSIONTRACKER_TEST(
1282 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
1284 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
1285 : public OcclusionTrackerTest
{
1287 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
1288 : OcclusionTrackerTest(opaque_layers
) {}
1289 void RunMyTest() override
{
1290 TestContentLayerImpl
* parent
= this->CreateRoot(
1291 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1292 LayerImpl
* surface
=
1293 this->CreateDrawingSurface(parent
, this->identity_matrix
, gfx::PointF(),
1294 gfx::Size(100, 100), true);
1295 this->CreateReplicaLayer(surface
,
1296 this->identity_matrix
,
1297 gfx::PointF(0.f
, 100.f
),
1298 gfx::Size(100, 100));
1299 LayerImpl
* topmost
=
1300 this->CreateDrawingLayer(parent
, this->identity_matrix
, gfx::PointF(),
1301 gfx::Size(100, 110), true);
1302 this->CalcDrawEtc(parent
);
1304 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1306 // |topmost| occludes the surface, but not the entire surface's replica.
1307 this->VisitLayer(topmost
, &occlusion
);
1309 EXPECT_EQ(gfx::Rect().ToString(),
1310 occlusion
.occlusion_from_outside_target().ToString());
1311 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
1312 occlusion
.occlusion_from_inside_target().ToString());
1314 this->VisitLayer(surface
, &occlusion
);
1316 // Render target with replica ignores occlusion from outside.
1317 EXPECT_EQ(gfx::Rect().ToString(),
1318 occlusion
.occlusion_from_outside_target().ToString());
1319 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
1320 occlusion
.occlusion_from_inside_target().ToString());
1322 this->EnterContributingSurface(surface
, &occlusion
);
1324 // Only occlusion from outside the surface occludes the surface/replica.
1325 EXPECT_EQ(gfx::Rect().ToString(),
1326 occlusion
.occlusion_on_contributing_surface_from_outside_target()
1328 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
1329 occlusion
.occlusion_on_contributing_surface_from_inside_target()
1334 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
1336 class OcclusionTrackerTestSurfaceChildOfSurface
: public OcclusionTrackerTest
{
1338 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
1339 : OcclusionTrackerTest(opaque_layers
) {}
1340 void RunMyTest() override
{
1341 // This test verifies that the surface cliprect does not end up empty and
1342 // clip away the entire unoccluded rect.
1344 TestContentLayerImpl
* parent
= this->CreateRoot(
1345 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1346 LayerImpl
* surface
=
1347 this->CreateDrawingSurface(parent
, this->identity_matrix
, gfx::PointF(),
1348 gfx::Size(100, 100), false);
1349 LayerImpl
* surface_child
= this->CreateDrawingSurface(
1350 surface
, this->identity_matrix
, gfx::PointF(0.f
, 10.f
),
1351 gfx::Size(100, 50), true);
1352 LayerImpl
* topmost
= this->CreateDrawingLayer(
1353 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
1354 this->CalcDrawEtc(parent
);
1356 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(-100, -100, 1000, 1000));
1358 // |topmost| occludes everything partially so we know occlusion is happening
1360 this->VisitLayer(topmost
, &occlusion
);
1362 EXPECT_EQ(gfx::Rect().ToString(),
1363 occlusion
.occlusion_from_outside_target().ToString());
1364 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1365 occlusion
.occlusion_from_inside_target().ToString());
1367 this->VisitLayer(surface_child
, &occlusion
);
1369 // surface_child increases the occlusion in the screen by a narrow sliver.
1370 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
1371 occlusion
.occlusion_from_outside_target().ToString());
1372 // In its own surface, surface_child is at 0,0 as is its occlusion.
1373 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1374 occlusion
.occlusion_from_inside_target().ToString());
1376 // The root layer always has a clip rect. So the parent of |surface| has a
1377 // clip rect. However, the owning layer for |surface| does not mask to
1378 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
1379 // |surface_child| exercises different code paths as its parent does not
1380 // have a clip rect.
1382 this->EnterContributingSurface(surface_child
, &occlusion
);
1383 // The |surface_child| can't occlude its own surface, but occlusion from
1385 EXPECT_EQ(gfx::Rect().ToString(),
1386 occlusion
.occlusion_on_contributing_surface_from_outside_target()
1388 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1389 occlusion
.occlusion_on_contributing_surface_from_inside_target()
1391 this->LeaveContributingSurface(surface_child
, &occlusion
);
1393 // When the surface_child's occlusion is transformed up to its parent, make
1394 // sure it is not clipped away inappropriately.
1395 this->EnterLayer(surface
, &occlusion
);
1396 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1397 occlusion
.occlusion_from_outside_target().ToString());
1398 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
1399 occlusion
.occlusion_from_inside_target().ToString());
1400 this->LeaveLayer(surface
, &occlusion
);
1402 this->EnterContributingSurface(surface
, &occlusion
);
1403 // The occlusion from inside |surface| can't affect the surface, but
1405 EXPECT_EQ(gfx::Rect().ToString(),
1406 occlusion
.occlusion_on_contributing_surface_from_outside_target()
1408 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1409 occlusion
.occlusion_on_contributing_surface_from_inside_target()
1412 this->LeaveContributingSurface(surface
, &occlusion
);
1413 this->EnterLayer(parent
, &occlusion
);
1414 // The occlusion in |surface| and without are merged into the parent.
1415 EXPECT_EQ(gfx::Rect().ToString(),
1416 occlusion
.occlusion_from_outside_target().ToString());
1417 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
1418 occlusion
.occlusion_from_inside_target().ToString());
1422 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
1424 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
1425 : public OcclusionTrackerTest
{
1427 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
1429 : OcclusionTrackerTest(opaque_layers
) {}
1430 void RunMyTest() override
{
1431 gfx::Transform scale_by_half
;
1432 scale_by_half
.Scale(0.5, 0.5);
1434 FilterOperations filters
;
1435 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1437 // Save the distance of influence for the blur effect.
1438 int outset_top
, outset_right
, outset_bottom
, outset_left
;
1440 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
1447 LAST_DIRECTION
= BOTTOM
,
1450 for (int i
= 0; i
<= LAST_DIRECTION
; ++i
) {
1453 // Make a 50x50 filtered surface that is adjacent to occluding layers
1454 // which are above it in the z-order in various configurations. The
1455 // surface is scaled to test that the pixel moving is done in the target
1456 // space, where the background filter is applied.
1457 TestContentLayerImpl
* parent
= this->CreateRoot(
1458 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
1459 LayerImpl
* filtered_surface
= this->CreateDrawingLayer(
1460 parent
, scale_by_half
, gfx::PointF(50.f
, 50.f
), gfx::Size(100, 100),
1462 filtered_surface
->SetHasRenderSurface(true);
1463 filtered_surface
->SetBackgroundFilters(filters
);
1464 gfx::Rect occlusion_rect
;
1467 occlusion_rect
= gfx::Rect(0, 0, 50, 200);
1470 occlusion_rect
= gfx::Rect(100, 0, 50, 200);
1473 occlusion_rect
= gfx::Rect(0, 0, 200, 50);
1476 occlusion_rect
= gfx::Rect(0, 100, 200, 50);
1480 LayerImpl
* occluding_layer
= this->CreateDrawingLayer(
1481 parent
, this->identity_matrix
, occlusion_rect
.origin(),
1482 occlusion_rect
.size(), true);
1483 this->CalcDrawEtc(parent
);
1485 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 200, 200));
1487 // This layer occludes pixels directly beside the filtered_surface.
1488 // Because filtered surface blends pixels in a radius, it will need to see
1489 // some of the pixels (up to radius far) underneath the occluding layers.
1490 this->VisitLayer(occluding_layer
, &occlusion
);
1492 EXPECT_EQ(occlusion_rect
.ToString(),
1493 occlusion
.occlusion_from_inside_target().ToString());
1494 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1496 this->VisitLayer(filtered_surface
, &occlusion
);
1498 // The occlusion is used fully inside the surface.
1499 gfx::Rect occlusion_inside_surface
=
1500 occlusion_rect
- gfx::Vector2d(50, 50);
1501 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1502 EXPECT_EQ(occlusion_inside_surface
.ToString(),
1503 occlusion
.occlusion_from_outside_target().ToString());
1505 // The surface has a background blur, so it needs pixels that are
1506 // currently considered occluded in order to be drawn. So the pixels it
1507 // needs should be removed some the occluded area so that when we get to
1508 // the parent they are drawn.
1509 this->VisitContributingSurface(filtered_surface
, &occlusion
);
1510 this->EnterLayer(parent
, &occlusion
);
1512 gfx::Rect expected_occlusion
= occlusion_rect
;
1515 expected_occlusion
.Inset(0, 0, outset_right
, 0);
1518 expected_occlusion
.Inset(outset_right
, 0, 0, 0);
1521 expected_occlusion
.Inset(0, 0, 0, outset_right
);
1524 expected_occlusion
.Inset(0, outset_right
, 0, 0);
1528 EXPECT_EQ(expected_occlusion
.ToString(),
1529 occlusion
.occlusion_from_inside_target().ToString());
1530 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1532 this->DestroyLayers();
1537 ALL_OCCLUSIONTRACKER_TEST(
1538 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
1540 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
1541 : public OcclusionTrackerTest
{
1543 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
1545 : OcclusionTrackerTest(opaque_layers
) {}
1546 void RunMyTest() override
{
1547 gfx::Transform scale_by_half
;
1548 scale_by_half
.Scale(0.5, 0.5);
1550 // Makes two surfaces that completely cover |parent|. The occlusion both
1551 // above and below the filters will be reduced by each of them.
1552 TestContentLayerImpl
* root
= this->CreateRoot(
1553 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
1554 LayerImpl
* parent
= this->CreateSurface(root
, scale_by_half
, gfx::PointF(),
1555 gfx::Size(150, 150));
1556 parent
->SetMasksToBounds(true);
1557 LayerImpl
* filtered_surface1
= this->CreateDrawingLayer(
1558 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
1559 LayerImpl
* filtered_surface2
= this->CreateDrawingLayer(
1560 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
1561 LayerImpl
* occluding_layer_above
= this->CreateDrawingLayer(
1562 parent
, this->identity_matrix
, gfx::PointF(100.f
, 100.f
),
1563 gfx::Size(50, 50), true);
1565 // Filters make the layers own surfaces.
1566 filtered_surface1
->SetHasRenderSurface(true);
1567 filtered_surface2
->SetHasRenderSurface(true);
1568 FilterOperations filters
;
1569 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
1570 filtered_surface1
->SetBackgroundFilters(filters
);
1571 filtered_surface2
->SetBackgroundFilters(filters
);
1573 // Save the distance of influence for the blur effect.
1574 int outset_top
, outset_right
, outset_bottom
, outset_left
;
1576 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
1578 this->CalcDrawEtc(root
);
1580 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1582 this->VisitLayer(occluding_layer_above
, &occlusion
);
1583 EXPECT_EQ(gfx::Rect().ToString(),
1584 occlusion
.occlusion_from_outside_target().ToString());
1585 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
1586 occlusion
.occlusion_from_inside_target().ToString());
1588 this->VisitLayer(filtered_surface2
, &occlusion
);
1589 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
1590 this->VisitLayer(filtered_surface1
, &occlusion
);
1591 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
1593 // Test expectations in the target.
1594 gfx::Rect expected_occlusion
=
1595 gfx::Rect(100 / 2 + outset_right
* 2,
1596 100 / 2 + outset_bottom
* 2,
1597 50 / 2 - (outset_left
+ outset_right
) * 2,
1598 50 / 2 - (outset_top
+ outset_bottom
) * 2);
1599 EXPECT_EQ(expected_occlusion
.ToString(),
1600 occlusion
.occlusion_from_inside_target().ToString());
1602 // Test expectations in the screen are the same as in the target, as the
1603 // render surface is 1:1 with the screen.
1604 EXPECT_EQ(expected_occlusion
.ToString(),
1605 occlusion
.occlusion_from_outside_target().ToString());
1609 ALL_OCCLUSIONTRACKER_TEST(
1610 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
1612 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
1613 : public OcclusionTrackerTest
{
1615 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
1617 : OcclusionTrackerTest(opaque_layers
) {}
1618 void RunMyTest() override
{
1619 gfx::Transform scale_by_half
;
1620 scale_by_half
.Scale(0.5, 0.5);
1622 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
1623 // centered below each. The surface is scaled to test that the pixel moving
1624 // is done in the target space, where the background filter is applied, but
1625 // the surface appears at 50, 50 and the replica at 200, 50.
1626 TestContentLayerImpl
* parent
= this->CreateRoot(
1627 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
1628 LayerImpl
* behind_surface_layer
= this->CreateDrawingLayer(
1629 parent
, this->identity_matrix
, gfx::PointF(60.f
, 60.f
),
1630 gfx::Size(30, 30), true);
1631 LayerImpl
* behind_replica_layer
= this->CreateDrawingLayer(
1632 parent
, this->identity_matrix
, gfx::PointF(210.f
, 60.f
),
1633 gfx::Size(30, 30), true);
1634 LayerImpl
* filtered_surface
=
1635 this->CreateDrawingLayer(parent
, scale_by_half
, gfx::PointF(50.f
, 50.f
),
1636 gfx::Size(100, 100), false);
1637 this->CreateReplicaLayer(filtered_surface
,
1638 this->identity_matrix
,
1639 gfx::PointF(300.f
, 0.f
),
1642 // Filters make the layer own a surface.
1643 filtered_surface
->SetHasRenderSurface(true);
1644 FilterOperations filters
;
1645 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
1646 filtered_surface
->SetBackgroundFilters(filters
);
1648 this->CalcDrawEtc(parent
);
1650 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1652 // The surface has a background blur, so it blurs non-opaque pixels below
1654 this->VisitLayer(filtered_surface
, &occlusion
);
1655 this->VisitContributingSurface(filtered_surface
, &occlusion
);
1657 this->VisitLayer(behind_replica_layer
, &occlusion
);
1659 // The layers behind the surface are not blurred, and their occlusion does
1660 // not change, until we leave the surface. So it should not be modified by
1662 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
1663 EXPECT_EQ(occlusion_behind_replica
.ToString(),
1664 occlusion
.occlusion_from_inside_target().ToString());
1665 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1667 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
1668 // without existing occlusion interfering.
1669 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1671 this->VisitLayer(behind_surface_layer
, &occlusion
);
1673 // The layers behind the surface are not blurred, and their occlusion does
1674 // not change, until we leave the surface. So it should not be modified by
1676 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
1677 EXPECT_EQ(occlusion_behind_surface
.ToString(),
1678 occlusion
.occlusion_from_inside_target().ToString());
1679 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1683 ALL_OCCLUSIONTRACKER_TEST(
1684 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
1686 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
1687 : public OcclusionTrackerTest
{
1689 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
1691 : OcclusionTrackerTest(opaque_layers
) {}
1692 void RunMyTest() override
{
1693 gfx::Transform scale_by_half
;
1694 scale_by_half
.Scale(0.5, 0.5);
1696 // Make a 50x50 filtered surface that is completely occluded by an opaque
1697 // layer which is above it in the z-order. The surface is
1698 // scaled to test that the pixel moving is done in the target space, where
1699 // the background filter is applied, but the surface appears at 50, 50.
1700 TestContentLayerImpl
* parent
= this->CreateRoot(
1701 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
1702 LayerImpl
* filtered_surface
=
1703 this->CreateDrawingLayer(parent
, scale_by_half
, gfx::PointF(50.f
, 50.f
),
1704 gfx::Size(100, 100), false);
1705 LayerImpl
* occluding_layer
= this->CreateDrawingLayer(
1706 parent
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
),
1707 gfx::Size(50, 50), true);
1709 // Filters make the layer own a surface.
1710 filtered_surface
->SetHasRenderSurface(true);
1711 FilterOperations filters
;
1712 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
1713 filtered_surface
->SetBackgroundFilters(filters
);
1715 this->CalcDrawEtc(parent
);
1717 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1719 this->VisitLayer(occluding_layer
, &occlusion
);
1721 this->VisitLayer(filtered_surface
, &occlusion
);
1723 // The layers above the filtered surface occlude from outside.
1724 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
1726 EXPECT_EQ(gfx::Rect().ToString(),
1727 occlusion
.occlusion_from_inside_target().ToString());
1728 EXPECT_EQ(occlusion_above_surface
.ToString(),
1729 occlusion
.occlusion_from_outside_target().ToString());
1732 // The surface has a background blur, so it blurs non-opaque pixels below
1734 this->VisitContributingSurface(filtered_surface
, &occlusion
);
1736 // The filter is completely occluded, so it should not blur anything and
1737 // reduce any occlusion.
1738 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
1740 EXPECT_EQ(occlusion_above_surface
.ToString(),
1741 occlusion
.occlusion_from_inside_target().ToString());
1742 EXPECT_EQ(gfx::Rect().ToString(),
1743 occlusion
.occlusion_from_outside_target().ToString());
1748 ALL_OCCLUSIONTRACKER_TEST(
1749 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
1751 class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
1752 : public OcclusionTrackerTest
{
1754 explicit OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded(
1756 : OcclusionTrackerTest(opaque_layers
) {}
1757 void RunMyTest() override
{
1758 gfx::Transform scale_by_half
;
1759 scale_by_half
.Scale(0.5, 0.5);
1761 // Make a surface and its replica, each 50x50, that are partially occluded
1762 // by opaque layers which are above them in the z-order. The surface is
1763 // scaled to test that the pixel moving is done in the target space, where
1764 // the background filter is applied, but the surface appears at 50, 50 and
1765 // the replica at 200, 50.
1766 TestContentLayerImpl
* parent
= this->CreateRoot(
1767 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
1768 LayerImpl
* filtered_surface
=
1769 this->CreateDrawingLayer(parent
, scale_by_half
, gfx::PointF(50.f
, 50.f
),
1770 gfx::Size(100, 100), false);
1771 this->CreateReplicaLayer(filtered_surface
,
1772 this->identity_matrix
,
1773 gfx::PointF(300.f
, 0.f
),
1775 LayerImpl
* above_surface_layer
= this->CreateDrawingLayer(
1776 parent
, this->identity_matrix
, gfx::PointF(70.f
, 50.f
),
1777 gfx::Size(30, 50), true);
1778 LayerImpl
* above_replica_layer
= this->CreateDrawingLayer(
1779 parent
, this->identity_matrix
, gfx::PointF(200.f
, 50.f
),
1780 gfx::Size(30, 50), true);
1781 LayerImpl
* beside_surface_layer
= this->CreateDrawingLayer(
1782 parent
, this->identity_matrix
, gfx::PointF(90.f
, 40.f
),
1783 gfx::Size(10, 10), true);
1784 LayerImpl
* beside_replica_layer
= this->CreateDrawingLayer(
1785 parent
, this->identity_matrix
, gfx::PointF(200.f
, 40.f
),
1786 gfx::Size(10, 10), true);
1788 // Filters make the layer own a surface.
1789 filtered_surface
->SetHasRenderSurface(true);
1790 FilterOperations filters
;
1791 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
1792 filtered_surface
->SetBackgroundFilters(filters
);
1794 // Save the distance of influence for the blur effect.
1795 int outset_top
, outset_right
, outset_bottom
, outset_left
;
1797 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
1799 this->CalcDrawEtc(parent
);
1801 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1803 this->VisitLayer(beside_replica_layer
, &occlusion
);
1804 this->VisitLayer(beside_surface_layer
, &occlusion
);
1805 this->VisitLayer(above_replica_layer
, &occlusion
);
1806 this->VisitLayer(above_surface_layer
, &occlusion
);
1808 // The surface has a background blur, so it blurs non-opaque pixels below
1810 this->VisitLayer(filtered_surface
, &occlusion
);
1811 this->VisitContributingSurface(filtered_surface
, &occlusion
);
1813 // The filter in the surface and replica are partially unoccluded. Only the
1814 // unoccluded parts should reduce occlusion. This means it will push back
1815 // the occlusion that touches the unoccluded part (occlusion_above___), but
1816 // it will not touch occlusion_beside____ since that is not beside the
1817 // unoccluded part of the surface, even though it is beside the occluded
1818 // part of the surface.
1819 gfx::Rect occlusion_above_surface
=
1820 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
1821 gfx::Rect occlusion_above_replica
=
1822 gfx::Rect(200, 50, 30 - outset_left
, 50);
1823 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
1824 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
1826 SimpleEnclosedRegion expected_occlusion
;
1827 expected_occlusion
.Union(occlusion_beside_replica
);
1828 expected_occlusion
.Union(occlusion_beside_surface
);
1829 expected_occlusion
.Union(occlusion_above_replica
);
1830 expected_occlusion
.Union(occlusion_above_surface
);
1832 EXPECT_EQ(expected_occlusion
.ToString(),
1833 occlusion
.occlusion_from_inside_target().ToString());
1834 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1836 const SimpleEnclosedRegion
& actual_occlusion
=
1837 occlusion
.occlusion_from_inside_target();
1838 for (size_t i
= 0; i
< expected_occlusion
.GetRegionComplexity(); ++i
) {
1839 ASSERT_LT(i
, actual_occlusion
.GetRegionComplexity());
1840 EXPECT_EQ(expected_occlusion
.GetRect(i
), actual_occlusion
.GetRect(i
));
1845 ALL_OCCLUSIONTRACKER_TEST(
1846 OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
);
1848 class OcclusionTrackerTestBlendModeDoesNotOcclude
1849 : public OcclusionTrackerTest
{
1851 explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers
)
1852 : OcclusionTrackerTest(opaque_layers
) {}
1853 void RunMyTest() override
{
1854 TestContentLayerImpl
* parent
= this->CreateRoot(
1855 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1856 LayerImpl
* blend_mode_layer
= this->CreateDrawingLayer(
1857 parent
, this->identity_matrix
, gfx::PointF(0.f
, 0.f
),
1858 gfx::Size(100, 100), true);
1859 LayerImpl
* top_layer
= this->CreateDrawingLayer(
1860 parent
, this->identity_matrix
, gfx::PointF(10.f
, 12.f
),
1861 gfx::Size(20, 22), true);
1863 // Blend mode makes the layer own a surface.
1864 blend_mode_layer
->SetHasRenderSurface(true);
1865 blend_mode_layer
->SetBlendMode(SkXfermode::kMultiply_Mode
);
1867 this->CalcDrawEtc(parent
);
1869 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1871 this->VisitLayer(top_layer
, &occlusion
);
1872 // |top_layer| occludes.
1873 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1874 occlusion
.occlusion_from_inside_target().ToString());
1875 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1877 this->VisitLayer(blend_mode_layer
, &occlusion
);
1878 // |top_layer| occludes but not |blend_mode_layer|.
1879 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1880 occlusion
.occlusion_from_outside_target().ToString());
1881 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1883 this->VisitContributingSurface(blend_mode_layer
, &occlusion
);
1884 // |top_layer| occludes but not |blend_mode_layer|.
1885 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1886 occlusion
.occlusion_from_inside_target().ToString());
1887 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1891 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude
);
1893 class OcclusionTrackerTestMinimumTrackingSize
: public OcclusionTrackerTest
{
1895 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
1896 : OcclusionTrackerTest(opaque_layers
) {}
1897 void RunMyTest() override
{
1898 gfx::Size
tracking_size(100, 100);
1899 gfx::Size
below_tracking_size(99, 99);
1901 TestContentLayerImpl
* parent
= this->CreateRoot(
1902 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
1903 LayerImpl
* large
= this->CreateDrawingLayer(
1904 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
1906 this->CreateDrawingLayer(parent
, this->identity_matrix
, gfx::PointF(),
1907 below_tracking_size
, true);
1908 this->CalcDrawEtc(parent
);
1910 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1911 occlusion
.set_minimum_tracking_size(tracking_size
);
1913 // The small layer is not tracked because it is too small.
1914 this->VisitLayer(small
, &occlusion
);
1916 EXPECT_EQ(gfx::Rect().ToString(),
1917 occlusion
.occlusion_from_outside_target().ToString());
1918 EXPECT_EQ(gfx::Rect().ToString(),
1919 occlusion
.occlusion_from_inside_target().ToString());
1921 // The large layer is tracked as it is large enough.
1922 this->VisitLayer(large
, &occlusion
);
1924 EXPECT_EQ(gfx::Rect().ToString(),
1925 occlusion
.occlusion_from_outside_target().ToString());
1926 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
1927 occlusion
.occlusion_from_inside_target().ToString());
1931 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
1933 class OcclusionTrackerTestScaledLayerIsClipped
: public OcclusionTrackerTest
{
1935 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
1936 : OcclusionTrackerTest(opaque_layers
) {}
1937 void RunMyTest() override
{
1938 gfx::Transform scale_transform
;
1939 scale_transform
.Scale(512.0, 512.0);
1941 TestContentLayerImpl
* parent
= this->CreateRoot(
1942 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
1944 this->CreateLayer(parent
, this->identity_matrix
,
1945 gfx::PointF(10.f
, 10.f
), gfx::Size(50, 50));
1946 clip
->SetMasksToBounds(true);
1947 LayerImpl
* scale
= this->CreateLayer(clip
, scale_transform
, gfx::PointF(),
1949 LayerImpl
* scaled
= this->CreateDrawingLayer(
1950 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
1951 this->CalcDrawEtc(parent
);
1953 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1955 this->VisitLayer(scaled
, &occlusion
);
1957 EXPECT_EQ(gfx::Rect().ToString(),
1958 occlusion
.occlusion_from_outside_target().ToString());
1959 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
1960 occlusion
.occlusion_from_inside_target().ToString());
1964 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
1966 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
1967 : public OcclusionTrackerTest
{
1969 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
1970 : OcclusionTrackerTest(opaque_layers
) {}
1971 void RunMyTest() override
{
1972 gfx::Transform scale_transform
;
1973 scale_transform
.Scale(512.0, 512.0);
1975 TestContentLayerImpl
* parent
= this->CreateRoot(
1976 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
1978 this->CreateLayer(parent
, this->identity_matrix
,
1979 gfx::PointF(10.f
, 10.f
), gfx::Size(50, 50));
1980 clip
->SetMasksToBounds(true);
1981 LayerImpl
* surface
= this->CreateDrawingSurface(
1982 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
1983 LayerImpl
* scale
= this->CreateLayer(surface
, scale_transform
,
1984 gfx::PointF(), gfx::Size(1, 1));
1985 LayerImpl
* scaled
= this->CreateDrawingLayer(
1986 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
1987 this->CalcDrawEtc(parent
);
1989 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1991 this->VisitLayer(scaled
, &occlusion
);
1992 this->VisitLayer(surface
, &occlusion
);
1993 this->VisitContributingSurface(surface
, &occlusion
);
1995 EXPECT_EQ(gfx::Rect().ToString(),
1996 occlusion
.occlusion_from_outside_target().ToString());
1997 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
1998 occlusion
.occlusion_from_inside_target().ToString());
2002 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
2004 class OcclusionTrackerTestCopyRequestDoesOcclude
: public OcclusionTrackerTest
{
2006 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
2007 : OcclusionTrackerTest(opaque_layers
) {}
2008 void RunMyTest() override
{
2009 TestContentLayerImpl
* root
= this->CreateRoot(
2010 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2011 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
2012 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2013 LayerImpl
* copy
= this->CreateLayer(
2014 parent
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
2015 this->AddCopyRequest(copy
);
2016 LayerImpl
* copy_child
= this->CreateDrawingLayer(
2017 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
2018 LayerImpl
* top_layer
=
2019 this->CreateDrawingLayer(root
, this->identity_matrix
,
2020 gfx::PointF(50, 0), gfx::Size(50, 400), true);
2021 this->CalcDrawEtc(root
);
2023 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
2025 this->VisitLayer(top_layer
, &occlusion
);
2026 EXPECT_EQ(gfx::Rect().ToString(),
2027 occlusion
.occlusion_from_outside_target().ToString());
2028 EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(),
2029 occlusion
.occlusion_from_inside_target().ToString());
2031 this->VisitLayer(copy_child
, &occlusion
);
2032 // Layers outside the copy request do not occlude.
2033 EXPECT_EQ(gfx::Rect().ToString(),
2034 occlusion
.occlusion_from_outside_target().ToString());
2035 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2036 occlusion
.occlusion_from_inside_target().ToString());
2038 // CopyRequests cause the layer to own a surface.
2039 this->VisitContributingSurface(copy
, &occlusion
);
2041 // The occlusion from the copy should be kept.
2042 EXPECT_EQ(gfx::Rect().ToString(),
2043 occlusion
.occlusion_from_outside_target().ToString());
2044 EXPECT_EQ(gfx::Rect(50, 0, 250, 400).ToString(),
2045 occlusion
.occlusion_from_inside_target().ToString());
2049 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
2051 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2052 : public OcclusionTrackerTest
{
2054 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2056 : OcclusionTrackerTest(opaque_layers
) {}
2057 void RunMyTest() override
{
2058 TestContentLayerImpl
* root
= this->CreateRoot(
2059 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2060 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
2061 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2062 LayerImpl
* hide
= this->CreateLayer(parent
, this->identity_matrix
,
2063 gfx::Point(), gfx::Size());
2064 LayerImpl
* copy
= this->CreateLayer(
2065 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
2066 this->AddCopyRequest(copy
);
2067 LayerImpl
* copy_child
= this->CreateDrawingLayer(
2068 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
2070 // The |copy| layer is hidden but since it is being copied, it will be
2072 hide
->SetHideLayerAndSubtree(true);
2074 this->CalcDrawEtc(root
);
2076 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
2078 this->VisitLayer(copy_child
, &occlusion
);
2079 EXPECT_EQ(gfx::Rect().ToString(),
2080 occlusion
.occlusion_from_outside_target().ToString());
2081 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2082 occlusion
.occlusion_from_inside_target().ToString());
2084 // CopyRequests cause the layer to own a surface.
2085 this->VisitContributingSurface(copy
, &occlusion
);
2087 // The occlusion from the copy should be dropped since it is hidden.
2088 EXPECT_EQ(gfx::Rect().ToString(),
2089 occlusion
.occlusion_from_outside_target().ToString());
2090 EXPECT_EQ(gfx::Rect().ToString(),
2091 occlusion
.occlusion_from_inside_target().ToString());
2095 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
2097 class OcclusionTrackerTestOccludedLayer
: public OcclusionTrackerTest
{
2099 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers
)
2100 : OcclusionTrackerTest(opaque_layers
) {}
2101 void RunMyTest() override
{
2102 gfx::Transform translate
;
2103 translate
.Translate(10.0, 20.0);
2104 TestContentLayerImpl
* root
= this->CreateRoot(
2105 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2106 LayerImpl
* surface
= this->CreateSurface(root
, this->identity_matrix
,
2107 gfx::Point(), gfx::Size(200, 200));
2108 LayerImpl
* layer
= this->CreateDrawingLayer(
2109 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2110 TestContentLayerImpl
* outside_layer
= this->CreateDrawingLayer(
2111 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2112 this->CalcDrawEtc(root
);
2114 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 200, 200));
2115 this->VisitLayer(outside_layer
, &occlusion
);
2116 this->EnterLayer(layer
, &occlusion
);
2118 // No occlusion, is not occluded.
2119 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2120 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2121 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100)));
2123 // Partial occlusion from outside, is not occluded.
2124 occlusion
.set_occlusion_from_outside_target(
2125 SimpleEnclosedRegion(50, 50, 100, 100));
2126 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2127 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2128 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2129 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2130 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2131 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2132 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2133 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2134 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2136 // Full occlusion from outside, is occluded.
2137 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2138 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2139 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2140 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2142 // Partial occlusion from inside, is not occluded.
2143 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2144 occlusion
.set_occlusion_from_inside_target(
2145 SimpleEnclosedRegion(50, 50, 100, 100));
2146 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2147 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2148 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2149 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2150 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2151 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2152 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2153 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2155 // Full occlusion from inside, is occluded.
2156 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2157 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2158 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2159 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2161 // Partial occlusion from both, is not occluded.
2162 occlusion
.set_occlusion_from_outside_target(
2163 SimpleEnclosedRegion(50, 50, 100, 50));
2164 occlusion
.set_occlusion_from_inside_target(
2165 SimpleEnclosedRegion(50, 100, 100, 50));
2166 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2167 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2168 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2169 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2170 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2171 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2172 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2173 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2175 // Full occlusion from both, is occluded.
2176 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2177 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2178 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2179 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2183 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer
)
2185 class OcclusionTrackerTestUnoccludedLayerQuery
: public OcclusionTrackerTest
{
2187 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers
)
2188 : OcclusionTrackerTest(opaque_layers
) {}
2189 void RunMyTest() override
{
2190 gfx::Transform translate
;
2191 translate
.Translate(10.0, 20.0);
2192 TestContentLayerImpl
* root
= this->CreateRoot(
2193 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2194 LayerImpl
* surface
= this->CreateSurface(root
, this->identity_matrix
,
2195 gfx::Point(), gfx::Size(200, 200));
2196 LayerImpl
* layer
= this->CreateDrawingLayer(
2197 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2198 TestContentLayerImpl
* outside_layer
= this->CreateDrawingLayer(
2199 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2200 this->CalcDrawEtc(root
);
2202 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 200, 200));
2203 this->VisitLayer(outside_layer
, &occlusion
);
2204 this->EnterLayer(layer
, &occlusion
);
2206 // No occlusion, is not occluded.
2207 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2208 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2209 EXPECT_EQ(gfx::Rect(100, 100),
2210 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(100, 100)));
2212 // Partial occlusion from outside.
2213 occlusion
.set_occlusion_from_outside_target(
2214 SimpleEnclosedRegion(50, 50, 100, 100));
2215 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2217 gfx::Rect(0, 0, 100, 100),
2218 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
2219 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2220 occlusion
.UnoccludedLayerContentRect(
2221 layer
, gfx::Rect(90, 30, 100, 100)));
2222 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2223 occlusion
.UnoccludedLayerContentRect(layer
,
2224 gfx::Rect(40, 0, 100, 100)));
2225 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2226 occlusion
.UnoccludedLayerContentRect(
2227 layer
, gfx::Rect(40, 80, 100, 100)));
2229 gfx::Rect(0, 0, 80, 100),
2230 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
2231 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2232 occlusion
.UnoccludedLayerContentRect(
2233 layer
, gfx::Rect(90, 80, 100, 100)));
2234 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2235 occlusion
.UnoccludedLayerContentRect(layer
,
2236 gfx::Rect(0, 80, 100, 100)));
2237 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2238 occlusion
.UnoccludedLayerContentRect(layer
,
2239 gfx::Rect(90, 0, 100, 100)));
2241 // Full occlusion from outside, is occluded.
2242 EXPECT_EQ(gfx::Rect(),
2243 occlusion
.UnoccludedLayerContentRect(
2244 layer
, gfx::Rect(40, 30, 100, 100)));
2247 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
2248 EXPECT_EQ(gfx::Rect(),
2249 occlusion
.UnoccludedLayerContentRect(
2250 layer
, gfx::Rect(130, 120, 10, 10)));
2253 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
2255 // Partial occlusion from inside, is not occluded.
2256 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2257 occlusion
.set_occlusion_from_inside_target(
2258 SimpleEnclosedRegion(50, 50, 100, 100));
2260 gfx::Rect(0, 0, 100, 100),
2261 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
2262 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2263 occlusion
.UnoccludedLayerContentRect(
2264 layer
, gfx::Rect(90, 30, 100, 100)));
2265 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2266 occlusion
.UnoccludedLayerContentRect(layer
,
2267 gfx::Rect(40, 0, 100, 100)));
2268 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2269 occlusion
.UnoccludedLayerContentRect(
2270 layer
, gfx::Rect(40, 80, 100, 100)));
2272 gfx::Rect(0, 0, 80, 100),
2273 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
2274 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2275 occlusion
.UnoccludedLayerContentRect(
2276 layer
, gfx::Rect(90, 80, 100, 100)));
2277 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2278 occlusion
.UnoccludedLayerContentRect(layer
,
2279 gfx::Rect(0, 80, 100, 100)));
2280 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2281 occlusion
.UnoccludedLayerContentRect(layer
,
2282 gfx::Rect(90, 0, 100, 100)));
2284 // Full occlusion from inside, is occluded.
2285 EXPECT_EQ(gfx::Rect(),
2286 occlusion
.UnoccludedLayerContentRect(
2287 layer
, gfx::Rect(40, 30, 100, 100)));
2290 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
2291 EXPECT_EQ(gfx::Rect(),
2292 occlusion
.UnoccludedLayerContentRect(
2293 layer
, gfx::Rect(130, 120, 10, 10)));
2296 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
2298 // Partial occlusion from both, is not occluded.
2299 occlusion
.set_occlusion_from_outside_target(
2300 SimpleEnclosedRegion(50, 50, 100, 50));
2301 occlusion
.set_occlusion_from_inside_target(
2302 SimpleEnclosedRegion(50, 100, 100, 50));
2304 gfx::Rect(0, 0, 100, 100),
2305 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
2306 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
2308 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
2309 occlusion
.UnoccludedLayerContentRect(
2310 layer
, gfx::Rect(90, 30, 100, 100)));
2311 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2312 occlusion
.UnoccludedLayerContentRect(layer
,
2313 gfx::Rect(40, 0, 100, 100)));
2314 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2315 occlusion
.UnoccludedLayerContentRect(
2316 layer
, gfx::Rect(40, 80, 100, 100)));
2318 gfx::Rect(0, 0, 80, 100),
2319 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
2320 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2321 occlusion
.UnoccludedLayerContentRect(
2322 layer
, gfx::Rect(90, 80, 100, 100)));
2323 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2324 occlusion
.UnoccludedLayerContentRect(layer
,
2325 gfx::Rect(0, 80, 100, 100)));
2326 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2327 occlusion
.UnoccludedLayerContentRect(layer
,
2328 gfx::Rect(90, 0, 100, 100)));
2330 // Full occlusion from both, is occluded.
2331 EXPECT_EQ(gfx::Rect(),
2332 occlusion
.UnoccludedLayerContentRect(
2333 layer
, gfx::Rect(40, 30, 100, 100)));
2336 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
2337 EXPECT_EQ(gfx::Rect(),
2338 occlusion
.UnoccludedLayerContentRect(
2339 layer
, gfx::Rect(130, 120, 10, 10)));
2342 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
2346 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery
)
2348 class OcclusionTrackerTestUnoccludedSurfaceQuery
: public OcclusionTrackerTest
{
2350 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers
)
2351 : OcclusionTrackerTest(opaque_layers
) {}
2352 void RunMyTest() override
{
2353 gfx::Transform translate
;
2354 translate
.Translate(10.0, 20.0);
2355 TestContentLayerImpl
* root
= this->CreateRoot(
2356 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2357 LayerImpl
* surface
=
2358 this->CreateSurface(root
, translate
, gfx::Point(), gfx::Size(200, 200));
2360 this->CreateDrawingLayer(surface
, this->identity_matrix
, gfx::Point(),
2361 gfx::Size(200, 200), false);
2362 TestContentLayerImpl
* outside_layer
= this->CreateDrawingLayer(
2363 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2364 this->CalcDrawEtc(root
);
2366 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 200, 200));
2367 this->VisitLayer(outside_layer
, &occlusion
);
2368 this->VisitLayer(layer
, &occlusion
);
2369 this->EnterContributingSurface(surface
, &occlusion
);
2371 // No occlusion, is not occluded.
2372 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
2373 SimpleEnclosedRegion());
2374 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
2375 SimpleEnclosedRegion());
2377 gfx::Rect(100, 100),
2378 occlusion
.UnoccludedSurfaceContentRect(surface
, gfx::Rect(100, 100)));
2380 // Partial occlusion from outside.
2381 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
2382 SimpleEnclosedRegion(50, 50, 100, 100));
2383 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
2384 SimpleEnclosedRegion());
2385 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2386 occlusion
.UnoccludedSurfaceContentRect(
2387 surface
, gfx::Rect(0, 0, 100, 100)));
2388 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2389 occlusion
.UnoccludedSurfaceContentRect(
2390 surface
, gfx::Rect(90, 30, 100, 100)));
2391 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2392 occlusion
.UnoccludedSurfaceContentRect(
2393 surface
, gfx::Rect(40, 0, 100, 100)));
2394 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2395 occlusion
.UnoccludedSurfaceContentRect(
2396 surface
, gfx::Rect(40, 80, 100, 100)));
2397 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2398 occlusion
.UnoccludedSurfaceContentRect(surface
,
2399 gfx::Rect(0, 0, 80, 100)));
2400 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2401 occlusion
.UnoccludedSurfaceContentRect(
2402 surface
, gfx::Rect(90, 80, 100, 100)));
2403 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2404 occlusion
.UnoccludedSurfaceContentRect(
2405 surface
, gfx::Rect(0, 80, 100, 100)));
2406 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2407 occlusion
.UnoccludedSurfaceContentRect(
2408 surface
, gfx::Rect(90, 0, 100, 100)));
2410 // Full occlusion from outside, is occluded.
2411 EXPECT_EQ(gfx::Rect(),
2412 occlusion
.UnoccludedSurfaceContentRect(
2413 surface
, gfx::Rect(40, 30, 100, 100)));
2414 EXPECT_EQ(gfx::Rect(),
2415 occlusion
.UnoccludedSurfaceContentRect(
2416 surface
, gfx::Rect(40, 30, 10, 10)));
2417 EXPECT_EQ(gfx::Rect(),
2418 occlusion
.UnoccludedSurfaceContentRect(
2419 surface
, gfx::Rect(130, 120, 10, 10)));
2420 EXPECT_EQ(gfx::Rect(),
2421 occlusion
.UnoccludedSurfaceContentRect(
2422 surface
, gfx::Rect(80, 70, 50, 50)));
2424 // Partial occlusion from inside, is not occluded.
2425 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
2426 SimpleEnclosedRegion());
2427 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
2428 SimpleEnclosedRegion(50, 50, 100, 100));
2429 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2430 occlusion
.UnoccludedSurfaceContentRect(
2431 surface
, gfx::Rect(0, 0, 100, 100)));
2432 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2433 occlusion
.UnoccludedSurfaceContentRect(
2434 surface
, gfx::Rect(90, 30, 100, 100)));
2435 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2436 occlusion
.UnoccludedSurfaceContentRect(
2437 surface
, gfx::Rect(40, 0, 100, 100)));
2438 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2439 occlusion
.UnoccludedSurfaceContentRect(
2440 surface
, gfx::Rect(40, 80, 100, 100)));
2441 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2442 occlusion
.UnoccludedSurfaceContentRect(surface
,
2443 gfx::Rect(0, 0, 80, 100)));
2444 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2445 occlusion
.UnoccludedSurfaceContentRect(
2446 surface
, gfx::Rect(90, 80, 100, 100)));
2447 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2448 occlusion
.UnoccludedSurfaceContentRect(
2449 surface
, gfx::Rect(0, 80, 100, 100)));
2450 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2451 occlusion
.UnoccludedSurfaceContentRect(
2452 surface
, gfx::Rect(90, 0, 100, 100)));
2454 // Full occlusion from inside, is occluded.
2455 EXPECT_EQ(gfx::Rect(),
2456 occlusion
.UnoccludedSurfaceContentRect(
2457 surface
, gfx::Rect(40, 30, 100, 100)));
2458 EXPECT_EQ(gfx::Rect(),
2459 occlusion
.UnoccludedSurfaceContentRect(
2460 surface
, gfx::Rect(40, 30, 10, 10)));
2461 EXPECT_EQ(gfx::Rect(),
2462 occlusion
.UnoccludedSurfaceContentRect(
2463 surface
, gfx::Rect(130, 120, 10, 10)));
2464 EXPECT_EQ(gfx::Rect(),
2465 occlusion
.UnoccludedSurfaceContentRect(
2466 surface
, gfx::Rect(80, 70, 50, 50)));
2468 // Partial occlusion from both, is not occluded.
2469 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
2470 SimpleEnclosedRegion(50, 50, 100, 50));
2471 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
2472 SimpleEnclosedRegion(50, 100, 100, 50));
2473 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2474 occlusion
.UnoccludedSurfaceContentRect(
2475 surface
, gfx::Rect(0, 0, 100, 100)));
2476 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
2478 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
2479 occlusion
.UnoccludedSurfaceContentRect(
2480 surface
, gfx::Rect(90, 30, 100, 100)));
2481 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2482 occlusion
.UnoccludedSurfaceContentRect(
2483 surface
, gfx::Rect(40, 0, 100, 100)));
2484 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2485 occlusion
.UnoccludedSurfaceContentRect(
2486 surface
, gfx::Rect(40, 80, 100, 100)));
2487 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2488 occlusion
.UnoccludedSurfaceContentRect(surface
,
2489 gfx::Rect(0, 0, 80, 100)));
2490 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2491 occlusion
.UnoccludedSurfaceContentRect(
2492 surface
, gfx::Rect(90, 80, 100, 100)));
2493 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2494 occlusion
.UnoccludedSurfaceContentRect(
2495 surface
, gfx::Rect(0, 80, 100, 100)));
2496 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2497 occlusion
.UnoccludedSurfaceContentRect(
2498 surface
, gfx::Rect(90, 0, 100, 100)));
2500 // Full occlusion from both, is occluded.
2501 EXPECT_EQ(gfx::Rect(),
2502 occlusion
.UnoccludedSurfaceContentRect(
2503 surface
, gfx::Rect(40, 30, 100, 100)));
2504 EXPECT_EQ(gfx::Rect(),
2505 occlusion
.UnoccludedSurfaceContentRect(
2506 surface
, gfx::Rect(40, 30, 10, 10)));
2507 EXPECT_EQ(gfx::Rect(),
2508 occlusion
.UnoccludedSurfaceContentRect(
2509 surface
, gfx::Rect(130, 120, 10, 10)));
2510 EXPECT_EQ(gfx::Rect(),
2511 occlusion
.UnoccludedSurfaceContentRect(
2512 surface
, gfx::Rect(80, 70, 50, 50)));
2516 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery
)