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_impl_
.clear();
199 replica_layers_
.clear();
200 mask_layers_
.clear();
201 ResetLayerIterator();
204 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
206 void AddCopyRequest(Layer
* layer
) {
207 layer
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
208 base::Bind(&OcclusionTrackerTest::CopyOutputCallback
,
209 base::Unretained(this))));
212 void AddCopyRequest(LayerImpl
* layer
) {
213 ScopedPtrVector
<CopyOutputRequest
> requests
;
214 requests
.push_back(CopyOutputRequest::CreateBitmapRequest(base::Bind(
215 &OcclusionTrackerTest::CopyOutputCallback
, base::Unretained(this))));
216 layer
->SetHasRenderSurface(true);
217 layer
->PassCopyRequests(&requests
);
220 void CalcDrawEtc(TestContentLayerImpl
* root
) {
221 DCHECK(root
== root_
.get());
223 // These occlusion tests attach and detach layers in multiple
224 // iterations, so rebuild property trees every time.
225 root
->layer_tree_impl()->property_trees()->needs_rebuild
= true;
227 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root
);
229 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
230 root
, root
->bounds(), &render_surface_layer_list_impl_
);
231 inputs
.can_adjust_raster_scales
= true;
232 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
234 layer_iterator_
= layer_iterator_begin_
=
235 LayerIterator::Begin(&render_surface_layer_list_impl_
);
238 void EnterLayer(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
239 ASSERT_EQ(*layer_iterator_
, layer
);
240 ASSERT_TRUE(layer_iterator_
.represents_itself());
241 occlusion
->EnterLayer(layer_iterator_
);
244 void LeaveLayer(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
245 ASSERT_EQ(*layer_iterator_
, layer
);
246 ASSERT_TRUE(layer_iterator_
.represents_itself());
247 occlusion
->LeaveLayer(layer_iterator_
);
251 void VisitLayer(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
252 EnterLayer(layer
, occlusion
);
253 LeaveLayer(layer
, occlusion
);
256 void EnterContributingSurface(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
257 ASSERT_EQ(*layer_iterator_
, layer
);
258 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
259 occlusion
->EnterLayer(layer_iterator_
);
260 occlusion
->LeaveLayer(layer_iterator_
);
262 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
263 occlusion
->EnterLayer(layer_iterator_
);
266 void LeaveContributingSurface(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
267 ASSERT_EQ(*layer_iterator_
, layer
);
268 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
269 occlusion
->LeaveLayer(layer_iterator_
);
273 void VisitContributingSurface(LayerImpl
* layer
, OcclusionTracker
* occlusion
) {
274 EnterContributingSurface(layer
, occlusion
);
275 LeaveContributingSurface(layer
, occlusion
);
278 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
280 const gfx::Transform identity_matrix
;
283 void SetRootLayerOnMainThread(Layer
* root
) {
284 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
287 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
289 void SetProperties(LayerImpl
* layer
,
290 const gfx::Transform
& transform
,
291 const gfx::PointF
& position
,
292 const gfx::Size
& bounds
) {
293 layer
->SetTransform(transform
);
294 layer
->SetPosition(position
);
295 layer
->SetBounds(bounds
);
298 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
299 owning_layer
->SetReplicaLayer(layer
.Pass());
302 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
303 owning_layer
->SetMaskLayer(layer
.Pass());
307 FakeLayerTreeHostClient client_
;
308 TestTaskGraphRunner task_graph_runner_
;
309 scoped_ptr
<FakeLayerTreeHost
> host_
;
310 // These hold ownership of the layers for the duration of the test.
311 scoped_ptr
<LayerImpl
> root_
;
312 LayerImplList render_surface_layer_list_impl_
;
313 LayerIterator layer_iterator_begin_
;
314 LayerIterator layer_iterator_
;
315 LayerList replica_layers_
;
316 LayerList mask_layers_
;
317 int next_layer_impl_id_
;
320 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
321 class ClassName##ImplThreadOpaqueLayers : public ClassName { \
322 public: /* NOLINT(whitespace/indent) */ \
323 ClassName##ImplThreadOpaqueLayers() : ClassName(true) {} \
325 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
326 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
327 class ClassName##ImplThreadOpaquePaints : public ClassName { \
328 public: /* NOLINT(whitespace/indent) */ \
329 ClassName##ImplThreadOpaquePaints() : ClassName(false) {} \
331 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
333 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
334 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
335 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
337 class OcclusionTrackerTestIdentityTransforms
: public OcclusionTrackerTest
{
339 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
340 : OcclusionTrackerTest(opaque_layers
) {}
342 void RunMyTest() override
{
343 TestContentLayerImpl
* root
= this->CreateRoot(
344 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
345 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
346 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
347 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
348 parent
, this->identity_matrix
, gfx::PointF(30.f
, 30.f
),
349 gfx::Size(500, 500), true);
350 parent
->SetMasksToBounds(true);
351 this->CalcDrawEtc(root
);
353 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
355 this->VisitLayer(layer
, &occlusion
);
356 this->EnterLayer(parent
, &occlusion
);
358 EXPECT_EQ(gfx::Rect().ToString(),
359 occlusion
.occlusion_from_outside_target().ToString());
360 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
361 occlusion
.occlusion_from_inside_target().ToString());
365 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
367 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
{
369 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
370 : OcclusionTrackerTest(opaque_layers
) {}
371 void RunMyTest() override
{
372 gfx::Transform layer_transform
;
373 layer_transform
.Translate(250.0, 250.0);
374 layer_transform
.Rotate(90.0);
375 layer_transform
.Translate(-250.0, -250.0);
377 TestContentLayerImpl
* root
= this->CreateRoot(
378 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
379 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
380 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
381 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
382 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
384 parent
->SetMasksToBounds(true);
385 this->CalcDrawEtc(root
);
387 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
389 this->VisitLayer(layer
, &occlusion
);
390 this->EnterLayer(parent
, &occlusion
);
392 EXPECT_EQ(gfx::Rect().ToString(),
393 occlusion
.occlusion_from_outside_target().ToString());
394 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
395 occlusion
.occlusion_from_inside_target().ToString());
399 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
401 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
{
403 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
404 : OcclusionTrackerTest(opaque_layers
) {}
405 void RunMyTest() override
{
406 gfx::Transform layer_transform
;
407 layer_transform
.Translate(20.0, 20.0);
409 TestContentLayerImpl
* root
= this->CreateRoot(
410 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
411 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
412 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
413 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
414 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
416 parent
->SetMasksToBounds(true);
417 this->CalcDrawEtc(root
);
419 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
421 this->VisitLayer(layer
, &occlusion
);
422 this->EnterLayer(parent
, &occlusion
);
424 EXPECT_EQ(gfx::Rect().ToString(),
425 occlusion
.occlusion_from_outside_target().ToString());
426 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
427 occlusion
.occlusion_from_inside_target().ToString());
431 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
433 class OcclusionTrackerTestChildInRotatedChild
: public OcclusionTrackerTest
{
435 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
436 : OcclusionTrackerTest(opaque_layers
) {}
437 void RunMyTest() override
{
438 gfx::Transform child_transform
;
439 child_transform
.Translate(250.0, 250.0);
440 child_transform
.Rotate(90.0);
441 child_transform
.Translate(-250.0, -250.0);
443 TestContentLayerImpl
* parent
= this->CreateRoot(
444 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
445 parent
->SetMasksToBounds(true);
446 LayerImpl
* child
= this->CreateSurface(
447 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
448 child
->SetMasksToBounds(true);
449 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
450 child
, this->identity_matrix
, gfx::PointF(10.f
, 10.f
),
451 gfx::Size(500, 500), true);
452 this->CalcDrawEtc(parent
);
454 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
456 this->VisitLayer(layer
, &occlusion
);
457 this->EnterContributingSurface(child
, &occlusion
);
459 EXPECT_EQ(gfx::Rect().ToString(),
460 occlusion
.occlusion_from_outside_target().ToString());
461 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
462 occlusion
.occlusion_from_inside_target().ToString());
464 this->LeaveContributingSurface(child
, &occlusion
);
465 this->EnterLayer(parent
, &occlusion
);
467 EXPECT_EQ(gfx::Rect().ToString(),
468 occlusion
.occlusion_from_outside_target().ToString());
469 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
470 occlusion
.occlusion_from_inside_target().ToString());
472 /* Justification for the above occlusion from |layer|:
474 +---------------------+
477 | 30 + ---------------------------------+
479 | |10+---------------------------------+
483 +----|--|-------------+ | |
491 +--|-------------------------------+ |
493 +---------------------------------+
496 +---------------------+
497 | |30 Visible region of |layer|: /////
499 | +---------------------------------+
501 | +---------------------------------+ |
502 | | |///////////////| 420 | |
503 | | |///////////////|60 | |
504 | | |///////////////| | |
505 +--|--|---------------+ | |
513 | +------------------------------|--+
515 +---------------------------------+
522 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
524 class OcclusionTrackerTestScaledRenderSurface
: public OcclusionTrackerTest
{
526 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
527 : OcclusionTrackerTest(opaque_layers
) {}
529 void RunMyTest() override
{
530 TestContentLayerImpl
* parent
= this->CreateRoot(
531 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
533 gfx::Transform layer1_matrix
;
534 layer1_matrix
.Scale(2.0, 2.0);
535 TestContentLayerImpl
* layer1
= this->CreateDrawingLayer(
536 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
537 layer1
->SetHasRenderSurface(true);
539 gfx::Transform layer2_matrix
;
540 layer2_matrix
.Translate(25.0, 25.0);
541 TestContentLayerImpl
* layer2
= this->CreateDrawingLayer(
542 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
543 TestContentLayerImpl
* occluder
= this->CreateDrawingLayer(
544 parent
, this->identity_matrix
, gfx::PointF(100.f
, 100.f
),
545 gfx::Size(500, 500), true);
546 this->CalcDrawEtc(parent
);
548 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
550 this->VisitLayer(occluder
, &occlusion
);
551 this->EnterLayer(layer2
, &occlusion
);
553 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
554 occlusion
.occlusion_from_outside_target().ToString());
555 EXPECT_EQ(gfx::Rect().ToString(),
556 occlusion
.occlusion_from_inside_target().ToString());
560 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
562 class OcclusionTrackerTestVisitTargetTwoTimes
: public OcclusionTrackerTest
{
564 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
565 : OcclusionTrackerTest(opaque_layers
) {}
566 void RunMyTest() override
{
567 TestContentLayerImpl
* root
= this->CreateRoot(
568 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
569 LayerImpl
* surface
= this->CreateSurface(
570 root
, this->identity_matrix
, gfx::PointF(30.f
, 30.f
), gfx::Size());
571 TestContentLayerImpl
* surface_child
= this->CreateDrawingLayer(
572 surface
, this->identity_matrix
, gfx::PointF(10.f
, 10.f
),
573 gfx::Size(50, 50), true);
574 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
575 // first, instead of |surface|'s. This exercises different code in
576 // LeaveToRenderTarget, as the target surface has already been seen when
577 // leaving |surface| later.
578 TestContentLayerImpl
* top_layer
= this->CreateDrawingLayer(
579 root
, this->identity_matrix
, gfx::PointF(40.f
, 90.f
), gfx::Size(50, 20),
581 this->CalcDrawEtc(root
);
583 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
585 this->VisitLayer(top_layer
, &occlusion
);
587 EXPECT_EQ(gfx::Rect().ToString(),
588 occlusion
.occlusion_from_outside_target().ToString());
589 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
590 occlusion
.occlusion_from_inside_target().ToString());
592 this->VisitLayer(surface_child
, &occlusion
);
594 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
595 occlusion
.occlusion_from_outside_target().ToString());
596 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
597 occlusion
.occlusion_from_inside_target().ToString());
599 this->EnterContributingSurface(surface
, &occlusion
);
601 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
602 occlusion
.occlusion_from_outside_target().ToString());
603 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
604 occlusion
.occlusion_from_inside_target().ToString());
606 // Occlusion from |top_layer| already in the root target should get merged
607 // with the occlusion from the |surface| we are leaving now.
608 this->LeaveContributingSurface(surface
, &occlusion
);
609 this->EnterLayer(root
, &occlusion
);
611 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
612 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
613 occlusion
.occlusion_from_inside_target().ToString());
617 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
619 class OcclusionTrackerTestSurfaceRotatedOffAxis
: public OcclusionTrackerTest
{
621 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
622 : OcclusionTrackerTest(opaque_layers
) {}
623 void RunMyTest() override
{
624 gfx::Transform child_transform
;
625 child_transform
.Translate(250.0, 250.0);
626 child_transform
.Rotate(95.0);
627 child_transform
.Translate(-250.0, -250.0);
629 gfx::Transform layer_transform
;
630 layer_transform
.Translate(10.0, 10.0);
632 TestContentLayerImpl
* root
= this->CreateRoot(
633 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
634 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
635 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
636 LayerImpl
* child
= this->CreateSurface(
637 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
638 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
639 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
640 this->CalcDrawEtc(root
);
642 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
644 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
645 layer_transform
, layer
->visible_layer_rect());
647 this->VisitLayer(layer
, &occlusion
);
648 this->EnterContributingSurface(child
, &occlusion
);
650 EXPECT_EQ(gfx::Rect().ToString(),
651 occlusion
.occlusion_from_outside_target().ToString());
652 EXPECT_EQ(clipped_layer_in_child
.ToString(),
653 occlusion
.occlusion_from_inside_target().ToString());
655 this->LeaveContributingSurface(child
, &occlusion
);
656 this->EnterLayer(parent
, &occlusion
);
658 EXPECT_EQ(gfx::Rect().ToString(),
659 occlusion
.occlusion_from_outside_target().ToString());
660 EXPECT_EQ(gfx::Rect().ToString(),
661 occlusion
.occlusion_from_inside_target().ToString());
665 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
667 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
668 : public OcclusionTrackerTest
{
670 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
671 : OcclusionTrackerTest(opaque_layers
) {}
672 void RunMyTest() override
{
673 gfx::Transform child_transform
;
674 child_transform
.Translate(250.0, 250.0);
675 child_transform
.Rotate(90.0);
676 child_transform
.Translate(-250.0, -250.0);
678 TestContentLayerImpl
* root
= this->CreateRoot(
679 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
680 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
681 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
682 parent
->SetMasksToBounds(true);
683 TestContentLayerImpl
* child
= this->CreateDrawingSurface(
684 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
686 child
->SetMasksToBounds(true);
687 TestContentLayerImpl
* layer1
= this->CreateDrawingLayer(
688 child
, this->identity_matrix
, gfx::PointF(10.f
, 10.f
),
689 gfx::Size(500, 500), true);
690 TestContentLayerImpl
* layer2
= this->CreateDrawingLayer(
691 child
, this->identity_matrix
, gfx::PointF(10.f
, 450.f
),
692 gfx::Size(500, 60), true);
693 this->CalcDrawEtc(root
);
695 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
697 this->VisitLayer(layer2
, &occlusion
);
698 this->VisitLayer(layer1
, &occlusion
);
699 this->VisitLayer(child
, &occlusion
);
700 this->EnterContributingSurface(child
, &occlusion
);
702 EXPECT_EQ(gfx::Rect().ToString(),
703 occlusion
.occlusion_from_outside_target().ToString());
704 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
705 occlusion
.occlusion_from_inside_target().ToString());
707 this->LeaveContributingSurface(child
, &occlusion
);
708 this->EnterLayer(parent
, &occlusion
);
710 EXPECT_EQ(gfx::Rect().ToString(),
711 occlusion
.occlusion_from_outside_target().ToString());
712 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
713 occlusion
.occlusion_from_inside_target().ToString());
715 /* Justification for the above occlusion from |layer1| and |layer2|:
717 +---------------------+
718 | |30 Visible region of |layer1|: /////
719 | | Visible region of |layer2|: \\\\\
720 | +---------------------------------+
722 | +---------------+-----------------+ |
723 | | |\\\\\\\\\\\\|//| 420 | |
724 | | |\\\\\\\\\\\\|//|60 | |
725 | | |\\\\\\\\\\\\|//| | |
726 +--|--|------------|--+ | |
734 | +------------|-----------------|--+
736 +---------------+-----------------+
742 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
744 class OcclusionTrackerTestOverlappingSurfaceSiblings
745 : public OcclusionTrackerTest
{
747 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
748 : OcclusionTrackerTest(opaque_layers
) {}
749 void RunMyTest() override
{
750 TestContentLayerImpl
* parent
= this->CreateRoot(
751 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
752 parent
->SetMasksToBounds(true);
753 LayerImpl
* child1
= this->CreateSurface(
754 parent
, this->identity_matrix
, gfx::PointF(10.f
, 0.f
), gfx::Size());
755 LayerImpl
* child2
= this->CreateSurface(
756 parent
, this->identity_matrix
, gfx::PointF(30.f
, 0.f
), gfx::Size());
757 TestContentLayerImpl
* layer1
= this->CreateDrawingLayer(
758 child1
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 50), true);
759 TestContentLayerImpl
* layer2
= this->CreateDrawingLayer(
760 child2
, this->identity_matrix
, gfx::PointF(10.f
, 0.f
),
761 gfx::Size(40, 50), true);
762 this->CalcDrawEtc(parent
);
764 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
766 this->VisitLayer(layer2
, &occlusion
);
767 this->EnterContributingSurface(child2
, &occlusion
);
769 // layer2's occlusion.
770 EXPECT_EQ(gfx::Rect().ToString(),
771 occlusion
.occlusion_from_outside_target().ToString());
772 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
773 occlusion
.occlusion_from_inside_target().ToString());
775 this->LeaveContributingSurface(child2
, &occlusion
);
776 this->VisitLayer(layer1
, &occlusion
);
777 this->EnterContributingSurface(child1
, &occlusion
);
779 // layer2's occlusion in the target space of layer1.
780 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
781 occlusion
.occlusion_from_outside_target().ToString());
782 // layer1's occlusion.
783 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
784 occlusion
.occlusion_from_inside_target().ToString());
786 this->LeaveContributingSurface(child1
, &occlusion
);
787 this->EnterLayer(parent
, &occlusion
);
789 // The occlusion from from layer1 and layer2 is merged.
790 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
791 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
792 occlusion
.occlusion_from_inside_target().ToString());
796 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
798 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
799 : public OcclusionTrackerTest
{
801 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
803 : OcclusionTrackerTest(opaque_layers
) {}
804 void RunMyTest() override
{
805 gfx::Transform child1_transform
;
806 child1_transform
.Translate(250.0, 250.0);
807 child1_transform
.Rotate(-90.0);
808 child1_transform
.Translate(-250.0, -250.0);
810 gfx::Transform child2_transform
;
811 child2_transform
.Translate(250.0, 250.0);
812 child2_transform
.Rotate(90.0);
813 child2_transform
.Translate(-250.0, -250.0);
815 TestContentLayerImpl
* parent
= this->CreateRoot(
816 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
817 parent
->SetMasksToBounds(true);
818 LayerImpl
* child1
= this->CreateSurface(
819 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
820 LayerImpl
* child2
= this->CreateDrawingSurface(parent
, child2_transform
,
821 gfx::PointF(20.f
, 40.f
),
822 gfx::Size(10, 10), false);
823 TestContentLayerImpl
* layer1
= this->CreateDrawingLayer(
824 child1
, this->identity_matrix
, gfx::PointF(-10.f
, -20.f
),
825 gfx::Size(510, 510), true);
826 TestContentLayerImpl
* layer2
= this->CreateDrawingLayer(
827 child2
, this->identity_matrix
, gfx::PointF(-10.f
, -10.f
),
828 gfx::Size(510, 510), true);
829 this->CalcDrawEtc(parent
);
831 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
833 this->VisitLayer(layer2
, &occlusion
);
834 this->EnterLayer(child2
, &occlusion
);
836 EXPECT_EQ(gfx::Rect().ToString(),
837 occlusion
.occlusion_from_outside_target().ToString());
838 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
839 occlusion
.occlusion_from_inside_target().ToString());
841 this->LeaveLayer(child2
, &occlusion
);
842 this->EnterContributingSurface(child2
, &occlusion
);
844 EXPECT_EQ(gfx::Rect().ToString(),
845 occlusion
.occlusion_from_outside_target().ToString());
846 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
847 occlusion
.occlusion_from_inside_target().ToString());
849 this->LeaveContributingSurface(child2
, &occlusion
);
850 this->VisitLayer(layer1
, &occlusion
);
851 this->EnterContributingSurface(child1
, &occlusion
);
853 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
854 occlusion
.occlusion_from_outside_target().ToString());
855 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
856 occlusion
.occlusion_from_inside_target().ToString());
858 this->LeaveContributingSurface(child1
, &occlusion
);
859 this->EnterLayer(parent
, &occlusion
);
861 EXPECT_EQ(gfx::Rect().ToString(),
862 occlusion
.occlusion_from_outside_target().ToString());
863 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
864 occlusion
.occlusion_from_inside_target().ToString());
866 /* Justification for the above occlusion:
868 +---------------------+
870 10+----------------------------------+
872 |20+----------------------------------+
876 +|-|------------------+ | |
884 +----------------------------------+ |
886 +----------------------------------+
892 ALL_OCCLUSIONTRACKER_TEST(
893 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
895 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
{
897 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
898 : OcclusionTrackerTest(opaque_layers
) {}
899 void RunMyTest() override
{
900 gfx::Transform layer_transform
;
901 layer_transform
.Translate(250.0, 250.0);
902 layer_transform
.Rotate(90.0);
903 layer_transform
.Translate(-250.0, -250.0);
905 TestContentLayerImpl
* parent
= this->CreateRoot(
906 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
907 parent
->SetMasksToBounds(true);
908 TestContentLayerImpl
* blur_layer
= this->CreateDrawingLayer(
909 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
911 TestContentLayerImpl
* opaque_layer
= this->CreateDrawingLayer(
912 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
914 TestContentLayerImpl
* opacity_layer
= this->CreateDrawingLayer(
915 parent
, layer_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500),
918 blur_layer
->SetHasRenderSurface(true);
919 FilterOperations filters
;
920 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
921 blur_layer
->SetFilters(filters
);
923 opaque_layer
->SetHasRenderSurface(true);
925 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
926 opaque_layer
->SetFilters(filters
);
928 opacity_layer
->SetHasRenderSurface(true);
930 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
931 opacity_layer
->SetFilters(filters
);
933 this->CalcDrawEtc(parent
);
935 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
937 // Opacity layer won't contribute to occlusion.
938 this->VisitLayer(opacity_layer
, &occlusion
);
939 this->EnterContributingSurface(opacity_layer
, &occlusion
);
941 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
942 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
944 // And has nothing to contribute to its parent surface.
945 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
946 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
947 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
949 // Opaque layer will contribute to occlusion.
950 this->VisitLayer(opaque_layer
, &occlusion
);
951 this->EnterContributingSurface(opaque_layer
, &occlusion
);
953 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
954 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
955 occlusion
.occlusion_from_inside_target().ToString());
957 // And it gets translated to the parent surface.
958 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
959 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
960 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
961 occlusion
.occlusion_from_inside_target().ToString());
963 // The blur layer needs to throw away any occlusion from outside its
965 this->EnterLayer(blur_layer
, &occlusion
);
966 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
967 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
969 // And it won't contribute to occlusion.
970 this->LeaveLayer(blur_layer
, &occlusion
);
971 this->EnterContributingSurface(blur_layer
, &occlusion
);
972 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
973 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
975 // But the opaque layer's occlusion is preserved on the parent.
976 this->LeaveContributingSurface(blur_layer
, &occlusion
);
977 this->EnterLayer(parent
, &occlusion
);
978 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
979 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
980 occlusion
.occlusion_from_inside_target().ToString());
984 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
986 class OcclusionTrackerTestReplicaDoesOcclude
: public OcclusionTrackerTest
{
988 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
989 : OcclusionTrackerTest(opaque_layers
) {}
990 void RunMyTest() override
{
991 TestContentLayerImpl
* parent
= this->CreateRoot(
992 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
993 LayerImpl
* surface
= this->CreateDrawingSurface(
994 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
995 this->CreateReplicaLayer(
996 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
997 this->CalcDrawEtc(parent
);
999 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1001 this->VisitLayer(surface
, &occlusion
);
1003 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1004 occlusion
.occlusion_from_inside_target().ToString());
1006 this->VisitContributingSurface(surface
, &occlusion
);
1007 this->EnterLayer(parent
, &occlusion
);
1009 // The surface and replica should both be occluding the parent.
1010 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1011 occlusion
.occlusion_from_inside_target().ToString());
1015 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1017 class OcclusionTrackerTestReplicaWithClipping
: public OcclusionTrackerTest
{
1019 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1020 : OcclusionTrackerTest(opaque_layers
) {}
1021 void RunMyTest() override
{
1022 TestContentLayerImpl
* parent
= this->CreateRoot(
1023 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1024 parent
->SetMasksToBounds(true);
1025 LayerImpl
* surface
= this->CreateDrawingSurface(
1026 parent
, this->identity_matrix
, gfx::PointF(0.f
, 100.f
),
1027 gfx::Size(50, 50), true);
1028 this->CreateReplicaLayer(
1029 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1030 this->CalcDrawEtc(parent
);
1032 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1034 this->VisitLayer(surface
, &occlusion
);
1036 // The surface layer's occlusion in its own space.
1037 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1038 occlusion
.occlusion_from_inside_target().ToString());
1039 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1041 this->VisitContributingSurface(surface
, &occlusion
);
1042 this->EnterLayer(parent
, &occlusion
);
1044 // The surface and replica should both be occluding the parent, the
1045 // replica's occlusion is clipped by the parent.
1046 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1047 occlusion
.occlusion_from_inside_target().ToString());
1048 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1052 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1054 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
{
1056 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1057 : OcclusionTrackerTest(opaque_layers
) {}
1058 void RunMyTest() override
{
1059 TestContentLayerImpl
* parent
= this->CreateRoot(
1060 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1061 LayerImpl
* surface
= this->CreateDrawingSurface(
1062 parent
, this->identity_matrix
, gfx::PointF(0.f
, 100.f
),
1063 gfx::Size(50, 50), true);
1064 LayerImpl
* replica
= this->CreateReplicaLayer(
1065 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1066 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1067 this->CalcDrawEtc(parent
);
1069 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1071 this->VisitLayer(surface
, &occlusion
);
1073 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1074 occlusion
.occlusion_from_inside_target().ToString());
1076 this->VisitContributingSurface(surface
, &occlusion
);
1077 this->EnterLayer(parent
, &occlusion
);
1079 // The replica should not be occluding the parent, since it has a mask
1081 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1082 occlusion
.occlusion_from_inside_target().ToString());
1086 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1088 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1089 : public OcclusionTrackerTest
{
1091 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1092 : OcclusionTrackerTest(opaque_layers
) {}
1093 void RunMyTest() override
{
1094 TestContentLayerImpl
* parent
= this->CreateRoot(
1095 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1096 TestContentLayerImpl
* layer
=
1097 this->CreateDrawingSurface(parent
, this->identity_matrix
, gfx::PointF(),
1098 gfx::Size(200, 200), false);
1099 this->CalcDrawEtc(parent
);
1101 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1102 this->EnterLayer(layer
, &occlusion
);
1104 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1105 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1107 this->LeaveLayer(layer
, &occlusion
);
1108 this->VisitContributingSurface(layer
, &occlusion
);
1109 this->EnterLayer(parent
, &occlusion
);
1111 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1112 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1116 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1118 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1119 : public OcclusionTrackerTest
{
1121 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1122 : OcclusionTrackerTest(opaque_layers
) {}
1123 void RunMyTest() override
{
1124 TestContentLayerImpl
* parent
= this->CreateRoot(
1125 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1126 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
1127 parent
, this->identity_matrix
, gfx::PointF(100.f
, 100.f
),
1128 gfx::Size(200, 200), false);
1129 this->CalcDrawEtc(parent
);
1131 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1132 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1134 this->ResetLayerIterator();
1135 this->VisitLayer(layer
, &occlusion
);
1136 this->EnterLayer(parent
, &occlusion
);
1138 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1139 occlusion
.occlusion_from_inside_target().ToString());
1142 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1143 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1145 this->ResetLayerIterator();
1146 this->VisitLayer(layer
, &occlusion
);
1147 this->EnterLayer(parent
, &occlusion
);
1149 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1150 occlusion
.occlusion_from_inside_target().ToString());
1153 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1154 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1156 this->ResetLayerIterator();
1157 this->VisitLayer(layer
, &occlusion
);
1158 this->EnterLayer(parent
, &occlusion
);
1160 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1161 occlusion
.occlusion_from_inside_target().ToString());
1166 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1168 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1169 : public OcclusionTrackerTest
{
1171 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1173 : OcclusionTrackerTest(opaque_layers
) {}
1174 void RunMyTest() override
{
1175 gfx::Transform transform
;
1176 transform
.Translate(50.0, 50.0);
1177 transform
.ApplyPerspectiveDepth(100.0);
1178 transform
.Translate3d(0.0, 0.0, 110.0);
1179 transform
.Translate(-50.0, -50.0);
1181 TestContentLayerImpl
* parent
= this->CreateRoot(
1182 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1183 TestContentLayerImpl
* layer
= this->CreateDrawingLayer(
1184 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
1185 parent
->SetShouldFlattenTransform(false);
1186 parent
->Set3dSortingContextId(1);
1187 layer
->SetShouldFlattenTransform(false);
1188 layer
->Set3dSortingContextId(1);
1189 this->CalcDrawEtc(parent
);
1191 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1193 // The |layer| is entirely behind the camera and should not occlude.
1194 this->VisitLayer(layer
, &occlusion
);
1195 this->EnterLayer(parent
, &occlusion
);
1196 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1197 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1201 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1202 : public OcclusionTrackerTest
{
1204 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1206 : OcclusionTrackerTest(opaque_layers
) {}
1207 void RunMyTest() override
{
1208 gfx::Transform surface_transform
;
1209 surface_transform
.Translate(300.0, 300.0);
1210 surface_transform
.Scale(2.0, 2.0);
1211 surface_transform
.Translate(-150.0, -150.0);
1213 TestContentLayerImpl
* parent
= this->CreateRoot(
1214 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
1215 TestContentLayerImpl
* surface
= this->CreateDrawingSurface(
1216 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
1217 TestContentLayerImpl
* surface2
= this->CreateDrawingSurface(
1218 parent
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
),
1219 gfx::Size(300, 300), false);
1220 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1221 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1222 this->CalcDrawEtc(parent
);
1224 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1226 this->VisitLayer(surface2
, &occlusion
);
1227 this->VisitContributingSurface(surface2
, &occlusion
);
1229 EXPECT_EQ(gfx::Rect().ToString(),
1230 occlusion
.occlusion_from_outside_target().ToString());
1231 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1232 occlusion
.occlusion_from_inside_target().ToString());
1234 // Clear any stored occlusion.
1235 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1236 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1238 this->VisitLayer(surface
, &occlusion
);
1239 this->VisitContributingSurface(surface
, &occlusion
);
1241 EXPECT_EQ(gfx::Rect().ToString(),
1242 occlusion
.occlusion_from_outside_target().ToString());
1243 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1244 occlusion
.occlusion_from_inside_target().ToString());
1248 ALL_OCCLUSIONTRACKER_TEST(
1249 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
1251 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1252 : public OcclusionTrackerTest
{
1254 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
1256 : OcclusionTrackerTest(opaque_layers
) {}
1257 void RunMyTest() override
{
1258 TestContentLayerImpl
* parent
= this->CreateRoot(
1259 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1260 parent
->SetMasksToBounds(true);
1261 TestContentLayerImpl
* surface
=
1262 this->CreateDrawingSurface(parent
, this->identity_matrix
, gfx::PointF(),
1263 gfx::Size(500, 300), false);
1264 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
1265 this->CalcDrawEtc(parent
);
1267 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1269 this->VisitLayer(surface
, &occlusion
);
1270 this->VisitContributingSurface(surface
, &occlusion
);
1272 EXPECT_EQ(gfx::Rect().ToString(),
1273 occlusion
.occlusion_from_outside_target().ToString());
1274 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
1275 occlusion
.occlusion_from_inside_target().ToString());
1279 ALL_OCCLUSIONTRACKER_TEST(
1280 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
1282 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
1283 : public OcclusionTrackerTest
{
1285 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
1286 : OcclusionTrackerTest(opaque_layers
) {}
1287 void RunMyTest() override
{
1288 TestContentLayerImpl
* parent
= this->CreateRoot(
1289 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1290 LayerImpl
* surface
=
1291 this->CreateDrawingSurface(parent
, this->identity_matrix
, gfx::PointF(),
1292 gfx::Size(100, 100), true);
1293 this->CreateReplicaLayer(surface
,
1294 this->identity_matrix
,
1295 gfx::PointF(0.f
, 100.f
),
1296 gfx::Size(100, 100));
1297 LayerImpl
* topmost
=
1298 this->CreateDrawingLayer(parent
, this->identity_matrix
, gfx::PointF(),
1299 gfx::Size(100, 110), true);
1300 this->CalcDrawEtc(parent
);
1302 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1304 // |topmost| occludes the surface, but not the entire surface's replica.
1305 this->VisitLayer(topmost
, &occlusion
);
1307 EXPECT_EQ(gfx::Rect().ToString(),
1308 occlusion
.occlusion_from_outside_target().ToString());
1309 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
1310 occlusion
.occlusion_from_inside_target().ToString());
1312 this->VisitLayer(surface
, &occlusion
);
1314 // Render target with replica ignores occlusion from outside.
1315 EXPECT_EQ(gfx::Rect().ToString(),
1316 occlusion
.occlusion_from_outside_target().ToString());
1317 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
1318 occlusion
.occlusion_from_inside_target().ToString());
1320 this->EnterContributingSurface(surface
, &occlusion
);
1322 // Only occlusion from outside the surface occludes the surface/replica.
1323 EXPECT_EQ(gfx::Rect().ToString(),
1324 occlusion
.occlusion_on_contributing_surface_from_outside_target()
1326 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
1327 occlusion
.occlusion_on_contributing_surface_from_inside_target()
1332 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
1334 class OcclusionTrackerTestSurfaceChildOfSurface
: public OcclusionTrackerTest
{
1336 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
1337 : OcclusionTrackerTest(opaque_layers
) {}
1338 void RunMyTest() override
{
1339 // This test verifies that the surface cliprect does not end up empty and
1340 // clip away the entire unoccluded rect.
1342 TestContentLayerImpl
* parent
= this->CreateRoot(
1343 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1344 LayerImpl
* surface
=
1345 this->CreateDrawingSurface(parent
, this->identity_matrix
, gfx::PointF(),
1346 gfx::Size(100, 100), false);
1347 LayerImpl
* surface_child
= this->CreateDrawingSurface(
1348 surface
, this->identity_matrix
, gfx::PointF(0.f
, 10.f
),
1349 gfx::Size(100, 50), true);
1350 LayerImpl
* topmost
= this->CreateDrawingLayer(
1351 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
1352 this->CalcDrawEtc(parent
);
1354 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(-100, -100, 1000, 1000));
1356 // |topmost| occludes everything partially so we know occlusion is happening
1358 this->VisitLayer(topmost
, &occlusion
);
1360 EXPECT_EQ(gfx::Rect().ToString(),
1361 occlusion
.occlusion_from_outside_target().ToString());
1362 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1363 occlusion
.occlusion_from_inside_target().ToString());
1365 this->VisitLayer(surface_child
, &occlusion
);
1367 // surface_child increases the occlusion in the screen by a narrow sliver.
1368 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
1369 occlusion
.occlusion_from_outside_target().ToString());
1370 // In its own surface, surface_child is at 0,0 as is its occlusion.
1371 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1372 occlusion
.occlusion_from_inside_target().ToString());
1374 // The root layer always has a clip rect. So the parent of |surface| has a
1375 // clip rect. However, the owning layer for |surface| does not mask to
1376 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
1377 // |surface_child| exercises different code paths as its parent does not
1378 // have a clip rect.
1380 this->EnterContributingSurface(surface_child
, &occlusion
);
1381 // The |surface_child| can't occlude its own surface, but occlusion from
1383 EXPECT_EQ(gfx::Rect().ToString(),
1384 occlusion
.occlusion_on_contributing_surface_from_outside_target()
1386 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1387 occlusion
.occlusion_on_contributing_surface_from_inside_target()
1389 this->LeaveContributingSurface(surface_child
, &occlusion
);
1391 // When the surface_child's occlusion is transformed up to its parent, make
1392 // sure it is not clipped away inappropriately.
1393 this->EnterLayer(surface
, &occlusion
);
1394 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1395 occlusion
.occlusion_from_outside_target().ToString());
1396 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
1397 occlusion
.occlusion_from_inside_target().ToString());
1398 this->LeaveLayer(surface
, &occlusion
);
1400 this->EnterContributingSurface(surface
, &occlusion
);
1401 // The occlusion from inside |surface| can't affect the surface, but
1403 EXPECT_EQ(gfx::Rect().ToString(),
1404 occlusion
.occlusion_on_contributing_surface_from_outside_target()
1406 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1407 occlusion
.occlusion_on_contributing_surface_from_inside_target()
1410 this->LeaveContributingSurface(surface
, &occlusion
);
1411 this->EnterLayer(parent
, &occlusion
);
1412 // The occlusion in |surface| and without are merged into the parent.
1413 EXPECT_EQ(gfx::Rect().ToString(),
1414 occlusion
.occlusion_from_outside_target().ToString());
1415 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
1416 occlusion
.occlusion_from_inside_target().ToString());
1420 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
1422 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
1423 : public OcclusionTrackerTest
{
1425 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
1427 : OcclusionTrackerTest(opaque_layers
) {}
1428 void RunMyTest() override
{
1429 gfx::Transform scale_by_half
;
1430 scale_by_half
.Scale(0.5, 0.5);
1432 FilterOperations filters
;
1433 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1435 // Save the distance of influence for the blur effect.
1436 int outset_top
, outset_right
, outset_bottom
, outset_left
;
1438 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
1445 LAST_DIRECTION
= BOTTOM
,
1448 for (int i
= 0; i
<= LAST_DIRECTION
; ++i
) {
1451 // Make a 50x50 filtered surface that is adjacent to occluding layers
1452 // which are above it in the z-order in various configurations. The
1453 // surface is scaled to test that the pixel moving is done in the target
1454 // space, where the background filter is applied.
1455 TestContentLayerImpl
* parent
= this->CreateRoot(
1456 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
1457 LayerImpl
* filtered_surface
= this->CreateDrawingLayer(
1458 parent
, scale_by_half
, gfx::PointF(50.f
, 50.f
), gfx::Size(100, 100),
1460 filtered_surface
->SetHasRenderSurface(true);
1461 filtered_surface
->SetBackgroundFilters(filters
);
1462 gfx::Rect occlusion_rect
;
1465 occlusion_rect
= gfx::Rect(0, 0, 50, 200);
1468 occlusion_rect
= gfx::Rect(100, 0, 50, 200);
1471 occlusion_rect
= gfx::Rect(0, 0, 200, 50);
1474 occlusion_rect
= gfx::Rect(0, 100, 200, 50);
1478 LayerImpl
* occluding_layer
= this->CreateDrawingLayer(
1479 parent
, this->identity_matrix
, occlusion_rect
.origin(),
1480 occlusion_rect
.size(), true);
1481 this->CalcDrawEtc(parent
);
1483 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 200, 200));
1485 // This layer occludes pixels directly beside the filtered_surface.
1486 // Because filtered surface blends pixels in a radius, it will need to see
1487 // some of the pixels (up to radius far) underneath the occluding layers.
1488 this->VisitLayer(occluding_layer
, &occlusion
);
1490 EXPECT_EQ(occlusion_rect
.ToString(),
1491 occlusion
.occlusion_from_inside_target().ToString());
1492 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1494 this->VisitLayer(filtered_surface
, &occlusion
);
1496 // The occlusion is used fully inside the surface.
1497 gfx::Rect occlusion_inside_surface
=
1498 occlusion_rect
- gfx::Vector2d(50, 50);
1499 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1500 EXPECT_EQ(occlusion_inside_surface
.ToString(),
1501 occlusion
.occlusion_from_outside_target().ToString());
1503 // The surface has a background blur, so it needs pixels that are
1504 // currently considered occluded in order to be drawn. So the pixels it
1505 // needs should be removed some the occluded area so that when we get to
1506 // the parent they are drawn.
1507 this->VisitContributingSurface(filtered_surface
, &occlusion
);
1508 this->EnterLayer(parent
, &occlusion
);
1510 gfx::Rect expected_occlusion
= occlusion_rect
;
1513 expected_occlusion
.Inset(0, 0, outset_right
, 0);
1516 expected_occlusion
.Inset(outset_right
, 0, 0, 0);
1519 expected_occlusion
.Inset(0, 0, 0, outset_right
);
1522 expected_occlusion
.Inset(0, outset_right
, 0, 0);
1526 EXPECT_EQ(expected_occlusion
.ToString(),
1527 occlusion
.occlusion_from_inside_target().ToString());
1528 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1530 this->DestroyLayers();
1535 ALL_OCCLUSIONTRACKER_TEST(
1536 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
1538 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
1539 : public OcclusionTrackerTest
{
1541 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
1543 : OcclusionTrackerTest(opaque_layers
) {}
1544 void RunMyTest() override
{
1545 gfx::Transform scale_by_half
;
1546 scale_by_half
.Scale(0.5, 0.5);
1548 // Makes two surfaces that completely cover |parent|. The occlusion both
1549 // above and below the filters will be reduced by each of them.
1550 TestContentLayerImpl
* root
= this->CreateRoot(
1551 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
1552 LayerImpl
* parent
= this->CreateSurface(root
, scale_by_half
, gfx::PointF(),
1553 gfx::Size(150, 150));
1554 parent
->SetMasksToBounds(true);
1555 LayerImpl
* filtered_surface1
= this->CreateDrawingLayer(
1556 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
1557 LayerImpl
* filtered_surface2
= this->CreateDrawingLayer(
1558 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
1559 LayerImpl
* occluding_layer_above
= this->CreateDrawingLayer(
1560 parent
, this->identity_matrix
, gfx::PointF(100.f
, 100.f
),
1561 gfx::Size(50, 50), true);
1563 // Filters make the layers own surfaces.
1564 filtered_surface1
->SetHasRenderSurface(true);
1565 filtered_surface2
->SetHasRenderSurface(true);
1566 FilterOperations filters
;
1567 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
1568 filtered_surface1
->SetBackgroundFilters(filters
);
1569 filtered_surface2
->SetBackgroundFilters(filters
);
1571 // Save the distance of influence for the blur effect.
1572 int outset_top
, outset_right
, outset_bottom
, outset_left
;
1574 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
1576 this->CalcDrawEtc(root
);
1578 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1580 this->VisitLayer(occluding_layer_above
, &occlusion
);
1581 EXPECT_EQ(gfx::Rect().ToString(),
1582 occlusion
.occlusion_from_outside_target().ToString());
1583 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
1584 occlusion
.occlusion_from_inside_target().ToString());
1586 this->VisitLayer(filtered_surface2
, &occlusion
);
1587 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
1588 this->VisitLayer(filtered_surface1
, &occlusion
);
1589 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
1591 // Test expectations in the target.
1592 gfx::Rect expected_occlusion
=
1593 gfx::Rect(100 / 2 + outset_right
* 2,
1594 100 / 2 + outset_bottom
* 2,
1595 50 / 2 - (outset_left
+ outset_right
) * 2,
1596 50 / 2 - (outset_top
+ outset_bottom
) * 2);
1597 EXPECT_EQ(expected_occlusion
.ToString(),
1598 occlusion
.occlusion_from_inside_target().ToString());
1600 // Test expectations in the screen are the same as in the target, as the
1601 // render surface is 1:1 with the screen.
1602 EXPECT_EQ(expected_occlusion
.ToString(),
1603 occlusion
.occlusion_from_outside_target().ToString());
1607 ALL_OCCLUSIONTRACKER_TEST(
1608 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
1610 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
1611 : public OcclusionTrackerTest
{
1613 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
1615 : OcclusionTrackerTest(opaque_layers
) {}
1616 void RunMyTest() override
{
1617 gfx::Transform scale_by_half
;
1618 scale_by_half
.Scale(0.5, 0.5);
1620 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
1621 // centered below each. The surface is scaled to test that the pixel moving
1622 // is done in the target space, where the background filter is applied, but
1623 // the surface appears at 50, 50 and the replica at 200, 50.
1624 TestContentLayerImpl
* parent
= this->CreateRoot(
1625 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
1626 LayerImpl
* behind_surface_layer
= this->CreateDrawingLayer(
1627 parent
, this->identity_matrix
, gfx::PointF(60.f
, 60.f
),
1628 gfx::Size(30, 30), true);
1629 LayerImpl
* behind_replica_layer
= this->CreateDrawingLayer(
1630 parent
, this->identity_matrix
, gfx::PointF(210.f
, 60.f
),
1631 gfx::Size(30, 30), true);
1632 LayerImpl
* filtered_surface
=
1633 this->CreateDrawingLayer(parent
, scale_by_half
, gfx::PointF(50.f
, 50.f
),
1634 gfx::Size(100, 100), false);
1635 this->CreateReplicaLayer(filtered_surface
,
1636 this->identity_matrix
,
1637 gfx::PointF(300.f
, 0.f
),
1640 // Filters make the layer own a surface.
1641 filtered_surface
->SetHasRenderSurface(true);
1642 FilterOperations filters
;
1643 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
1644 filtered_surface
->SetBackgroundFilters(filters
);
1646 this->CalcDrawEtc(parent
);
1648 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1650 // The surface has a background blur, so it blurs non-opaque pixels below
1652 this->VisitLayer(filtered_surface
, &occlusion
);
1653 this->VisitContributingSurface(filtered_surface
, &occlusion
);
1655 this->VisitLayer(behind_replica_layer
, &occlusion
);
1657 // The layers behind the surface are not blurred, and their occlusion does
1658 // not change, until we leave the surface. So it should not be modified by
1660 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
1661 EXPECT_EQ(occlusion_behind_replica
.ToString(),
1662 occlusion
.occlusion_from_inside_target().ToString());
1663 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1665 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
1666 // without existing occlusion interfering.
1667 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1669 this->VisitLayer(behind_surface_layer
, &occlusion
);
1671 // The layers behind the surface are not blurred, and their occlusion does
1672 // not change, until we leave the surface. So it should not be modified by
1674 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
1675 EXPECT_EQ(occlusion_behind_surface
.ToString(),
1676 occlusion
.occlusion_from_inside_target().ToString());
1677 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1681 ALL_OCCLUSIONTRACKER_TEST(
1682 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
1684 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
1685 : public OcclusionTrackerTest
{
1687 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
1689 : OcclusionTrackerTest(opaque_layers
) {}
1690 void RunMyTest() override
{
1691 gfx::Transform scale_by_half
;
1692 scale_by_half
.Scale(0.5, 0.5);
1694 // Make a 50x50 filtered surface that is completely occluded by an opaque
1695 // layer which is above it in the z-order. The surface is
1696 // scaled to test that the pixel moving is done in the target space, where
1697 // the background filter is applied, but the surface appears at 50, 50.
1698 TestContentLayerImpl
* parent
= this->CreateRoot(
1699 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
1700 LayerImpl
* filtered_surface
=
1701 this->CreateDrawingLayer(parent
, scale_by_half
, gfx::PointF(50.f
, 50.f
),
1702 gfx::Size(100, 100), false);
1703 LayerImpl
* occluding_layer
= this->CreateDrawingLayer(
1704 parent
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
),
1705 gfx::Size(50, 50), true);
1707 // Filters make the layer own a surface.
1708 filtered_surface
->SetHasRenderSurface(true);
1709 FilterOperations filters
;
1710 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
1711 filtered_surface
->SetBackgroundFilters(filters
);
1713 this->CalcDrawEtc(parent
);
1715 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1717 this->VisitLayer(occluding_layer
, &occlusion
);
1719 this->VisitLayer(filtered_surface
, &occlusion
);
1721 // The layers above the filtered surface occlude from outside.
1722 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
1724 EXPECT_EQ(gfx::Rect().ToString(),
1725 occlusion
.occlusion_from_inside_target().ToString());
1726 EXPECT_EQ(occlusion_above_surface
.ToString(),
1727 occlusion
.occlusion_from_outside_target().ToString());
1730 // The surface has a background blur, so it blurs non-opaque pixels below
1732 this->VisitContributingSurface(filtered_surface
, &occlusion
);
1734 // The filter is completely occluded, so it should not blur anything and
1735 // reduce any occlusion.
1736 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
1738 EXPECT_EQ(occlusion_above_surface
.ToString(),
1739 occlusion
.occlusion_from_inside_target().ToString());
1740 EXPECT_EQ(gfx::Rect().ToString(),
1741 occlusion
.occlusion_from_outside_target().ToString());
1746 ALL_OCCLUSIONTRACKER_TEST(
1747 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
1749 class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
1750 : public OcclusionTrackerTest
{
1752 explicit OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded(
1754 : OcclusionTrackerTest(opaque_layers
) {}
1755 void RunMyTest() override
{
1756 gfx::Transform scale_by_half
;
1757 scale_by_half
.Scale(0.5, 0.5);
1759 // Make a surface and its replica, each 50x50, that are partially occluded
1760 // by opaque layers which are above them in the z-order. The surface is
1761 // scaled to test that the pixel moving is done in the target space, where
1762 // the background filter is applied, but the surface appears at 50, 50 and
1763 // the replica at 200, 50.
1764 TestContentLayerImpl
* parent
= this->CreateRoot(
1765 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
1766 LayerImpl
* filtered_surface
=
1767 this->CreateDrawingLayer(parent
, scale_by_half
, gfx::PointF(50.f
, 50.f
),
1768 gfx::Size(100, 100), false);
1769 this->CreateReplicaLayer(filtered_surface
,
1770 this->identity_matrix
,
1771 gfx::PointF(300.f
, 0.f
),
1773 LayerImpl
* above_surface_layer
= this->CreateDrawingLayer(
1774 parent
, this->identity_matrix
, gfx::PointF(70.f
, 50.f
),
1775 gfx::Size(30, 50), true);
1776 LayerImpl
* above_replica_layer
= this->CreateDrawingLayer(
1777 parent
, this->identity_matrix
, gfx::PointF(200.f
, 50.f
),
1778 gfx::Size(30, 50), true);
1779 LayerImpl
* beside_surface_layer
= this->CreateDrawingLayer(
1780 parent
, this->identity_matrix
, gfx::PointF(90.f
, 40.f
),
1781 gfx::Size(10, 10), true);
1782 LayerImpl
* beside_replica_layer
= this->CreateDrawingLayer(
1783 parent
, this->identity_matrix
, gfx::PointF(200.f
, 40.f
),
1784 gfx::Size(10, 10), true);
1786 // Filters make the layer own a surface.
1787 filtered_surface
->SetHasRenderSurface(true);
1788 FilterOperations filters
;
1789 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
1790 filtered_surface
->SetBackgroundFilters(filters
);
1792 // Save the distance of influence for the blur effect.
1793 int outset_top
, outset_right
, outset_bottom
, outset_left
;
1795 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
1797 this->CalcDrawEtc(parent
);
1799 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1801 this->VisitLayer(beside_replica_layer
, &occlusion
);
1802 this->VisitLayer(beside_surface_layer
, &occlusion
);
1803 this->VisitLayer(above_replica_layer
, &occlusion
);
1804 this->VisitLayer(above_surface_layer
, &occlusion
);
1806 // The surface has a background blur, so it blurs non-opaque pixels below
1808 this->VisitLayer(filtered_surface
, &occlusion
);
1809 this->VisitContributingSurface(filtered_surface
, &occlusion
);
1811 // The filter in the surface and replica are partially unoccluded. Only the
1812 // unoccluded parts should reduce occlusion. This means it will push back
1813 // the occlusion that touches the unoccluded part (occlusion_above___), but
1814 // it will not touch occlusion_beside____ since that is not beside the
1815 // unoccluded part of the surface, even though it is beside the occluded
1816 // part of the surface.
1817 gfx::Rect occlusion_above_surface
=
1818 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
1819 gfx::Rect occlusion_above_replica
=
1820 gfx::Rect(200, 50, 30 - outset_left
, 50);
1821 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
1822 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
1824 SimpleEnclosedRegion expected_occlusion
;
1825 expected_occlusion
.Union(occlusion_beside_replica
);
1826 expected_occlusion
.Union(occlusion_beside_surface
);
1827 expected_occlusion
.Union(occlusion_above_replica
);
1828 expected_occlusion
.Union(occlusion_above_surface
);
1830 EXPECT_EQ(expected_occlusion
.ToString(),
1831 occlusion
.occlusion_from_inside_target().ToString());
1832 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1834 const SimpleEnclosedRegion
& actual_occlusion
=
1835 occlusion
.occlusion_from_inside_target();
1836 for (size_t i
= 0; i
< expected_occlusion
.GetRegionComplexity(); ++i
) {
1837 ASSERT_LT(i
, actual_occlusion
.GetRegionComplexity());
1838 EXPECT_EQ(expected_occlusion
.GetRect(i
), actual_occlusion
.GetRect(i
));
1843 ALL_OCCLUSIONTRACKER_TEST(
1844 OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
);
1846 class OcclusionTrackerTestBlendModeDoesNotOcclude
1847 : public OcclusionTrackerTest
{
1849 explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers
)
1850 : OcclusionTrackerTest(opaque_layers
) {}
1851 void RunMyTest() override
{
1852 TestContentLayerImpl
* parent
= this->CreateRoot(
1853 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1854 LayerImpl
* blend_mode_layer
= this->CreateDrawingLayer(
1855 parent
, this->identity_matrix
, gfx::PointF(0.f
, 0.f
),
1856 gfx::Size(100, 100), true);
1857 LayerImpl
* top_layer
= this->CreateDrawingLayer(
1858 parent
, this->identity_matrix
, gfx::PointF(10.f
, 12.f
),
1859 gfx::Size(20, 22), true);
1861 // Blend mode makes the layer own a surface.
1862 blend_mode_layer
->SetHasRenderSurface(true);
1863 blend_mode_layer
->SetBlendMode(SkXfermode::kMultiply_Mode
);
1865 this->CalcDrawEtc(parent
);
1867 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1869 this->VisitLayer(top_layer
, &occlusion
);
1870 // |top_layer| occludes.
1871 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1872 occlusion
.occlusion_from_inside_target().ToString());
1873 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1875 this->VisitLayer(blend_mode_layer
, &occlusion
);
1876 // |top_layer| occludes but not |blend_mode_layer|.
1877 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1878 occlusion
.occlusion_from_outside_target().ToString());
1879 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1881 this->VisitContributingSurface(blend_mode_layer
, &occlusion
);
1882 // |top_layer| occludes but not |blend_mode_layer|.
1883 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1884 occlusion
.occlusion_from_inside_target().ToString());
1885 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1889 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude
);
1891 class OcclusionTrackerTestMinimumTrackingSize
: public OcclusionTrackerTest
{
1893 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
1894 : OcclusionTrackerTest(opaque_layers
) {}
1895 void RunMyTest() override
{
1896 gfx::Size
tracking_size(100, 100);
1897 gfx::Size
below_tracking_size(99, 99);
1899 TestContentLayerImpl
* parent
= this->CreateRoot(
1900 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
1901 LayerImpl
* large
= this->CreateDrawingLayer(
1902 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
1904 this->CreateDrawingLayer(parent
, this->identity_matrix
, gfx::PointF(),
1905 below_tracking_size
, true);
1906 this->CalcDrawEtc(parent
);
1908 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1909 occlusion
.set_minimum_tracking_size(tracking_size
);
1911 // The small layer is not tracked because it is too small.
1912 this->VisitLayer(small
, &occlusion
);
1914 EXPECT_EQ(gfx::Rect().ToString(),
1915 occlusion
.occlusion_from_outside_target().ToString());
1916 EXPECT_EQ(gfx::Rect().ToString(),
1917 occlusion
.occlusion_from_inside_target().ToString());
1919 // The large layer is tracked as it is large enough.
1920 this->VisitLayer(large
, &occlusion
);
1922 EXPECT_EQ(gfx::Rect().ToString(),
1923 occlusion
.occlusion_from_outside_target().ToString());
1924 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
1925 occlusion
.occlusion_from_inside_target().ToString());
1929 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
1931 class OcclusionTrackerTestScaledLayerIsClipped
: public OcclusionTrackerTest
{
1933 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
1934 : OcclusionTrackerTest(opaque_layers
) {}
1935 void RunMyTest() override
{
1936 gfx::Transform scale_transform
;
1937 scale_transform
.Scale(512.0, 512.0);
1939 TestContentLayerImpl
* parent
= this->CreateRoot(
1940 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
1942 this->CreateLayer(parent
, this->identity_matrix
,
1943 gfx::PointF(10.f
, 10.f
), gfx::Size(50, 50));
1944 clip
->SetMasksToBounds(true);
1945 LayerImpl
* scale
= this->CreateLayer(clip
, scale_transform
, gfx::PointF(),
1947 LayerImpl
* scaled
= this->CreateDrawingLayer(
1948 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
1949 this->CalcDrawEtc(parent
);
1951 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1953 this->VisitLayer(scaled
, &occlusion
);
1955 EXPECT_EQ(gfx::Rect().ToString(),
1956 occlusion
.occlusion_from_outside_target().ToString());
1957 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
1958 occlusion
.occlusion_from_inside_target().ToString());
1962 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
1964 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
1965 : public OcclusionTrackerTest
{
1967 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
1968 : OcclusionTrackerTest(opaque_layers
) {}
1969 void RunMyTest() override
{
1970 gfx::Transform scale_transform
;
1971 scale_transform
.Scale(512.0, 512.0);
1973 TestContentLayerImpl
* parent
= this->CreateRoot(
1974 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
1976 this->CreateLayer(parent
, this->identity_matrix
,
1977 gfx::PointF(10.f
, 10.f
), gfx::Size(50, 50));
1978 clip
->SetMasksToBounds(true);
1979 LayerImpl
* surface
= this->CreateDrawingSurface(
1980 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
1981 LayerImpl
* scale
= this->CreateLayer(surface
, scale_transform
,
1982 gfx::PointF(), gfx::Size(1, 1));
1983 LayerImpl
* scaled
= this->CreateDrawingLayer(
1984 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
1985 this->CalcDrawEtc(parent
);
1987 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
1989 this->VisitLayer(scaled
, &occlusion
);
1990 this->VisitLayer(surface
, &occlusion
);
1991 this->VisitContributingSurface(surface
, &occlusion
);
1993 EXPECT_EQ(gfx::Rect().ToString(),
1994 occlusion
.occlusion_from_outside_target().ToString());
1995 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
1996 occlusion
.occlusion_from_inside_target().ToString());
2000 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
2002 class OcclusionTrackerTestCopyRequestDoesOcclude
: public OcclusionTrackerTest
{
2004 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
2005 : OcclusionTrackerTest(opaque_layers
) {}
2006 void RunMyTest() override
{
2007 TestContentLayerImpl
* root
= this->CreateRoot(
2008 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2009 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
2010 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2011 LayerImpl
* copy
= this->CreateLayer(
2012 parent
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
2013 this->AddCopyRequest(copy
);
2014 LayerImpl
* copy_child
= this->CreateDrawingLayer(
2015 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
2016 LayerImpl
* top_layer
=
2017 this->CreateDrawingLayer(root
, this->identity_matrix
,
2018 gfx::PointF(50, 0), gfx::Size(50, 400), true);
2019 this->CalcDrawEtc(root
);
2021 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
2023 this->VisitLayer(top_layer
, &occlusion
);
2024 EXPECT_EQ(gfx::Rect().ToString(),
2025 occlusion
.occlusion_from_outside_target().ToString());
2026 EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(),
2027 occlusion
.occlusion_from_inside_target().ToString());
2029 this->VisitLayer(copy_child
, &occlusion
);
2030 // Layers outside the copy request do not occlude.
2031 EXPECT_EQ(gfx::Rect().ToString(),
2032 occlusion
.occlusion_from_outside_target().ToString());
2033 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2034 occlusion
.occlusion_from_inside_target().ToString());
2036 // CopyRequests cause the layer to own a surface.
2037 this->VisitContributingSurface(copy
, &occlusion
);
2039 // The occlusion from the copy should be kept.
2040 EXPECT_EQ(gfx::Rect().ToString(),
2041 occlusion
.occlusion_from_outside_target().ToString());
2042 EXPECT_EQ(gfx::Rect(50, 0, 250, 400).ToString(),
2043 occlusion
.occlusion_from_inside_target().ToString());
2047 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
2049 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2050 : public OcclusionTrackerTest
{
2052 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2054 : OcclusionTrackerTest(opaque_layers
) {}
2055 void RunMyTest() override
{
2056 TestContentLayerImpl
* root
= this->CreateRoot(
2057 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2058 TestContentLayerImpl
* parent
= this->CreateDrawingLayer(
2059 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2060 LayerImpl
* hide
= this->CreateLayer(parent
, this->identity_matrix
,
2061 gfx::Point(), gfx::Size());
2062 LayerImpl
* copy
= this->CreateLayer(
2063 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
2064 this->AddCopyRequest(copy
);
2065 LayerImpl
* copy_child
= this->CreateDrawingLayer(
2066 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
2068 // The |copy| layer is hidden but since it is being copied, it will be
2070 hide
->SetHideLayerAndSubtree(true);
2072 this->CalcDrawEtc(root
);
2074 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 1000, 1000));
2076 this->VisitLayer(copy_child
, &occlusion
);
2077 EXPECT_EQ(gfx::Rect().ToString(),
2078 occlusion
.occlusion_from_outside_target().ToString());
2079 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2080 occlusion
.occlusion_from_inside_target().ToString());
2082 // CopyRequests cause the layer to own a surface.
2083 this->VisitContributingSurface(copy
, &occlusion
);
2085 // The occlusion from the copy should be dropped since it is hidden.
2086 EXPECT_EQ(gfx::Rect().ToString(),
2087 occlusion
.occlusion_from_outside_target().ToString());
2088 EXPECT_EQ(gfx::Rect().ToString(),
2089 occlusion
.occlusion_from_inside_target().ToString());
2093 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
2095 class OcclusionTrackerTestOccludedLayer
: public OcclusionTrackerTest
{
2097 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers
)
2098 : OcclusionTrackerTest(opaque_layers
) {}
2099 void RunMyTest() override
{
2100 gfx::Transform translate
;
2101 translate
.Translate(10.0, 20.0);
2102 TestContentLayerImpl
* root
= this->CreateRoot(
2103 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2104 LayerImpl
* surface
= this->CreateSurface(root
, this->identity_matrix
,
2105 gfx::Point(), gfx::Size(200, 200));
2106 LayerImpl
* layer
= this->CreateDrawingLayer(
2107 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2108 TestContentLayerImpl
* outside_layer
= this->CreateDrawingLayer(
2109 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2110 this->CalcDrawEtc(root
);
2112 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 200, 200));
2113 this->VisitLayer(outside_layer
, &occlusion
);
2114 this->EnterLayer(layer
, &occlusion
);
2116 // No occlusion, is not occluded.
2117 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2118 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2119 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100)));
2121 // Partial occlusion from outside, is not occluded.
2122 occlusion
.set_occlusion_from_outside_target(
2123 SimpleEnclosedRegion(50, 50, 100, 100));
2124 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2125 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2126 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2127 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2128 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2129 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2130 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2131 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2132 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2134 // Full occlusion from outside, is occluded.
2135 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2136 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2137 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2138 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2140 // Partial occlusion from inside, is not occluded.
2141 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2142 occlusion
.set_occlusion_from_inside_target(
2143 SimpleEnclosedRegion(50, 50, 100, 100));
2144 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2145 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2146 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2147 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2148 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2149 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2150 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2151 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2153 // Full occlusion from inside, is occluded.
2154 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2155 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2156 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2157 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2159 // Partial occlusion from both, is not occluded.
2160 occlusion
.set_occlusion_from_outside_target(
2161 SimpleEnclosedRegion(50, 50, 100, 50));
2162 occlusion
.set_occlusion_from_inside_target(
2163 SimpleEnclosedRegion(50, 100, 100, 50));
2164 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2165 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2166 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2167 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2168 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2169 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2170 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2171 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2173 // Full occlusion from both, is occluded.
2174 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2175 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2176 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2177 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2181 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer
)
2183 class OcclusionTrackerTestUnoccludedLayerQuery
: public OcclusionTrackerTest
{
2185 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers
)
2186 : OcclusionTrackerTest(opaque_layers
) {}
2187 void RunMyTest() override
{
2188 gfx::Transform translate
;
2189 translate
.Translate(10.0, 20.0);
2190 TestContentLayerImpl
* root
= this->CreateRoot(
2191 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2192 LayerImpl
* surface
= this->CreateSurface(root
, this->identity_matrix
,
2193 gfx::Point(), gfx::Size(200, 200));
2194 LayerImpl
* layer
= this->CreateDrawingLayer(
2195 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2196 TestContentLayerImpl
* outside_layer
= this->CreateDrawingLayer(
2197 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2198 this->CalcDrawEtc(root
);
2200 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 200, 200));
2201 this->VisitLayer(outside_layer
, &occlusion
);
2202 this->EnterLayer(layer
, &occlusion
);
2204 // No occlusion, is not occluded.
2205 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2206 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2207 EXPECT_EQ(gfx::Rect(100, 100),
2208 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(100, 100)));
2210 // Partial occlusion from outside.
2211 occlusion
.set_occlusion_from_outside_target(
2212 SimpleEnclosedRegion(50, 50, 100, 100));
2213 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2215 gfx::Rect(0, 0, 100, 100),
2216 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
2217 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2218 occlusion
.UnoccludedLayerContentRect(
2219 layer
, gfx::Rect(90, 30, 100, 100)));
2220 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2221 occlusion
.UnoccludedLayerContentRect(layer
,
2222 gfx::Rect(40, 0, 100, 100)));
2223 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2224 occlusion
.UnoccludedLayerContentRect(
2225 layer
, gfx::Rect(40, 80, 100, 100)));
2227 gfx::Rect(0, 0, 80, 100),
2228 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
2229 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2230 occlusion
.UnoccludedLayerContentRect(
2231 layer
, gfx::Rect(90, 80, 100, 100)));
2232 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2233 occlusion
.UnoccludedLayerContentRect(layer
,
2234 gfx::Rect(0, 80, 100, 100)));
2235 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2236 occlusion
.UnoccludedLayerContentRect(layer
,
2237 gfx::Rect(90, 0, 100, 100)));
2239 // Full occlusion from outside, is occluded.
2240 EXPECT_EQ(gfx::Rect(),
2241 occlusion
.UnoccludedLayerContentRect(
2242 layer
, gfx::Rect(40, 30, 100, 100)));
2245 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
2246 EXPECT_EQ(gfx::Rect(),
2247 occlusion
.UnoccludedLayerContentRect(
2248 layer
, gfx::Rect(130, 120, 10, 10)));
2251 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
2253 // Partial occlusion from inside, is not occluded.
2254 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2255 occlusion
.set_occlusion_from_inside_target(
2256 SimpleEnclosedRegion(50, 50, 100, 100));
2258 gfx::Rect(0, 0, 100, 100),
2259 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
2260 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2261 occlusion
.UnoccludedLayerContentRect(
2262 layer
, gfx::Rect(90, 30, 100, 100)));
2263 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2264 occlusion
.UnoccludedLayerContentRect(layer
,
2265 gfx::Rect(40, 0, 100, 100)));
2266 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2267 occlusion
.UnoccludedLayerContentRect(
2268 layer
, gfx::Rect(40, 80, 100, 100)));
2270 gfx::Rect(0, 0, 80, 100),
2271 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
2272 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2273 occlusion
.UnoccludedLayerContentRect(
2274 layer
, gfx::Rect(90, 80, 100, 100)));
2275 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2276 occlusion
.UnoccludedLayerContentRect(layer
,
2277 gfx::Rect(0, 80, 100, 100)));
2278 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2279 occlusion
.UnoccludedLayerContentRect(layer
,
2280 gfx::Rect(90, 0, 100, 100)));
2282 // Full occlusion from inside, is occluded.
2283 EXPECT_EQ(gfx::Rect(),
2284 occlusion
.UnoccludedLayerContentRect(
2285 layer
, gfx::Rect(40, 30, 100, 100)));
2288 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
2289 EXPECT_EQ(gfx::Rect(),
2290 occlusion
.UnoccludedLayerContentRect(
2291 layer
, gfx::Rect(130, 120, 10, 10)));
2294 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
2296 // Partial occlusion from both, is not occluded.
2297 occlusion
.set_occlusion_from_outside_target(
2298 SimpleEnclosedRegion(50, 50, 100, 50));
2299 occlusion
.set_occlusion_from_inside_target(
2300 SimpleEnclosedRegion(50, 100, 100, 50));
2302 gfx::Rect(0, 0, 100, 100),
2303 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
2304 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
2306 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
2307 occlusion
.UnoccludedLayerContentRect(
2308 layer
, gfx::Rect(90, 30, 100, 100)));
2309 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2310 occlusion
.UnoccludedLayerContentRect(layer
,
2311 gfx::Rect(40, 0, 100, 100)));
2312 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2313 occlusion
.UnoccludedLayerContentRect(
2314 layer
, gfx::Rect(40, 80, 100, 100)));
2316 gfx::Rect(0, 0, 80, 100),
2317 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
2318 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2319 occlusion
.UnoccludedLayerContentRect(
2320 layer
, gfx::Rect(90, 80, 100, 100)));
2321 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2322 occlusion
.UnoccludedLayerContentRect(layer
,
2323 gfx::Rect(0, 80, 100, 100)));
2324 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2325 occlusion
.UnoccludedLayerContentRect(layer
,
2326 gfx::Rect(90, 0, 100, 100)));
2328 // Full occlusion from both, is occluded.
2329 EXPECT_EQ(gfx::Rect(),
2330 occlusion
.UnoccludedLayerContentRect(
2331 layer
, gfx::Rect(40, 30, 100, 100)));
2334 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
2335 EXPECT_EQ(gfx::Rect(),
2336 occlusion
.UnoccludedLayerContentRect(
2337 layer
, gfx::Rect(130, 120, 10, 10)));
2340 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
2344 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery
)
2346 class OcclusionTrackerTestUnoccludedSurfaceQuery
: public OcclusionTrackerTest
{
2348 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers
)
2349 : OcclusionTrackerTest(opaque_layers
) {}
2350 void RunMyTest() override
{
2351 gfx::Transform translate
;
2352 translate
.Translate(10.0, 20.0);
2353 TestContentLayerImpl
* root
= this->CreateRoot(
2354 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2355 LayerImpl
* surface
=
2356 this->CreateSurface(root
, translate
, gfx::Point(), gfx::Size(200, 200));
2358 this->CreateDrawingLayer(surface
, this->identity_matrix
, gfx::Point(),
2359 gfx::Size(200, 200), false);
2360 TestContentLayerImpl
* outside_layer
= this->CreateDrawingLayer(
2361 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2362 this->CalcDrawEtc(root
);
2364 TestOcclusionTrackerWithClip
occlusion(gfx::Rect(0, 0, 200, 200));
2365 this->VisitLayer(outside_layer
, &occlusion
);
2366 this->VisitLayer(layer
, &occlusion
);
2367 this->EnterContributingSurface(surface
, &occlusion
);
2369 // No occlusion, is not occluded.
2370 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
2371 SimpleEnclosedRegion());
2372 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
2373 SimpleEnclosedRegion());
2375 gfx::Rect(100, 100),
2376 occlusion
.UnoccludedSurfaceContentRect(surface
, gfx::Rect(100, 100)));
2378 // Partial occlusion from outside.
2379 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
2380 SimpleEnclosedRegion(50, 50, 100, 100));
2381 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
2382 SimpleEnclosedRegion());
2383 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2384 occlusion
.UnoccludedSurfaceContentRect(
2385 surface
, gfx::Rect(0, 0, 100, 100)));
2386 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2387 occlusion
.UnoccludedSurfaceContentRect(
2388 surface
, gfx::Rect(90, 30, 100, 100)));
2389 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2390 occlusion
.UnoccludedSurfaceContentRect(
2391 surface
, gfx::Rect(40, 0, 100, 100)));
2392 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2393 occlusion
.UnoccludedSurfaceContentRect(
2394 surface
, gfx::Rect(40, 80, 100, 100)));
2395 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2396 occlusion
.UnoccludedSurfaceContentRect(surface
,
2397 gfx::Rect(0, 0, 80, 100)));
2398 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2399 occlusion
.UnoccludedSurfaceContentRect(
2400 surface
, gfx::Rect(90, 80, 100, 100)));
2401 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2402 occlusion
.UnoccludedSurfaceContentRect(
2403 surface
, gfx::Rect(0, 80, 100, 100)));
2404 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2405 occlusion
.UnoccludedSurfaceContentRect(
2406 surface
, gfx::Rect(90, 0, 100, 100)));
2408 // Full occlusion from outside, is occluded.
2409 EXPECT_EQ(gfx::Rect(),
2410 occlusion
.UnoccludedSurfaceContentRect(
2411 surface
, gfx::Rect(40, 30, 100, 100)));
2412 EXPECT_EQ(gfx::Rect(),
2413 occlusion
.UnoccludedSurfaceContentRect(
2414 surface
, gfx::Rect(40, 30, 10, 10)));
2415 EXPECT_EQ(gfx::Rect(),
2416 occlusion
.UnoccludedSurfaceContentRect(
2417 surface
, gfx::Rect(130, 120, 10, 10)));
2418 EXPECT_EQ(gfx::Rect(),
2419 occlusion
.UnoccludedSurfaceContentRect(
2420 surface
, gfx::Rect(80, 70, 50, 50)));
2422 // Partial occlusion from inside, is not occluded.
2423 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
2424 SimpleEnclosedRegion());
2425 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
2426 SimpleEnclosedRegion(50, 50, 100, 100));
2427 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2428 occlusion
.UnoccludedSurfaceContentRect(
2429 surface
, gfx::Rect(0, 0, 100, 100)));
2430 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2431 occlusion
.UnoccludedSurfaceContentRect(
2432 surface
, gfx::Rect(90, 30, 100, 100)));
2433 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2434 occlusion
.UnoccludedSurfaceContentRect(
2435 surface
, gfx::Rect(40, 0, 100, 100)));
2436 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2437 occlusion
.UnoccludedSurfaceContentRect(
2438 surface
, gfx::Rect(40, 80, 100, 100)));
2439 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2440 occlusion
.UnoccludedSurfaceContentRect(surface
,
2441 gfx::Rect(0, 0, 80, 100)));
2442 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2443 occlusion
.UnoccludedSurfaceContentRect(
2444 surface
, gfx::Rect(90, 80, 100, 100)));
2445 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2446 occlusion
.UnoccludedSurfaceContentRect(
2447 surface
, gfx::Rect(0, 80, 100, 100)));
2448 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2449 occlusion
.UnoccludedSurfaceContentRect(
2450 surface
, gfx::Rect(90, 0, 100, 100)));
2452 // Full occlusion from inside, is occluded.
2453 EXPECT_EQ(gfx::Rect(),
2454 occlusion
.UnoccludedSurfaceContentRect(
2455 surface
, gfx::Rect(40, 30, 100, 100)));
2456 EXPECT_EQ(gfx::Rect(),
2457 occlusion
.UnoccludedSurfaceContentRect(
2458 surface
, gfx::Rect(40, 30, 10, 10)));
2459 EXPECT_EQ(gfx::Rect(),
2460 occlusion
.UnoccludedSurfaceContentRect(
2461 surface
, gfx::Rect(130, 120, 10, 10)));
2462 EXPECT_EQ(gfx::Rect(),
2463 occlusion
.UnoccludedSurfaceContentRect(
2464 surface
, gfx::Rect(80, 70, 50, 50)));
2466 // Partial occlusion from both, is not occluded.
2467 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
2468 SimpleEnclosedRegion(50, 50, 100, 50));
2469 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
2470 SimpleEnclosedRegion(50, 100, 100, 50));
2471 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2472 occlusion
.UnoccludedSurfaceContentRect(
2473 surface
, gfx::Rect(0, 0, 100, 100)));
2474 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
2476 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
2477 occlusion
.UnoccludedSurfaceContentRect(
2478 surface
, gfx::Rect(90, 30, 100, 100)));
2479 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2480 occlusion
.UnoccludedSurfaceContentRect(
2481 surface
, gfx::Rect(40, 0, 100, 100)));
2482 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2483 occlusion
.UnoccludedSurfaceContentRect(
2484 surface
, gfx::Rect(40, 80, 100, 100)));
2485 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2486 occlusion
.UnoccludedSurfaceContentRect(surface
,
2487 gfx::Rect(0, 0, 80, 100)));
2488 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2489 occlusion
.UnoccludedSurfaceContentRect(
2490 surface
, gfx::Rect(90, 80, 100, 100)));
2491 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2492 occlusion
.UnoccludedSurfaceContentRect(
2493 surface
, gfx::Rect(0, 80, 100, 100)));
2494 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2495 occlusion
.UnoccludedSurfaceContentRect(
2496 surface
, gfx::Rect(90, 0, 100, 100)));
2498 // Full occlusion from both, is occluded.
2499 EXPECT_EQ(gfx::Rect(),
2500 occlusion
.UnoccludedSurfaceContentRect(
2501 surface
, gfx::Rect(40, 30, 100, 100)));
2502 EXPECT_EQ(gfx::Rect(),
2503 occlusion
.UnoccludedSurfaceContentRect(
2504 surface
, gfx::Rect(40, 30, 10, 10)));
2505 EXPECT_EQ(gfx::Rect(),
2506 occlusion
.UnoccludedSurfaceContentRect(
2507 surface
, gfx::Rect(130, 120, 10, 10)));
2508 EXPECT_EQ(gfx::Rect(),
2509 occlusion
.UnoccludedSurfaceContentRect(
2510 surface
, gfx::Rect(80, 70, 50, 50)));
2514 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery
)