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/trees/layer_tree_host_common.h"
22 #include "cc/trees/single_thread_proxy.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/gfx/transform.h"
30 class TestContentLayer
: public Layer
{
32 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
36 SimpleEnclosedRegion
VisibleContentOpaqueRegion() const override
{
37 if (override_opaque_contents_rect_
) {
38 return SimpleEnclosedRegion(
39 gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect()));
41 return Layer::VisibleContentOpaqueRegion();
43 void SetOpaqueContentsRect(const gfx::Rect
& opaque_contents_rect
) {
44 override_opaque_contents_rect_
= true;
45 opaque_contents_rect_
= opaque_contents_rect
;
49 ~TestContentLayer() override
{}
51 bool override_opaque_contents_rect_
;
52 gfx::Rect opaque_contents_rect_
;
55 class TestContentLayerImpl
: public LayerImpl
{
57 TestContentLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
58 : LayerImpl(tree_impl
, id
), override_opaque_contents_rect_(false) {
59 SetDrawsContent(true);
62 SimpleEnclosedRegion
VisibleContentOpaqueRegion() const override
{
63 if (override_opaque_contents_rect_
) {
64 return SimpleEnclosedRegion(
65 gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect()));
67 return LayerImpl::VisibleContentOpaqueRegion();
69 void SetOpaqueContentsRect(const gfx::Rect
& opaque_contents_rect
) {
70 override_opaque_contents_rect_
= true;
71 opaque_contents_rect_
= opaque_contents_rect
;
75 bool override_opaque_contents_rect_
;
76 gfx::Rect opaque_contents_rect_
;
79 template <typename LayerType
>
80 class TestOcclusionTrackerWithClip
: public TestOcclusionTracker
<LayerType
> {
82 explicit TestOcclusionTrackerWithClip(const gfx::Rect
& viewport_rect
)
83 : TestOcclusionTracker
<LayerType
>(viewport_rect
) {}
85 bool OccludedLayer(const LayerType
* layer
,
86 const gfx::Rect
& content_rect
) const {
87 DCHECK(layer
->visible_content_rect().Contains(content_rect
));
88 return this->GetCurrentOcclusionForLayer(layer
->draw_transform())
89 .IsOccluded(content_rect
);
92 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
93 // layer. Simple wrapper around GetUnoccludedContentRect.
94 gfx::Rect
UnoccludedLayerContentRect(const LayerType
* layer
,
95 const gfx::Rect
& content_rect
) const {
96 DCHECK(layer
->visible_content_rect().Contains(content_rect
));
97 return this->GetCurrentOcclusionForLayer(layer
->draw_transform())
98 .GetUnoccludedContentRect(content_rect
);
101 gfx::Rect
UnoccludedSurfaceContentRect(const LayerType
* layer
,
102 const gfx::Rect
& content_rect
) const {
103 typename
LayerType::RenderSurfaceType
* surface
= layer
->render_surface();
104 return this->UnoccludedContributingSurfaceContentRect(
105 content_rect
, surface
->draw_transform());
109 struct OcclusionTrackerTestMainThreadTypes
{
110 typedef Layer LayerType
;
111 typedef FakeLayerTreeHost HostType
;
112 typedef RenderSurface RenderSurfaceType
;
113 typedef TestContentLayer ContentLayerType
;
114 typedef scoped_refptr
<Layer
> LayerPtrType
;
115 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
116 typedef LayerIterator
<Layer
> TestLayerIterator
;
117 typedef OcclusionTracker
<Layer
> OcclusionTrackerType
;
119 static LayerPtrType
CreateLayer(HostType
* host
) { return Layer::Create(); }
120 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
121 return make_scoped_refptr(new ContentLayerType());
124 template <typename T
>
125 static LayerPtrType
PassLayerPtr(T
* layer
) {
126 LayerPtrType
ref(*layer
);
130 static void SetForceRenderSurface(LayerType
* layer
, bool force
) {
131 layer
->SetForceRenderSurface(force
);
134 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
136 static void RecursiveUpdateNumChildren(LayerType
* layerType
) {}
139 struct OcclusionTrackerTestImplThreadTypes
{
140 typedef LayerImpl LayerType
;
141 typedef LayerTreeImpl HostType
;
142 typedef RenderSurfaceImpl RenderSurfaceType
;
143 typedef TestContentLayerImpl ContentLayerType
;
144 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
145 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
146 typedef LayerIterator
<LayerImpl
> TestLayerIterator
;
147 typedef OcclusionTracker
<LayerImpl
> OcclusionTrackerType
;
149 static LayerPtrType
CreateLayer(HostType
* host
) {
150 return LayerImpl::Create(host
, next_layer_impl_id
++);
152 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
153 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
155 static int next_layer_impl_id
;
157 template <typename T
>
158 static LayerPtrType
PassLayerPtr(T
* layer
) {
159 return layer
->Pass();
162 static void SetForceRenderSurface(LayerType
* layer
, bool force
) {
163 layer
->SetHasRenderSurface(force
);
165 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
167 static void RecursiveUpdateNumChildren(LayerType
* layer
) {
168 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer
);
172 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
174 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
176 explicit OcclusionTrackerTest(bool opaque_layers
)
177 : opaque_layers_(opaque_layers
),
178 client_(FakeLayerTreeHostClient::DIRECT_3D
),
179 host_(FakeLayerTreeHost::Create(&client_
)) {}
181 virtual void RunMyTest() = 0;
183 void TearDown() override
{ DestroyLayers(); }
185 typename
Types::HostType
* GetHost();
187 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
188 const gfx::PointF
& position
,
189 const gfx::Size
& bounds
) {
190 typename
Types::ContentLayerPtrType
layer(
191 Types::CreateContentLayer(GetHost()));
192 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
193 SetProperties(layer_ptr
, transform
, position
, bounds
);
195 DCHECK(!root_
.get());
196 root_
= Types::PassLayerPtr(&layer
);
198 Types::SetForceRenderSurface(layer_ptr
, true);
199 SetRootLayerOnMainThread(layer_ptr
);
204 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
205 const gfx::Transform
& transform
,
206 const gfx::PointF
& position
,
207 const gfx::Size
& bounds
) {
208 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
209 typename
Types::LayerType
* layer_ptr
= layer
.get();
210 SetProperties(layer_ptr
, transform
, position
, bounds
);
211 parent
->AddChild(Types::PassLayerPtr(&layer
));
215 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
216 const gfx::Transform
& transform
,
217 const gfx::PointF
& position
,
218 const gfx::Size
& bounds
) {
219 typename
Types::LayerType
* layer
=
220 CreateLayer(parent
, transform
, position
, bounds
);
221 Types::SetForceRenderSurface(layer
, true);
225 typename
Types::ContentLayerType
* CreateDrawingLayer(
226 typename
Types::LayerType
* parent
,
227 const gfx::Transform
& transform
,
228 const gfx::PointF
& position
,
229 const gfx::Size
& bounds
,
231 typename
Types::ContentLayerPtrType
layer(
232 Types::CreateContentLayer(GetHost()));
233 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
234 SetProperties(layer_ptr
, transform
, position
, bounds
);
236 if (opaque_layers_
) {
237 layer_ptr
->SetContentsOpaque(opaque
);
239 layer_ptr
->SetContentsOpaque(false);
241 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
243 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
246 parent
->AddChild(Types::PassLayerPtr(&layer
));
250 typename
Types::LayerType
* CreateReplicaLayer(
251 typename
Types::LayerType
* owning_layer
,
252 const gfx::Transform
& transform
,
253 const gfx::PointF
& position
,
254 const gfx::Size
& bounds
) {
255 typename
Types::ContentLayerPtrType
layer(
256 Types::CreateContentLayer(GetHost()));
257 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
258 SetProperties(layer_ptr
, transform
, position
, bounds
);
259 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
263 typename
Types::LayerType
* CreateMaskLayer(
264 typename
Types::LayerType
* owning_layer
,
265 const gfx::Size
& bounds
) {
266 typename
Types::ContentLayerPtrType
layer(
267 Types::CreateContentLayer(GetHost()));
268 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
269 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
270 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
274 typename
Types::ContentLayerType
* CreateDrawingSurface(
275 typename
Types::LayerType
* parent
,
276 const gfx::Transform
& transform
,
277 const gfx::PointF
& position
,
278 const gfx::Size
& bounds
,
280 typename
Types::ContentLayerType
* layer
=
281 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
282 Types::SetForceRenderSurface(layer
, true);
286 void DestroyLayers() {
287 Types::DestroyLayer(&root_
);
288 render_surface_layer_list_
= nullptr;
289 render_surface_layer_list_impl_
.clear();
290 replica_layers_
.clear();
291 mask_layers_
.clear();
292 ResetLayerIterator();
295 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
297 void AddCopyRequest(Layer
* layer
) {
298 layer
->RequestCopyOfOutput(
299 CopyOutputRequest::CreateBitmapRequest(base::Bind(
300 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
301 base::Unretained(this))));
304 void AddCopyRequest(LayerImpl
* layer
) {
305 ScopedPtrVector
<CopyOutputRequest
> requests
;
307 CopyOutputRequest::CreateBitmapRequest(base::Bind(
308 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
309 base::Unretained(this))));
310 layer
->SetHasRenderSurface(true);
311 layer
->PassCopyRequests(&requests
);
314 void CalcDrawEtc(TestContentLayerImpl
* root
) {
315 DCHECK(root
== root_
.get());
317 Types::RecursiveUpdateNumChildren(root
);
318 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
319 root
, root
->bounds(), &render_surface_layer_list_impl_
);
320 inputs
.can_adjust_raster_scales
= true;
321 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
323 layer_iterator_
= layer_iterator_begin_
=
324 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
327 void CalcDrawEtc(TestContentLayer
* root
) {
328 DCHECK(root
== root_
.get());
329 DCHECK(!root
->render_surface());
331 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
332 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
333 root
, root
->bounds(), render_surface_layer_list_
.get());
334 inputs
.can_adjust_raster_scales
= true;
335 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
337 layer_iterator_
= layer_iterator_begin_
=
338 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
341 void EnterLayer(typename
Types::LayerType
* layer
,
342 typename
Types::OcclusionTrackerType
* occlusion
) {
343 ASSERT_EQ(*layer_iterator_
, layer
);
344 ASSERT_TRUE(layer_iterator_
.represents_itself());
345 occlusion
->EnterLayer(layer_iterator_
);
348 void LeaveLayer(typename
Types::LayerType
* layer
,
349 typename
Types::OcclusionTrackerType
* occlusion
) {
350 ASSERT_EQ(*layer_iterator_
, layer
);
351 ASSERT_TRUE(layer_iterator_
.represents_itself());
352 occlusion
->LeaveLayer(layer_iterator_
);
356 void VisitLayer(typename
Types::LayerType
* layer
,
357 typename
Types::OcclusionTrackerType
* occlusion
) {
358 EnterLayer(layer
, occlusion
);
359 LeaveLayer(layer
, occlusion
);
362 void EnterContributingSurface(
363 typename
Types::LayerType
* layer
,
364 typename
Types::OcclusionTrackerType
* occlusion
) {
365 ASSERT_EQ(*layer_iterator_
, layer
);
366 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
367 occlusion
->EnterLayer(layer_iterator_
);
368 occlusion
->LeaveLayer(layer_iterator_
);
370 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
371 occlusion
->EnterLayer(layer_iterator_
);
374 void LeaveContributingSurface(
375 typename
Types::LayerType
* layer
,
376 typename
Types::OcclusionTrackerType
* occlusion
) {
377 ASSERT_EQ(*layer_iterator_
, layer
);
378 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
379 occlusion
->LeaveLayer(layer_iterator_
);
383 void VisitContributingSurface(
384 typename
Types::LayerType
* layer
,
385 typename
Types::OcclusionTrackerType
* occlusion
) {
386 EnterContributingSurface(layer
, occlusion
);
387 LeaveContributingSurface(layer
, occlusion
);
390 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
392 const gfx::Transform identity_matrix
;
395 void SetRootLayerOnMainThread(Layer
* root
) {
396 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
399 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
401 void SetBaseProperties(typename
Types::LayerType
* layer
,
402 const gfx::Transform
& transform
,
403 const gfx::PointF
& position
,
404 const gfx::Size
& bounds
) {
405 layer
->SetTransform(transform
);
406 layer
->SetPosition(position
);
407 layer
->SetBounds(bounds
);
410 void SetProperties(Layer
* layer
,
411 const gfx::Transform
& transform
,
412 const gfx::PointF
& position
,
413 const gfx::Size
& bounds
) {
414 SetBaseProperties(layer
, transform
, position
, bounds
);
417 void SetProperties(LayerImpl
* layer
,
418 const gfx::Transform
& transform
,
419 const gfx::PointF
& position
,
420 const gfx::Size
& bounds
) {
421 SetBaseProperties(layer
, transform
, position
, bounds
);
423 layer
->SetContentBounds(layer
->bounds());
426 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
427 owning_layer
->SetReplicaLayer(layer
.get());
428 replica_layers_
.push_back(layer
);
431 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
432 owning_layer
->SetReplicaLayer(layer
.Pass());
435 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
436 owning_layer
->SetMaskLayer(layer
.get());
437 mask_layers_
.push_back(layer
);
440 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
441 owning_layer
->SetMaskLayer(layer
.Pass());
445 FakeLayerTreeHostClient client_
;
446 scoped_ptr
<FakeLayerTreeHost
> host_
;
447 // These hold ownership of the layers for the duration of the test.
448 typename
Types::LayerPtrType root_
;
449 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
450 LayerImplList render_surface_layer_list_impl_
;
451 typename
Types::TestLayerIterator layer_iterator_begin_
;
452 typename
Types::TestLayerIterator layer_iterator_
;
453 typename
Types::LayerType
* last_layer_visited_
;
454 LayerList replica_layers_
;
455 LayerList mask_layers_
;
460 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
466 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
467 return host_
->host_impl()->active_tree();
470 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
471 class ClassName##MainThreadOpaqueLayers \
472 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
473 public: /* NOLINT(whitespace/indent) */ \
474 ClassName##MainThreadOpaqueLayers() \
475 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
477 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
478 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
479 class ClassName##MainThreadOpaquePaints \
480 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
481 public: /* NOLINT(whitespace/indent) */ \
482 ClassName##MainThreadOpaquePaints() \
483 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
485 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
487 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
488 class ClassName##ImplThreadOpaqueLayers \
489 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
490 public: /* NOLINT(whitespace/indent) */ \
491 ClassName##ImplThreadOpaqueLayers() \
492 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
494 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
495 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
496 class ClassName##ImplThreadOpaquePaints \
497 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
498 public: /* NOLINT(whitespace/indent) */ \
499 ClassName##ImplThreadOpaquePaints() \
500 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
502 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
504 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
505 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
506 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
507 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
508 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
510 #define MAIN_THREAD_TEST(ClassName) \
511 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
513 #define IMPL_THREAD_TEST(ClassName) \
514 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
516 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
517 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
518 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
520 template <class Types
>
521 class OcclusionTrackerTestIdentityTransforms
522 : public OcclusionTrackerTest
<Types
> {
524 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
525 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
527 void RunMyTest() override
{
528 typename
Types::ContentLayerType
* root
= this->CreateRoot(
529 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
530 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
531 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
532 typename
Types::ContentLayerType
* layer
=
533 this->CreateDrawingLayer(parent
,
534 this->identity_matrix
,
535 gfx::PointF(30.f
, 30.f
),
538 parent
->SetMasksToBounds(true);
539 this->CalcDrawEtc(root
);
541 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
542 gfx::Rect(0, 0, 1000, 1000));
544 this->VisitLayer(layer
, &occlusion
);
545 this->EnterLayer(parent
, &occlusion
);
547 EXPECT_EQ(gfx::Rect().ToString(),
548 occlusion
.occlusion_from_outside_target().ToString());
549 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
550 occlusion
.occlusion_from_inside_target().ToString());
554 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
556 template <class Types
>
557 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
559 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
560 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
561 void RunMyTest() override
{
562 gfx::Transform layer_transform
;
563 layer_transform
.Translate(250.0, 250.0);
564 layer_transform
.Rotate(90.0);
565 layer_transform
.Translate(-250.0, -250.0);
567 typename
Types::ContentLayerType
* root
= this->CreateRoot(
568 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
569 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
570 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
571 typename
Types::ContentLayerType
* layer
=
572 this->CreateDrawingLayer(parent
,
574 gfx::PointF(30.f
, 30.f
),
577 parent
->SetMasksToBounds(true);
578 this->CalcDrawEtc(root
);
580 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
581 gfx::Rect(0, 0, 1000, 1000));
583 this->VisitLayer(layer
, &occlusion
);
584 this->EnterLayer(parent
, &occlusion
);
586 EXPECT_EQ(gfx::Rect().ToString(),
587 occlusion
.occlusion_from_outside_target().ToString());
588 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
589 occlusion
.occlusion_from_inside_target().ToString());
593 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
595 template <class Types
>
596 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
598 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
599 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
600 void RunMyTest() override
{
601 gfx::Transform layer_transform
;
602 layer_transform
.Translate(20.0, 20.0);
604 typename
Types::ContentLayerType
* root
= this->CreateRoot(
605 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
606 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
607 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
608 typename
Types::ContentLayerType
* layer
=
609 this->CreateDrawingLayer(parent
,
611 gfx::PointF(30.f
, 30.f
),
614 parent
->SetMasksToBounds(true);
615 this->CalcDrawEtc(root
);
617 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
618 gfx::Rect(0, 0, 1000, 1000));
620 this->VisitLayer(layer
, &occlusion
);
621 this->EnterLayer(parent
, &occlusion
);
623 EXPECT_EQ(gfx::Rect().ToString(),
624 occlusion
.occlusion_from_outside_target().ToString());
625 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
626 occlusion
.occlusion_from_inside_target().ToString());
630 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
632 template <class Types
>
633 class OcclusionTrackerTestChildInRotatedChild
634 : public OcclusionTrackerTest
<Types
> {
636 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
637 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
638 void RunMyTest() override
{
639 gfx::Transform child_transform
;
640 child_transform
.Translate(250.0, 250.0);
641 child_transform
.Rotate(90.0);
642 child_transform
.Translate(-250.0, -250.0);
644 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
645 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
646 parent
->SetMasksToBounds(true);
647 typename
Types::LayerType
* child
= this->CreateSurface(
648 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
649 child
->SetMasksToBounds(true);
650 typename
Types::ContentLayerType
* layer
=
651 this->CreateDrawingLayer(child
,
652 this->identity_matrix
,
653 gfx::PointF(10.f
, 10.f
),
656 this->CalcDrawEtc(parent
);
658 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
659 gfx::Rect(0, 0, 1000, 1000));
661 this->VisitLayer(layer
, &occlusion
);
662 this->EnterContributingSurface(child
, &occlusion
);
664 EXPECT_EQ(gfx::Rect().ToString(),
665 occlusion
.occlusion_from_outside_target().ToString());
666 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
667 occlusion
.occlusion_from_inside_target().ToString());
669 this->LeaveContributingSurface(child
, &occlusion
);
670 this->EnterLayer(parent
, &occlusion
);
672 EXPECT_EQ(gfx::Rect().ToString(),
673 occlusion
.occlusion_from_outside_target().ToString());
674 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
675 occlusion
.occlusion_from_inside_target().ToString());
677 /* Justification for the above occlusion from |layer|:
679 +---------------------+
682 | 30 + ---------------------------------+
684 | |10+---------------------------------+
688 +----|--|-------------+ | |
696 +--|-------------------------------+ |
698 +---------------------------------+
701 +---------------------+
702 | |30 Visible region of |layer|: /////
704 | +---------------------------------+
706 | +---------------------------------+ |
707 | | |///////////////| 420 | |
708 | | |///////////////|60 | |
709 | | |///////////////| | |
710 +--|--|---------------+ | |
718 | +------------------------------|--+
720 +---------------------------------+
727 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
729 template <class Types
>
730 class OcclusionTrackerTestScaledRenderSurface
731 : public OcclusionTrackerTest
<Types
> {
733 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
734 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
736 void RunMyTest() override
{
737 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
738 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
740 gfx::Transform layer1_matrix
;
741 layer1_matrix
.Scale(2.0, 2.0);
742 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
743 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
744 Types::SetForceRenderSurface(layer1
, true);
746 gfx::Transform layer2_matrix
;
747 layer2_matrix
.Translate(25.0, 25.0);
748 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
749 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
750 typename
Types::ContentLayerType
* occluder
=
751 this->CreateDrawingLayer(parent
,
752 this->identity_matrix
,
753 gfx::PointF(100.f
, 100.f
),
756 this->CalcDrawEtc(parent
);
758 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
759 gfx::Rect(0, 0, 1000, 1000));
761 this->VisitLayer(occluder
, &occlusion
);
762 this->EnterLayer(layer2
, &occlusion
);
764 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
765 occlusion
.occlusion_from_outside_target().ToString());
766 EXPECT_EQ(gfx::Rect().ToString(),
767 occlusion
.occlusion_from_inside_target().ToString());
771 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
773 template <class Types
>
774 class OcclusionTrackerTestVisitTargetTwoTimes
775 : public OcclusionTrackerTest
<Types
> {
777 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
778 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
779 void RunMyTest() override
{
780 typename
Types::ContentLayerType
* root
= this->CreateRoot(
781 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
782 typename
Types::LayerType
* surface
= this->CreateSurface(
783 root
, this->identity_matrix
, gfx::PointF(30.f
, 30.f
), gfx::Size());
784 typename
Types::ContentLayerType
* surface_child
=
785 this->CreateDrawingLayer(surface
,
786 this->identity_matrix
,
787 gfx::PointF(10.f
, 10.f
),
790 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
791 // first, instead of |surface|'s. This exercises different code in
792 // LeaveToRenderTarget, as the target surface has already been seen when
793 // leaving |surface| later.
794 typename
Types::ContentLayerType
* top_layer
=
795 this->CreateDrawingLayer(root
,
796 this->identity_matrix
,
797 gfx::PointF(40.f
, 90.f
),
800 this->CalcDrawEtc(root
);
802 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
803 gfx::Rect(0, 0, 1000, 1000));
805 this->VisitLayer(top_layer
, &occlusion
);
807 EXPECT_EQ(gfx::Rect().ToString(),
808 occlusion
.occlusion_from_outside_target().ToString());
809 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
810 occlusion
.occlusion_from_inside_target().ToString());
812 this->VisitLayer(surface_child
, &occlusion
);
814 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
815 occlusion
.occlusion_from_outside_target().ToString());
816 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
817 occlusion
.occlusion_from_inside_target().ToString());
819 this->EnterContributingSurface(surface
, &occlusion
);
821 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
822 occlusion
.occlusion_from_outside_target().ToString());
823 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
824 occlusion
.occlusion_from_inside_target().ToString());
826 // Occlusion from |top_layer| already in the root target should get merged
827 // with the occlusion from the |surface| we are leaving now.
828 this->LeaveContributingSurface(surface
, &occlusion
);
829 this->EnterLayer(root
, &occlusion
);
831 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
832 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
833 occlusion
.occlusion_from_inside_target().ToString());
837 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
839 template <class Types
>
840 class OcclusionTrackerTestSurfaceRotatedOffAxis
841 : public OcclusionTrackerTest
<Types
> {
843 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
844 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
845 void RunMyTest() override
{
846 gfx::Transform child_transform
;
847 child_transform
.Translate(250.0, 250.0);
848 child_transform
.Rotate(95.0);
849 child_transform
.Translate(-250.0, -250.0);
851 gfx::Transform layer_transform
;
852 layer_transform
.Translate(10.0, 10.0);
854 typename
Types::ContentLayerType
* root
= this->CreateRoot(
855 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
856 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
857 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
858 typename
Types::LayerType
* child
= this->CreateSurface(
859 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
860 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
861 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
862 this->CalcDrawEtc(root
);
864 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
865 gfx::Rect(0, 0, 1000, 1000));
867 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
868 layer_transform
, layer
->visible_content_rect());
870 this->VisitLayer(layer
, &occlusion
);
871 this->EnterContributingSurface(child
, &occlusion
);
873 EXPECT_EQ(gfx::Rect().ToString(),
874 occlusion
.occlusion_from_outside_target().ToString());
875 EXPECT_EQ(clipped_layer_in_child
.ToString(),
876 occlusion
.occlusion_from_inside_target().ToString());
878 this->LeaveContributingSurface(child
, &occlusion
);
879 this->EnterLayer(parent
, &occlusion
);
881 EXPECT_EQ(gfx::Rect().ToString(),
882 occlusion
.occlusion_from_outside_target().ToString());
883 EXPECT_EQ(gfx::Rect().ToString(),
884 occlusion
.occlusion_from_inside_target().ToString());
888 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
890 template <class Types
>
891 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
892 : public OcclusionTrackerTest
<Types
> {
894 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
895 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
896 void RunMyTest() override
{
897 gfx::Transform child_transform
;
898 child_transform
.Translate(250.0, 250.0);
899 child_transform
.Rotate(90.0);
900 child_transform
.Translate(-250.0, -250.0);
902 typename
Types::ContentLayerType
* root
= this->CreateRoot(
903 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
904 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
905 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
906 parent
->SetMasksToBounds(true);
907 typename
Types::ContentLayerType
* child
=
908 this->CreateDrawingSurface(parent
,
910 gfx::PointF(30.f
, 30.f
),
913 child
->SetMasksToBounds(true);
914 typename
Types::ContentLayerType
* layer1
=
915 this->CreateDrawingLayer(child
,
916 this->identity_matrix
,
917 gfx::PointF(10.f
, 10.f
),
920 typename
Types::ContentLayerType
* layer2
=
921 this->CreateDrawingLayer(child
,
922 this->identity_matrix
,
923 gfx::PointF(10.f
, 450.f
),
926 this->CalcDrawEtc(root
);
928 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
929 gfx::Rect(0, 0, 1000, 1000));
931 this->VisitLayer(layer2
, &occlusion
);
932 this->VisitLayer(layer1
, &occlusion
);
933 this->VisitLayer(child
, &occlusion
);
934 this->EnterContributingSurface(child
, &occlusion
);
936 EXPECT_EQ(gfx::Rect().ToString(),
937 occlusion
.occlusion_from_outside_target().ToString());
938 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
939 occlusion
.occlusion_from_inside_target().ToString());
941 this->LeaveContributingSurface(child
, &occlusion
);
942 this->EnterLayer(parent
, &occlusion
);
944 EXPECT_EQ(gfx::Rect().ToString(),
945 occlusion
.occlusion_from_outside_target().ToString());
946 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
947 occlusion
.occlusion_from_inside_target().ToString());
949 /* Justification for the above occlusion from |layer1| and |layer2|:
951 +---------------------+
952 | |30 Visible region of |layer1|: /////
953 | | Visible region of |layer2|: \\\\\
954 | +---------------------------------+
956 | +---------------+-----------------+ |
957 | | |\\\\\\\\\\\\|//| 420 | |
958 | | |\\\\\\\\\\\\|//|60 | |
959 | | |\\\\\\\\\\\\|//| | |
960 +--|--|------------|--+ | |
968 | +------------|-----------------|--+
970 +---------------+-----------------+
976 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
978 template <class Types
>
979 class OcclusionTrackerTestOverlappingSurfaceSiblings
980 : public OcclusionTrackerTest
<Types
> {
982 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
983 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
984 void RunMyTest() override
{
985 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
986 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
987 parent
->SetMasksToBounds(true);
988 typename
Types::LayerType
* child1
= this->CreateSurface(
989 parent
, this->identity_matrix
, gfx::PointF(10.f
, 0.f
), gfx::Size());
990 typename
Types::LayerType
* child2
= this->CreateSurface(
991 parent
, this->identity_matrix
, gfx::PointF(30.f
, 0.f
), gfx::Size());
992 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
993 child1
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 50), true);
994 typename
Types::ContentLayerType
* layer2
=
995 this->CreateDrawingLayer(child2
,
996 this->identity_matrix
,
997 gfx::PointF(10.f
, 0.f
),
1000 this->CalcDrawEtc(parent
);
1002 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1003 gfx::Rect(0, 0, 1000, 1000));
1005 this->VisitLayer(layer2
, &occlusion
);
1006 this->EnterContributingSurface(child2
, &occlusion
);
1008 // layer2's occlusion.
1009 EXPECT_EQ(gfx::Rect().ToString(),
1010 occlusion
.occlusion_from_outside_target().ToString());
1011 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
1012 occlusion
.occlusion_from_inside_target().ToString());
1014 this->LeaveContributingSurface(child2
, &occlusion
);
1015 this->VisitLayer(layer1
, &occlusion
);
1016 this->EnterContributingSurface(child1
, &occlusion
);
1018 // layer2's occlusion in the target space of layer1.
1019 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
1020 occlusion
.occlusion_from_outside_target().ToString());
1021 // layer1's occlusion.
1022 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
1023 occlusion
.occlusion_from_inside_target().ToString());
1025 this->LeaveContributingSurface(child1
, &occlusion
);
1026 this->EnterLayer(parent
, &occlusion
);
1028 // The occlusion from from layer1 and layer2 is merged.
1029 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1030 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
1031 occlusion
.occlusion_from_inside_target().ToString());
1035 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1037 template <class Types
>
1038 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1039 : public OcclusionTrackerTest
<Types
> {
1041 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1043 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1044 void RunMyTest() override
{
1045 gfx::Transform child1_transform
;
1046 child1_transform
.Translate(250.0, 250.0);
1047 child1_transform
.Rotate(-90.0);
1048 child1_transform
.Translate(-250.0, -250.0);
1050 gfx::Transform child2_transform
;
1051 child2_transform
.Translate(250.0, 250.0);
1052 child2_transform
.Rotate(90.0);
1053 child2_transform
.Translate(-250.0, -250.0);
1055 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1056 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1057 parent
->SetMasksToBounds(true);
1058 typename
Types::LayerType
* child1
= this->CreateSurface(
1059 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1060 typename
Types::LayerType
* child2
=
1061 this->CreateDrawingSurface(parent
,
1063 gfx::PointF(20.f
, 40.f
),
1066 typename
Types::ContentLayerType
* layer1
=
1067 this->CreateDrawingLayer(child1
,
1068 this->identity_matrix
,
1069 gfx::PointF(-10.f
, -20.f
),
1070 gfx::Size(510, 510),
1072 typename
Types::ContentLayerType
* layer2
=
1073 this->CreateDrawingLayer(child2
,
1074 this->identity_matrix
,
1075 gfx::PointF(-10.f
, -10.f
),
1076 gfx::Size(510, 510),
1078 this->CalcDrawEtc(parent
);
1080 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1081 gfx::Rect(0, 0, 1000, 1000));
1083 this->VisitLayer(layer2
, &occlusion
);
1084 this->EnterLayer(child2
, &occlusion
);
1086 EXPECT_EQ(gfx::Rect().ToString(),
1087 occlusion
.occlusion_from_outside_target().ToString());
1088 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1089 occlusion
.occlusion_from_inside_target().ToString());
1091 this->LeaveLayer(child2
, &occlusion
);
1092 this->EnterContributingSurface(child2
, &occlusion
);
1094 EXPECT_EQ(gfx::Rect().ToString(),
1095 occlusion
.occlusion_from_outside_target().ToString());
1096 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1097 occlusion
.occlusion_from_inside_target().ToString());
1099 this->LeaveContributingSurface(child2
, &occlusion
);
1100 this->VisitLayer(layer1
, &occlusion
);
1101 this->EnterContributingSurface(child1
, &occlusion
);
1103 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1104 occlusion
.occlusion_from_outside_target().ToString());
1105 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1106 occlusion
.occlusion_from_inside_target().ToString());
1108 this->LeaveContributingSurface(child1
, &occlusion
);
1109 this->EnterLayer(parent
, &occlusion
);
1111 EXPECT_EQ(gfx::Rect().ToString(),
1112 occlusion
.occlusion_from_outside_target().ToString());
1113 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1114 occlusion
.occlusion_from_inside_target().ToString());
1116 /* Justification for the above occlusion:
1118 +---------------------+
1120 10+----------------------------------+
1121 100 || 30 | layer2 |
1122 |20+----------------------------------+
1126 +|-|------------------+ | |
1134 +----------------------------------+ |
1136 +----------------------------------+
1142 ALL_OCCLUSIONTRACKER_TEST(
1143 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1145 template <class Types
>
1146 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1148 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1149 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1150 void RunMyTest() override
{
1151 gfx::Transform layer_transform
;
1152 layer_transform
.Translate(250.0, 250.0);
1153 layer_transform
.Rotate(90.0);
1154 layer_transform
.Translate(-250.0, -250.0);
1156 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1157 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1158 parent
->SetMasksToBounds(true);
1159 typename
Types::ContentLayerType
* blur_layer
=
1160 this->CreateDrawingLayer(parent
,
1162 gfx::PointF(30.f
, 30.f
),
1163 gfx::Size(500, 500),
1165 typename
Types::ContentLayerType
* opaque_layer
=
1166 this->CreateDrawingLayer(parent
,
1168 gfx::PointF(30.f
, 30.f
),
1169 gfx::Size(500, 500),
1171 typename
Types::ContentLayerType
* opacity_layer
=
1172 this->CreateDrawingLayer(parent
,
1174 gfx::PointF(30.f
, 30.f
),
1175 gfx::Size(500, 500),
1178 Types::SetForceRenderSurface(blur_layer
, true);
1179 FilterOperations filters
;
1180 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1181 blur_layer
->SetFilters(filters
);
1183 Types::SetForceRenderSurface(opaque_layer
, true);
1185 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1186 opaque_layer
->SetFilters(filters
);
1188 Types::SetForceRenderSurface(opacity_layer
, true);
1190 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1191 opacity_layer
->SetFilters(filters
);
1193 this->CalcDrawEtc(parent
);
1195 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1196 gfx::Rect(0, 0, 1000, 1000));
1198 // Opacity layer won't contribute to occlusion.
1199 this->VisitLayer(opacity_layer
, &occlusion
);
1200 this->EnterContributingSurface(opacity_layer
, &occlusion
);
1202 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1203 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1205 // And has nothing to contribute to its parent surface.
1206 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1207 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1208 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1210 // Opaque layer will contribute to occlusion.
1211 this->VisitLayer(opaque_layer
, &occlusion
);
1212 this->EnterContributingSurface(opaque_layer
, &occlusion
);
1214 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1215 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1216 occlusion
.occlusion_from_inside_target().ToString());
1218 // And it gets translated to the parent surface.
1219 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1220 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1221 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1222 occlusion
.occlusion_from_inside_target().ToString());
1224 // The blur layer needs to throw away any occlusion from outside its
1226 this->EnterLayer(blur_layer
, &occlusion
);
1227 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1228 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1230 // And it won't contribute to occlusion.
1231 this->LeaveLayer(blur_layer
, &occlusion
);
1232 this->EnterContributingSurface(blur_layer
, &occlusion
);
1233 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1234 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1236 // But the opaque layer's occlusion is preserved on the parent.
1237 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1238 this->EnterLayer(parent
, &occlusion
);
1239 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1240 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1241 occlusion
.occlusion_from_inside_target().ToString());
1245 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1247 template <class Types
>
1248 class OcclusionTrackerTestReplicaDoesOcclude
1249 : public OcclusionTrackerTest
<Types
> {
1251 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1252 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1253 void RunMyTest() override
{
1254 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1255 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1256 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
1257 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
1258 this->CreateReplicaLayer(
1259 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1260 this->CalcDrawEtc(parent
);
1262 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1263 gfx::Rect(0, 0, 1000, 1000));
1265 this->VisitLayer(surface
, &occlusion
);
1267 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1268 occlusion
.occlusion_from_inside_target().ToString());
1270 this->VisitContributingSurface(surface
, &occlusion
);
1271 this->EnterLayer(parent
, &occlusion
);
1273 // The surface and replica should both be occluding the parent.
1274 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1275 occlusion
.occlusion_from_inside_target().ToString());
1279 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1281 template <class Types
>
1282 class OcclusionTrackerTestReplicaWithClipping
1283 : public OcclusionTrackerTest
<Types
> {
1285 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1286 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1287 void RunMyTest() override
{
1288 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1289 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1290 parent
->SetMasksToBounds(true);
1291 typename
Types::LayerType
* surface
=
1292 this->CreateDrawingSurface(parent
,
1293 this->identity_matrix
,
1294 gfx::PointF(0.f
, 100.f
),
1297 this->CreateReplicaLayer(
1298 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1299 this->CalcDrawEtc(parent
);
1301 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1302 gfx::Rect(0, 0, 1000, 1000));
1304 this->VisitLayer(surface
, &occlusion
);
1306 // The surface layer's occlusion in its own space.
1307 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1308 occlusion
.occlusion_from_inside_target().ToString());
1309 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1311 this->VisitContributingSurface(surface
, &occlusion
);
1312 this->EnterLayer(parent
, &occlusion
);
1314 // The surface and replica should both be occluding the parent, the
1315 // replica's occlusion is clipped by the parent.
1316 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1317 occlusion
.occlusion_from_inside_target().ToString());
1318 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1322 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1324 template <class Types
>
1325 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1327 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1328 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1329 void RunMyTest() override
{
1330 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1331 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1332 typename
Types::LayerType
* surface
=
1333 this->CreateDrawingSurface(parent
,
1334 this->identity_matrix
,
1335 gfx::PointF(0.f
, 100.f
),
1338 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1339 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1340 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1341 this->CalcDrawEtc(parent
);
1343 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1344 gfx::Rect(0, 0, 1000, 1000));
1346 this->VisitLayer(surface
, &occlusion
);
1348 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1349 occlusion
.occlusion_from_inside_target().ToString());
1351 this->VisitContributingSurface(surface
, &occlusion
);
1352 this->EnterLayer(parent
, &occlusion
);
1354 // The replica should not be occluding the parent, since it has a mask
1356 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1357 occlusion
.occlusion_from_inside_target().ToString());
1361 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1363 template <class Types
>
1364 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1365 : public OcclusionTrackerTest
<Types
> {
1367 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1368 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1369 void RunMyTest() override
{
1370 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1371 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1372 typename
Types::ContentLayerType
* layer
=
1373 this->CreateDrawingSurface(parent
,
1374 this->identity_matrix
,
1376 gfx::Size(200, 200),
1378 this->CalcDrawEtc(parent
);
1380 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1381 gfx::Rect(0, 0, 1000, 1000));
1382 this->EnterLayer(layer
, &occlusion
);
1384 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1385 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1387 this->LeaveLayer(layer
, &occlusion
);
1388 this->VisitContributingSurface(layer
, &occlusion
);
1389 this->EnterLayer(parent
, &occlusion
);
1391 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1392 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1396 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1398 template <class Types
>
1399 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1400 : public OcclusionTrackerTest
<Types
> {
1402 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1403 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1404 void RunMyTest() override
{
1405 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1406 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1407 typename
Types::ContentLayerType
* layer
=
1408 this->CreateDrawingLayer(parent
,
1409 this->identity_matrix
,
1410 gfx::PointF(100.f
, 100.f
),
1411 gfx::Size(200, 200),
1413 this->CalcDrawEtc(parent
);
1415 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1416 gfx::Rect(0, 0, 1000, 1000));
1417 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1419 this->ResetLayerIterator();
1420 this->VisitLayer(layer
, &occlusion
);
1421 this->EnterLayer(parent
, &occlusion
);
1423 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1424 occlusion
.occlusion_from_inside_target().ToString());
1427 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1428 gfx::Rect(0, 0, 1000, 1000));
1429 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1431 this->ResetLayerIterator();
1432 this->VisitLayer(layer
, &occlusion
);
1433 this->EnterLayer(parent
, &occlusion
);
1435 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1436 occlusion
.occlusion_from_inside_target().ToString());
1439 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1440 gfx::Rect(0, 0, 1000, 1000));
1441 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1443 this->ResetLayerIterator();
1444 this->VisitLayer(layer
, &occlusion
);
1445 this->EnterLayer(parent
, &occlusion
);
1447 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1448 occlusion
.occlusion_from_inside_target().ToString());
1453 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1455 template <class Types
>
1456 class OcclusionTrackerTestUnsorted3dLayers
1457 : public OcclusionTrackerTest
<Types
> {
1459 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
1460 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1461 void RunMyTest() override
{
1462 // Currently, The main thread layer iterator does not iterate over 3d items
1463 // in sorted order, because layer sorting is not performed on the main
1464 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1465 // layer occludes other layers that have not yet been iterated over. For
1466 // now, the expected behavior is that a 3d layer simply does not add any
1467 // occlusion to the occlusion tracker.
1469 gfx::Transform translation_to_front
;
1470 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
1471 gfx::Transform translation_to_back
;
1472 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
1474 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1475 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1476 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
1477 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
1478 typename
Types::ContentLayerType
* child2
=
1479 this->CreateDrawingLayer(parent
,
1480 translation_to_front
,
1481 gfx::PointF(50.f
, 50.f
),
1482 gfx::Size(100, 100),
1484 parent
->SetShouldFlattenTransform(false);
1485 parent
->Set3dSortingContextId(1);
1486 child1
->Set3dSortingContextId(1);
1487 child2
->Set3dSortingContextId(1);
1489 this->CalcDrawEtc(parent
);
1491 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1492 gfx::Rect(0, 0, 1000, 1000));
1493 this->VisitLayer(child2
, &occlusion
);
1494 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1495 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1497 this->VisitLayer(child1
, &occlusion
);
1498 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1499 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1503 // This test will have different layer ordering on the impl thread; the test
1504 // will only work on the main thread.
1505 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1507 template <class Types
>
1508 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1509 : public OcclusionTrackerTest
<Types
> {
1511 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1513 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1514 void RunMyTest() override
{
1515 gfx::Transform transform
;
1516 transform
.Translate(50.0, 50.0);
1517 transform
.ApplyPerspectiveDepth(100.0);
1518 transform
.Translate3d(0.0, 0.0, 110.0);
1519 transform
.Translate(-50.0, -50.0);
1521 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1522 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1523 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1524 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
1525 parent
->SetShouldFlattenTransform(false);
1526 parent
->Set3dSortingContextId(1);
1527 layer
->SetShouldFlattenTransform(false);
1528 layer
->Set3dSortingContextId(1);
1529 this->CalcDrawEtc(parent
);
1531 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1532 gfx::Rect(0, 0, 1000, 1000));
1534 // The |layer| is entirely behind the camera and should not occlude.
1535 this->VisitLayer(layer
, &occlusion
);
1536 this->EnterLayer(parent
, &occlusion
);
1537 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1538 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1542 // This test requires accumulating occlusion of 3d layers, which are skipped by
1543 // the occlusion tracker on the main thread. So this test should run on the impl
1545 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
1547 template <class Types
>
1548 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
1549 : public OcclusionTrackerTest
<Types
> {
1551 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
1553 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1554 void RunMyTest() override
{
1555 gfx::Transform transform
;
1556 transform
.Translate(50.0, 50.0);
1557 transform
.ApplyPerspectiveDepth(100.0);
1558 transform
.Translate3d(0.0, 0.0, 99.0);
1559 transform
.Translate(-50.0, -50.0);
1561 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1562 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1563 parent
->SetMasksToBounds(true);
1564 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1565 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
1566 parent
->SetShouldFlattenTransform(false);
1567 parent
->Set3dSortingContextId(1);
1568 layer
->SetShouldFlattenTransform(false);
1569 layer
->Set3dSortingContextId(1);
1570 this->CalcDrawEtc(parent
);
1572 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1573 gfx::Rect(0, 0, 1000, 1000));
1575 // This is very close to the camera, so pixels in its visible_content_rect()
1576 // will actually go outside of the layer's clip rect. Ensure that those
1577 // pixels don't occlude things outside the clip rect.
1578 this->VisitLayer(layer
, &occlusion
);
1579 this->EnterLayer(parent
, &occlusion
);
1580 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
1581 occlusion
.occlusion_from_inside_target().ToString());
1582 EXPECT_EQ(gfx::Rect().ToString(),
1583 occlusion
.occlusion_from_outside_target().ToString());
1587 // This test requires accumulating occlusion of 3d layers, which are skipped by
1588 // the occlusion tracker on the main thread. So this test should run on the impl
1590 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
1592 template <class Types
>
1593 class OcclusionTrackerTestAnimationOpacity1OnMainThread
1594 : public OcclusionTrackerTest
<Types
> {
1596 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
1597 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1598 void RunMyTest() override
{
1602 // | +--surface_child
1603 // | +--surface_child2
1607 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1608 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1609 typename
Types::ContentLayerType
* layer
=
1610 this->CreateDrawingLayer(parent
,
1611 this->identity_matrix
,
1613 gfx::Size(300, 300),
1615 typename
Types::ContentLayerType
* surface
=
1616 this->CreateDrawingSurface(parent
,
1617 this->identity_matrix
,
1619 gfx::Size(300, 300),
1621 typename
Types::ContentLayerType
* surface_child
=
1622 this->CreateDrawingLayer(surface
,
1623 this->identity_matrix
,
1625 gfx::Size(200, 300),
1627 typename
Types::ContentLayerType
* surface_child2
=
1628 this->CreateDrawingLayer(surface
,
1629 this->identity_matrix
,
1631 gfx::Size(100, 300),
1633 typename
Types::ContentLayerType
* parent2
=
1634 this->CreateDrawingLayer(parent
,
1635 this->identity_matrix
,
1637 gfx::Size(300, 300),
1639 typename
Types::ContentLayerType
* topmost
=
1640 this->CreateDrawingLayer(parent
,
1641 this->identity_matrix
,
1642 gfx::PointF(250.f
, 0.f
),
1646 AddOpacityTransitionToController(
1647 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
1648 AddOpacityTransitionToController(
1649 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
1650 this->CalcDrawEtc(parent
);
1652 EXPECT_TRUE(layer
->draw_opacity_is_animating());
1653 EXPECT_FALSE(surface
->draw_opacity_is_animating());
1654 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
1656 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1657 gfx::Rect(0, 0, 1000, 1000));
1659 this->VisitLayer(topmost
, &occlusion
);
1660 this->EnterLayer(parent2
, &occlusion
);
1662 // This occlusion will affect all surfaces.
1663 EXPECT_EQ(gfx::Rect().ToString(),
1664 occlusion
.occlusion_from_outside_target().ToString());
1665 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1666 occlusion
.occlusion_from_inside_target().ToString());
1668 this->LeaveLayer(parent2
, &occlusion
);
1669 this->VisitLayer(surface_child2
, &occlusion
);
1670 this->EnterLayer(surface_child
, &occlusion
);
1671 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1672 occlusion
.occlusion_from_outside_target().ToString());
1673 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1674 occlusion
.occlusion_from_inside_target().ToString());
1676 this->LeaveLayer(surface_child
, &occlusion
);
1677 this->EnterLayer(surface
, &occlusion
);
1678 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1679 occlusion
.occlusion_from_outside_target().ToString());
1680 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1681 occlusion
.occlusion_from_inside_target().ToString());
1683 this->LeaveLayer(surface
, &occlusion
);
1684 this->EnterContributingSurface(surface
, &occlusion
);
1685 // Occlusion within the surface is lost when leaving the animating surface.
1686 EXPECT_EQ(gfx::Rect().ToString(),
1687 occlusion
.occlusion_from_outside_target().ToString());
1688 EXPECT_EQ(gfx::Rect().ToString(),
1689 occlusion
.occlusion_from_inside_target().ToString());
1691 this->LeaveContributingSurface(surface
, &occlusion
);
1692 // Occlusion from outside the animating surface still exists.
1693 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1694 occlusion
.occlusion_from_inside_target().ToString());
1695 EXPECT_EQ(gfx::Rect().ToString(),
1696 occlusion
.occlusion_from_outside_target().ToString());
1698 this->VisitLayer(layer
, &occlusion
);
1699 this->EnterLayer(parent
, &occlusion
);
1701 // Occlusion is not added for the animating |layer|.
1702 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1703 occlusion
.occlusion_from_inside_target().ToString());
1704 EXPECT_EQ(gfx::Rect().ToString(),
1705 occlusion
.occlusion_from_outside_target().ToString());
1709 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
1711 template <class Types
>
1712 class OcclusionTrackerTestAnimationOpacity0OnMainThread
1713 : public OcclusionTrackerTest
<Types
> {
1715 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
1716 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1717 void RunMyTest() override
{
1718 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1719 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1720 typename
Types::ContentLayerType
* layer
=
1721 this->CreateDrawingLayer(parent
,
1722 this->identity_matrix
,
1724 gfx::Size(300, 300),
1726 typename
Types::ContentLayerType
* surface
=
1727 this->CreateDrawingSurface(parent
,
1728 this->identity_matrix
,
1730 gfx::Size(300, 300),
1732 typename
Types::ContentLayerType
* surface_child
=
1733 this->CreateDrawingLayer(surface
,
1734 this->identity_matrix
,
1736 gfx::Size(200, 300),
1738 typename
Types::ContentLayerType
* surface_child2
=
1739 this->CreateDrawingLayer(surface
,
1740 this->identity_matrix
,
1742 gfx::Size(100, 300),
1744 typename
Types::ContentLayerType
* parent2
=
1745 this->CreateDrawingLayer(parent
,
1746 this->identity_matrix
,
1748 gfx::Size(300, 300),
1750 typename
Types::ContentLayerType
* topmost
=
1751 this->CreateDrawingLayer(parent
,
1752 this->identity_matrix
,
1753 gfx::PointF(250.f
, 0.f
),
1757 AddOpacityTransitionToController(
1758 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
1759 AddOpacityTransitionToController(
1760 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
1761 this->CalcDrawEtc(parent
);
1763 EXPECT_TRUE(layer
->draw_opacity_is_animating());
1764 EXPECT_FALSE(surface
->draw_opacity_is_animating());
1765 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
1767 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1768 gfx::Rect(0, 0, 1000, 1000));
1770 this->VisitLayer(topmost
, &occlusion
);
1771 this->EnterLayer(parent2
, &occlusion
);
1772 // This occlusion will affect all surfaces.
1773 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1774 occlusion
.occlusion_from_inside_target().ToString());
1775 EXPECT_EQ(gfx::Rect().ToString(),
1776 occlusion
.occlusion_from_outside_target().ToString());
1778 this->LeaveLayer(parent2
, &occlusion
);
1779 this->VisitLayer(surface_child2
, &occlusion
);
1780 this->EnterLayer(surface_child
, &occlusion
);
1781 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1782 occlusion
.occlusion_from_inside_target().ToString());
1783 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1784 occlusion
.occlusion_from_outside_target().ToString());
1786 this->LeaveLayer(surface_child
, &occlusion
);
1787 this->EnterLayer(surface
, &occlusion
);
1788 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1789 occlusion
.occlusion_from_inside_target().ToString());
1790 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1791 occlusion
.occlusion_from_outside_target().ToString());
1793 this->LeaveLayer(surface
, &occlusion
);
1794 this->EnterContributingSurface(surface
, &occlusion
);
1795 // Occlusion within the surface is lost when leaving the animating surface.
1796 EXPECT_EQ(gfx::Rect().ToString(),
1797 occlusion
.occlusion_from_inside_target().ToString());
1798 EXPECT_EQ(gfx::Rect().ToString(),
1799 occlusion
.occlusion_from_outside_target().ToString());
1801 this->LeaveContributingSurface(surface
, &occlusion
);
1802 // Occlusion from outside the animating surface still exists.
1803 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1804 occlusion
.occlusion_from_inside_target().ToString());
1805 EXPECT_EQ(gfx::Rect().ToString(),
1806 occlusion
.occlusion_from_outside_target().ToString());
1808 this->VisitLayer(layer
, &occlusion
);
1809 this->EnterLayer(parent
, &occlusion
);
1811 // Occlusion is not added for the animating |layer|.
1812 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1813 occlusion
.occlusion_from_inside_target().ToString());
1814 EXPECT_EQ(gfx::Rect().ToString(),
1815 occlusion
.occlusion_from_outside_target().ToString());
1819 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
1821 template <class Types
>
1822 class OcclusionTrackerTestAnimationTranslateOnMainThread
1823 : public OcclusionTrackerTest
<Types
> {
1825 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
1827 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1828 void RunMyTest() override
{
1829 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1830 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1831 typename
Types::ContentLayerType
* layer
=
1832 this->CreateDrawingLayer(parent
,
1833 this->identity_matrix
,
1835 gfx::Size(300, 300),
1837 typename
Types::ContentLayerType
* surface
=
1838 this->CreateDrawingSurface(parent
,
1839 this->identity_matrix
,
1841 gfx::Size(300, 300),
1843 typename
Types::ContentLayerType
* surface_child
=
1844 this->CreateDrawingLayer(surface
,
1845 this->identity_matrix
,
1847 gfx::Size(200, 300),
1849 typename
Types::ContentLayerType
* surface_child2
=
1850 this->CreateDrawingLayer(surface
,
1851 this->identity_matrix
,
1853 gfx::Size(100, 300),
1855 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
1856 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
1858 AddAnimatedTransformToController(
1859 layer
->layer_animation_controller(), 10.0, 30, 0);
1860 AddAnimatedTransformToController(
1861 surface
->layer_animation_controller(), 10.0, 30, 0);
1862 AddAnimatedTransformToController(
1863 surface_child
->layer_animation_controller(), 10.0, 30, 0);
1864 this->CalcDrawEtc(parent
);
1866 EXPECT_TRUE(layer
->draw_transform_is_animating());
1867 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
1869 surface
->render_surface()->target_surface_transforms_are_animating());
1871 surface
->render_surface()->screen_space_transforms_are_animating());
1872 // The surface owning layer doesn't animate against its own surface.
1873 EXPECT_FALSE(surface
->draw_transform_is_animating());
1874 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
1875 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
1876 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
1878 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1879 gfx::Rect(0, 0, 1000, 1000));
1881 this->VisitLayer(surface2
, &occlusion
);
1882 this->EnterContributingSurface(surface2
, &occlusion
);
1884 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1885 occlusion
.occlusion_from_inside_target().ToString());
1887 this->LeaveContributingSurface(surface2
, &occlusion
);
1888 this->EnterLayer(surface_child2
, &occlusion
);
1889 // surface_child2 is moving in screen space but not relative to its target,
1890 // so occlusion should happen in its target space only. It also means that
1891 // things occluding from outside the target (e.g. surface2) cannot occlude
1893 EXPECT_EQ(gfx::Rect().ToString(),
1894 occlusion
.occlusion_from_outside_target().ToString());
1895 EXPECT_EQ(gfx::Rect().ToString(),
1896 occlusion
.occlusion_from_inside_target().ToString());
1898 this->LeaveLayer(surface_child2
, &occlusion
);
1899 this->EnterLayer(surface_child
, &occlusion
);
1900 // surface_child2 added to the occlusion since it is not moving relative
1902 EXPECT_EQ(gfx::Rect().ToString(),
1903 occlusion
.occlusion_from_outside_target().ToString());
1904 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1905 occlusion
.occlusion_from_inside_target().ToString());
1907 this->LeaveLayer(surface_child
, &occlusion
);
1908 // surface_child is moving relative to its target, so it does not add
1910 EXPECT_EQ(gfx::Rect().ToString(),
1911 occlusion
.occlusion_from_outside_target().ToString());
1912 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1913 occlusion
.occlusion_from_inside_target().ToString());
1915 this->EnterLayer(surface
, &occlusion
);
1916 EXPECT_EQ(gfx::Rect().ToString(),
1917 occlusion
.occlusion_from_outside_target().ToString());
1918 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1919 occlusion
.occlusion_from_inside_target().ToString());
1921 this->LeaveLayer(surface
, &occlusion
);
1922 // The surface's owning layer is moving in screen space but not relative to
1923 // its target, so it adds to the occlusion.
1924 EXPECT_EQ(gfx::Rect().ToString(),
1925 occlusion
.occlusion_from_outside_target().ToString());
1926 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
1927 occlusion
.occlusion_from_inside_target().ToString());
1929 this->EnterContributingSurface(surface
, &occlusion
);
1930 this->LeaveContributingSurface(surface
, &occlusion
);
1931 // The |surface| is moving in the screen and in its target, so all occlusion
1932 // within the surface is lost when leaving it. Only the |surface2| occlusion
1934 EXPECT_EQ(gfx::Rect().ToString(),
1935 occlusion
.occlusion_from_outside_target().ToString());
1936 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1937 occlusion
.occlusion_from_inside_target().ToString());
1939 this->VisitLayer(layer
, &occlusion
);
1940 // The |layer| is animating in the screen and in its target, so no occlusion
1942 EXPECT_EQ(gfx::Rect().ToString(),
1943 occlusion
.occlusion_from_outside_target().ToString());
1944 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1945 occlusion
.occlusion_from_inside_target().ToString());
1949 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
1951 template <class Types
>
1952 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1953 : public OcclusionTrackerTest
<Types
> {
1955 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1957 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1958 void RunMyTest() override
{
1959 gfx::Transform surface_transform
;
1960 surface_transform
.Translate(300.0, 300.0);
1961 surface_transform
.Scale(2.0, 2.0);
1962 surface_transform
.Translate(-150.0, -150.0);
1964 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1965 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
1966 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
1967 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
1968 typename
Types::ContentLayerType
* surface2
=
1969 this->CreateDrawingSurface(parent
,
1970 this->identity_matrix
,
1971 gfx::PointF(50.f
, 50.f
),
1972 gfx::Size(300, 300),
1974 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1975 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1976 this->CalcDrawEtc(parent
);
1978 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1979 gfx::Rect(0, 0, 1000, 1000));
1981 this->VisitLayer(surface2
, &occlusion
);
1982 this->VisitContributingSurface(surface2
, &occlusion
);
1984 EXPECT_EQ(gfx::Rect().ToString(),
1985 occlusion
.occlusion_from_outside_target().ToString());
1986 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1987 occlusion
.occlusion_from_inside_target().ToString());
1989 // Clear any stored occlusion.
1990 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1991 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1993 this->VisitLayer(surface
, &occlusion
);
1994 this->VisitContributingSurface(surface
, &occlusion
);
1996 EXPECT_EQ(gfx::Rect().ToString(),
1997 occlusion
.occlusion_from_outside_target().ToString());
1998 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1999 occlusion
.occlusion_from_inside_target().ToString());
2003 MAIN_AND_IMPL_THREAD_TEST(
2004 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
2006 template <class Types
>
2007 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2008 : public OcclusionTrackerTest
<Types
> {
2010 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2012 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2013 void RunMyTest() override
{
2014 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2015 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2016 parent
->SetMasksToBounds(true);
2017 typename
Types::ContentLayerType
* surface
=
2018 this->CreateDrawingSurface(parent
,
2019 this->identity_matrix
,
2021 gfx::Size(500, 300),
2023 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2024 this->CalcDrawEtc(parent
);
2026 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2027 gfx::Rect(0, 0, 1000, 1000));
2029 this->VisitLayer(surface
, &occlusion
);
2030 this->VisitContributingSurface(surface
, &occlusion
);
2032 EXPECT_EQ(gfx::Rect().ToString(),
2033 occlusion
.occlusion_from_outside_target().ToString());
2034 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2035 occlusion
.occlusion_from_inside_target().ToString());
2039 MAIN_AND_IMPL_THREAD_TEST(
2040 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2042 template <class Types
>
2043 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2044 : public OcclusionTrackerTest
<Types
> {
2046 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
2047 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2048 void RunMyTest() override
{
2049 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2050 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2051 typename
Types::LayerType
* surface
=
2052 this->CreateDrawingSurface(parent
,
2053 this->identity_matrix
,
2055 gfx::Size(100, 100),
2057 this->CreateReplicaLayer(surface
,
2058 this->identity_matrix
,
2059 gfx::PointF(0.f
, 100.f
),
2060 gfx::Size(100, 100));
2061 typename
Types::LayerType
* topmost
=
2062 this->CreateDrawingLayer(parent
,
2063 this->identity_matrix
,
2065 gfx::Size(100, 110),
2067 this->CalcDrawEtc(parent
);
2069 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2070 gfx::Rect(0, 0, 1000, 1000));
2072 // |topmost| occludes the surface, but not the entire surface's replica.
2073 this->VisitLayer(topmost
, &occlusion
);
2075 EXPECT_EQ(gfx::Rect().ToString(),
2076 occlusion
.occlusion_from_outside_target().ToString());
2077 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2078 occlusion
.occlusion_from_inside_target().ToString());
2080 this->VisitLayer(surface
, &occlusion
);
2082 // Render target with replica ignores occlusion from outside.
2083 EXPECT_EQ(gfx::Rect().ToString(),
2084 occlusion
.occlusion_from_outside_target().ToString());
2085 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2086 occlusion
.occlusion_from_inside_target().ToString());
2088 this->EnterContributingSurface(surface
, &occlusion
);
2090 // Only occlusion from outside the surface occludes the surface/replica.
2091 EXPECT_EQ(gfx::Rect().ToString(),
2092 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2094 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2095 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2100 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2102 template <class Types
>
2103 class OcclusionTrackerTestSurfaceChildOfSurface
2104 : public OcclusionTrackerTest
<Types
> {
2106 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
2107 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2108 void RunMyTest() override
{
2109 // This test verifies that the surface cliprect does not end up empty and
2110 // clip away the entire unoccluded rect.
2112 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2113 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2114 typename
Types::LayerType
* surface
=
2115 this->CreateDrawingSurface(parent
,
2116 this->identity_matrix
,
2118 gfx::Size(100, 100),
2120 typename
Types::LayerType
* surface_child
=
2121 this->CreateDrawingSurface(surface
,
2122 this->identity_matrix
,
2123 gfx::PointF(0.f
, 10.f
),
2126 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
2127 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
2128 this->CalcDrawEtc(parent
);
2130 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2131 gfx::Rect(-100, -100, 1000, 1000));
2133 // |topmost| occludes everything partially so we know occlusion is happening
2135 this->VisitLayer(topmost
, &occlusion
);
2137 EXPECT_EQ(gfx::Rect().ToString(),
2138 occlusion
.occlusion_from_outside_target().ToString());
2139 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2140 occlusion
.occlusion_from_inside_target().ToString());
2142 this->VisitLayer(surface_child
, &occlusion
);
2144 // surface_child increases the occlusion in the screen by a narrow sliver.
2145 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2146 occlusion
.occlusion_from_outside_target().ToString());
2147 // In its own surface, surface_child is at 0,0 as is its occlusion.
2148 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2149 occlusion
.occlusion_from_inside_target().ToString());
2151 // The root layer always has a clip rect. So the parent of |surface| has a
2152 // clip rect. However, the owning layer for |surface| does not mask to
2153 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2154 // |surface_child| exercises different code paths as its parent does not
2155 // have a clip rect.
2157 this->EnterContributingSurface(surface_child
, &occlusion
);
2158 // The |surface_child| can't occlude its own surface, but occlusion from
2160 EXPECT_EQ(gfx::Rect().ToString(),
2161 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2163 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2164 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2166 this->LeaveContributingSurface(surface_child
, &occlusion
);
2168 // When the surface_child's occlusion is transformed up to its parent, make
2169 // sure it is not clipped away inappropriately.
2170 this->EnterLayer(surface
, &occlusion
);
2171 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2172 occlusion
.occlusion_from_outside_target().ToString());
2173 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2174 occlusion
.occlusion_from_inside_target().ToString());
2175 this->LeaveLayer(surface
, &occlusion
);
2177 this->EnterContributingSurface(surface
, &occlusion
);
2178 // The occlusion from inside |surface| can't affect the surface, but
2180 EXPECT_EQ(gfx::Rect().ToString(),
2181 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2183 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2184 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2187 this->LeaveContributingSurface(surface
, &occlusion
);
2188 this->EnterLayer(parent
, &occlusion
);
2189 // The occlusion in |surface| and without are merged into the parent.
2190 EXPECT_EQ(gfx::Rect().ToString(),
2191 occlusion
.occlusion_from_outside_target().ToString());
2192 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
2193 occlusion
.occlusion_from_inside_target().ToString());
2197 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2199 template <class Types
>
2200 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2201 : public OcclusionTrackerTest
<Types
> {
2203 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2205 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2206 void RunMyTest() override
{
2207 gfx::Transform scale_by_half
;
2208 scale_by_half
.Scale(0.5, 0.5);
2210 FilterOperations filters
;
2211 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
2213 // Save the distance of influence for the blur effect.
2214 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2216 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2223 LAST_DIRECTION
= BOTTOM
,
2226 for (int i
= 0; i
<= LAST_DIRECTION
; ++i
) {
2229 // Make a 50x50 filtered surface that is adjacent to occluding layers
2230 // which are above it in the z-order in various configurations. The
2231 // surface is scaled to test that the pixel moving is done in the target
2232 // space, where the background filter is applied.
2233 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2234 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
2235 typename
Types::LayerType
* filtered_surface
=
2236 this->CreateDrawingLayer(parent
,
2238 gfx::PointF(50.f
, 50.f
),
2239 gfx::Size(100, 100),
2241 Types::SetForceRenderSurface(filtered_surface
, true);
2242 filtered_surface
->SetBackgroundFilters(filters
);
2243 gfx::Rect occlusion_rect
;
2246 occlusion_rect
= gfx::Rect(0, 0, 50, 200);
2249 occlusion_rect
= gfx::Rect(100, 0, 50, 200);
2252 occlusion_rect
= gfx::Rect(0, 0, 200, 50);
2255 occlusion_rect
= gfx::Rect(0, 100, 200, 50);
2259 typename
Types::LayerType
* occluding_layer
=
2260 this->CreateDrawingLayer(parent
,
2261 this->identity_matrix
,
2262 occlusion_rect
.origin(),
2263 occlusion_rect
.size(),
2265 this->CalcDrawEtc(parent
);
2267 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2268 gfx::Rect(0, 0, 200, 200));
2270 // This layer occludes pixels directly beside the filtered_surface.
2271 // Because filtered surface blends pixels in a radius, it will need to see
2272 // some of the pixels (up to radius far) underneath the occluding layers.
2273 this->VisitLayer(occluding_layer
, &occlusion
);
2275 EXPECT_EQ(occlusion_rect
.ToString(),
2276 occlusion
.occlusion_from_inside_target().ToString());
2277 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2279 this->VisitLayer(filtered_surface
, &occlusion
);
2281 // The occlusion is used fully inside the surface.
2282 gfx::Rect occlusion_inside_surface
=
2283 occlusion_rect
- gfx::Vector2d(50, 50);
2284 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2285 EXPECT_EQ(occlusion_inside_surface
.ToString(),
2286 occlusion
.occlusion_from_outside_target().ToString());
2288 // The surface has a background blur, so it needs pixels that are
2289 // currently considered occluded in order to be drawn. So the pixels it
2290 // needs should be removed some the occluded area so that when we get to
2291 // the parent they are drawn.
2292 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2293 this->EnterLayer(parent
, &occlusion
);
2295 gfx::Rect expected_occlusion
= occlusion_rect
;
2298 expected_occlusion
.Inset(0, 0, outset_right
, 0);
2301 expected_occlusion
.Inset(outset_right
, 0, 0, 0);
2304 expected_occlusion
.Inset(0, 0, 0, outset_right
);
2307 expected_occlusion
.Inset(0, outset_right
, 0, 0);
2311 EXPECT_EQ(expected_occlusion
.ToString(),
2312 occlusion
.occlusion_from_inside_target().ToString());
2313 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2315 this->DestroyLayers();
2320 ALL_OCCLUSIONTRACKER_TEST(
2321 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
2323 template <class Types
>
2324 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
2325 : public OcclusionTrackerTest
<Types
> {
2327 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
2329 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2330 void RunMyTest() override
{
2331 gfx::Transform scale_by_half
;
2332 scale_by_half
.Scale(0.5, 0.5);
2334 // Makes two surfaces that completely cover |parent|. The occlusion both
2335 // above and below the filters will be reduced by each of them.
2336 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2337 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
2338 typename
Types::LayerType
* parent
= this->CreateSurface(
2339 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
2340 parent
->SetMasksToBounds(true);
2341 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
2342 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
2343 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
2344 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
2345 typename
Types::LayerType
* occluding_layer_above
=
2346 this->CreateDrawingLayer(parent
,
2347 this->identity_matrix
,
2348 gfx::PointF(100.f
, 100.f
),
2352 // Filters make the layers own surfaces.
2353 Types::SetForceRenderSurface(filtered_surface1
, true);
2354 Types::SetForceRenderSurface(filtered_surface2
, true);
2355 FilterOperations filters
;
2356 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
2357 filtered_surface1
->SetBackgroundFilters(filters
);
2358 filtered_surface2
->SetBackgroundFilters(filters
);
2360 // Save the distance of influence for the blur effect.
2361 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2363 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2365 this->CalcDrawEtc(root
);
2367 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2368 gfx::Rect(0, 0, 1000, 1000));
2370 this->VisitLayer(occluding_layer_above
, &occlusion
);
2371 EXPECT_EQ(gfx::Rect().ToString(),
2372 occlusion
.occlusion_from_outside_target().ToString());
2373 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
2374 occlusion
.occlusion_from_inside_target().ToString());
2376 this->VisitLayer(filtered_surface2
, &occlusion
);
2377 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
2378 this->VisitLayer(filtered_surface1
, &occlusion
);
2379 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
2381 // Test expectations in the target.
2382 gfx::Rect expected_occlusion
=
2383 gfx::Rect(100 / 2 + outset_right
* 2,
2384 100 / 2 + outset_bottom
* 2,
2385 50 / 2 - (outset_left
+ outset_right
) * 2,
2386 50 / 2 - (outset_top
+ outset_bottom
) * 2);
2387 EXPECT_EQ(expected_occlusion
.ToString(),
2388 occlusion
.occlusion_from_inside_target().ToString());
2390 // Test expectations in the screen are the same as in the target, as the
2391 // render surface is 1:1 with the screen.
2392 EXPECT_EQ(expected_occlusion
.ToString(),
2393 occlusion
.occlusion_from_outside_target().ToString());
2397 ALL_OCCLUSIONTRACKER_TEST(
2398 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
2400 template <class Types
>
2401 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
2402 : public OcclusionTrackerTest
<Types
> {
2404 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
2406 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2407 void RunMyTest() override
{
2408 gfx::Transform scale_by_half
;
2409 scale_by_half
.Scale(0.5, 0.5);
2411 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
2412 // centered below each. The surface is scaled to test that the pixel moving
2413 // is done in the target space, where the background filter is applied, but
2414 // the surface appears at 50, 50 and the replica at 200, 50.
2415 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2416 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
2417 typename
Types::LayerType
* behind_surface_layer
=
2418 this->CreateDrawingLayer(parent
,
2419 this->identity_matrix
,
2420 gfx::PointF(60.f
, 60.f
),
2423 typename
Types::LayerType
* behind_replica_layer
=
2424 this->CreateDrawingLayer(parent
,
2425 this->identity_matrix
,
2426 gfx::PointF(210.f
, 60.f
),
2429 typename
Types::LayerType
* filtered_surface
=
2430 this->CreateDrawingLayer(parent
,
2432 gfx::PointF(50.f
, 50.f
),
2433 gfx::Size(100, 100),
2435 this->CreateReplicaLayer(filtered_surface
,
2436 this->identity_matrix
,
2437 gfx::PointF(300.f
, 0.f
),
2440 // Filters make the layer own a surface.
2441 Types::SetForceRenderSurface(filtered_surface
, true);
2442 FilterOperations filters
;
2443 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2444 filtered_surface
->SetBackgroundFilters(filters
);
2446 this->CalcDrawEtc(parent
);
2448 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2449 gfx::Rect(0, 0, 1000, 1000));
2451 // The surface has a background blur, so it blurs non-opaque pixels below
2453 this->VisitLayer(filtered_surface
, &occlusion
);
2454 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2456 this->VisitLayer(behind_replica_layer
, &occlusion
);
2458 // The layers behind the surface are not blurred, and their occlusion does
2459 // not change, until we leave the surface. So it should not be modified by
2461 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
2462 EXPECT_EQ(occlusion_behind_replica
.ToString(),
2463 occlusion
.occlusion_from_inside_target().ToString());
2464 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2466 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
2467 // without existing occlusion interfering.
2468 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2470 this->VisitLayer(behind_surface_layer
, &occlusion
);
2472 // The layers behind the surface are not blurred, and their occlusion does
2473 // not change, until we leave the surface. So it should not be modified by
2475 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
2476 EXPECT_EQ(occlusion_behind_surface
.ToString(),
2477 occlusion
.occlusion_from_inside_target().ToString());
2478 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2482 ALL_OCCLUSIONTRACKER_TEST(
2483 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
2485 template <class Types
>
2486 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
2487 : public OcclusionTrackerTest
<Types
> {
2489 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
2491 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2492 void RunMyTest() override
{
2493 gfx::Transform scale_by_half
;
2494 scale_by_half
.Scale(0.5, 0.5);
2496 // Make a 50x50 filtered surface that is completely occluded by an opaque
2497 // layer which is above it in the z-order. The surface is
2498 // scaled to test that the pixel moving is done in the target space, where
2499 // the background filter is applied, but the surface appears at 50, 50.
2500 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2501 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
2502 typename
Types::LayerType
* filtered_surface
=
2503 this->CreateDrawingLayer(parent
,
2505 gfx::PointF(50.f
, 50.f
),
2506 gfx::Size(100, 100),
2508 typename
Types::LayerType
* occluding_layer
=
2509 this->CreateDrawingLayer(parent
,
2510 this->identity_matrix
,
2511 gfx::PointF(50.f
, 50.f
),
2515 // Filters make the layer own a surface.
2516 Types::SetForceRenderSurface(filtered_surface
, true);
2517 FilterOperations filters
;
2518 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2519 filtered_surface
->SetBackgroundFilters(filters
);
2521 this->CalcDrawEtc(parent
);
2523 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2524 gfx::Rect(0, 0, 1000, 1000));
2526 this->VisitLayer(occluding_layer
, &occlusion
);
2528 this->VisitLayer(filtered_surface
, &occlusion
);
2530 // The layers above the filtered surface occlude from outside.
2531 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
2533 EXPECT_EQ(gfx::Rect().ToString(),
2534 occlusion
.occlusion_from_inside_target().ToString());
2535 EXPECT_EQ(occlusion_above_surface
.ToString(),
2536 occlusion
.occlusion_from_outside_target().ToString());
2539 // The surface has a background blur, so it blurs non-opaque pixels below
2541 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2543 // The filter is completely occluded, so it should not blur anything and
2544 // reduce any occlusion.
2545 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
2547 EXPECT_EQ(occlusion_above_surface
.ToString(),
2548 occlusion
.occlusion_from_inside_target().ToString());
2549 EXPECT_EQ(gfx::Rect().ToString(),
2550 occlusion
.occlusion_from_outside_target().ToString());
2555 ALL_OCCLUSIONTRACKER_TEST(
2556 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
2558 template <class Types
>
2559 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
2560 : public OcclusionTrackerTest
<Types
> {
2563 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
2565 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2566 void RunMyTest() override
{
2567 gfx::Transform scale_by_half
;
2568 scale_by_half
.Scale(0.5, 0.5);
2570 // Make a surface and its replica, each 50x50, that are partially occluded
2571 // by opaque layers which are above them in the z-order. The surface is
2572 // scaled to test that the pixel moving is done in the target space, where
2573 // the background filter is applied, but the surface appears at 50, 50 and
2574 // the replica at 200, 50.
2575 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2576 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
2577 typename
Types::LayerType
* filtered_surface
=
2578 this->CreateDrawingLayer(parent
,
2580 gfx::PointF(50.f
, 50.f
),
2581 gfx::Size(100, 100),
2583 this->CreateReplicaLayer(filtered_surface
,
2584 this->identity_matrix
,
2585 gfx::PointF(300.f
, 0.f
),
2587 typename
Types::LayerType
* above_surface_layer
=
2588 this->CreateDrawingLayer(parent
,
2589 this->identity_matrix
,
2590 gfx::PointF(70.f
, 50.f
),
2593 typename
Types::LayerType
* above_replica_layer
=
2594 this->CreateDrawingLayer(parent
,
2595 this->identity_matrix
,
2596 gfx::PointF(200.f
, 50.f
),
2599 typename
Types::LayerType
* beside_surface_layer
=
2600 this->CreateDrawingLayer(parent
,
2601 this->identity_matrix
,
2602 gfx::PointF(90.f
, 40.f
),
2605 typename
Types::LayerType
* beside_replica_layer
=
2606 this->CreateDrawingLayer(parent
,
2607 this->identity_matrix
,
2608 gfx::PointF(200.f
, 40.f
),
2612 // Filters make the layer own a surface.
2613 Types::SetForceRenderSurface(filtered_surface
, true);
2614 FilterOperations filters
;
2615 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2616 filtered_surface
->SetBackgroundFilters(filters
);
2618 // Save the distance of influence for the blur effect.
2619 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2621 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2623 this->CalcDrawEtc(parent
);
2625 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2626 gfx::Rect(0, 0, 1000, 1000));
2628 this->VisitLayer(beside_replica_layer
, &occlusion
);
2629 this->VisitLayer(beside_surface_layer
, &occlusion
);
2630 this->VisitLayer(above_replica_layer
, &occlusion
);
2631 this->VisitLayer(above_surface_layer
, &occlusion
);
2633 // The surface has a background blur, so it blurs non-opaque pixels below
2635 this->VisitLayer(filtered_surface
, &occlusion
);
2636 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2638 // The filter in the surface and replica are partially unoccluded. Only the
2639 // unoccluded parts should reduce occlusion. This means it will push back
2640 // the occlusion that touches the unoccluded part (occlusion_above___), but
2641 // it will not touch occlusion_beside____ since that is not beside the
2642 // unoccluded part of the surface, even though it is beside the occluded
2643 // part of the surface.
2644 gfx::Rect occlusion_above_surface
=
2645 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
2646 gfx::Rect occlusion_above_replica
=
2647 gfx::Rect(200, 50, 30 - outset_left
, 50);
2648 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
2649 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
2651 SimpleEnclosedRegion expected_occlusion
;
2652 expected_occlusion
.Union(occlusion_beside_replica
);
2653 expected_occlusion
.Union(occlusion_beside_surface
);
2654 expected_occlusion
.Union(occlusion_above_replica
);
2655 expected_occlusion
.Union(occlusion_above_surface
);
2657 EXPECT_EQ(expected_occlusion
.ToString(),
2658 occlusion
.occlusion_from_inside_target().ToString());
2659 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2661 const SimpleEnclosedRegion
& actual_occlusion
=
2662 occlusion
.occlusion_from_inside_target();
2663 for (size_t i
= 0; i
< expected_occlusion
.GetRegionComplexity(); ++i
) {
2664 ASSERT_LT(i
, actual_occlusion
.GetRegionComplexity());
2665 EXPECT_EQ(expected_occlusion
.GetRect(i
), actual_occlusion
.GetRect(i
));
2670 ALL_OCCLUSIONTRACKER_TEST(
2671 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
2673 template <class Types
>
2674 class OcclusionTrackerTestMinimumTrackingSize
2675 : public OcclusionTrackerTest
<Types
> {
2677 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
2678 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2679 void RunMyTest() override
{
2680 gfx::Size
tracking_size(100, 100);
2681 gfx::Size
below_tracking_size(99, 99);
2683 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2684 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2685 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
2686 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
2687 typename
Types::LayerType
* small
=
2688 this->CreateDrawingLayer(parent
,
2689 this->identity_matrix
,
2691 below_tracking_size
,
2693 this->CalcDrawEtc(parent
);
2695 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2696 gfx::Rect(0, 0, 1000, 1000));
2697 occlusion
.set_minimum_tracking_size(tracking_size
);
2699 // The small layer is not tracked because it is too small.
2700 this->VisitLayer(small
, &occlusion
);
2702 EXPECT_EQ(gfx::Rect().ToString(),
2703 occlusion
.occlusion_from_outside_target().ToString());
2704 EXPECT_EQ(gfx::Rect().ToString(),
2705 occlusion
.occlusion_from_inside_target().ToString());
2707 // The large layer is tracked as it is large enough.
2708 this->VisitLayer(large
, &occlusion
);
2710 EXPECT_EQ(gfx::Rect().ToString(),
2711 occlusion
.occlusion_from_outside_target().ToString());
2712 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
2713 occlusion
.occlusion_from_inside_target().ToString());
2717 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
2719 template <class Types
>
2720 class OcclusionTrackerTestScaledLayerIsClipped
2721 : public OcclusionTrackerTest
<Types
> {
2723 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
2724 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2725 void RunMyTest() override
{
2726 gfx::Transform scale_transform
;
2727 scale_transform
.Scale(512.0, 512.0);
2729 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2730 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2731 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
2732 this->identity_matrix
,
2733 gfx::PointF(10.f
, 10.f
),
2735 clip
->SetMasksToBounds(true);
2736 typename
Types::LayerType
* scale
= this->CreateLayer(
2737 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
2738 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
2739 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
2740 this->CalcDrawEtc(parent
);
2742 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2743 gfx::Rect(0, 0, 1000, 1000));
2745 this->VisitLayer(scaled
, &occlusion
);
2747 EXPECT_EQ(gfx::Rect().ToString(),
2748 occlusion
.occlusion_from_outside_target().ToString());
2749 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2750 occlusion
.occlusion_from_inside_target().ToString());
2754 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
2756 template <class Types
>
2757 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
2758 : public OcclusionTrackerTest
<Types
> {
2760 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
2761 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2762 void RunMyTest() override
{
2763 gfx::Transform scale_transform
;
2764 scale_transform
.Scale(512.0, 512.0);
2766 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2767 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2768 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
2769 this->identity_matrix
,
2770 gfx::PointF(10.f
, 10.f
),
2772 clip
->SetMasksToBounds(true);
2773 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
2774 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
2775 typename
Types::LayerType
* scale
= this->CreateLayer(
2776 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
2777 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
2778 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
2779 this->CalcDrawEtc(parent
);
2781 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2782 gfx::Rect(0, 0, 1000, 1000));
2784 this->VisitLayer(scaled
, &occlusion
);
2785 this->VisitLayer(surface
, &occlusion
);
2786 this->VisitContributingSurface(surface
, &occlusion
);
2788 EXPECT_EQ(gfx::Rect().ToString(),
2789 occlusion
.occlusion_from_outside_target().ToString());
2790 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2791 occlusion
.occlusion_from_inside_target().ToString());
2795 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
2797 template <class Types
>
2798 class OcclusionTrackerTestCopyRequestDoesOcclude
2799 : public OcclusionTrackerTest
<Types
> {
2801 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
2802 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2803 void RunMyTest() override
{
2804 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2805 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2806 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
2807 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2808 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
2809 this->identity_matrix
,
2811 gfx::Size(200, 400));
2812 this->AddCopyRequest(copy
);
2813 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
2815 this->identity_matrix
,
2817 gfx::Size(200, 400),
2819 this->CalcDrawEtc(root
);
2821 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2822 gfx::Rect(0, 0, 1000, 1000));
2824 this->VisitLayer(copy_child
, &occlusion
);
2825 EXPECT_EQ(gfx::Rect().ToString(),
2826 occlusion
.occlusion_from_outside_target().ToString());
2827 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2828 occlusion
.occlusion_from_inside_target().ToString());
2830 // CopyRequests cause the layer to own a surface.
2831 this->VisitContributingSurface(copy
, &occlusion
);
2833 // The occlusion from the copy should be kept.
2834 EXPECT_EQ(gfx::Rect().ToString(),
2835 occlusion
.occlusion_from_outside_target().ToString());
2836 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
2837 occlusion
.occlusion_from_inside_target().ToString());
2841 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
2843 template <class Types
>
2844 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2845 : public OcclusionTrackerTest
<Types
> {
2847 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2849 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2850 void RunMyTest() override
{
2851 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2852 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2853 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
2854 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2855 typename
Types::LayerType
* hide
= this->CreateLayer(
2856 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
2857 typename
Types::LayerType
* copy
= this->CreateLayer(
2858 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
2859 this->AddCopyRequest(copy
);
2860 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
2861 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
2863 // The |copy| layer is hidden but since it is being copied, it will be
2865 hide
->SetHideLayerAndSubtree(true);
2867 this->CalcDrawEtc(root
);
2869 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2870 gfx::Rect(0, 0, 1000, 1000));
2872 this->VisitLayer(copy_child
, &occlusion
);
2873 EXPECT_EQ(gfx::Rect().ToString(),
2874 occlusion
.occlusion_from_outside_target().ToString());
2875 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2876 occlusion
.occlusion_from_inside_target().ToString());
2878 // CopyRequests cause the layer to own a surface.
2879 this->VisitContributingSurface(copy
, &occlusion
);
2881 // The occlusion from the copy should be dropped since it is hidden.
2882 EXPECT_EQ(gfx::Rect().ToString(),
2883 occlusion
.occlusion_from_outside_target().ToString());
2884 EXPECT_EQ(gfx::Rect().ToString(),
2885 occlusion
.occlusion_from_inside_target().ToString());
2889 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
2891 template <class Types
>
2892 class OcclusionTrackerTestOccludedLayer
: public OcclusionTrackerTest
<Types
> {
2894 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers
)
2895 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2896 void RunMyTest() override
{
2897 gfx::Transform translate
;
2898 translate
.Translate(10.0, 20.0);
2899 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2900 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2901 typename
Types::LayerType
* surface
= this->CreateSurface(
2902 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2903 typename
Types::LayerType
* layer
= this->CreateDrawingLayer(
2904 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2905 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
2906 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2907 this->CalcDrawEtc(root
);
2909 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2910 gfx::Rect(0, 0, 200, 200));
2911 this->VisitLayer(outside_layer
, &occlusion
);
2912 this->EnterLayer(layer
, &occlusion
);
2914 // No occlusion, is not occluded.
2915 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2916 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2917 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100)));
2919 // Partial occlusion from outside, is not occluded.
2920 occlusion
.set_occlusion_from_outside_target(
2921 SimpleEnclosedRegion(50, 50, 100, 100));
2922 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2923 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2924 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2925 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2926 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2927 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2928 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2929 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2930 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2932 // Full occlusion from outside, is occluded.
2933 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2934 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2935 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2936 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2938 // Partial occlusion from inside, is not occluded.
2939 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2940 occlusion
.set_occlusion_from_inside_target(
2941 SimpleEnclosedRegion(50, 50, 100, 100));
2942 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2943 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2944 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2945 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2946 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2947 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2948 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2949 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2951 // Full occlusion from inside, is occluded.
2952 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2953 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2954 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2955 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2957 // Partial occlusion from both, is not occluded.
2958 occlusion
.set_occlusion_from_outside_target(
2959 SimpleEnclosedRegion(50, 50, 100, 50));
2960 occlusion
.set_occlusion_from_inside_target(
2961 SimpleEnclosedRegion(50, 100, 100, 50));
2962 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2963 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2964 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2965 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2966 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2967 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2968 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2969 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2971 // Full occlusion from both, is occluded.
2972 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2973 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2974 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2975 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2979 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer
)
2981 template <class Types
>
2982 class OcclusionTrackerTestUnoccludedLayerQuery
2983 : public OcclusionTrackerTest
<Types
> {
2985 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers
)
2986 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2987 void RunMyTest() override
{
2988 gfx::Transform translate
;
2989 translate
.Translate(10.0, 20.0);
2990 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2991 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2992 typename
Types::LayerType
* surface
= this->CreateSurface(
2993 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2994 typename
Types::LayerType
* layer
= this->CreateDrawingLayer(
2995 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2996 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
2997 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2998 this->CalcDrawEtc(root
);
3000 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3001 gfx::Rect(0, 0, 200, 200));
3002 this->VisitLayer(outside_layer
, &occlusion
);
3003 this->EnterLayer(layer
, &occlusion
);
3005 // No occlusion, is not occluded.
3006 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3007 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3008 EXPECT_EQ(gfx::Rect(100, 100),
3009 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(100, 100)));
3011 // Partial occlusion from outside.
3012 occlusion
.set_occlusion_from_outside_target(
3013 SimpleEnclosedRegion(50, 50, 100, 100));
3014 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3016 gfx::Rect(0, 0, 100, 100),
3017 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3018 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3019 occlusion
.UnoccludedLayerContentRect(
3020 layer
, gfx::Rect(90, 30, 100, 100)));
3021 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3022 occlusion
.UnoccludedLayerContentRect(layer
,
3023 gfx::Rect(40, 0, 100, 100)));
3024 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3025 occlusion
.UnoccludedLayerContentRect(
3026 layer
, gfx::Rect(40, 80, 100, 100)));
3028 gfx::Rect(0, 0, 80, 100),
3029 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3030 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3031 occlusion
.UnoccludedLayerContentRect(
3032 layer
, gfx::Rect(90, 80, 100, 100)));
3033 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3034 occlusion
.UnoccludedLayerContentRect(layer
,
3035 gfx::Rect(0, 80, 100, 100)));
3036 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3037 occlusion
.UnoccludedLayerContentRect(layer
,
3038 gfx::Rect(90, 0, 100, 100)));
3040 // Full occlusion from outside, is occluded.
3041 EXPECT_EQ(gfx::Rect(),
3042 occlusion
.UnoccludedLayerContentRect(
3043 layer
, gfx::Rect(40, 30, 100, 100)));
3046 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3047 EXPECT_EQ(gfx::Rect(),
3048 occlusion
.UnoccludedLayerContentRect(
3049 layer
, gfx::Rect(130, 120, 10, 10)));
3052 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3054 // Partial occlusion from inside, is not occluded.
3055 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3056 occlusion
.set_occlusion_from_inside_target(
3057 SimpleEnclosedRegion(50, 50, 100, 100));
3059 gfx::Rect(0, 0, 100, 100),
3060 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3061 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3062 occlusion
.UnoccludedLayerContentRect(
3063 layer
, gfx::Rect(90, 30, 100, 100)));
3064 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3065 occlusion
.UnoccludedLayerContentRect(layer
,
3066 gfx::Rect(40, 0, 100, 100)));
3067 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3068 occlusion
.UnoccludedLayerContentRect(
3069 layer
, gfx::Rect(40, 80, 100, 100)));
3071 gfx::Rect(0, 0, 80, 100),
3072 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3073 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3074 occlusion
.UnoccludedLayerContentRect(
3075 layer
, gfx::Rect(90, 80, 100, 100)));
3076 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3077 occlusion
.UnoccludedLayerContentRect(layer
,
3078 gfx::Rect(0, 80, 100, 100)));
3079 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3080 occlusion
.UnoccludedLayerContentRect(layer
,
3081 gfx::Rect(90, 0, 100, 100)));
3083 // Full occlusion from inside, is occluded.
3084 EXPECT_EQ(gfx::Rect(),
3085 occlusion
.UnoccludedLayerContentRect(
3086 layer
, gfx::Rect(40, 30, 100, 100)));
3089 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3090 EXPECT_EQ(gfx::Rect(),
3091 occlusion
.UnoccludedLayerContentRect(
3092 layer
, gfx::Rect(130, 120, 10, 10)));
3095 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3097 // Partial occlusion from both, is not occluded.
3098 occlusion
.set_occlusion_from_outside_target(
3099 SimpleEnclosedRegion(50, 50, 100, 50));
3100 occlusion
.set_occlusion_from_inside_target(
3101 SimpleEnclosedRegion(50, 100, 100, 50));
3103 gfx::Rect(0, 0, 100, 100),
3104 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3105 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3107 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3108 occlusion
.UnoccludedLayerContentRect(
3109 layer
, gfx::Rect(90, 30, 100, 100)));
3110 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3111 occlusion
.UnoccludedLayerContentRect(layer
,
3112 gfx::Rect(40, 0, 100, 100)));
3113 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3114 occlusion
.UnoccludedLayerContentRect(
3115 layer
, gfx::Rect(40, 80, 100, 100)));
3117 gfx::Rect(0, 0, 80, 100),
3118 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3119 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3120 occlusion
.UnoccludedLayerContentRect(
3121 layer
, gfx::Rect(90, 80, 100, 100)));
3122 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3123 occlusion
.UnoccludedLayerContentRect(layer
,
3124 gfx::Rect(0, 80, 100, 100)));
3125 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3126 occlusion
.UnoccludedLayerContentRect(layer
,
3127 gfx::Rect(90, 0, 100, 100)));
3129 // Full occlusion from both, is occluded.
3130 EXPECT_EQ(gfx::Rect(),
3131 occlusion
.UnoccludedLayerContentRect(
3132 layer
, gfx::Rect(40, 30, 100, 100)));
3135 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3136 EXPECT_EQ(gfx::Rect(),
3137 occlusion
.UnoccludedLayerContentRect(
3138 layer
, gfx::Rect(130, 120, 10, 10)));
3141 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3145 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery
)
3147 template <class Types
>
3148 class OcclusionTrackerTestUnoccludedSurfaceQuery
3149 : public OcclusionTrackerTest
<Types
> {
3151 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers
)
3152 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3153 void RunMyTest() override
{
3154 gfx::Transform translate
;
3155 translate
.Translate(10.0, 20.0);
3156 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3157 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
3158 typename
Types::LayerType
* surface
=
3159 this->CreateSurface(root
, translate
, gfx::Point(), gfx::Size(200, 200));
3160 typename
Types::LayerType
* layer
=
3161 this->CreateDrawingLayer(surface
,
3162 this->identity_matrix
,
3164 gfx::Size(200, 200),
3166 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
3167 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
3168 this->CalcDrawEtc(root
);
3170 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3171 gfx::Rect(0, 0, 200, 200));
3172 this->VisitLayer(outside_layer
, &occlusion
);
3173 this->VisitLayer(layer
, &occlusion
);
3174 this->EnterContributingSurface(surface
, &occlusion
);
3176 // No occlusion, is not occluded.
3177 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3178 SimpleEnclosedRegion());
3179 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3180 SimpleEnclosedRegion());
3182 gfx::Rect(100, 100),
3183 occlusion
.UnoccludedSurfaceContentRect(surface
, gfx::Rect(100, 100)));
3185 // Partial occlusion from outside.
3186 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3187 SimpleEnclosedRegion(50, 50, 100, 100));
3188 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3189 SimpleEnclosedRegion());
3190 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3191 occlusion
.UnoccludedSurfaceContentRect(
3192 surface
, gfx::Rect(0, 0, 100, 100)));
3193 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3194 occlusion
.UnoccludedSurfaceContentRect(
3195 surface
, gfx::Rect(90, 30, 100, 100)));
3196 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3197 occlusion
.UnoccludedSurfaceContentRect(
3198 surface
, gfx::Rect(40, 0, 100, 100)));
3199 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3200 occlusion
.UnoccludedSurfaceContentRect(
3201 surface
, gfx::Rect(40, 80, 100, 100)));
3202 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3203 occlusion
.UnoccludedSurfaceContentRect(surface
,
3204 gfx::Rect(0, 0, 80, 100)));
3205 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3206 occlusion
.UnoccludedSurfaceContentRect(
3207 surface
, gfx::Rect(90, 80, 100, 100)));
3208 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3209 occlusion
.UnoccludedSurfaceContentRect(
3210 surface
, gfx::Rect(0, 80, 100, 100)));
3211 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3212 occlusion
.UnoccludedSurfaceContentRect(
3213 surface
, gfx::Rect(90, 0, 100, 100)));
3215 // Full occlusion from outside, is occluded.
3216 EXPECT_EQ(gfx::Rect(),
3217 occlusion
.UnoccludedSurfaceContentRect(
3218 surface
, gfx::Rect(40, 30, 100, 100)));
3219 EXPECT_EQ(gfx::Rect(),
3220 occlusion
.UnoccludedSurfaceContentRect(
3221 surface
, gfx::Rect(40, 30, 10, 10)));
3222 EXPECT_EQ(gfx::Rect(),
3223 occlusion
.UnoccludedSurfaceContentRect(
3224 surface
, gfx::Rect(130, 120, 10, 10)));
3225 EXPECT_EQ(gfx::Rect(),
3226 occlusion
.UnoccludedSurfaceContentRect(
3227 surface
, gfx::Rect(80, 70, 50, 50)));
3229 // Partial occlusion from inside, is not occluded.
3230 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3231 SimpleEnclosedRegion());
3232 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3233 SimpleEnclosedRegion(50, 50, 100, 100));
3234 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3235 occlusion
.UnoccludedSurfaceContentRect(
3236 surface
, gfx::Rect(0, 0, 100, 100)));
3237 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3238 occlusion
.UnoccludedSurfaceContentRect(
3239 surface
, gfx::Rect(90, 30, 100, 100)));
3240 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3241 occlusion
.UnoccludedSurfaceContentRect(
3242 surface
, gfx::Rect(40, 0, 100, 100)));
3243 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3244 occlusion
.UnoccludedSurfaceContentRect(
3245 surface
, gfx::Rect(40, 80, 100, 100)));
3246 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3247 occlusion
.UnoccludedSurfaceContentRect(surface
,
3248 gfx::Rect(0, 0, 80, 100)));
3249 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3250 occlusion
.UnoccludedSurfaceContentRect(
3251 surface
, gfx::Rect(90, 80, 100, 100)));
3252 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3253 occlusion
.UnoccludedSurfaceContentRect(
3254 surface
, gfx::Rect(0, 80, 100, 100)));
3255 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3256 occlusion
.UnoccludedSurfaceContentRect(
3257 surface
, gfx::Rect(90, 0, 100, 100)));
3259 // Full occlusion from inside, is occluded.
3260 EXPECT_EQ(gfx::Rect(),
3261 occlusion
.UnoccludedSurfaceContentRect(
3262 surface
, gfx::Rect(40, 30, 100, 100)));
3263 EXPECT_EQ(gfx::Rect(),
3264 occlusion
.UnoccludedSurfaceContentRect(
3265 surface
, gfx::Rect(40, 30, 10, 10)));
3266 EXPECT_EQ(gfx::Rect(),
3267 occlusion
.UnoccludedSurfaceContentRect(
3268 surface
, gfx::Rect(130, 120, 10, 10)));
3269 EXPECT_EQ(gfx::Rect(),
3270 occlusion
.UnoccludedSurfaceContentRect(
3271 surface
, gfx::Rect(80, 70, 50, 50)));
3273 // Partial occlusion from both, is not occluded.
3274 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3275 SimpleEnclosedRegion(50, 50, 100, 50));
3276 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3277 SimpleEnclosedRegion(50, 100, 100, 50));
3278 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3279 occlusion
.UnoccludedSurfaceContentRect(
3280 surface
, gfx::Rect(0, 0, 100, 100)));
3281 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3283 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3284 occlusion
.UnoccludedSurfaceContentRect(
3285 surface
, gfx::Rect(90, 30, 100, 100)));
3286 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3287 occlusion
.UnoccludedSurfaceContentRect(
3288 surface
, gfx::Rect(40, 0, 100, 100)));
3289 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3290 occlusion
.UnoccludedSurfaceContentRect(
3291 surface
, gfx::Rect(40, 80, 100, 100)));
3292 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3293 occlusion
.UnoccludedSurfaceContentRect(surface
,
3294 gfx::Rect(0, 0, 80, 100)));
3295 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3296 occlusion
.UnoccludedSurfaceContentRect(
3297 surface
, gfx::Rect(90, 80, 100, 100)));
3298 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3299 occlusion
.UnoccludedSurfaceContentRect(
3300 surface
, gfx::Rect(0, 80, 100, 100)));
3301 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3302 occlusion
.UnoccludedSurfaceContentRect(
3303 surface
, gfx::Rect(90, 0, 100, 100)));
3305 // Full occlusion from both, is occluded.
3306 EXPECT_EQ(gfx::Rect(),
3307 occlusion
.UnoccludedSurfaceContentRect(
3308 surface
, gfx::Rect(40, 30, 100, 100)));
3309 EXPECT_EQ(gfx::Rect(),
3310 occlusion
.UnoccludedSurfaceContentRect(
3311 surface
, gfx::Rect(40, 30, 10, 10)));
3312 EXPECT_EQ(gfx::Rect(),
3313 occlusion
.UnoccludedSurfaceContentRect(
3314 surface
, gfx::Rect(130, 120, 10, 10)));
3315 EXPECT_EQ(gfx::Rect(),
3316 occlusion
.UnoccludedSurfaceContentRect(
3317 surface
, gfx::Rect(80, 70, 50, 50)));
3321 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery
)