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
);
131 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
133 static void RecursiveUpdateNumChildren(LayerType
* layerType
) {}
136 struct OcclusionTrackerTestImplThreadTypes
{
137 typedef LayerImpl LayerType
;
138 typedef LayerTreeImpl HostType
;
139 typedef RenderSurfaceImpl RenderSurfaceType
;
140 typedef TestContentLayerImpl ContentLayerType
;
141 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
142 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
143 typedef LayerIterator
<LayerImpl
> TestLayerIterator
;
144 typedef OcclusionTracker
<LayerImpl
> OcclusionTrackerType
;
146 static LayerPtrType
CreateLayer(HostType
* host
) {
147 return LayerImpl::Create(host
, next_layer_impl_id
++);
149 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
150 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
152 static int next_layer_impl_id
;
154 template <typename T
>
155 static LayerPtrType
PassLayerPtr(T
* layer
) {
156 return layer
->Pass();
159 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
161 static void RecursiveUpdateNumChildren(LayerType
* layer
) {
162 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer
);
166 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
168 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
170 explicit OcclusionTrackerTest(bool opaque_layers
)
171 : opaque_layers_(opaque_layers
),
172 client_(FakeLayerTreeHostClient::DIRECT_3D
),
173 host_(FakeLayerTreeHost::Create(&client_
)) {}
175 virtual void RunMyTest() = 0;
177 virtual void TearDown() { DestroyLayers(); }
179 typename
Types::HostType
* GetHost();
181 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
182 const gfx::PointF
& position
,
183 const gfx::Size
& bounds
) {
184 typename
Types::ContentLayerPtrType
layer(
185 Types::CreateContentLayer(GetHost()));
186 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
187 SetProperties(layer_ptr
, transform
, position
, bounds
);
189 DCHECK(!root_
.get());
190 root_
= Types::PassLayerPtr(&layer
);
192 SetRootLayerOnMainThread(layer_ptr
);
197 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
198 const gfx::Transform
& transform
,
199 const gfx::PointF
& position
,
200 const gfx::Size
& bounds
) {
201 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
202 typename
Types::LayerType
* layer_ptr
= layer
.get();
203 SetProperties(layer_ptr
, transform
, position
, bounds
);
204 parent
->AddChild(Types::PassLayerPtr(&layer
));
208 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
209 const gfx::Transform
& transform
,
210 const gfx::PointF
& position
,
211 const gfx::Size
& bounds
) {
212 typename
Types::LayerType
* layer
=
213 CreateLayer(parent
, transform
, position
, bounds
);
214 layer
->SetForceRenderSurface(true);
218 typename
Types::ContentLayerType
* CreateDrawingLayer(
219 typename
Types::LayerType
* parent
,
220 const gfx::Transform
& transform
,
221 const gfx::PointF
& position
,
222 const gfx::Size
& bounds
,
224 typename
Types::ContentLayerPtrType
layer(
225 Types::CreateContentLayer(GetHost()));
226 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
227 SetProperties(layer_ptr
, transform
, position
, bounds
);
229 if (opaque_layers_
) {
230 layer_ptr
->SetContentsOpaque(opaque
);
232 layer_ptr
->SetContentsOpaque(false);
234 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
236 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
239 parent
->AddChild(Types::PassLayerPtr(&layer
));
243 typename
Types::LayerType
* CreateReplicaLayer(
244 typename
Types::LayerType
* owning_layer
,
245 const gfx::Transform
& transform
,
246 const gfx::PointF
& position
,
247 const gfx::Size
& bounds
) {
248 typename
Types::ContentLayerPtrType
layer(
249 Types::CreateContentLayer(GetHost()));
250 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
251 SetProperties(layer_ptr
, transform
, position
, bounds
);
252 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
256 typename
Types::LayerType
* CreateMaskLayer(
257 typename
Types::LayerType
* owning_layer
,
258 const gfx::Size
& bounds
) {
259 typename
Types::ContentLayerPtrType
layer(
260 Types::CreateContentLayer(GetHost()));
261 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
262 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
263 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
267 typename
Types::ContentLayerType
* CreateDrawingSurface(
268 typename
Types::LayerType
* parent
,
269 const gfx::Transform
& transform
,
270 const gfx::PointF
& position
,
271 const gfx::Size
& bounds
,
273 typename
Types::ContentLayerType
* layer
=
274 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
275 layer
->SetForceRenderSurface(true);
279 void DestroyLayers() {
280 Types::DestroyLayer(&root_
);
281 render_surface_layer_list_
= nullptr;
282 render_surface_layer_list_impl_
.clear();
283 replica_layers_
.clear();
284 mask_layers_
.clear();
285 ResetLayerIterator();
288 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
290 void AddCopyRequest(Layer
* layer
) {
291 layer
->RequestCopyOfOutput(
292 CopyOutputRequest::CreateBitmapRequest(base::Bind(
293 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
294 base::Unretained(this))));
297 void AddCopyRequest(LayerImpl
* layer
) {
298 ScopedPtrVector
<CopyOutputRequest
> requests
;
300 CopyOutputRequest::CreateBitmapRequest(base::Bind(
301 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
302 base::Unretained(this))));
303 layer
->PassCopyRequests(&requests
);
306 void CalcDrawEtc(TestContentLayerImpl
* root
) {
307 DCHECK(root
== root_
.get());
308 DCHECK(!root
->render_surface());
310 Types::RecursiveUpdateNumChildren(root
);
311 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
312 root
, root
->bounds(), &render_surface_layer_list_impl_
);
313 inputs
.can_adjust_raster_scales
= true;
314 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
316 layer_iterator_
= layer_iterator_begin_
=
317 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
320 void CalcDrawEtc(TestContentLayer
* root
) {
321 DCHECK(root
== root_
.get());
322 DCHECK(!root
->render_surface());
324 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
325 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
326 root
, root
->bounds(), render_surface_layer_list_
.get());
327 inputs
.can_adjust_raster_scales
= true;
328 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
330 layer_iterator_
= layer_iterator_begin_
=
331 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
334 void EnterLayer(typename
Types::LayerType
* layer
,
335 typename
Types::OcclusionTrackerType
* occlusion
) {
336 ASSERT_EQ(*layer_iterator_
, layer
);
337 ASSERT_TRUE(layer_iterator_
.represents_itself());
338 occlusion
->EnterLayer(layer_iterator_
);
341 void LeaveLayer(typename
Types::LayerType
* layer
,
342 typename
Types::OcclusionTrackerType
* occlusion
) {
343 ASSERT_EQ(*layer_iterator_
, layer
);
344 ASSERT_TRUE(layer_iterator_
.represents_itself());
345 occlusion
->LeaveLayer(layer_iterator_
);
349 void VisitLayer(typename
Types::LayerType
* layer
,
350 typename
Types::OcclusionTrackerType
* occlusion
) {
351 EnterLayer(layer
, occlusion
);
352 LeaveLayer(layer
, occlusion
);
355 void EnterContributingSurface(
356 typename
Types::LayerType
* layer
,
357 typename
Types::OcclusionTrackerType
* occlusion
) {
358 ASSERT_EQ(*layer_iterator_
, layer
);
359 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
360 occlusion
->EnterLayer(layer_iterator_
);
361 occlusion
->LeaveLayer(layer_iterator_
);
363 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
364 occlusion
->EnterLayer(layer_iterator_
);
367 void LeaveContributingSurface(
368 typename
Types::LayerType
* layer
,
369 typename
Types::OcclusionTrackerType
* occlusion
) {
370 ASSERT_EQ(*layer_iterator_
, layer
);
371 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
372 occlusion
->LeaveLayer(layer_iterator_
);
376 void VisitContributingSurface(
377 typename
Types::LayerType
* layer
,
378 typename
Types::OcclusionTrackerType
* occlusion
) {
379 EnterContributingSurface(layer
, occlusion
);
380 LeaveContributingSurface(layer
, occlusion
);
383 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
385 const gfx::Transform identity_matrix
;
388 void SetRootLayerOnMainThread(Layer
* root
) {
389 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
392 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
394 void SetBaseProperties(typename
Types::LayerType
* layer
,
395 const gfx::Transform
& transform
,
396 const gfx::PointF
& position
,
397 const gfx::Size
& bounds
) {
398 layer
->SetTransform(transform
);
399 layer
->SetPosition(position
);
400 layer
->SetBounds(bounds
);
403 void SetProperties(Layer
* layer
,
404 const gfx::Transform
& transform
,
405 const gfx::PointF
& position
,
406 const gfx::Size
& bounds
) {
407 SetBaseProperties(layer
, transform
, position
, bounds
);
410 void SetProperties(LayerImpl
* layer
,
411 const gfx::Transform
& transform
,
412 const gfx::PointF
& position
,
413 const gfx::Size
& bounds
) {
414 SetBaseProperties(layer
, transform
, position
, bounds
);
416 layer
->SetContentBounds(layer
->bounds());
419 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
420 owning_layer
->SetReplicaLayer(layer
.get());
421 replica_layers_
.push_back(layer
);
424 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
425 owning_layer
->SetReplicaLayer(layer
.Pass());
428 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
429 owning_layer
->SetMaskLayer(layer
.get());
430 mask_layers_
.push_back(layer
);
433 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
434 owning_layer
->SetMaskLayer(layer
.Pass());
438 FakeLayerTreeHostClient client_
;
439 scoped_ptr
<FakeLayerTreeHost
> host_
;
440 // These hold ownership of the layers for the duration of the test.
441 typename
Types::LayerPtrType root_
;
442 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
443 LayerImplList render_surface_layer_list_impl_
;
444 typename
Types::TestLayerIterator layer_iterator_begin_
;
445 typename
Types::TestLayerIterator layer_iterator_
;
446 typename
Types::LayerType
* last_layer_visited_
;
447 LayerList replica_layers_
;
448 LayerList mask_layers_
;
453 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
459 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
460 return host_
->host_impl()->active_tree();
463 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
464 class ClassName##MainThreadOpaqueLayers \
465 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
466 public: /* NOLINT(whitespace/indent) */ \
467 ClassName##MainThreadOpaqueLayers() \
468 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
470 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
471 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
472 class ClassName##MainThreadOpaquePaints \
473 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
474 public: /* NOLINT(whitespace/indent) */ \
475 ClassName##MainThreadOpaquePaints() \
476 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
478 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
480 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
481 class ClassName##ImplThreadOpaqueLayers \
482 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
483 public: /* NOLINT(whitespace/indent) */ \
484 ClassName##ImplThreadOpaqueLayers() \
485 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
487 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
488 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
489 class ClassName##ImplThreadOpaquePaints \
490 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
491 public: /* NOLINT(whitespace/indent) */ \
492 ClassName##ImplThreadOpaquePaints() \
493 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
495 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
497 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
498 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
499 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
500 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
501 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
503 #define MAIN_THREAD_TEST(ClassName) \
504 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
506 #define IMPL_THREAD_TEST(ClassName) \
507 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
509 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
510 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
511 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
513 template <class Types
>
514 class OcclusionTrackerTestIdentityTransforms
515 : public OcclusionTrackerTest
<Types
> {
517 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
518 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
521 typename
Types::ContentLayerType
* root
= this->CreateRoot(
522 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
523 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
524 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
525 typename
Types::ContentLayerType
* layer
=
526 this->CreateDrawingLayer(parent
,
527 this->identity_matrix
,
528 gfx::PointF(30.f
, 30.f
),
531 parent
->SetMasksToBounds(true);
532 this->CalcDrawEtc(root
);
534 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
535 gfx::Rect(0, 0, 1000, 1000));
537 this->VisitLayer(layer
, &occlusion
);
538 this->EnterLayer(parent
, &occlusion
);
540 EXPECT_EQ(gfx::Rect().ToString(),
541 occlusion
.occlusion_from_outside_target().ToString());
542 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
543 occlusion
.occlusion_from_inside_target().ToString());
547 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
549 template <class Types
>
550 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
552 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
553 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
555 gfx::Transform layer_transform
;
556 layer_transform
.Translate(250.0, 250.0);
557 layer_transform
.Rotate(90.0);
558 layer_transform
.Translate(-250.0, -250.0);
560 typename
Types::ContentLayerType
* root
= this->CreateRoot(
561 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
562 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
563 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
564 typename
Types::ContentLayerType
* layer
=
565 this->CreateDrawingLayer(parent
,
567 gfx::PointF(30.f
, 30.f
),
570 parent
->SetMasksToBounds(true);
571 this->CalcDrawEtc(root
);
573 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
574 gfx::Rect(0, 0, 1000, 1000));
576 this->VisitLayer(layer
, &occlusion
);
577 this->EnterLayer(parent
, &occlusion
);
579 EXPECT_EQ(gfx::Rect().ToString(),
580 occlusion
.occlusion_from_outside_target().ToString());
581 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
582 occlusion
.occlusion_from_inside_target().ToString());
586 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
588 template <class Types
>
589 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
591 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
592 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
594 gfx::Transform layer_transform
;
595 layer_transform
.Translate(20.0, 20.0);
597 typename
Types::ContentLayerType
* root
= this->CreateRoot(
598 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
599 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
600 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
601 typename
Types::ContentLayerType
* layer
=
602 this->CreateDrawingLayer(parent
,
604 gfx::PointF(30.f
, 30.f
),
607 parent
->SetMasksToBounds(true);
608 this->CalcDrawEtc(root
);
610 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
611 gfx::Rect(0, 0, 1000, 1000));
613 this->VisitLayer(layer
, &occlusion
);
614 this->EnterLayer(parent
, &occlusion
);
616 EXPECT_EQ(gfx::Rect().ToString(),
617 occlusion
.occlusion_from_outside_target().ToString());
618 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
619 occlusion
.occlusion_from_inside_target().ToString());
623 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
625 template <class Types
>
626 class OcclusionTrackerTestChildInRotatedChild
627 : public OcclusionTrackerTest
<Types
> {
629 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
630 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
632 gfx::Transform child_transform
;
633 child_transform
.Translate(250.0, 250.0);
634 child_transform
.Rotate(90.0);
635 child_transform
.Translate(-250.0, -250.0);
637 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
638 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
639 parent
->SetMasksToBounds(true);
640 typename
Types::LayerType
* child
= this->CreateSurface(
641 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
642 child
->SetMasksToBounds(true);
643 typename
Types::ContentLayerType
* layer
=
644 this->CreateDrawingLayer(child
,
645 this->identity_matrix
,
646 gfx::PointF(10.f
, 10.f
),
649 this->CalcDrawEtc(parent
);
651 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
652 gfx::Rect(0, 0, 1000, 1000));
654 this->VisitLayer(layer
, &occlusion
);
655 this->EnterContributingSurface(child
, &occlusion
);
657 EXPECT_EQ(gfx::Rect().ToString(),
658 occlusion
.occlusion_from_outside_target().ToString());
659 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
660 occlusion
.occlusion_from_inside_target().ToString());
662 this->LeaveContributingSurface(child
, &occlusion
);
663 this->EnterLayer(parent
, &occlusion
);
665 EXPECT_EQ(gfx::Rect().ToString(),
666 occlusion
.occlusion_from_outside_target().ToString());
667 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
668 occlusion
.occlusion_from_inside_target().ToString());
670 /* Justification for the above occlusion from |layer|:
672 +---------------------+
675 | 30 + ---------------------------------+
677 | |10+---------------------------------+
681 +----|--|-------------+ | |
689 +--|-------------------------------+ |
691 +---------------------------------+
694 +---------------------+
695 | |30 Visible region of |layer|: /////
697 | +---------------------------------+
699 | +---------------------------------+ |
700 | | |///////////////| 420 | |
701 | | |///////////////|60 | |
702 | | |///////////////| | |
703 +--|--|---------------+ | |
711 | +------------------------------|--+
713 +---------------------------------+
720 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
722 template <class Types
>
723 class OcclusionTrackerTestScaledRenderSurface
724 : public OcclusionTrackerTest
<Types
> {
726 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
727 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
730 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
731 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
733 gfx::Transform layer1_matrix
;
734 layer1_matrix
.Scale(2.0, 2.0);
735 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
736 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
737 layer1
->SetForceRenderSurface(true);
739 gfx::Transform layer2_matrix
;
740 layer2_matrix
.Translate(25.0, 25.0);
741 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
742 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
743 typename
Types::ContentLayerType
* occluder
=
744 this->CreateDrawingLayer(parent
,
745 this->identity_matrix
,
746 gfx::PointF(100.f
, 100.f
),
749 this->CalcDrawEtc(parent
);
751 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
752 gfx::Rect(0, 0, 1000, 1000));
754 this->VisitLayer(occluder
, &occlusion
);
755 this->EnterLayer(layer2
, &occlusion
);
757 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
758 occlusion
.occlusion_from_outside_target().ToString());
759 EXPECT_EQ(gfx::Rect().ToString(),
760 occlusion
.occlusion_from_inside_target().ToString());
764 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
766 template <class Types
>
767 class OcclusionTrackerTestVisitTargetTwoTimes
768 : public OcclusionTrackerTest
<Types
> {
770 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
771 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
773 typename
Types::ContentLayerType
* root
= this->CreateRoot(
774 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
775 typename
Types::LayerType
* surface
= this->CreateSurface(
776 root
, this->identity_matrix
, gfx::PointF(30.f
, 30.f
), gfx::Size());
777 typename
Types::ContentLayerType
* surface_child
=
778 this->CreateDrawingLayer(surface
,
779 this->identity_matrix
,
780 gfx::PointF(10.f
, 10.f
),
783 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
784 // first, instead of |surface|'s. This exercises different code in
785 // LeaveToRenderTarget, as the target surface has already been seen when
786 // leaving |surface| later.
787 typename
Types::ContentLayerType
* top_layer
=
788 this->CreateDrawingLayer(root
,
789 this->identity_matrix
,
790 gfx::PointF(40.f
, 90.f
),
793 this->CalcDrawEtc(root
);
795 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
796 gfx::Rect(0, 0, 1000, 1000));
798 this->VisitLayer(top_layer
, &occlusion
);
800 EXPECT_EQ(gfx::Rect().ToString(),
801 occlusion
.occlusion_from_outside_target().ToString());
802 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
803 occlusion
.occlusion_from_inside_target().ToString());
805 this->VisitLayer(surface_child
, &occlusion
);
807 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
808 occlusion
.occlusion_from_outside_target().ToString());
809 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
810 occlusion
.occlusion_from_inside_target().ToString());
812 this->EnterContributingSurface(surface
, &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 // Occlusion from |top_layer| already in the root target should get merged
820 // with the occlusion from the |surface| we are leaving now.
821 this->LeaveContributingSurface(surface
, &occlusion
);
822 this->EnterLayer(root
, &occlusion
);
824 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
825 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
826 occlusion
.occlusion_from_inside_target().ToString());
830 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
832 template <class Types
>
833 class OcclusionTrackerTestSurfaceRotatedOffAxis
834 : public OcclusionTrackerTest
<Types
> {
836 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
837 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
839 gfx::Transform child_transform
;
840 child_transform
.Translate(250.0, 250.0);
841 child_transform
.Rotate(95.0);
842 child_transform
.Translate(-250.0, -250.0);
844 gfx::Transform layer_transform
;
845 layer_transform
.Translate(10.0, 10.0);
847 typename
Types::ContentLayerType
* root
= this->CreateRoot(
848 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
849 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
850 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
851 typename
Types::LayerType
* child
= this->CreateLayer(
852 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
853 child
->SetMasksToBounds(true);
854 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
855 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
856 this->CalcDrawEtc(root
);
858 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
859 gfx::Rect(0, 0, 1000, 1000));
861 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
862 layer_transform
, layer
->visible_content_rect());
864 this->VisitLayer(layer
, &occlusion
);
865 this->EnterContributingSurface(child
, &occlusion
);
867 EXPECT_EQ(gfx::Rect().ToString(),
868 occlusion
.occlusion_from_outside_target().ToString());
869 EXPECT_EQ(clipped_layer_in_child
.ToString(),
870 occlusion
.occlusion_from_inside_target().ToString());
872 this->LeaveContributingSurface(child
, &occlusion
);
873 this->EnterLayer(parent
, &occlusion
);
875 EXPECT_EQ(gfx::Rect().ToString(),
876 occlusion
.occlusion_from_outside_target().ToString());
877 EXPECT_EQ(gfx::Rect().ToString(),
878 occlusion
.occlusion_from_inside_target().ToString());
882 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
884 template <class Types
>
885 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
886 : public OcclusionTrackerTest
<Types
> {
888 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
889 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
891 gfx::Transform child_transform
;
892 child_transform
.Translate(250.0, 250.0);
893 child_transform
.Rotate(90.0);
894 child_transform
.Translate(-250.0, -250.0);
896 typename
Types::ContentLayerType
* root
= this->CreateRoot(
897 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
898 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
899 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
900 parent
->SetMasksToBounds(true);
901 typename
Types::ContentLayerType
* child
=
902 this->CreateDrawingSurface(parent
,
904 gfx::PointF(30.f
, 30.f
),
907 child
->SetMasksToBounds(true);
908 typename
Types::ContentLayerType
* layer1
=
909 this->CreateDrawingLayer(child
,
910 this->identity_matrix
,
911 gfx::PointF(10.f
, 10.f
),
914 typename
Types::ContentLayerType
* layer2
=
915 this->CreateDrawingLayer(child
,
916 this->identity_matrix
,
917 gfx::PointF(10.f
, 450.f
),
920 this->CalcDrawEtc(root
);
922 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
923 gfx::Rect(0, 0, 1000, 1000));
925 this->VisitLayer(layer2
, &occlusion
);
926 this->VisitLayer(layer1
, &occlusion
);
927 this->VisitLayer(child
, &occlusion
);
928 this->EnterContributingSurface(child
, &occlusion
);
930 EXPECT_EQ(gfx::Rect().ToString(),
931 occlusion
.occlusion_from_outside_target().ToString());
932 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
933 occlusion
.occlusion_from_inside_target().ToString());
935 this->LeaveContributingSurface(child
, &occlusion
);
936 this->EnterLayer(parent
, &occlusion
);
938 EXPECT_EQ(gfx::Rect().ToString(),
939 occlusion
.occlusion_from_outside_target().ToString());
940 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
941 occlusion
.occlusion_from_inside_target().ToString());
943 /* Justification for the above occlusion from |layer1| and |layer2|:
945 +---------------------+
946 | |30 Visible region of |layer1|: /////
947 | | Visible region of |layer2|: \\\\\
948 | +---------------------------------+
950 | +---------------+-----------------+ |
951 | | |\\\\\\\\\\\\|//| 420 | |
952 | | |\\\\\\\\\\\\|//|60 | |
953 | | |\\\\\\\\\\\\|//| | |
954 +--|--|------------|--+ | |
962 | +------------|-----------------|--+
964 +---------------+-----------------+
970 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
972 template <class Types
>
973 class OcclusionTrackerTestOverlappingSurfaceSiblings
974 : public OcclusionTrackerTest
<Types
> {
976 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
977 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
979 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
980 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
981 parent
->SetMasksToBounds(true);
982 typename
Types::LayerType
* child1
= this->CreateSurface(
983 parent
, this->identity_matrix
, gfx::PointF(10.f
, 0.f
), gfx::Size());
984 typename
Types::LayerType
* child2
= this->CreateSurface(
985 parent
, this->identity_matrix
, gfx::PointF(30.f
, 0.f
), gfx::Size());
986 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
987 child1
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 50), true);
988 typename
Types::ContentLayerType
* layer2
=
989 this->CreateDrawingLayer(child2
,
990 this->identity_matrix
,
991 gfx::PointF(10.f
, 0.f
),
994 this->CalcDrawEtc(parent
);
996 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
997 gfx::Rect(0, 0, 1000, 1000));
999 this->VisitLayer(layer2
, &occlusion
);
1000 this->EnterContributingSurface(child2
, &occlusion
);
1002 // layer2's occlusion.
1003 EXPECT_EQ(gfx::Rect().ToString(),
1004 occlusion
.occlusion_from_outside_target().ToString());
1005 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
1006 occlusion
.occlusion_from_inside_target().ToString());
1008 this->LeaveContributingSurface(child2
, &occlusion
);
1009 this->VisitLayer(layer1
, &occlusion
);
1010 this->EnterContributingSurface(child1
, &occlusion
);
1012 // layer2's occlusion in the target space of layer1.
1013 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
1014 occlusion
.occlusion_from_outside_target().ToString());
1015 // layer1's occlusion.
1016 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
1017 occlusion
.occlusion_from_inside_target().ToString());
1019 this->LeaveContributingSurface(child1
, &occlusion
);
1020 this->EnterLayer(parent
, &occlusion
);
1022 // The occlusion from from layer1 and layer2 is merged.
1023 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1024 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
1025 occlusion
.occlusion_from_inside_target().ToString());
1029 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1031 template <class Types
>
1032 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1033 : public OcclusionTrackerTest
<Types
> {
1035 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1037 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1039 gfx::Transform child1_transform
;
1040 child1_transform
.Translate(250.0, 250.0);
1041 child1_transform
.Rotate(-90.0);
1042 child1_transform
.Translate(-250.0, -250.0);
1044 gfx::Transform child2_transform
;
1045 child2_transform
.Translate(250.0, 250.0);
1046 child2_transform
.Rotate(90.0);
1047 child2_transform
.Translate(-250.0, -250.0);
1049 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1050 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1051 parent
->SetMasksToBounds(true);
1052 typename
Types::LayerType
* child1
= this->CreateSurface(
1053 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1054 typename
Types::LayerType
* child2
=
1055 this->CreateDrawingSurface(parent
,
1057 gfx::PointF(20.f
, 40.f
),
1060 typename
Types::ContentLayerType
* layer1
=
1061 this->CreateDrawingLayer(child1
,
1062 this->identity_matrix
,
1063 gfx::PointF(-10.f
, -20.f
),
1064 gfx::Size(510, 510),
1066 typename
Types::ContentLayerType
* layer2
=
1067 this->CreateDrawingLayer(child2
,
1068 this->identity_matrix
,
1069 gfx::PointF(-10.f
, -10.f
),
1070 gfx::Size(510, 510),
1072 this->CalcDrawEtc(parent
);
1074 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1075 gfx::Rect(0, 0, 1000, 1000));
1077 this->VisitLayer(layer2
, &occlusion
);
1078 this->EnterLayer(child2
, &occlusion
);
1080 EXPECT_EQ(gfx::Rect().ToString(),
1081 occlusion
.occlusion_from_outside_target().ToString());
1082 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1083 occlusion
.occlusion_from_inside_target().ToString());
1085 this->LeaveLayer(child2
, &occlusion
);
1086 this->EnterContributingSurface(child2
, &occlusion
);
1088 EXPECT_EQ(gfx::Rect().ToString(),
1089 occlusion
.occlusion_from_outside_target().ToString());
1090 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1091 occlusion
.occlusion_from_inside_target().ToString());
1093 this->LeaveContributingSurface(child2
, &occlusion
);
1094 this->VisitLayer(layer1
, &occlusion
);
1095 this->EnterContributingSurface(child1
, &occlusion
);
1097 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1098 occlusion
.occlusion_from_outside_target().ToString());
1099 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1100 occlusion
.occlusion_from_inside_target().ToString());
1102 this->LeaveContributingSurface(child1
, &occlusion
);
1103 this->EnterLayer(parent
, &occlusion
);
1105 EXPECT_EQ(gfx::Rect().ToString(),
1106 occlusion
.occlusion_from_outside_target().ToString());
1107 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1108 occlusion
.occlusion_from_inside_target().ToString());
1110 /* Justification for the above occlusion:
1112 +---------------------+
1114 10+----------------------------------+
1115 100 || 30 | layer2 |
1116 |20+----------------------------------+
1120 +|-|------------------+ | |
1128 +----------------------------------+ |
1130 +----------------------------------+
1136 ALL_OCCLUSIONTRACKER_TEST(
1137 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1139 template <class Types
>
1140 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1142 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1143 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1145 gfx::Transform layer_transform
;
1146 layer_transform
.Translate(250.0, 250.0);
1147 layer_transform
.Rotate(90.0);
1148 layer_transform
.Translate(-250.0, -250.0);
1150 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1151 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1152 parent
->SetMasksToBounds(true);
1153 typename
Types::ContentLayerType
* blur_layer
=
1154 this->CreateDrawingLayer(parent
,
1156 gfx::PointF(30.f
, 30.f
),
1157 gfx::Size(500, 500),
1159 typename
Types::ContentLayerType
* opaque_layer
=
1160 this->CreateDrawingLayer(parent
,
1162 gfx::PointF(30.f
, 30.f
),
1163 gfx::Size(500, 500),
1165 typename
Types::ContentLayerType
* opacity_layer
=
1166 this->CreateDrawingLayer(parent
,
1168 gfx::PointF(30.f
, 30.f
),
1169 gfx::Size(500, 500),
1172 FilterOperations filters
;
1173 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1174 blur_layer
->SetFilters(filters
);
1177 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1178 opaque_layer
->SetFilters(filters
);
1181 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1182 opacity_layer
->SetFilters(filters
);
1184 this->CalcDrawEtc(parent
);
1186 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1187 gfx::Rect(0, 0, 1000, 1000));
1189 // Opacity layer won't contribute to occlusion.
1190 this->VisitLayer(opacity_layer
, &occlusion
);
1191 this->EnterContributingSurface(opacity_layer
, &occlusion
);
1193 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1194 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1196 // And has nothing to contribute to its parent surface.
1197 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1198 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1199 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1201 // Opaque layer will contribute to occlusion.
1202 this->VisitLayer(opaque_layer
, &occlusion
);
1203 this->EnterContributingSurface(opaque_layer
, &occlusion
);
1205 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1206 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1207 occlusion
.occlusion_from_inside_target().ToString());
1209 // And it gets translated to the parent surface.
1210 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1211 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1212 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1213 occlusion
.occlusion_from_inside_target().ToString());
1215 // The blur layer needs to throw away any occlusion from outside its
1217 this->EnterLayer(blur_layer
, &occlusion
);
1218 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1219 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1221 // And it won't contribute to occlusion.
1222 this->LeaveLayer(blur_layer
, &occlusion
);
1223 this->EnterContributingSurface(blur_layer
, &occlusion
);
1224 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1225 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1227 // But the opaque layer's occlusion is preserved on the parent.
1228 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1229 this->EnterLayer(parent
, &occlusion
);
1230 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1231 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1232 occlusion
.occlusion_from_inside_target().ToString());
1236 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1238 template <class Types
>
1239 class OcclusionTrackerTestReplicaDoesOcclude
1240 : public OcclusionTrackerTest
<Types
> {
1242 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1243 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1245 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1246 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1247 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
1248 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
1249 this->CreateReplicaLayer(
1250 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1251 this->CalcDrawEtc(parent
);
1253 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1254 gfx::Rect(0, 0, 1000, 1000));
1256 this->VisitLayer(surface
, &occlusion
);
1258 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1259 occlusion
.occlusion_from_inside_target().ToString());
1261 this->VisitContributingSurface(surface
, &occlusion
);
1262 this->EnterLayer(parent
, &occlusion
);
1264 // The surface and replica should both be occluding the parent.
1265 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1266 occlusion
.occlusion_from_inside_target().ToString());
1270 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1272 template <class Types
>
1273 class OcclusionTrackerTestReplicaWithClipping
1274 : public OcclusionTrackerTest
<Types
> {
1276 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1277 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1279 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1280 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1281 parent
->SetMasksToBounds(true);
1282 typename
Types::LayerType
* surface
=
1283 this->CreateDrawingSurface(parent
,
1284 this->identity_matrix
,
1285 gfx::PointF(0.f
, 100.f
),
1288 this->CreateReplicaLayer(
1289 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1290 this->CalcDrawEtc(parent
);
1292 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1293 gfx::Rect(0, 0, 1000, 1000));
1295 this->VisitLayer(surface
, &occlusion
);
1297 // The surface layer's occlusion in its own space.
1298 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1299 occlusion
.occlusion_from_inside_target().ToString());
1300 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1302 this->VisitContributingSurface(surface
, &occlusion
);
1303 this->EnterLayer(parent
, &occlusion
);
1305 // The surface and replica should both be occluding the parent, the
1306 // replica's occlusion is clipped by the parent.
1307 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1308 occlusion
.occlusion_from_inside_target().ToString());
1309 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1313 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1315 template <class Types
>
1316 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1318 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1319 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1321 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1322 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1323 typename
Types::LayerType
* surface
=
1324 this->CreateDrawingSurface(parent
,
1325 this->identity_matrix
,
1326 gfx::PointF(0.f
, 100.f
),
1329 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1330 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1331 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1332 this->CalcDrawEtc(parent
);
1334 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1335 gfx::Rect(0, 0, 1000, 1000));
1337 this->VisitLayer(surface
, &occlusion
);
1339 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1340 occlusion
.occlusion_from_inside_target().ToString());
1342 this->VisitContributingSurface(surface
, &occlusion
);
1343 this->EnterLayer(parent
, &occlusion
);
1345 // The replica should not be occluding the parent, since it has a mask
1347 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1348 occlusion
.occlusion_from_inside_target().ToString());
1352 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1354 template <class Types
>
1355 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1356 : public OcclusionTrackerTest
<Types
> {
1358 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1359 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1361 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1362 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1363 typename
Types::ContentLayerType
* layer
=
1364 this->CreateDrawingSurface(parent
,
1365 this->identity_matrix
,
1367 gfx::Size(200, 200),
1369 this->CalcDrawEtc(parent
);
1371 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1372 gfx::Rect(0, 0, 1000, 1000));
1373 this->EnterLayer(layer
, &occlusion
);
1375 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1376 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1378 this->LeaveLayer(layer
, &occlusion
);
1379 this->VisitContributingSurface(layer
, &occlusion
);
1380 this->EnterLayer(parent
, &occlusion
);
1382 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1383 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1387 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1389 template <class Types
>
1390 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1391 : public OcclusionTrackerTest
<Types
> {
1393 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1394 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1396 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1397 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1398 typename
Types::ContentLayerType
* layer
=
1399 this->CreateDrawingLayer(parent
,
1400 this->identity_matrix
,
1401 gfx::PointF(100.f
, 100.f
),
1402 gfx::Size(200, 200),
1404 this->CalcDrawEtc(parent
);
1406 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1407 gfx::Rect(0, 0, 1000, 1000));
1408 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1410 this->ResetLayerIterator();
1411 this->VisitLayer(layer
, &occlusion
);
1412 this->EnterLayer(parent
, &occlusion
);
1414 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1415 occlusion
.occlusion_from_inside_target().ToString());
1418 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1419 gfx::Rect(0, 0, 1000, 1000));
1420 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1422 this->ResetLayerIterator();
1423 this->VisitLayer(layer
, &occlusion
);
1424 this->EnterLayer(parent
, &occlusion
);
1426 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1427 occlusion
.occlusion_from_inside_target().ToString());
1430 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1431 gfx::Rect(0, 0, 1000, 1000));
1432 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1434 this->ResetLayerIterator();
1435 this->VisitLayer(layer
, &occlusion
);
1436 this->EnterLayer(parent
, &occlusion
);
1438 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1439 occlusion
.occlusion_from_inside_target().ToString());
1444 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1446 template <class Types
>
1447 class OcclusionTrackerTestUnsorted3dLayers
1448 : public OcclusionTrackerTest
<Types
> {
1450 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
1451 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1453 // Currently, The main thread layer iterator does not iterate over 3d items
1454 // in sorted order, because layer sorting is not performed on the main
1455 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1456 // layer occludes other layers that have not yet been iterated over. For
1457 // now, the expected behavior is that a 3d layer simply does not add any
1458 // occlusion to the occlusion tracker.
1460 gfx::Transform translation_to_front
;
1461 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
1462 gfx::Transform translation_to_back
;
1463 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
1465 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1466 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1467 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
1468 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
1469 typename
Types::ContentLayerType
* child2
=
1470 this->CreateDrawingLayer(parent
,
1471 translation_to_front
,
1472 gfx::PointF(50.f
, 50.f
),
1473 gfx::Size(100, 100),
1475 parent
->SetShouldFlattenTransform(false);
1476 parent
->Set3dSortingContextId(1);
1477 child1
->Set3dSortingContextId(1);
1478 child2
->Set3dSortingContextId(1);
1480 this->CalcDrawEtc(parent
);
1482 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1483 gfx::Rect(0, 0, 1000, 1000));
1484 this->VisitLayer(child2
, &occlusion
);
1485 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1486 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1488 this->VisitLayer(child1
, &occlusion
);
1489 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1490 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1494 // This test will have different layer ordering on the impl thread; the test
1495 // will only work on the main thread.
1496 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1498 template <class Types
>
1499 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1500 : public OcclusionTrackerTest
<Types
> {
1502 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1504 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1506 gfx::Transform transform
;
1507 transform
.Translate(50.0, 50.0);
1508 transform
.ApplyPerspectiveDepth(100.0);
1509 transform
.Translate3d(0.0, 0.0, 110.0);
1510 transform
.Translate(-50.0, -50.0);
1512 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1513 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1514 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1515 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
1516 parent
->SetShouldFlattenTransform(false);
1517 parent
->Set3dSortingContextId(1);
1518 layer
->SetShouldFlattenTransform(false);
1519 layer
->Set3dSortingContextId(1);
1520 this->CalcDrawEtc(parent
);
1522 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1523 gfx::Rect(0, 0, 1000, 1000));
1525 // The |layer| is entirely behind the camera and should not occlude.
1526 this->VisitLayer(layer
, &occlusion
);
1527 this->EnterLayer(parent
, &occlusion
);
1528 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1529 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1533 // This test requires accumulating occlusion of 3d layers, which are skipped by
1534 // the occlusion tracker on the main thread. So this test should run on the impl
1536 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
1538 template <class Types
>
1539 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
1540 : public OcclusionTrackerTest
<Types
> {
1542 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
1544 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1546 gfx::Transform transform
;
1547 transform
.Translate(50.0, 50.0);
1548 transform
.ApplyPerspectiveDepth(100.0);
1549 transform
.Translate3d(0.0, 0.0, 99.0);
1550 transform
.Translate(-50.0, -50.0);
1552 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1553 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1554 parent
->SetMasksToBounds(true);
1555 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1556 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
1557 parent
->SetShouldFlattenTransform(false);
1558 parent
->Set3dSortingContextId(1);
1559 layer
->SetShouldFlattenTransform(false);
1560 layer
->Set3dSortingContextId(1);
1561 this->CalcDrawEtc(parent
);
1563 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1564 gfx::Rect(0, 0, 1000, 1000));
1566 // This is very close to the camera, so pixels in its visible_content_rect()
1567 // will actually go outside of the layer's clip rect. Ensure that those
1568 // pixels don't occlude things outside the clip rect.
1569 this->VisitLayer(layer
, &occlusion
);
1570 this->EnterLayer(parent
, &occlusion
);
1571 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
1572 occlusion
.occlusion_from_inside_target().ToString());
1573 EXPECT_EQ(gfx::Rect().ToString(),
1574 occlusion
.occlusion_from_outside_target().ToString());
1578 // This test requires accumulating occlusion of 3d layers, which are skipped by
1579 // the occlusion tracker on the main thread. So this test should run on the impl
1581 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
1583 template <class Types
>
1584 class OcclusionTrackerTestAnimationOpacity1OnMainThread
1585 : public OcclusionTrackerTest
<Types
> {
1587 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
1588 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1593 // | +--surface_child
1594 // | +--surface_child2
1598 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1599 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1600 typename
Types::ContentLayerType
* layer
=
1601 this->CreateDrawingLayer(parent
,
1602 this->identity_matrix
,
1604 gfx::Size(300, 300),
1606 typename
Types::ContentLayerType
* surface
=
1607 this->CreateDrawingSurface(parent
,
1608 this->identity_matrix
,
1610 gfx::Size(300, 300),
1612 typename
Types::ContentLayerType
* surface_child
=
1613 this->CreateDrawingLayer(surface
,
1614 this->identity_matrix
,
1616 gfx::Size(200, 300),
1618 typename
Types::ContentLayerType
* surface_child2
=
1619 this->CreateDrawingLayer(surface
,
1620 this->identity_matrix
,
1622 gfx::Size(100, 300),
1624 typename
Types::ContentLayerType
* parent2
=
1625 this->CreateDrawingLayer(parent
,
1626 this->identity_matrix
,
1628 gfx::Size(300, 300),
1630 typename
Types::ContentLayerType
* topmost
=
1631 this->CreateDrawingLayer(parent
,
1632 this->identity_matrix
,
1633 gfx::PointF(250.f
, 0.f
),
1637 AddOpacityTransitionToController(
1638 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
1639 AddOpacityTransitionToController(
1640 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
1641 this->CalcDrawEtc(parent
);
1643 EXPECT_TRUE(layer
->draw_opacity_is_animating());
1644 EXPECT_FALSE(surface
->draw_opacity_is_animating());
1645 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
1647 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1648 gfx::Rect(0, 0, 1000, 1000));
1650 this->VisitLayer(topmost
, &occlusion
);
1651 this->EnterLayer(parent2
, &occlusion
);
1653 // This occlusion will affect all surfaces.
1654 EXPECT_EQ(gfx::Rect().ToString(),
1655 occlusion
.occlusion_from_outside_target().ToString());
1656 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1657 occlusion
.occlusion_from_inside_target().ToString());
1659 this->LeaveLayer(parent2
, &occlusion
);
1660 this->VisitLayer(surface_child2
, &occlusion
);
1661 this->EnterLayer(surface_child
, &occlusion
);
1662 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1663 occlusion
.occlusion_from_outside_target().ToString());
1664 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1665 occlusion
.occlusion_from_inside_target().ToString());
1667 this->LeaveLayer(surface_child
, &occlusion
);
1668 this->EnterLayer(surface
, &occlusion
);
1669 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1670 occlusion
.occlusion_from_outside_target().ToString());
1671 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1672 occlusion
.occlusion_from_inside_target().ToString());
1674 this->LeaveLayer(surface
, &occlusion
);
1675 this->EnterContributingSurface(surface
, &occlusion
);
1676 // Occlusion within the surface is lost when leaving the animating surface.
1677 EXPECT_EQ(gfx::Rect().ToString(),
1678 occlusion
.occlusion_from_outside_target().ToString());
1679 EXPECT_EQ(gfx::Rect().ToString(),
1680 occlusion
.occlusion_from_inside_target().ToString());
1682 this->LeaveContributingSurface(surface
, &occlusion
);
1683 // Occlusion from outside the animating surface still exists.
1684 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1685 occlusion
.occlusion_from_inside_target().ToString());
1686 EXPECT_EQ(gfx::Rect().ToString(),
1687 occlusion
.occlusion_from_outside_target().ToString());
1689 this->VisitLayer(layer
, &occlusion
);
1690 this->EnterLayer(parent
, &occlusion
);
1692 // Occlusion is not added for the animating |layer|.
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());
1700 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
1702 template <class Types
>
1703 class OcclusionTrackerTestAnimationOpacity0OnMainThread
1704 : public OcclusionTrackerTest
<Types
> {
1706 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
1707 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1709 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1710 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1711 typename
Types::ContentLayerType
* layer
=
1712 this->CreateDrawingLayer(parent
,
1713 this->identity_matrix
,
1715 gfx::Size(300, 300),
1717 typename
Types::ContentLayerType
* surface
=
1718 this->CreateDrawingSurface(parent
,
1719 this->identity_matrix
,
1721 gfx::Size(300, 300),
1723 typename
Types::ContentLayerType
* surface_child
=
1724 this->CreateDrawingLayer(surface
,
1725 this->identity_matrix
,
1727 gfx::Size(200, 300),
1729 typename
Types::ContentLayerType
* surface_child2
=
1730 this->CreateDrawingLayer(surface
,
1731 this->identity_matrix
,
1733 gfx::Size(100, 300),
1735 typename
Types::ContentLayerType
* parent2
=
1736 this->CreateDrawingLayer(parent
,
1737 this->identity_matrix
,
1739 gfx::Size(300, 300),
1741 typename
Types::ContentLayerType
* topmost
=
1742 this->CreateDrawingLayer(parent
,
1743 this->identity_matrix
,
1744 gfx::PointF(250.f
, 0.f
),
1748 AddOpacityTransitionToController(
1749 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
1750 AddOpacityTransitionToController(
1751 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
1752 this->CalcDrawEtc(parent
);
1754 EXPECT_TRUE(layer
->draw_opacity_is_animating());
1755 EXPECT_FALSE(surface
->draw_opacity_is_animating());
1756 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
1758 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1759 gfx::Rect(0, 0, 1000, 1000));
1761 this->VisitLayer(topmost
, &occlusion
);
1762 this->EnterLayer(parent2
, &occlusion
);
1763 // This occlusion will affect all surfaces.
1764 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1765 occlusion
.occlusion_from_inside_target().ToString());
1766 EXPECT_EQ(gfx::Rect().ToString(),
1767 occlusion
.occlusion_from_outside_target().ToString());
1769 this->LeaveLayer(parent2
, &occlusion
);
1770 this->VisitLayer(surface_child2
, &occlusion
);
1771 this->EnterLayer(surface_child
, &occlusion
);
1772 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1773 occlusion
.occlusion_from_inside_target().ToString());
1774 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1775 occlusion
.occlusion_from_outside_target().ToString());
1777 this->LeaveLayer(surface_child
, &occlusion
);
1778 this->EnterLayer(surface
, &occlusion
);
1779 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1780 occlusion
.occlusion_from_inside_target().ToString());
1781 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1782 occlusion
.occlusion_from_outside_target().ToString());
1784 this->LeaveLayer(surface
, &occlusion
);
1785 this->EnterContributingSurface(surface
, &occlusion
);
1786 // Occlusion within the surface is lost when leaving the animating surface.
1787 EXPECT_EQ(gfx::Rect().ToString(),
1788 occlusion
.occlusion_from_inside_target().ToString());
1789 EXPECT_EQ(gfx::Rect().ToString(),
1790 occlusion
.occlusion_from_outside_target().ToString());
1792 this->LeaveContributingSurface(surface
, &occlusion
);
1793 // Occlusion from outside the animating surface still exists.
1794 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1795 occlusion
.occlusion_from_inside_target().ToString());
1796 EXPECT_EQ(gfx::Rect().ToString(),
1797 occlusion
.occlusion_from_outside_target().ToString());
1799 this->VisitLayer(layer
, &occlusion
);
1800 this->EnterLayer(parent
, &occlusion
);
1802 // Occlusion is not added for the animating |layer|.
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());
1810 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
1812 template <class Types
>
1813 class OcclusionTrackerTestAnimationTranslateOnMainThread
1814 : public OcclusionTrackerTest
<Types
> {
1816 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
1818 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1820 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1821 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1822 typename
Types::ContentLayerType
* layer
=
1823 this->CreateDrawingLayer(parent
,
1824 this->identity_matrix
,
1826 gfx::Size(300, 300),
1828 typename
Types::ContentLayerType
* surface
=
1829 this->CreateDrawingSurface(parent
,
1830 this->identity_matrix
,
1832 gfx::Size(300, 300),
1834 typename
Types::ContentLayerType
* surface_child
=
1835 this->CreateDrawingLayer(surface
,
1836 this->identity_matrix
,
1838 gfx::Size(200, 300),
1840 typename
Types::ContentLayerType
* surface_child2
=
1841 this->CreateDrawingLayer(surface
,
1842 this->identity_matrix
,
1844 gfx::Size(100, 300),
1846 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
1847 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
1849 AddAnimatedTransformToController(
1850 layer
->layer_animation_controller(), 10.0, 30, 0);
1851 AddAnimatedTransformToController(
1852 surface
->layer_animation_controller(), 10.0, 30, 0);
1853 AddAnimatedTransformToController(
1854 surface_child
->layer_animation_controller(), 10.0, 30, 0);
1855 this->CalcDrawEtc(parent
);
1857 EXPECT_TRUE(layer
->draw_transform_is_animating());
1858 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
1860 surface
->render_surface()->target_surface_transforms_are_animating());
1862 surface
->render_surface()->screen_space_transforms_are_animating());
1863 // The surface owning layer doesn't animate against its own surface.
1864 EXPECT_FALSE(surface
->draw_transform_is_animating());
1865 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
1866 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
1867 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
1869 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1870 gfx::Rect(0, 0, 1000, 1000));
1872 this->VisitLayer(surface2
, &occlusion
);
1873 this->EnterContributingSurface(surface2
, &occlusion
);
1875 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1876 occlusion
.occlusion_from_inside_target().ToString());
1878 this->LeaveContributingSurface(surface2
, &occlusion
);
1879 this->EnterLayer(surface_child2
, &occlusion
);
1880 // surface_child2 is moving in screen space but not relative to its target,
1881 // so occlusion should happen in its target space only. It also means that
1882 // things occluding from outside the target (e.g. surface2) cannot occlude
1884 EXPECT_EQ(gfx::Rect().ToString(),
1885 occlusion
.occlusion_from_outside_target().ToString());
1886 EXPECT_EQ(gfx::Rect().ToString(),
1887 occlusion
.occlusion_from_inside_target().ToString());
1889 this->LeaveLayer(surface_child2
, &occlusion
);
1890 this->EnterLayer(surface_child
, &occlusion
);
1891 // surface_child2 added to the occlusion since it is not moving relative
1893 EXPECT_EQ(gfx::Rect().ToString(),
1894 occlusion
.occlusion_from_outside_target().ToString());
1895 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1896 occlusion
.occlusion_from_inside_target().ToString());
1898 this->LeaveLayer(surface_child
, &occlusion
);
1899 // surface_child is moving relative to its target, so it does not add
1901 EXPECT_EQ(gfx::Rect().ToString(),
1902 occlusion
.occlusion_from_outside_target().ToString());
1903 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1904 occlusion
.occlusion_from_inside_target().ToString());
1906 this->EnterLayer(surface
, &occlusion
);
1907 EXPECT_EQ(gfx::Rect().ToString(),
1908 occlusion
.occlusion_from_outside_target().ToString());
1909 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1910 occlusion
.occlusion_from_inside_target().ToString());
1912 this->LeaveLayer(surface
, &occlusion
);
1913 // The surface's owning layer is moving in screen space but not relative to
1914 // its target, so it adds to the occlusion.
1915 EXPECT_EQ(gfx::Rect().ToString(),
1916 occlusion
.occlusion_from_outside_target().ToString());
1917 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
1918 occlusion
.occlusion_from_inside_target().ToString());
1920 this->EnterContributingSurface(surface
, &occlusion
);
1921 this->LeaveContributingSurface(surface
, &occlusion
);
1922 // The |surface| is moving in the screen and in its target, so all occlusion
1923 // within the surface is lost when leaving it. Only the |surface2| occlusion
1925 EXPECT_EQ(gfx::Rect().ToString(),
1926 occlusion
.occlusion_from_outside_target().ToString());
1927 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1928 occlusion
.occlusion_from_inside_target().ToString());
1930 this->VisitLayer(layer
, &occlusion
);
1931 // The |layer| is animating in the screen and in its target, so no occlusion
1933 EXPECT_EQ(gfx::Rect().ToString(),
1934 occlusion
.occlusion_from_outside_target().ToString());
1935 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1936 occlusion
.occlusion_from_inside_target().ToString());
1940 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
1942 template <class Types
>
1943 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1944 : public OcclusionTrackerTest
<Types
> {
1946 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1948 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1950 gfx::Transform surface_transform
;
1951 surface_transform
.Translate(300.0, 300.0);
1952 surface_transform
.Scale(2.0, 2.0);
1953 surface_transform
.Translate(-150.0, -150.0);
1955 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1956 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
1957 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
1958 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
1959 typename
Types::ContentLayerType
* surface2
=
1960 this->CreateDrawingSurface(parent
,
1961 this->identity_matrix
,
1962 gfx::PointF(50.f
, 50.f
),
1963 gfx::Size(300, 300),
1965 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1966 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1967 this->CalcDrawEtc(parent
);
1969 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1970 gfx::Rect(0, 0, 1000, 1000));
1972 this->VisitLayer(surface2
, &occlusion
);
1973 this->VisitContributingSurface(surface2
, &occlusion
);
1975 EXPECT_EQ(gfx::Rect().ToString(),
1976 occlusion
.occlusion_from_outside_target().ToString());
1977 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1978 occlusion
.occlusion_from_inside_target().ToString());
1980 // Clear any stored occlusion.
1981 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1982 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1984 this->VisitLayer(surface
, &occlusion
);
1985 this->VisitContributingSurface(surface
, &occlusion
);
1987 EXPECT_EQ(gfx::Rect().ToString(),
1988 occlusion
.occlusion_from_outside_target().ToString());
1989 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1990 occlusion
.occlusion_from_inside_target().ToString());
1994 MAIN_AND_IMPL_THREAD_TEST(
1995 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
1997 template <class Types
>
1998 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1999 : public OcclusionTrackerTest
<Types
> {
2001 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2003 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2005 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2006 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2007 parent
->SetMasksToBounds(true);
2008 typename
Types::ContentLayerType
* surface
=
2009 this->CreateDrawingSurface(parent
,
2010 this->identity_matrix
,
2012 gfx::Size(500, 300),
2014 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2015 this->CalcDrawEtc(parent
);
2017 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2018 gfx::Rect(0, 0, 1000, 1000));
2020 this->VisitLayer(surface
, &occlusion
);
2021 this->VisitContributingSurface(surface
, &occlusion
);
2023 EXPECT_EQ(gfx::Rect().ToString(),
2024 occlusion
.occlusion_from_outside_target().ToString());
2025 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2026 occlusion
.occlusion_from_inside_target().ToString());
2030 MAIN_AND_IMPL_THREAD_TEST(
2031 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2033 template <class Types
>
2034 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2035 : public OcclusionTrackerTest
<Types
> {
2037 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
2038 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2040 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2041 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2042 typename
Types::LayerType
* surface
=
2043 this->CreateDrawingSurface(parent
,
2044 this->identity_matrix
,
2046 gfx::Size(100, 100),
2048 this->CreateReplicaLayer(surface
,
2049 this->identity_matrix
,
2050 gfx::PointF(0.f
, 100.f
),
2051 gfx::Size(100, 100));
2052 typename
Types::LayerType
* topmost
=
2053 this->CreateDrawingLayer(parent
,
2054 this->identity_matrix
,
2056 gfx::Size(100, 110),
2058 this->CalcDrawEtc(parent
);
2060 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2061 gfx::Rect(0, 0, 1000, 1000));
2063 // |topmost| occludes the surface, but not the entire surface's replica.
2064 this->VisitLayer(topmost
, &occlusion
);
2066 EXPECT_EQ(gfx::Rect().ToString(),
2067 occlusion
.occlusion_from_outside_target().ToString());
2068 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2069 occlusion
.occlusion_from_inside_target().ToString());
2071 this->VisitLayer(surface
, &occlusion
);
2073 // Render target with replica ignores occlusion from outside.
2074 EXPECT_EQ(gfx::Rect().ToString(),
2075 occlusion
.occlusion_from_outside_target().ToString());
2076 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2077 occlusion
.occlusion_from_inside_target().ToString());
2079 this->EnterContributingSurface(surface
, &occlusion
);
2081 // Only occlusion from outside the surface occludes the surface/replica.
2082 EXPECT_EQ(gfx::Rect().ToString(),
2083 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2085 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2086 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2091 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2093 template <class Types
>
2094 class OcclusionTrackerTestSurfaceChildOfSurface
2095 : public OcclusionTrackerTest
<Types
> {
2097 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
2098 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2100 // This test verifies that the surface cliprect does not end up empty and
2101 // clip away the entire unoccluded rect.
2103 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2104 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2105 typename
Types::LayerType
* surface
=
2106 this->CreateDrawingSurface(parent
,
2107 this->identity_matrix
,
2109 gfx::Size(100, 100),
2111 typename
Types::LayerType
* surface_child
=
2112 this->CreateDrawingSurface(surface
,
2113 this->identity_matrix
,
2114 gfx::PointF(0.f
, 10.f
),
2117 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
2118 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
2119 this->CalcDrawEtc(parent
);
2121 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2122 gfx::Rect(-100, -100, 1000, 1000));
2124 // |topmost| occludes everything partially so we know occlusion is happening
2126 this->VisitLayer(topmost
, &occlusion
);
2128 EXPECT_EQ(gfx::Rect().ToString(),
2129 occlusion
.occlusion_from_outside_target().ToString());
2130 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2131 occlusion
.occlusion_from_inside_target().ToString());
2133 this->VisitLayer(surface_child
, &occlusion
);
2135 // surface_child increases the occlusion in the screen by a narrow sliver.
2136 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2137 occlusion
.occlusion_from_outside_target().ToString());
2138 // In its own surface, surface_child is at 0,0 as is its occlusion.
2139 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2140 occlusion
.occlusion_from_inside_target().ToString());
2142 // The root layer always has a clip rect. So the parent of |surface| has a
2143 // clip rect. However, the owning layer for |surface| does not mask to
2144 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2145 // |surface_child| exercises different code paths as its parent does not
2146 // have a clip rect.
2148 this->EnterContributingSurface(surface_child
, &occlusion
);
2149 // The |surface_child| can't occlude its own surface, but occlusion from
2151 EXPECT_EQ(gfx::Rect().ToString(),
2152 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2154 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2155 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2157 this->LeaveContributingSurface(surface_child
, &occlusion
);
2159 // When the surface_child's occlusion is transformed up to its parent, make
2160 // sure it is not clipped away inappropriately.
2161 this->EnterLayer(surface
, &occlusion
);
2162 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2163 occlusion
.occlusion_from_outside_target().ToString());
2164 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2165 occlusion
.occlusion_from_inside_target().ToString());
2166 this->LeaveLayer(surface
, &occlusion
);
2168 this->EnterContributingSurface(surface
, &occlusion
);
2169 // The occlusion from inside |surface| can't affect the surface, but
2171 EXPECT_EQ(gfx::Rect().ToString(),
2172 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2174 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2175 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2178 this->LeaveContributingSurface(surface
, &occlusion
);
2179 this->EnterLayer(parent
, &occlusion
);
2180 // The occlusion in |surface| and without are merged into the parent.
2181 EXPECT_EQ(gfx::Rect().ToString(),
2182 occlusion
.occlusion_from_outside_target().ToString());
2183 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
2184 occlusion
.occlusion_from_inside_target().ToString());
2188 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2190 template <class Types
>
2191 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2192 : public OcclusionTrackerTest
<Types
> {
2194 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2196 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2198 gfx::Transform scale_by_half
;
2199 scale_by_half
.Scale(0.5, 0.5);
2201 FilterOperations filters
;
2202 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
2204 // Save the distance of influence for the blur effect.
2205 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2207 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2214 LAST_DIRECTION
= BOTTOM
,
2217 for (int i
= 0; i
<= LAST_DIRECTION
; ++i
) {
2220 // Make a 50x50 filtered surface that is adjacent to occluding layers
2221 // which are above it in the z-order in various configurations. The
2222 // surface is scaled to test that the pixel moving is done in the target
2223 // space, where the background filter is applied.
2224 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2225 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
2226 typename
Types::LayerType
* filtered_surface
=
2227 this->CreateDrawingLayer(parent
,
2229 gfx::PointF(50.f
, 50.f
),
2230 gfx::Size(100, 100),
2232 filtered_surface
->SetBackgroundFilters(filters
);
2234 gfx::Rect occlusion_rect
;
2237 occlusion_rect
= gfx::Rect(0, 0, 50, 200);
2240 occlusion_rect
= gfx::Rect(100, 0, 50, 200);
2243 occlusion_rect
= gfx::Rect(0, 0, 200, 50);
2246 occlusion_rect
= gfx::Rect(0, 100, 200, 50);
2250 typename
Types::LayerType
* occluding_layer
=
2251 this->CreateDrawingLayer(parent
,
2252 this->identity_matrix
,
2253 occlusion_rect
.origin(),
2254 occlusion_rect
.size(),
2256 this->CalcDrawEtc(parent
);
2258 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2259 gfx::Rect(0, 0, 200, 200));
2261 // This layer occludes pixels directly beside the filtered_surface.
2262 // Because filtered surface blends pixels in a radius, it will need to see
2263 // some of the pixels (up to radius far) underneath the occluding layers.
2264 this->VisitLayer(occluding_layer
, &occlusion
);
2266 EXPECT_EQ(occlusion_rect
.ToString(),
2267 occlusion
.occlusion_from_inside_target().ToString());
2268 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2270 this->VisitLayer(filtered_surface
, &occlusion
);
2272 // The occlusion is used fully inside the surface.
2273 gfx::Rect occlusion_inside_surface
=
2274 occlusion_rect
- gfx::Vector2d(50, 50);
2275 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2276 EXPECT_EQ(occlusion_inside_surface
.ToString(),
2277 occlusion
.occlusion_from_outside_target().ToString());
2279 // The surface has a background blur, so it needs pixels that are
2280 // currently considered occluded in order to be drawn. So the pixels it
2281 // needs should be removed some the occluded area so that when we get to
2282 // the parent they are drawn.
2283 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2284 this->EnterLayer(parent
, &occlusion
);
2286 gfx::Rect expected_occlusion
= occlusion_rect
;
2289 expected_occlusion
.Inset(0, 0, outset_right
, 0);
2292 expected_occlusion
.Inset(outset_right
, 0, 0, 0);
2295 expected_occlusion
.Inset(0, 0, 0, outset_right
);
2298 expected_occlusion
.Inset(0, outset_right
, 0, 0);
2302 EXPECT_EQ(expected_occlusion
.ToString(),
2303 occlusion
.occlusion_from_inside_target().ToString());
2304 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2306 this->DestroyLayers();
2311 ALL_OCCLUSIONTRACKER_TEST(
2312 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
2314 template <class Types
>
2315 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
2316 : public OcclusionTrackerTest
<Types
> {
2318 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
2320 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2322 gfx::Transform scale_by_half
;
2323 scale_by_half
.Scale(0.5, 0.5);
2325 // Makes two surfaces that completely cover |parent|. The occlusion both
2326 // above and below the filters will be reduced by each of them.
2327 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2328 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
2329 typename
Types::LayerType
* parent
= this->CreateSurface(
2330 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
2331 parent
->SetMasksToBounds(true);
2332 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
2333 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
2334 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
2335 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
2336 typename
Types::LayerType
* occluding_layer_above
=
2337 this->CreateDrawingLayer(parent
,
2338 this->identity_matrix
,
2339 gfx::PointF(100.f
, 100.f
),
2343 // Filters make the layers own surfaces.
2344 FilterOperations filters
;
2345 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
2346 filtered_surface1
->SetBackgroundFilters(filters
);
2347 filtered_surface2
->SetBackgroundFilters(filters
);
2349 // Save the distance of influence for the blur effect.
2350 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2352 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2354 this->CalcDrawEtc(root
);
2356 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2357 gfx::Rect(0, 0, 1000, 1000));
2359 this->VisitLayer(occluding_layer_above
, &occlusion
);
2360 EXPECT_EQ(gfx::Rect().ToString(),
2361 occlusion
.occlusion_from_outside_target().ToString());
2362 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
2363 occlusion
.occlusion_from_inside_target().ToString());
2365 this->VisitLayer(filtered_surface2
, &occlusion
);
2366 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
2367 this->VisitLayer(filtered_surface1
, &occlusion
);
2368 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
2370 // Test expectations in the target.
2371 gfx::Rect expected_occlusion
=
2372 gfx::Rect(100 / 2 + outset_right
* 2,
2373 100 / 2 + outset_bottom
* 2,
2374 50 / 2 - (outset_left
+ outset_right
) * 2,
2375 50 / 2 - (outset_top
+ outset_bottom
) * 2);
2376 EXPECT_EQ(expected_occlusion
.ToString(),
2377 occlusion
.occlusion_from_inside_target().ToString());
2379 // Test expectations in the screen are the same as in the target, as the
2380 // render surface is 1:1 with the screen.
2381 EXPECT_EQ(expected_occlusion
.ToString(),
2382 occlusion
.occlusion_from_outside_target().ToString());
2386 ALL_OCCLUSIONTRACKER_TEST(
2387 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
2389 template <class Types
>
2390 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
2391 : public OcclusionTrackerTest
<Types
> {
2393 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
2395 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2397 gfx::Transform scale_by_half
;
2398 scale_by_half
.Scale(0.5, 0.5);
2400 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
2401 // centered below each. The surface is scaled to test that the pixel moving
2402 // is done in the target space, where the background filter is applied, but
2403 // the surface appears at 50, 50 and the replica at 200, 50.
2404 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2405 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
2406 typename
Types::LayerType
* behind_surface_layer
=
2407 this->CreateDrawingLayer(parent
,
2408 this->identity_matrix
,
2409 gfx::PointF(60.f
, 60.f
),
2412 typename
Types::LayerType
* behind_replica_layer
=
2413 this->CreateDrawingLayer(parent
,
2414 this->identity_matrix
,
2415 gfx::PointF(210.f
, 60.f
),
2418 typename
Types::LayerType
* filtered_surface
=
2419 this->CreateDrawingLayer(parent
,
2421 gfx::PointF(50.f
, 50.f
),
2422 gfx::Size(100, 100),
2424 this->CreateReplicaLayer(filtered_surface
,
2425 this->identity_matrix
,
2426 gfx::PointF(300.f
, 0.f
),
2429 // Filters make the layer own a surface.
2430 FilterOperations filters
;
2431 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2432 filtered_surface
->SetBackgroundFilters(filters
);
2434 this->CalcDrawEtc(parent
);
2436 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2437 gfx::Rect(0, 0, 1000, 1000));
2439 // The surface has a background blur, so it blurs non-opaque pixels below
2441 this->VisitLayer(filtered_surface
, &occlusion
);
2442 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2444 this->VisitLayer(behind_replica_layer
, &occlusion
);
2446 // The layers behind the surface are not blurred, and their occlusion does
2447 // not change, until we leave the surface. So it should not be modified by
2449 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
2450 EXPECT_EQ(occlusion_behind_replica
.ToString(),
2451 occlusion
.occlusion_from_inside_target().ToString());
2452 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2454 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
2455 // without existing occlusion interfering.
2456 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2458 this->VisitLayer(behind_surface_layer
, &occlusion
);
2460 // The layers behind the surface are not blurred, and their occlusion does
2461 // not change, until we leave the surface. So it should not be modified by
2463 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
2464 EXPECT_EQ(occlusion_behind_surface
.ToString(),
2465 occlusion
.occlusion_from_inside_target().ToString());
2466 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2470 ALL_OCCLUSIONTRACKER_TEST(
2471 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
2473 template <class Types
>
2474 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
2475 : public OcclusionTrackerTest
<Types
> {
2477 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
2479 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2481 gfx::Transform scale_by_half
;
2482 scale_by_half
.Scale(0.5, 0.5);
2484 // Make a 50x50 filtered surface that is completely occluded by an opaque
2485 // layer which is above it in the z-order. The surface is
2486 // scaled to test that the pixel moving is done in the target space, where
2487 // the background filter is applied, but the surface appears at 50, 50.
2488 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2489 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
2490 typename
Types::LayerType
* filtered_surface
=
2491 this->CreateDrawingLayer(parent
,
2493 gfx::PointF(50.f
, 50.f
),
2494 gfx::Size(100, 100),
2496 typename
Types::LayerType
* occluding_layer
=
2497 this->CreateDrawingLayer(parent
,
2498 this->identity_matrix
,
2499 gfx::PointF(50.f
, 50.f
),
2503 // Filters make the layer own a surface.
2504 FilterOperations filters
;
2505 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2506 filtered_surface
->SetBackgroundFilters(filters
);
2508 this->CalcDrawEtc(parent
);
2510 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2511 gfx::Rect(0, 0, 1000, 1000));
2513 this->VisitLayer(occluding_layer
, &occlusion
);
2515 this->VisitLayer(filtered_surface
, &occlusion
);
2517 // The layers above the filtered surface occlude from outside.
2518 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
2520 EXPECT_EQ(gfx::Rect().ToString(),
2521 occlusion
.occlusion_from_inside_target().ToString());
2522 EXPECT_EQ(occlusion_above_surface
.ToString(),
2523 occlusion
.occlusion_from_outside_target().ToString());
2526 // The surface has a background blur, so it blurs non-opaque pixels below
2528 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2530 // The filter is completely occluded, so it should not blur anything and
2531 // reduce any occlusion.
2532 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
2534 EXPECT_EQ(occlusion_above_surface
.ToString(),
2535 occlusion
.occlusion_from_inside_target().ToString());
2536 EXPECT_EQ(gfx::Rect().ToString(),
2537 occlusion
.occlusion_from_outside_target().ToString());
2542 ALL_OCCLUSIONTRACKER_TEST(
2543 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
2545 template <class Types
>
2546 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
2547 : public OcclusionTrackerTest
<Types
> {
2550 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
2552 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2554 gfx::Transform scale_by_half
;
2555 scale_by_half
.Scale(0.5, 0.5);
2557 // Make a surface and its replica, each 50x50, that are partially occluded
2558 // by opaque layers which are above them in the z-order. The surface is
2559 // scaled to test that the pixel moving is done in the target space, where
2560 // the background filter is applied, but the surface appears at 50, 50 and
2561 // the replica at 200, 50.
2562 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2563 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
2564 typename
Types::LayerType
* filtered_surface
=
2565 this->CreateDrawingLayer(parent
,
2567 gfx::PointF(50.f
, 50.f
),
2568 gfx::Size(100, 100),
2570 this->CreateReplicaLayer(filtered_surface
,
2571 this->identity_matrix
,
2572 gfx::PointF(300.f
, 0.f
),
2574 typename
Types::LayerType
* above_surface_layer
=
2575 this->CreateDrawingLayer(parent
,
2576 this->identity_matrix
,
2577 gfx::PointF(70.f
, 50.f
),
2580 typename
Types::LayerType
* above_replica_layer
=
2581 this->CreateDrawingLayer(parent
,
2582 this->identity_matrix
,
2583 gfx::PointF(200.f
, 50.f
),
2586 typename
Types::LayerType
* beside_surface_layer
=
2587 this->CreateDrawingLayer(parent
,
2588 this->identity_matrix
,
2589 gfx::PointF(90.f
, 40.f
),
2592 typename
Types::LayerType
* beside_replica_layer
=
2593 this->CreateDrawingLayer(parent
,
2594 this->identity_matrix
,
2595 gfx::PointF(200.f
, 40.f
),
2599 // Filters make the layer own a surface.
2600 FilterOperations filters
;
2601 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2602 filtered_surface
->SetBackgroundFilters(filters
);
2604 // Save the distance of influence for the blur effect.
2605 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2607 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2609 this->CalcDrawEtc(parent
);
2611 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2612 gfx::Rect(0, 0, 1000, 1000));
2614 this->VisitLayer(beside_replica_layer
, &occlusion
);
2615 this->VisitLayer(beside_surface_layer
, &occlusion
);
2616 this->VisitLayer(above_replica_layer
, &occlusion
);
2617 this->VisitLayer(above_surface_layer
, &occlusion
);
2619 // The surface has a background blur, so it blurs non-opaque pixels below
2621 this->VisitLayer(filtered_surface
, &occlusion
);
2622 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2624 // The filter in the surface and replica are partially unoccluded. Only the
2625 // unoccluded parts should reduce occlusion. This means it will push back
2626 // the occlusion that touches the unoccluded part (occlusion_above___), but
2627 // it will not touch occlusion_beside____ since that is not beside the
2628 // unoccluded part of the surface, even though it is beside the occluded
2629 // part of the surface.
2630 gfx::Rect occlusion_above_surface
=
2631 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
2632 gfx::Rect occlusion_above_replica
=
2633 gfx::Rect(200, 50, 30 - outset_left
, 50);
2634 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
2635 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
2637 SimpleEnclosedRegion expected_occlusion
;
2638 expected_occlusion
.Union(occlusion_beside_replica
);
2639 expected_occlusion
.Union(occlusion_beside_surface
);
2640 expected_occlusion
.Union(occlusion_above_replica
);
2641 expected_occlusion
.Union(occlusion_above_surface
);
2643 EXPECT_EQ(expected_occlusion
.ToString(),
2644 occlusion
.occlusion_from_inside_target().ToString());
2645 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2647 const SimpleEnclosedRegion
& actual_occlusion
=
2648 occlusion
.occlusion_from_inside_target();
2649 for (size_t i
= 0; i
< expected_occlusion
.GetRegionComplexity(); ++i
) {
2650 ASSERT_LT(i
, actual_occlusion
.GetRegionComplexity());
2651 EXPECT_EQ(expected_occlusion
.GetRect(i
), actual_occlusion
.GetRect(i
));
2656 ALL_OCCLUSIONTRACKER_TEST(
2657 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
2659 template <class Types
>
2660 class OcclusionTrackerTestMinimumTrackingSize
2661 : public OcclusionTrackerTest
<Types
> {
2663 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
2664 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2666 gfx::Size
tracking_size(100, 100);
2667 gfx::Size
below_tracking_size(99, 99);
2669 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2670 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2671 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
2672 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
2673 typename
Types::LayerType
* small
=
2674 this->CreateDrawingLayer(parent
,
2675 this->identity_matrix
,
2677 below_tracking_size
,
2679 this->CalcDrawEtc(parent
);
2681 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2682 gfx::Rect(0, 0, 1000, 1000));
2683 occlusion
.set_minimum_tracking_size(tracking_size
);
2685 // The small layer is not tracked because it is too small.
2686 this->VisitLayer(small
, &occlusion
);
2688 EXPECT_EQ(gfx::Rect().ToString(),
2689 occlusion
.occlusion_from_outside_target().ToString());
2690 EXPECT_EQ(gfx::Rect().ToString(),
2691 occlusion
.occlusion_from_inside_target().ToString());
2693 // The large layer is tracked as it is large enough.
2694 this->VisitLayer(large
, &occlusion
);
2696 EXPECT_EQ(gfx::Rect().ToString(),
2697 occlusion
.occlusion_from_outside_target().ToString());
2698 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
2699 occlusion
.occlusion_from_inside_target().ToString());
2703 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
2705 template <class Types
>
2706 class OcclusionTrackerTestScaledLayerIsClipped
2707 : public OcclusionTrackerTest
<Types
> {
2709 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
2710 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2712 gfx::Transform scale_transform
;
2713 scale_transform
.Scale(512.0, 512.0);
2715 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2716 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2717 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
2718 this->identity_matrix
,
2719 gfx::PointF(10.f
, 10.f
),
2721 clip
->SetMasksToBounds(true);
2722 typename
Types::LayerType
* scale
= this->CreateLayer(
2723 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
2724 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
2725 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
2726 this->CalcDrawEtc(parent
);
2728 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2729 gfx::Rect(0, 0, 1000, 1000));
2731 this->VisitLayer(scaled
, &occlusion
);
2733 EXPECT_EQ(gfx::Rect().ToString(),
2734 occlusion
.occlusion_from_outside_target().ToString());
2735 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2736 occlusion
.occlusion_from_inside_target().ToString());
2740 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
2742 template <class Types
>
2743 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
2744 : public OcclusionTrackerTest
<Types
> {
2746 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
2747 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2749 gfx::Transform scale_transform
;
2750 scale_transform
.Scale(512.0, 512.0);
2752 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2753 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2754 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
2755 this->identity_matrix
,
2756 gfx::PointF(10.f
, 10.f
),
2758 clip
->SetMasksToBounds(true);
2759 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
2760 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
2761 typename
Types::LayerType
* scale
= this->CreateLayer(
2762 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
2763 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
2764 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
2765 this->CalcDrawEtc(parent
);
2767 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2768 gfx::Rect(0, 0, 1000, 1000));
2770 this->VisitLayer(scaled
, &occlusion
);
2771 this->VisitLayer(surface
, &occlusion
);
2772 this->VisitContributingSurface(surface
, &occlusion
);
2774 EXPECT_EQ(gfx::Rect().ToString(),
2775 occlusion
.occlusion_from_outside_target().ToString());
2776 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2777 occlusion
.occlusion_from_inside_target().ToString());
2781 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
2783 template <class Types
>
2784 class OcclusionTrackerTestCopyRequestDoesOcclude
2785 : public OcclusionTrackerTest
<Types
> {
2787 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
2788 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2790 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2791 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2792 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
2793 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2794 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
2795 this->identity_matrix
,
2797 gfx::Size(200, 400));
2798 this->AddCopyRequest(copy
);
2799 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
2801 this->identity_matrix
,
2803 gfx::Size(200, 400),
2805 this->CalcDrawEtc(root
);
2807 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2808 gfx::Rect(0, 0, 1000, 1000));
2810 this->VisitLayer(copy_child
, &occlusion
);
2811 EXPECT_EQ(gfx::Rect().ToString(),
2812 occlusion
.occlusion_from_outside_target().ToString());
2813 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2814 occlusion
.occlusion_from_inside_target().ToString());
2816 // CopyRequests cause the layer to own a surface.
2817 this->VisitContributingSurface(copy
, &occlusion
);
2819 // The occlusion from the copy should be kept.
2820 EXPECT_EQ(gfx::Rect().ToString(),
2821 occlusion
.occlusion_from_outside_target().ToString());
2822 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
2823 occlusion
.occlusion_from_inside_target().ToString());
2827 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
2829 template <class Types
>
2830 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2831 : public OcclusionTrackerTest
<Types
> {
2833 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2835 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2837 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2838 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2839 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
2840 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2841 typename
Types::LayerType
* hide
= this->CreateLayer(
2842 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
2843 typename
Types::LayerType
* copy
= this->CreateLayer(
2844 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
2845 this->AddCopyRequest(copy
);
2846 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
2847 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
2849 // The |copy| layer is hidden but since it is being copied, it will be
2851 hide
->SetHideLayerAndSubtree(true);
2853 this->CalcDrawEtc(root
);
2855 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2856 gfx::Rect(0, 0, 1000, 1000));
2858 this->VisitLayer(copy_child
, &occlusion
);
2859 EXPECT_EQ(gfx::Rect().ToString(),
2860 occlusion
.occlusion_from_outside_target().ToString());
2861 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2862 occlusion
.occlusion_from_inside_target().ToString());
2864 // CopyRequests cause the layer to own a surface.
2865 this->VisitContributingSurface(copy
, &occlusion
);
2867 // The occlusion from the copy should be dropped since it is hidden.
2868 EXPECT_EQ(gfx::Rect().ToString(),
2869 occlusion
.occlusion_from_outside_target().ToString());
2870 EXPECT_EQ(gfx::Rect().ToString(),
2871 occlusion
.occlusion_from_inside_target().ToString());
2875 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
2877 template <class Types
>
2878 class OcclusionTrackerTestOccludedLayer
: public OcclusionTrackerTest
<Types
> {
2880 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers
)
2881 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2883 gfx::Transform translate
;
2884 translate
.Translate(10.0, 20.0);
2885 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2886 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2887 typename
Types::LayerType
* surface
= this->CreateSurface(
2888 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2889 typename
Types::LayerType
* layer
= this->CreateDrawingLayer(
2890 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2891 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
2892 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2893 this->CalcDrawEtc(root
);
2895 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2896 gfx::Rect(0, 0, 200, 200));
2897 this->VisitLayer(outside_layer
, &occlusion
);
2898 this->EnterLayer(layer
, &occlusion
);
2900 // No occlusion, is not occluded.
2901 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2902 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2903 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100)));
2905 // Partial occlusion from outside, is not occluded.
2906 occlusion
.set_occlusion_from_outside_target(
2907 SimpleEnclosedRegion(50, 50, 100, 100));
2908 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2909 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2910 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2911 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2912 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2913 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2914 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2915 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2916 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2918 // Full occlusion from outside, is occluded.
2919 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2920 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2921 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2922 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2924 // Partial occlusion from inside, is not occluded.
2925 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2926 occlusion
.set_occlusion_from_inside_target(
2927 SimpleEnclosedRegion(50, 50, 100, 100));
2928 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2929 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2930 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2931 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2932 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2933 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2934 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2935 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2937 // Full occlusion from inside, is occluded.
2938 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2939 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2940 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2941 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2943 // Partial occlusion from both, is not occluded.
2944 occlusion
.set_occlusion_from_outside_target(
2945 SimpleEnclosedRegion(50, 50, 100, 50));
2946 occlusion
.set_occlusion_from_inside_target(
2947 SimpleEnclosedRegion(50, 100, 100, 50));
2948 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2949 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2950 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2951 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2952 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2953 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2954 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2955 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2957 // Full occlusion from both, is occluded.
2958 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2959 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2960 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2961 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2965 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer
)
2967 template <class Types
>
2968 class OcclusionTrackerTestUnoccludedLayerQuery
2969 : public OcclusionTrackerTest
<Types
> {
2971 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers
)
2972 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2974 gfx::Transform translate
;
2975 translate
.Translate(10.0, 20.0);
2976 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2977 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2978 typename
Types::LayerType
* surface
= this->CreateSurface(
2979 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2980 typename
Types::LayerType
* layer
= this->CreateDrawingLayer(
2981 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2982 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
2983 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2984 this->CalcDrawEtc(root
);
2986 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2987 gfx::Rect(0, 0, 200, 200));
2988 this->VisitLayer(outside_layer
, &occlusion
);
2989 this->EnterLayer(layer
, &occlusion
);
2991 // No occlusion, is not occluded.
2992 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2993 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2994 EXPECT_EQ(gfx::Rect(100, 100),
2995 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(100, 100)));
2997 // Partial occlusion from outside.
2998 occlusion
.set_occlusion_from_outside_target(
2999 SimpleEnclosedRegion(50, 50, 100, 100));
3000 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3002 gfx::Rect(0, 0, 100, 100),
3003 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3004 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3005 occlusion
.UnoccludedLayerContentRect(
3006 layer
, gfx::Rect(90, 30, 100, 100)));
3007 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3008 occlusion
.UnoccludedLayerContentRect(layer
,
3009 gfx::Rect(40, 0, 100, 100)));
3010 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3011 occlusion
.UnoccludedLayerContentRect(
3012 layer
, gfx::Rect(40, 80, 100, 100)));
3014 gfx::Rect(0, 0, 80, 100),
3015 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3016 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3017 occlusion
.UnoccludedLayerContentRect(
3018 layer
, gfx::Rect(90, 80, 100, 100)));
3019 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3020 occlusion
.UnoccludedLayerContentRect(layer
,
3021 gfx::Rect(0, 80, 100, 100)));
3022 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3023 occlusion
.UnoccludedLayerContentRect(layer
,
3024 gfx::Rect(90, 0, 100, 100)));
3026 // Full occlusion from outside, is occluded.
3027 EXPECT_EQ(gfx::Rect(),
3028 occlusion
.UnoccludedLayerContentRect(
3029 layer
, gfx::Rect(40, 30, 100, 100)));
3032 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3033 EXPECT_EQ(gfx::Rect(),
3034 occlusion
.UnoccludedLayerContentRect(
3035 layer
, gfx::Rect(130, 120, 10, 10)));
3038 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3040 // Partial occlusion from inside, is not occluded.
3041 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3042 occlusion
.set_occlusion_from_inside_target(
3043 SimpleEnclosedRegion(50, 50, 100, 100));
3045 gfx::Rect(0, 0, 100, 100),
3046 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3047 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3048 occlusion
.UnoccludedLayerContentRect(
3049 layer
, gfx::Rect(90, 30, 100, 100)));
3050 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3051 occlusion
.UnoccludedLayerContentRect(layer
,
3052 gfx::Rect(40, 0, 100, 100)));
3053 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3054 occlusion
.UnoccludedLayerContentRect(
3055 layer
, gfx::Rect(40, 80, 100, 100)));
3057 gfx::Rect(0, 0, 80, 100),
3058 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3059 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3060 occlusion
.UnoccludedLayerContentRect(
3061 layer
, gfx::Rect(90, 80, 100, 100)));
3062 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3063 occlusion
.UnoccludedLayerContentRect(layer
,
3064 gfx::Rect(0, 80, 100, 100)));
3065 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3066 occlusion
.UnoccludedLayerContentRect(layer
,
3067 gfx::Rect(90, 0, 100, 100)));
3069 // Full occlusion from inside, is occluded.
3070 EXPECT_EQ(gfx::Rect(),
3071 occlusion
.UnoccludedLayerContentRect(
3072 layer
, gfx::Rect(40, 30, 100, 100)));
3075 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3076 EXPECT_EQ(gfx::Rect(),
3077 occlusion
.UnoccludedLayerContentRect(
3078 layer
, gfx::Rect(130, 120, 10, 10)));
3081 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3083 // Partial occlusion from both, is not occluded.
3084 occlusion
.set_occlusion_from_outside_target(
3085 SimpleEnclosedRegion(50, 50, 100, 50));
3086 occlusion
.set_occlusion_from_inside_target(
3087 SimpleEnclosedRegion(50, 100, 100, 50));
3089 gfx::Rect(0, 0, 100, 100),
3090 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3091 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3093 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3094 occlusion
.UnoccludedLayerContentRect(
3095 layer
, gfx::Rect(90, 30, 100, 100)));
3096 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3097 occlusion
.UnoccludedLayerContentRect(layer
,
3098 gfx::Rect(40, 0, 100, 100)));
3099 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3100 occlusion
.UnoccludedLayerContentRect(
3101 layer
, gfx::Rect(40, 80, 100, 100)));
3103 gfx::Rect(0, 0, 80, 100),
3104 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3105 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3106 occlusion
.UnoccludedLayerContentRect(
3107 layer
, gfx::Rect(90, 80, 100, 100)));
3108 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3109 occlusion
.UnoccludedLayerContentRect(layer
,
3110 gfx::Rect(0, 80, 100, 100)));
3111 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3112 occlusion
.UnoccludedLayerContentRect(layer
,
3113 gfx::Rect(90, 0, 100, 100)));
3115 // Full occlusion from both, is occluded.
3116 EXPECT_EQ(gfx::Rect(),
3117 occlusion
.UnoccludedLayerContentRect(
3118 layer
, gfx::Rect(40, 30, 100, 100)));
3121 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3122 EXPECT_EQ(gfx::Rect(),
3123 occlusion
.UnoccludedLayerContentRect(
3124 layer
, gfx::Rect(130, 120, 10, 10)));
3127 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3131 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery
)
3133 template <class Types
>
3134 class OcclusionTrackerTestUnoccludedSurfaceQuery
3135 : public OcclusionTrackerTest
<Types
> {
3137 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers
)
3138 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3140 gfx::Transform translate
;
3141 translate
.Translate(10.0, 20.0);
3142 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3143 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
3144 typename
Types::LayerType
* surface
=
3145 this->CreateSurface(root
, translate
, gfx::Point(), gfx::Size(200, 200));
3146 typename
Types::LayerType
* layer
=
3147 this->CreateDrawingLayer(surface
,
3148 this->identity_matrix
,
3150 gfx::Size(200, 200),
3152 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
3153 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
3154 this->CalcDrawEtc(root
);
3156 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3157 gfx::Rect(0, 0, 200, 200));
3158 this->VisitLayer(outside_layer
, &occlusion
);
3159 this->VisitLayer(layer
, &occlusion
);
3160 this->EnterContributingSurface(surface
, &occlusion
);
3162 // No occlusion, is not occluded.
3163 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3164 SimpleEnclosedRegion());
3165 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3166 SimpleEnclosedRegion());
3168 gfx::Rect(100, 100),
3169 occlusion
.UnoccludedSurfaceContentRect(surface
, gfx::Rect(100, 100)));
3171 // Partial occlusion from outside.
3172 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3173 SimpleEnclosedRegion(50, 50, 100, 100));
3174 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3175 SimpleEnclosedRegion());
3176 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3177 occlusion
.UnoccludedSurfaceContentRect(
3178 surface
, gfx::Rect(0, 0, 100, 100)));
3179 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3180 occlusion
.UnoccludedSurfaceContentRect(
3181 surface
, gfx::Rect(90, 30, 100, 100)));
3182 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3183 occlusion
.UnoccludedSurfaceContentRect(
3184 surface
, gfx::Rect(40, 0, 100, 100)));
3185 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3186 occlusion
.UnoccludedSurfaceContentRect(
3187 surface
, gfx::Rect(40, 80, 100, 100)));
3188 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3189 occlusion
.UnoccludedSurfaceContentRect(surface
,
3190 gfx::Rect(0, 0, 80, 100)));
3191 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3192 occlusion
.UnoccludedSurfaceContentRect(
3193 surface
, gfx::Rect(90, 80, 100, 100)));
3194 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3195 occlusion
.UnoccludedSurfaceContentRect(
3196 surface
, gfx::Rect(0, 80, 100, 100)));
3197 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3198 occlusion
.UnoccludedSurfaceContentRect(
3199 surface
, gfx::Rect(90, 0, 100, 100)));
3201 // Full occlusion from outside, is occluded.
3202 EXPECT_EQ(gfx::Rect(),
3203 occlusion
.UnoccludedSurfaceContentRect(
3204 surface
, gfx::Rect(40, 30, 100, 100)));
3205 EXPECT_EQ(gfx::Rect(),
3206 occlusion
.UnoccludedSurfaceContentRect(
3207 surface
, gfx::Rect(40, 30, 10, 10)));
3208 EXPECT_EQ(gfx::Rect(),
3209 occlusion
.UnoccludedSurfaceContentRect(
3210 surface
, gfx::Rect(130, 120, 10, 10)));
3211 EXPECT_EQ(gfx::Rect(),
3212 occlusion
.UnoccludedSurfaceContentRect(
3213 surface
, gfx::Rect(80, 70, 50, 50)));
3215 // Partial occlusion from inside, is not occluded.
3216 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3217 SimpleEnclosedRegion());
3218 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3219 SimpleEnclosedRegion(50, 50, 100, 100));
3220 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3221 occlusion
.UnoccludedSurfaceContentRect(
3222 surface
, gfx::Rect(0, 0, 100, 100)));
3223 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3224 occlusion
.UnoccludedSurfaceContentRect(
3225 surface
, gfx::Rect(90, 30, 100, 100)));
3226 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3227 occlusion
.UnoccludedSurfaceContentRect(
3228 surface
, gfx::Rect(40, 0, 100, 100)));
3229 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3230 occlusion
.UnoccludedSurfaceContentRect(
3231 surface
, gfx::Rect(40, 80, 100, 100)));
3232 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3233 occlusion
.UnoccludedSurfaceContentRect(surface
,
3234 gfx::Rect(0, 0, 80, 100)));
3235 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3236 occlusion
.UnoccludedSurfaceContentRect(
3237 surface
, gfx::Rect(90, 80, 100, 100)));
3238 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3239 occlusion
.UnoccludedSurfaceContentRect(
3240 surface
, gfx::Rect(0, 80, 100, 100)));
3241 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3242 occlusion
.UnoccludedSurfaceContentRect(
3243 surface
, gfx::Rect(90, 0, 100, 100)));
3245 // Full occlusion from inside, is occluded.
3246 EXPECT_EQ(gfx::Rect(),
3247 occlusion
.UnoccludedSurfaceContentRect(
3248 surface
, gfx::Rect(40, 30, 100, 100)));
3249 EXPECT_EQ(gfx::Rect(),
3250 occlusion
.UnoccludedSurfaceContentRect(
3251 surface
, gfx::Rect(40, 30, 10, 10)));
3252 EXPECT_EQ(gfx::Rect(),
3253 occlusion
.UnoccludedSurfaceContentRect(
3254 surface
, gfx::Rect(130, 120, 10, 10)));
3255 EXPECT_EQ(gfx::Rect(),
3256 occlusion
.UnoccludedSurfaceContentRect(
3257 surface
, gfx::Rect(80, 70, 50, 50)));
3259 // Partial occlusion from both, is not occluded.
3260 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3261 SimpleEnclosedRegion(50, 50, 100, 50));
3262 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3263 SimpleEnclosedRegion(50, 100, 100, 50));
3264 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3265 occlusion
.UnoccludedSurfaceContentRect(
3266 surface
, gfx::Rect(0, 0, 100, 100)));
3267 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3269 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3270 occlusion
.UnoccludedSurfaceContentRect(
3271 surface
, gfx::Rect(90, 30, 100, 100)));
3272 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3273 occlusion
.UnoccludedSurfaceContentRect(
3274 surface
, gfx::Rect(40, 0, 100, 100)));
3275 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3276 occlusion
.UnoccludedSurfaceContentRect(
3277 surface
, gfx::Rect(40, 80, 100, 100)));
3278 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3279 occlusion
.UnoccludedSurfaceContentRect(surface
,
3280 gfx::Rect(0, 0, 80, 100)));
3281 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3282 occlusion
.UnoccludedSurfaceContentRect(
3283 surface
, gfx::Rect(90, 80, 100, 100)));
3284 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3285 occlusion
.UnoccludedSurfaceContentRect(
3286 surface
, gfx::Rect(0, 80, 100, 100)));
3287 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3288 occlusion
.UnoccludedSurfaceContentRect(
3289 surface
, gfx::Rect(90, 0, 100, 100)));
3291 // Full occlusion from both, is occluded.
3292 EXPECT_EQ(gfx::Rect(),
3293 occlusion
.UnoccludedSurfaceContentRect(
3294 surface
, gfx::Rect(40, 30, 100, 100)));
3295 EXPECT_EQ(gfx::Rect(),
3296 occlusion
.UnoccludedSurfaceContentRect(
3297 surface
, gfx::Rect(40, 30, 10, 10)));
3298 EXPECT_EQ(gfx::Rect(),
3299 occlusion
.UnoccludedSurfaceContentRect(
3300 surface
, gfx::Rect(130, 120, 10, 10)));
3301 EXPECT_EQ(gfx::Rect(),
3302 occlusion
.UnoccludedSurfaceContentRect(
3303 surface
, gfx::Rect(80, 70, 50, 50)));
3307 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery
)