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->GetCurrentOcclusionForContributingSurface(
105 surface
->draw_transform())
106 .GetUnoccludedContentRect(content_rect
);
110 struct OcclusionTrackerTestMainThreadTypes
{
111 typedef Layer LayerType
;
112 typedef FakeLayerTreeHost HostType
;
113 typedef RenderSurface RenderSurfaceType
;
114 typedef TestContentLayer ContentLayerType
;
115 typedef scoped_refptr
<Layer
> LayerPtrType
;
116 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
117 typedef LayerIterator
<Layer
> TestLayerIterator
;
118 typedef OcclusionTracker
<Layer
> OcclusionTrackerType
;
120 static LayerPtrType
CreateLayer(HostType
* host
) { return Layer::Create(); }
121 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
122 return make_scoped_refptr(new ContentLayerType());
125 template <typename T
>
126 static LayerPtrType
PassLayerPtr(T
* layer
) {
127 LayerPtrType
ref(*layer
);
131 static void SetForceRenderSurface(LayerType
* layer
, bool force
) {
132 layer
->SetForceRenderSurface(force
);
135 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
137 static void RecursiveUpdateNumChildren(LayerType
* layerType
) {}
140 struct OcclusionTrackerTestImplThreadTypes
{
141 typedef LayerImpl LayerType
;
142 typedef LayerTreeImpl HostType
;
143 typedef RenderSurfaceImpl RenderSurfaceType
;
144 typedef TestContentLayerImpl ContentLayerType
;
145 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
146 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
147 typedef LayerIterator
<LayerImpl
> TestLayerIterator
;
148 typedef OcclusionTracker
<LayerImpl
> OcclusionTrackerType
;
150 static LayerPtrType
CreateLayer(HostType
* host
) {
151 return LayerImpl::Create(host
, next_layer_impl_id
++);
153 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
154 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
156 static int next_layer_impl_id
;
158 template <typename T
>
159 static LayerPtrType
PassLayerPtr(T
* layer
) {
160 return layer
->Pass();
163 static void SetForceRenderSurface(LayerType
* layer
, bool force
) {
164 layer
->SetHasRenderSurface(force
);
166 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
168 static void RecursiveUpdateNumChildren(LayerType
* layer
) {
169 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer
);
173 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
175 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
177 explicit OcclusionTrackerTest(bool opaque_layers
)
178 : opaque_layers_(opaque_layers
),
179 client_(FakeLayerTreeHostClient::DIRECT_3D
),
180 host_(FakeLayerTreeHost::Create(&client_
)) {}
182 virtual void RunMyTest() = 0;
184 void TearDown() override
{ DestroyLayers(); }
186 typename
Types::HostType
* GetHost();
188 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
189 const gfx::PointF
& position
,
190 const gfx::Size
& bounds
) {
191 typename
Types::ContentLayerPtrType
layer(
192 Types::CreateContentLayer(GetHost()));
193 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
194 SetProperties(layer_ptr
, transform
, position
, bounds
);
196 DCHECK(!root_
.get());
197 root_
= Types::PassLayerPtr(&layer
);
199 Types::SetForceRenderSurface(layer_ptr
, true);
200 SetRootLayerOnMainThread(layer_ptr
);
205 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
206 const gfx::Transform
& transform
,
207 const gfx::PointF
& position
,
208 const gfx::Size
& bounds
) {
209 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
210 typename
Types::LayerType
* layer_ptr
= layer
.get();
211 SetProperties(layer_ptr
, transform
, position
, bounds
);
212 parent
->AddChild(Types::PassLayerPtr(&layer
));
216 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
217 const gfx::Transform
& transform
,
218 const gfx::PointF
& position
,
219 const gfx::Size
& bounds
) {
220 typename
Types::LayerType
* layer
=
221 CreateLayer(parent
, transform
, position
, bounds
);
222 Types::SetForceRenderSurface(layer
, true);
226 typename
Types::ContentLayerType
* CreateDrawingLayer(
227 typename
Types::LayerType
* parent
,
228 const gfx::Transform
& transform
,
229 const gfx::PointF
& position
,
230 const gfx::Size
& bounds
,
232 typename
Types::ContentLayerPtrType
layer(
233 Types::CreateContentLayer(GetHost()));
234 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
235 SetProperties(layer_ptr
, transform
, position
, bounds
);
237 if (opaque_layers_
) {
238 layer_ptr
->SetContentsOpaque(opaque
);
240 layer_ptr
->SetContentsOpaque(false);
242 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
244 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
247 parent
->AddChild(Types::PassLayerPtr(&layer
));
251 typename
Types::LayerType
* CreateReplicaLayer(
252 typename
Types::LayerType
* owning_layer
,
253 const gfx::Transform
& transform
,
254 const gfx::PointF
& position
,
255 const gfx::Size
& bounds
) {
256 typename
Types::ContentLayerPtrType
layer(
257 Types::CreateContentLayer(GetHost()));
258 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
259 SetProperties(layer_ptr
, transform
, position
, bounds
);
260 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
264 typename
Types::LayerType
* CreateMaskLayer(
265 typename
Types::LayerType
* owning_layer
,
266 const gfx::Size
& bounds
) {
267 typename
Types::ContentLayerPtrType
layer(
268 Types::CreateContentLayer(GetHost()));
269 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
270 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
271 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
275 typename
Types::ContentLayerType
* CreateDrawingSurface(
276 typename
Types::LayerType
* parent
,
277 const gfx::Transform
& transform
,
278 const gfx::PointF
& position
,
279 const gfx::Size
& bounds
,
281 typename
Types::ContentLayerType
* layer
=
282 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
283 Types::SetForceRenderSurface(layer
, true);
287 void DestroyLayers() {
288 Types::DestroyLayer(&root_
);
289 render_surface_layer_list_
= nullptr;
290 render_surface_layer_list_impl_
.clear();
291 replica_layers_
.clear();
292 mask_layers_
.clear();
293 ResetLayerIterator();
296 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
298 void AddCopyRequest(Layer
* layer
) {
299 layer
->RequestCopyOfOutput(
300 CopyOutputRequest::CreateBitmapRequest(base::Bind(
301 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
302 base::Unretained(this))));
305 void AddCopyRequest(LayerImpl
* layer
) {
306 ScopedPtrVector
<CopyOutputRequest
> requests
;
308 CopyOutputRequest::CreateBitmapRequest(base::Bind(
309 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
310 base::Unretained(this))));
311 layer
->SetHasRenderSurface(true);
312 layer
->PassCopyRequests(&requests
);
315 void CalcDrawEtc(TestContentLayerImpl
* root
) {
316 DCHECK(root
== root_
.get());
318 Types::RecursiveUpdateNumChildren(root
);
319 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
320 root
, root
->bounds(), &render_surface_layer_list_impl_
);
321 inputs
.can_adjust_raster_scales
= true;
322 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
324 layer_iterator_
= layer_iterator_begin_
=
325 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
328 void CalcDrawEtc(TestContentLayer
* root
) {
329 DCHECK(root
== root_
.get());
330 DCHECK(!root
->render_surface());
332 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
333 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
334 root
, root
->bounds(), render_surface_layer_list_
.get());
335 inputs
.can_adjust_raster_scales
= true;
336 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
338 layer_iterator_
= layer_iterator_begin_
=
339 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
342 void EnterLayer(typename
Types::LayerType
* layer
,
343 typename
Types::OcclusionTrackerType
* occlusion
) {
344 ASSERT_EQ(*layer_iterator_
, layer
);
345 ASSERT_TRUE(layer_iterator_
.represents_itself());
346 occlusion
->EnterLayer(layer_iterator_
);
349 void LeaveLayer(typename
Types::LayerType
* layer
,
350 typename
Types::OcclusionTrackerType
* occlusion
) {
351 ASSERT_EQ(*layer_iterator_
, layer
);
352 ASSERT_TRUE(layer_iterator_
.represents_itself());
353 occlusion
->LeaveLayer(layer_iterator_
);
357 void VisitLayer(typename
Types::LayerType
* layer
,
358 typename
Types::OcclusionTrackerType
* occlusion
) {
359 EnterLayer(layer
, occlusion
);
360 LeaveLayer(layer
, occlusion
);
363 void EnterContributingSurface(
364 typename
Types::LayerType
* layer
,
365 typename
Types::OcclusionTrackerType
* occlusion
) {
366 ASSERT_EQ(*layer_iterator_
, layer
);
367 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
368 occlusion
->EnterLayer(layer_iterator_
);
369 occlusion
->LeaveLayer(layer_iterator_
);
371 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
372 occlusion
->EnterLayer(layer_iterator_
);
375 void LeaveContributingSurface(
376 typename
Types::LayerType
* layer
,
377 typename
Types::OcclusionTrackerType
* occlusion
) {
378 ASSERT_EQ(*layer_iterator_
, layer
);
379 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
380 occlusion
->LeaveLayer(layer_iterator_
);
384 void VisitContributingSurface(
385 typename
Types::LayerType
* layer
,
386 typename
Types::OcclusionTrackerType
* occlusion
) {
387 EnterContributingSurface(layer
, occlusion
);
388 LeaveContributingSurface(layer
, occlusion
);
391 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
393 const gfx::Transform identity_matrix
;
396 void SetRootLayerOnMainThread(Layer
* root
) {
397 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
400 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
402 void SetBaseProperties(typename
Types::LayerType
* layer
,
403 const gfx::Transform
& transform
,
404 const gfx::PointF
& position
,
405 const gfx::Size
& bounds
) {
406 layer
->SetTransform(transform
);
407 layer
->SetPosition(position
);
408 layer
->SetBounds(bounds
);
411 void SetProperties(Layer
* layer
,
412 const gfx::Transform
& transform
,
413 const gfx::PointF
& position
,
414 const gfx::Size
& bounds
) {
415 SetBaseProperties(layer
, transform
, position
, bounds
);
418 void SetProperties(LayerImpl
* layer
,
419 const gfx::Transform
& transform
,
420 const gfx::PointF
& position
,
421 const gfx::Size
& bounds
) {
422 SetBaseProperties(layer
, transform
, position
, bounds
);
424 layer
->SetContentBounds(layer
->bounds());
427 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
428 owning_layer
->SetReplicaLayer(layer
.get());
429 replica_layers_
.push_back(layer
);
432 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
433 owning_layer
->SetReplicaLayer(layer
.Pass());
436 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
437 owning_layer
->SetMaskLayer(layer
.get());
438 mask_layers_
.push_back(layer
);
441 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
442 owning_layer
->SetMaskLayer(layer
.Pass());
446 FakeLayerTreeHostClient client_
;
447 scoped_ptr
<FakeLayerTreeHost
> host_
;
448 // These hold ownership of the layers for the duration of the test.
449 typename
Types::LayerPtrType root_
;
450 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
451 LayerImplList render_surface_layer_list_impl_
;
452 typename
Types::TestLayerIterator layer_iterator_begin_
;
453 typename
Types::TestLayerIterator layer_iterator_
;
454 typename
Types::LayerType
* last_layer_visited_
;
455 LayerList replica_layers_
;
456 LayerList mask_layers_
;
461 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
467 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
468 return host_
->host_impl()->active_tree();
471 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
472 class ClassName##MainThreadOpaqueLayers \
473 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
474 public: /* NOLINT(whitespace/indent) */ \
475 ClassName##MainThreadOpaqueLayers() \
476 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
478 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
479 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
480 class ClassName##MainThreadOpaquePaints \
481 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
482 public: /* NOLINT(whitespace/indent) */ \
483 ClassName##MainThreadOpaquePaints() \
484 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
486 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
488 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
489 class ClassName##ImplThreadOpaqueLayers \
490 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
491 public: /* NOLINT(whitespace/indent) */ \
492 ClassName##ImplThreadOpaqueLayers() \
493 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
495 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
496 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
497 class ClassName##ImplThreadOpaquePaints \
498 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
499 public: /* NOLINT(whitespace/indent) */ \
500 ClassName##ImplThreadOpaquePaints() \
501 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
503 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
505 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
506 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
507 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
508 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
509 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
511 #define MAIN_THREAD_TEST(ClassName) \
512 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
514 #define IMPL_THREAD_TEST(ClassName) \
515 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
517 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
518 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
519 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
521 template <class Types
>
522 class OcclusionTrackerTestIdentityTransforms
523 : public OcclusionTrackerTest
<Types
> {
525 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
526 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
528 void RunMyTest() override
{
529 typename
Types::ContentLayerType
* root
= this->CreateRoot(
530 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
531 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
532 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
533 typename
Types::ContentLayerType
* layer
=
534 this->CreateDrawingLayer(parent
,
535 this->identity_matrix
,
536 gfx::PointF(30.f
, 30.f
),
539 parent
->SetMasksToBounds(true);
540 this->CalcDrawEtc(root
);
542 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
543 gfx::Rect(0, 0, 1000, 1000));
545 this->VisitLayer(layer
, &occlusion
);
546 this->EnterLayer(parent
, &occlusion
);
548 EXPECT_EQ(gfx::Rect().ToString(),
549 occlusion
.occlusion_from_outside_target().ToString());
550 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
551 occlusion
.occlusion_from_inside_target().ToString());
555 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
557 template <class Types
>
558 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
560 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
561 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
562 void RunMyTest() override
{
563 gfx::Transform layer_transform
;
564 layer_transform
.Translate(250.0, 250.0);
565 layer_transform
.Rotate(90.0);
566 layer_transform
.Translate(-250.0, -250.0);
568 typename
Types::ContentLayerType
* root
= this->CreateRoot(
569 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
570 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
571 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
572 typename
Types::ContentLayerType
* layer
=
573 this->CreateDrawingLayer(parent
,
575 gfx::PointF(30.f
, 30.f
),
578 parent
->SetMasksToBounds(true);
579 this->CalcDrawEtc(root
);
581 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
582 gfx::Rect(0, 0, 1000, 1000));
584 this->VisitLayer(layer
, &occlusion
);
585 this->EnterLayer(parent
, &occlusion
);
587 EXPECT_EQ(gfx::Rect().ToString(),
588 occlusion
.occlusion_from_outside_target().ToString());
589 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
590 occlusion
.occlusion_from_inside_target().ToString());
594 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
596 template <class Types
>
597 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
599 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
600 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
601 void RunMyTest() override
{
602 gfx::Transform layer_transform
;
603 layer_transform
.Translate(20.0, 20.0);
605 typename
Types::ContentLayerType
* root
= this->CreateRoot(
606 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
607 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
608 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
609 typename
Types::ContentLayerType
* layer
=
610 this->CreateDrawingLayer(parent
,
612 gfx::PointF(30.f
, 30.f
),
615 parent
->SetMasksToBounds(true);
616 this->CalcDrawEtc(root
);
618 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
619 gfx::Rect(0, 0, 1000, 1000));
621 this->VisitLayer(layer
, &occlusion
);
622 this->EnterLayer(parent
, &occlusion
);
624 EXPECT_EQ(gfx::Rect().ToString(),
625 occlusion
.occlusion_from_outside_target().ToString());
626 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
627 occlusion
.occlusion_from_inside_target().ToString());
631 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
633 template <class Types
>
634 class OcclusionTrackerTestChildInRotatedChild
635 : public OcclusionTrackerTest
<Types
> {
637 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
638 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
639 void RunMyTest() override
{
640 gfx::Transform child_transform
;
641 child_transform
.Translate(250.0, 250.0);
642 child_transform
.Rotate(90.0);
643 child_transform
.Translate(-250.0, -250.0);
645 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
646 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
647 parent
->SetMasksToBounds(true);
648 typename
Types::LayerType
* child
= this->CreateSurface(
649 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
650 child
->SetMasksToBounds(true);
651 typename
Types::ContentLayerType
* layer
=
652 this->CreateDrawingLayer(child
,
653 this->identity_matrix
,
654 gfx::PointF(10.f
, 10.f
),
657 this->CalcDrawEtc(parent
);
659 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
660 gfx::Rect(0, 0, 1000, 1000));
662 this->VisitLayer(layer
, &occlusion
);
663 this->EnterContributingSurface(child
, &occlusion
);
665 EXPECT_EQ(gfx::Rect().ToString(),
666 occlusion
.occlusion_from_outside_target().ToString());
667 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
668 occlusion
.occlusion_from_inside_target().ToString());
670 this->LeaveContributingSurface(child
, &occlusion
);
671 this->EnterLayer(parent
, &occlusion
);
673 EXPECT_EQ(gfx::Rect().ToString(),
674 occlusion
.occlusion_from_outside_target().ToString());
675 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
676 occlusion
.occlusion_from_inside_target().ToString());
678 /* Justification for the above occlusion from |layer|:
680 +---------------------+
683 | 30 + ---------------------------------+
685 | |10+---------------------------------+
689 +----|--|-------------+ | |
697 +--|-------------------------------+ |
699 +---------------------------------+
702 +---------------------+
703 | |30 Visible region of |layer|: /////
705 | +---------------------------------+
707 | +---------------------------------+ |
708 | | |///////////////| 420 | |
709 | | |///////////////|60 | |
710 | | |///////////////| | |
711 +--|--|---------------+ | |
719 | +------------------------------|--+
721 +---------------------------------+
728 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
730 template <class Types
>
731 class OcclusionTrackerTestScaledRenderSurface
732 : public OcclusionTrackerTest
<Types
> {
734 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
735 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
737 void RunMyTest() override
{
738 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
739 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
741 gfx::Transform layer1_matrix
;
742 layer1_matrix
.Scale(2.0, 2.0);
743 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
744 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
745 Types::SetForceRenderSurface(layer1
, true);
747 gfx::Transform layer2_matrix
;
748 layer2_matrix
.Translate(25.0, 25.0);
749 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
750 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
751 typename
Types::ContentLayerType
* occluder
=
752 this->CreateDrawingLayer(parent
,
753 this->identity_matrix
,
754 gfx::PointF(100.f
, 100.f
),
757 this->CalcDrawEtc(parent
);
759 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
760 gfx::Rect(0, 0, 1000, 1000));
762 this->VisitLayer(occluder
, &occlusion
);
763 this->EnterLayer(layer2
, &occlusion
);
765 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
766 occlusion
.occlusion_from_outside_target().ToString());
767 EXPECT_EQ(gfx::Rect().ToString(),
768 occlusion
.occlusion_from_inside_target().ToString());
772 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
774 template <class Types
>
775 class OcclusionTrackerTestVisitTargetTwoTimes
776 : public OcclusionTrackerTest
<Types
> {
778 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
779 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
780 void RunMyTest() override
{
781 typename
Types::ContentLayerType
* root
= this->CreateRoot(
782 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
783 typename
Types::LayerType
* surface
= this->CreateSurface(
784 root
, this->identity_matrix
, gfx::PointF(30.f
, 30.f
), gfx::Size());
785 typename
Types::ContentLayerType
* surface_child
=
786 this->CreateDrawingLayer(surface
,
787 this->identity_matrix
,
788 gfx::PointF(10.f
, 10.f
),
791 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
792 // first, instead of |surface|'s. This exercises different code in
793 // LeaveToRenderTarget, as the target surface has already been seen when
794 // leaving |surface| later.
795 typename
Types::ContentLayerType
* top_layer
=
796 this->CreateDrawingLayer(root
,
797 this->identity_matrix
,
798 gfx::PointF(40.f
, 90.f
),
801 this->CalcDrawEtc(root
);
803 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
804 gfx::Rect(0, 0, 1000, 1000));
806 this->VisitLayer(top_layer
, &occlusion
);
808 EXPECT_EQ(gfx::Rect().ToString(),
809 occlusion
.occlusion_from_outside_target().ToString());
810 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
811 occlusion
.occlusion_from_inside_target().ToString());
813 this->VisitLayer(surface_child
, &occlusion
);
815 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
816 occlusion
.occlusion_from_outside_target().ToString());
817 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
818 occlusion
.occlusion_from_inside_target().ToString());
820 this->EnterContributingSurface(surface
, &occlusion
);
822 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
823 occlusion
.occlusion_from_outside_target().ToString());
824 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
825 occlusion
.occlusion_from_inside_target().ToString());
827 // Occlusion from |top_layer| already in the root target should get merged
828 // with the occlusion from the |surface| we are leaving now.
829 this->LeaveContributingSurface(surface
, &occlusion
);
830 this->EnterLayer(root
, &occlusion
);
832 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
833 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
834 occlusion
.occlusion_from_inside_target().ToString());
838 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
840 template <class Types
>
841 class OcclusionTrackerTestSurfaceRotatedOffAxis
842 : public OcclusionTrackerTest
<Types
> {
844 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
845 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
846 void RunMyTest() override
{
847 gfx::Transform child_transform
;
848 child_transform
.Translate(250.0, 250.0);
849 child_transform
.Rotate(95.0);
850 child_transform
.Translate(-250.0, -250.0);
852 gfx::Transform layer_transform
;
853 layer_transform
.Translate(10.0, 10.0);
855 typename
Types::ContentLayerType
* root
= this->CreateRoot(
856 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
857 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
858 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
859 typename
Types::LayerType
* child
= this->CreateSurface(
860 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
861 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
862 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
863 this->CalcDrawEtc(root
);
865 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
866 gfx::Rect(0, 0, 1000, 1000));
868 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
869 layer_transform
, layer
->visible_content_rect());
871 this->VisitLayer(layer
, &occlusion
);
872 this->EnterContributingSurface(child
, &occlusion
);
874 EXPECT_EQ(gfx::Rect().ToString(),
875 occlusion
.occlusion_from_outside_target().ToString());
876 EXPECT_EQ(clipped_layer_in_child
.ToString(),
877 occlusion
.occlusion_from_inside_target().ToString());
879 this->LeaveContributingSurface(child
, &occlusion
);
880 this->EnterLayer(parent
, &occlusion
);
882 EXPECT_EQ(gfx::Rect().ToString(),
883 occlusion
.occlusion_from_outside_target().ToString());
884 EXPECT_EQ(gfx::Rect().ToString(),
885 occlusion
.occlusion_from_inside_target().ToString());
889 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
891 template <class Types
>
892 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
893 : public OcclusionTrackerTest
<Types
> {
895 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
896 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
897 void RunMyTest() override
{
898 gfx::Transform child_transform
;
899 child_transform
.Translate(250.0, 250.0);
900 child_transform
.Rotate(90.0);
901 child_transform
.Translate(-250.0, -250.0);
903 typename
Types::ContentLayerType
* root
= this->CreateRoot(
904 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
905 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
906 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
907 parent
->SetMasksToBounds(true);
908 typename
Types::ContentLayerType
* child
=
909 this->CreateDrawingSurface(parent
,
911 gfx::PointF(30.f
, 30.f
),
914 child
->SetMasksToBounds(true);
915 typename
Types::ContentLayerType
* layer1
=
916 this->CreateDrawingLayer(child
,
917 this->identity_matrix
,
918 gfx::PointF(10.f
, 10.f
),
921 typename
Types::ContentLayerType
* layer2
=
922 this->CreateDrawingLayer(child
,
923 this->identity_matrix
,
924 gfx::PointF(10.f
, 450.f
),
927 this->CalcDrawEtc(root
);
929 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
930 gfx::Rect(0, 0, 1000, 1000));
932 this->VisitLayer(layer2
, &occlusion
);
933 this->VisitLayer(layer1
, &occlusion
);
934 this->VisitLayer(child
, &occlusion
);
935 this->EnterContributingSurface(child
, &occlusion
);
937 EXPECT_EQ(gfx::Rect().ToString(),
938 occlusion
.occlusion_from_outside_target().ToString());
939 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
940 occlusion
.occlusion_from_inside_target().ToString());
942 this->LeaveContributingSurface(child
, &occlusion
);
943 this->EnterLayer(parent
, &occlusion
);
945 EXPECT_EQ(gfx::Rect().ToString(),
946 occlusion
.occlusion_from_outside_target().ToString());
947 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
948 occlusion
.occlusion_from_inside_target().ToString());
950 /* Justification for the above occlusion from |layer1| and |layer2|:
952 +---------------------+
953 | |30 Visible region of |layer1|: /////
954 | | Visible region of |layer2|: \\\\\
955 | +---------------------------------+
957 | +---------------+-----------------+ |
958 | | |\\\\\\\\\\\\|//| 420 | |
959 | | |\\\\\\\\\\\\|//|60 | |
960 | | |\\\\\\\\\\\\|//| | |
961 +--|--|------------|--+ | |
969 | +------------|-----------------|--+
971 +---------------+-----------------+
977 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
979 template <class Types
>
980 class OcclusionTrackerTestOverlappingSurfaceSiblings
981 : public OcclusionTrackerTest
<Types
> {
983 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
984 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
985 void RunMyTest() override
{
986 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
987 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
988 parent
->SetMasksToBounds(true);
989 typename
Types::LayerType
* child1
= this->CreateSurface(
990 parent
, this->identity_matrix
, gfx::PointF(10.f
, 0.f
), gfx::Size());
991 typename
Types::LayerType
* child2
= this->CreateSurface(
992 parent
, this->identity_matrix
, gfx::PointF(30.f
, 0.f
), gfx::Size());
993 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
994 child1
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 50), true);
995 typename
Types::ContentLayerType
* layer2
=
996 this->CreateDrawingLayer(child2
,
997 this->identity_matrix
,
998 gfx::PointF(10.f
, 0.f
),
1001 this->CalcDrawEtc(parent
);
1003 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1004 gfx::Rect(0, 0, 1000, 1000));
1006 this->VisitLayer(layer2
, &occlusion
);
1007 this->EnterContributingSurface(child2
, &occlusion
);
1009 // layer2's occlusion.
1010 EXPECT_EQ(gfx::Rect().ToString(),
1011 occlusion
.occlusion_from_outside_target().ToString());
1012 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
1013 occlusion
.occlusion_from_inside_target().ToString());
1015 this->LeaveContributingSurface(child2
, &occlusion
);
1016 this->VisitLayer(layer1
, &occlusion
);
1017 this->EnterContributingSurface(child1
, &occlusion
);
1019 // layer2's occlusion in the target space of layer1.
1020 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
1021 occlusion
.occlusion_from_outside_target().ToString());
1022 // layer1's occlusion.
1023 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
1024 occlusion
.occlusion_from_inside_target().ToString());
1026 this->LeaveContributingSurface(child1
, &occlusion
);
1027 this->EnterLayer(parent
, &occlusion
);
1029 // The occlusion from from layer1 and layer2 is merged.
1030 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1031 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
1032 occlusion
.occlusion_from_inside_target().ToString());
1036 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1038 template <class Types
>
1039 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1040 : public OcclusionTrackerTest
<Types
> {
1042 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1044 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1045 void RunMyTest() override
{
1046 gfx::Transform child1_transform
;
1047 child1_transform
.Translate(250.0, 250.0);
1048 child1_transform
.Rotate(-90.0);
1049 child1_transform
.Translate(-250.0, -250.0);
1051 gfx::Transform child2_transform
;
1052 child2_transform
.Translate(250.0, 250.0);
1053 child2_transform
.Rotate(90.0);
1054 child2_transform
.Translate(-250.0, -250.0);
1056 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1057 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1058 parent
->SetMasksToBounds(true);
1059 typename
Types::LayerType
* child1
= this->CreateSurface(
1060 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1061 typename
Types::LayerType
* child2
=
1062 this->CreateDrawingSurface(parent
,
1064 gfx::PointF(20.f
, 40.f
),
1067 typename
Types::ContentLayerType
* layer1
=
1068 this->CreateDrawingLayer(child1
,
1069 this->identity_matrix
,
1070 gfx::PointF(-10.f
, -20.f
),
1071 gfx::Size(510, 510),
1073 typename
Types::ContentLayerType
* layer2
=
1074 this->CreateDrawingLayer(child2
,
1075 this->identity_matrix
,
1076 gfx::PointF(-10.f
, -10.f
),
1077 gfx::Size(510, 510),
1079 this->CalcDrawEtc(parent
);
1081 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1082 gfx::Rect(0, 0, 1000, 1000));
1084 this->VisitLayer(layer2
, &occlusion
);
1085 this->EnterLayer(child2
, &occlusion
);
1087 EXPECT_EQ(gfx::Rect().ToString(),
1088 occlusion
.occlusion_from_outside_target().ToString());
1089 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1090 occlusion
.occlusion_from_inside_target().ToString());
1092 this->LeaveLayer(child2
, &occlusion
);
1093 this->EnterContributingSurface(child2
, &occlusion
);
1095 EXPECT_EQ(gfx::Rect().ToString(),
1096 occlusion
.occlusion_from_outside_target().ToString());
1097 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1098 occlusion
.occlusion_from_inside_target().ToString());
1100 this->LeaveContributingSurface(child2
, &occlusion
);
1101 this->VisitLayer(layer1
, &occlusion
);
1102 this->EnterContributingSurface(child1
, &occlusion
);
1104 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1105 occlusion
.occlusion_from_outside_target().ToString());
1106 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1107 occlusion
.occlusion_from_inside_target().ToString());
1109 this->LeaveContributingSurface(child1
, &occlusion
);
1110 this->EnterLayer(parent
, &occlusion
);
1112 EXPECT_EQ(gfx::Rect().ToString(),
1113 occlusion
.occlusion_from_outside_target().ToString());
1114 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1115 occlusion
.occlusion_from_inside_target().ToString());
1117 /* Justification for the above occlusion:
1119 +---------------------+
1121 10+----------------------------------+
1122 100 || 30 | layer2 |
1123 |20+----------------------------------+
1127 +|-|------------------+ | |
1135 +----------------------------------+ |
1137 +----------------------------------+
1143 ALL_OCCLUSIONTRACKER_TEST(
1144 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1146 template <class Types
>
1147 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1149 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1150 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1151 void RunMyTest() override
{
1152 gfx::Transform layer_transform
;
1153 layer_transform
.Translate(250.0, 250.0);
1154 layer_transform
.Rotate(90.0);
1155 layer_transform
.Translate(-250.0, -250.0);
1157 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1158 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1159 parent
->SetMasksToBounds(true);
1160 typename
Types::ContentLayerType
* blur_layer
=
1161 this->CreateDrawingLayer(parent
,
1163 gfx::PointF(30.f
, 30.f
),
1164 gfx::Size(500, 500),
1166 typename
Types::ContentLayerType
* opaque_layer
=
1167 this->CreateDrawingLayer(parent
,
1169 gfx::PointF(30.f
, 30.f
),
1170 gfx::Size(500, 500),
1172 typename
Types::ContentLayerType
* opacity_layer
=
1173 this->CreateDrawingLayer(parent
,
1175 gfx::PointF(30.f
, 30.f
),
1176 gfx::Size(500, 500),
1179 Types::SetForceRenderSurface(blur_layer
, true);
1180 FilterOperations filters
;
1181 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1182 blur_layer
->SetFilters(filters
);
1184 Types::SetForceRenderSurface(opaque_layer
, true);
1186 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1187 opaque_layer
->SetFilters(filters
);
1189 Types::SetForceRenderSurface(opacity_layer
, true);
1191 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1192 opacity_layer
->SetFilters(filters
);
1194 this->CalcDrawEtc(parent
);
1196 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1197 gfx::Rect(0, 0, 1000, 1000));
1199 // Opacity layer won't contribute to occlusion.
1200 this->VisitLayer(opacity_layer
, &occlusion
);
1201 this->EnterContributingSurface(opacity_layer
, &occlusion
);
1203 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1204 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1206 // And has nothing to contribute to its parent surface.
1207 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1208 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1209 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1211 // Opaque layer will contribute to occlusion.
1212 this->VisitLayer(opaque_layer
, &occlusion
);
1213 this->EnterContributingSurface(opaque_layer
, &occlusion
);
1215 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1216 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1217 occlusion
.occlusion_from_inside_target().ToString());
1219 // And it gets translated to the parent surface.
1220 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1221 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1222 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1223 occlusion
.occlusion_from_inside_target().ToString());
1225 // The blur layer needs to throw away any occlusion from outside its
1227 this->EnterLayer(blur_layer
, &occlusion
);
1228 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1229 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1231 // And it won't contribute to occlusion.
1232 this->LeaveLayer(blur_layer
, &occlusion
);
1233 this->EnterContributingSurface(blur_layer
, &occlusion
);
1234 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1235 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1237 // But the opaque layer's occlusion is preserved on the parent.
1238 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1239 this->EnterLayer(parent
, &occlusion
);
1240 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1241 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1242 occlusion
.occlusion_from_inside_target().ToString());
1246 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1248 template <class Types
>
1249 class OcclusionTrackerTestReplicaDoesOcclude
1250 : public OcclusionTrackerTest
<Types
> {
1252 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1253 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1254 void RunMyTest() override
{
1255 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1256 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1257 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
1258 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
1259 this->CreateReplicaLayer(
1260 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1261 this->CalcDrawEtc(parent
);
1263 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1264 gfx::Rect(0, 0, 1000, 1000));
1266 this->VisitLayer(surface
, &occlusion
);
1268 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1269 occlusion
.occlusion_from_inside_target().ToString());
1271 this->VisitContributingSurface(surface
, &occlusion
);
1272 this->EnterLayer(parent
, &occlusion
);
1274 // The surface and replica should both be occluding the parent.
1275 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1276 occlusion
.occlusion_from_inside_target().ToString());
1280 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1282 template <class Types
>
1283 class OcclusionTrackerTestReplicaWithClipping
1284 : public OcclusionTrackerTest
<Types
> {
1286 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1287 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1288 void RunMyTest() override
{
1289 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1290 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1291 parent
->SetMasksToBounds(true);
1292 typename
Types::LayerType
* surface
=
1293 this->CreateDrawingSurface(parent
,
1294 this->identity_matrix
,
1295 gfx::PointF(0.f
, 100.f
),
1298 this->CreateReplicaLayer(
1299 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1300 this->CalcDrawEtc(parent
);
1302 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1303 gfx::Rect(0, 0, 1000, 1000));
1305 this->VisitLayer(surface
, &occlusion
);
1307 // The surface layer's occlusion in its own space.
1308 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1309 occlusion
.occlusion_from_inside_target().ToString());
1310 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1312 this->VisitContributingSurface(surface
, &occlusion
);
1313 this->EnterLayer(parent
, &occlusion
);
1315 // The surface and replica should both be occluding the parent, the
1316 // replica's occlusion is clipped by the parent.
1317 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1318 occlusion
.occlusion_from_inside_target().ToString());
1319 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1323 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1325 template <class Types
>
1326 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1328 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1329 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1330 void RunMyTest() override
{
1331 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1332 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1333 typename
Types::LayerType
* surface
=
1334 this->CreateDrawingSurface(parent
,
1335 this->identity_matrix
,
1336 gfx::PointF(0.f
, 100.f
),
1339 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1340 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1341 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1342 this->CalcDrawEtc(parent
);
1344 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1345 gfx::Rect(0, 0, 1000, 1000));
1347 this->VisitLayer(surface
, &occlusion
);
1349 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1350 occlusion
.occlusion_from_inside_target().ToString());
1352 this->VisitContributingSurface(surface
, &occlusion
);
1353 this->EnterLayer(parent
, &occlusion
);
1355 // The replica should not be occluding the parent, since it has a mask
1357 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1358 occlusion
.occlusion_from_inside_target().ToString());
1362 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1364 template <class Types
>
1365 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1366 : public OcclusionTrackerTest
<Types
> {
1368 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1369 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1370 void RunMyTest() override
{
1371 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1372 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1373 typename
Types::ContentLayerType
* layer
=
1374 this->CreateDrawingSurface(parent
,
1375 this->identity_matrix
,
1377 gfx::Size(200, 200),
1379 this->CalcDrawEtc(parent
);
1381 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1382 gfx::Rect(0, 0, 1000, 1000));
1383 this->EnterLayer(layer
, &occlusion
);
1385 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1386 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1388 this->LeaveLayer(layer
, &occlusion
);
1389 this->VisitContributingSurface(layer
, &occlusion
);
1390 this->EnterLayer(parent
, &occlusion
);
1392 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1393 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1397 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1399 template <class Types
>
1400 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1401 : public OcclusionTrackerTest
<Types
> {
1403 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1404 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1405 void RunMyTest() override
{
1406 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1407 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1408 typename
Types::ContentLayerType
* layer
=
1409 this->CreateDrawingLayer(parent
,
1410 this->identity_matrix
,
1411 gfx::PointF(100.f
, 100.f
),
1412 gfx::Size(200, 200),
1414 this->CalcDrawEtc(parent
);
1416 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1417 gfx::Rect(0, 0, 1000, 1000));
1418 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1420 this->ResetLayerIterator();
1421 this->VisitLayer(layer
, &occlusion
);
1422 this->EnterLayer(parent
, &occlusion
);
1424 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1425 occlusion
.occlusion_from_inside_target().ToString());
1428 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1429 gfx::Rect(0, 0, 1000, 1000));
1430 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1432 this->ResetLayerIterator();
1433 this->VisitLayer(layer
, &occlusion
);
1434 this->EnterLayer(parent
, &occlusion
);
1436 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1437 occlusion
.occlusion_from_inside_target().ToString());
1440 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1441 gfx::Rect(0, 0, 1000, 1000));
1442 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1444 this->ResetLayerIterator();
1445 this->VisitLayer(layer
, &occlusion
);
1446 this->EnterLayer(parent
, &occlusion
);
1448 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1449 occlusion
.occlusion_from_inside_target().ToString());
1454 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1456 template <class Types
>
1457 class OcclusionTrackerTestUnsorted3dLayers
1458 : public OcclusionTrackerTest
<Types
> {
1460 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
1461 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1462 void RunMyTest() override
{
1463 // Currently, The main thread layer iterator does not iterate over 3d items
1464 // in sorted order, because layer sorting is not performed on the main
1465 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1466 // layer occludes other layers that have not yet been iterated over. For
1467 // now, the expected behavior is that a 3d layer simply does not add any
1468 // occlusion to the occlusion tracker.
1470 gfx::Transform translation_to_front
;
1471 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
1472 gfx::Transform translation_to_back
;
1473 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
1475 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1476 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1477 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
1478 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
1479 typename
Types::ContentLayerType
* child2
=
1480 this->CreateDrawingLayer(parent
,
1481 translation_to_front
,
1482 gfx::PointF(50.f
, 50.f
),
1483 gfx::Size(100, 100),
1485 parent
->SetShouldFlattenTransform(false);
1486 parent
->Set3dSortingContextId(1);
1487 child1
->Set3dSortingContextId(1);
1488 child2
->Set3dSortingContextId(1);
1490 this->CalcDrawEtc(parent
);
1492 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1493 gfx::Rect(0, 0, 1000, 1000));
1494 this->VisitLayer(child2
, &occlusion
);
1495 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1496 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1498 this->VisitLayer(child1
, &occlusion
);
1499 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1500 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1504 // This test will have different layer ordering on the impl thread; the test
1505 // will only work on the main thread.
1506 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1508 template <class Types
>
1509 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1510 : public OcclusionTrackerTest
<Types
> {
1512 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1514 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1515 void RunMyTest() override
{
1516 gfx::Transform transform
;
1517 transform
.Translate(50.0, 50.0);
1518 transform
.ApplyPerspectiveDepth(100.0);
1519 transform
.Translate3d(0.0, 0.0, 110.0);
1520 transform
.Translate(-50.0, -50.0);
1522 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1523 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1524 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1525 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
1526 parent
->SetShouldFlattenTransform(false);
1527 parent
->Set3dSortingContextId(1);
1528 layer
->SetShouldFlattenTransform(false);
1529 layer
->Set3dSortingContextId(1);
1530 this->CalcDrawEtc(parent
);
1532 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1533 gfx::Rect(0, 0, 1000, 1000));
1535 // The |layer| is entirely behind the camera and should not occlude.
1536 this->VisitLayer(layer
, &occlusion
);
1537 this->EnterLayer(parent
, &occlusion
);
1538 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1539 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1543 template <class Types
>
1544 class OcclusionTrackerTestAnimationOpacity1OnMainThread
1545 : public OcclusionTrackerTest
<Types
> {
1547 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
1548 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1549 void RunMyTest() override
{
1553 // | +--surface_child
1554 // | +--surface_child2
1558 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1559 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1560 typename
Types::ContentLayerType
* layer
=
1561 this->CreateDrawingLayer(parent
,
1562 this->identity_matrix
,
1564 gfx::Size(300, 300),
1566 typename
Types::ContentLayerType
* surface
=
1567 this->CreateDrawingSurface(parent
,
1568 this->identity_matrix
,
1570 gfx::Size(300, 300),
1572 typename
Types::ContentLayerType
* surface_child
=
1573 this->CreateDrawingLayer(surface
,
1574 this->identity_matrix
,
1576 gfx::Size(200, 300),
1578 typename
Types::ContentLayerType
* surface_child2
=
1579 this->CreateDrawingLayer(surface
,
1580 this->identity_matrix
,
1582 gfx::Size(100, 300),
1584 typename
Types::ContentLayerType
* parent2
=
1585 this->CreateDrawingLayer(parent
,
1586 this->identity_matrix
,
1588 gfx::Size(300, 300),
1590 typename
Types::ContentLayerType
* topmost
=
1591 this->CreateDrawingLayer(parent
,
1592 this->identity_matrix
,
1593 gfx::PointF(250.f
, 0.f
),
1597 AddOpacityTransitionToController(
1598 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
1599 AddOpacityTransitionToController(
1600 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
1601 this->CalcDrawEtc(parent
);
1603 EXPECT_TRUE(layer
->draw_opacity_is_animating());
1604 EXPECT_FALSE(surface
->draw_opacity_is_animating());
1605 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
1607 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1608 gfx::Rect(0, 0, 1000, 1000));
1610 this->VisitLayer(topmost
, &occlusion
);
1611 this->EnterLayer(parent2
, &occlusion
);
1613 // This occlusion will affect all surfaces.
1614 EXPECT_EQ(gfx::Rect().ToString(),
1615 occlusion
.occlusion_from_outside_target().ToString());
1616 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1617 occlusion
.occlusion_from_inside_target().ToString());
1619 this->LeaveLayer(parent2
, &occlusion
);
1620 this->VisitLayer(surface_child2
, &occlusion
);
1621 this->EnterLayer(surface_child
, &occlusion
);
1622 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1623 occlusion
.occlusion_from_outside_target().ToString());
1624 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1625 occlusion
.occlusion_from_inside_target().ToString());
1627 this->LeaveLayer(surface_child
, &occlusion
);
1628 this->EnterLayer(surface
, &occlusion
);
1629 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1630 occlusion
.occlusion_from_outside_target().ToString());
1631 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1632 occlusion
.occlusion_from_inside_target().ToString());
1634 this->LeaveLayer(surface
, &occlusion
);
1635 this->EnterContributingSurface(surface
, &occlusion
);
1636 // Occlusion within the surface is lost when leaving the animating surface.
1637 EXPECT_EQ(gfx::Rect().ToString(),
1638 occlusion
.occlusion_from_outside_target().ToString());
1639 EXPECT_EQ(gfx::Rect().ToString(),
1640 occlusion
.occlusion_from_inside_target().ToString());
1642 this->LeaveContributingSurface(surface
, &occlusion
);
1643 // Occlusion from outside the animating surface still exists.
1644 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1645 occlusion
.occlusion_from_inside_target().ToString());
1646 EXPECT_EQ(gfx::Rect().ToString(),
1647 occlusion
.occlusion_from_outside_target().ToString());
1649 this->VisitLayer(layer
, &occlusion
);
1650 this->EnterLayer(parent
, &occlusion
);
1652 // Occlusion is not added for the animating |layer|.
1653 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1654 occlusion
.occlusion_from_inside_target().ToString());
1655 EXPECT_EQ(gfx::Rect().ToString(),
1656 occlusion
.occlusion_from_outside_target().ToString());
1660 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
1662 template <class Types
>
1663 class OcclusionTrackerTestAnimationOpacity0OnMainThread
1664 : public OcclusionTrackerTest
<Types
> {
1666 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
1667 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1668 void RunMyTest() override
{
1669 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1670 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1671 typename
Types::ContentLayerType
* layer
=
1672 this->CreateDrawingLayer(parent
,
1673 this->identity_matrix
,
1675 gfx::Size(300, 300),
1677 typename
Types::ContentLayerType
* surface
=
1678 this->CreateDrawingSurface(parent
,
1679 this->identity_matrix
,
1681 gfx::Size(300, 300),
1683 typename
Types::ContentLayerType
* surface_child
=
1684 this->CreateDrawingLayer(surface
,
1685 this->identity_matrix
,
1687 gfx::Size(200, 300),
1689 typename
Types::ContentLayerType
* surface_child2
=
1690 this->CreateDrawingLayer(surface
,
1691 this->identity_matrix
,
1693 gfx::Size(100, 300),
1695 typename
Types::ContentLayerType
* parent2
=
1696 this->CreateDrawingLayer(parent
,
1697 this->identity_matrix
,
1699 gfx::Size(300, 300),
1701 typename
Types::ContentLayerType
* topmost
=
1702 this->CreateDrawingLayer(parent
,
1703 this->identity_matrix
,
1704 gfx::PointF(250.f
, 0.f
),
1708 AddOpacityTransitionToController(
1709 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
1710 AddOpacityTransitionToController(
1711 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
1712 this->CalcDrawEtc(parent
);
1714 EXPECT_TRUE(layer
->draw_opacity_is_animating());
1715 EXPECT_FALSE(surface
->draw_opacity_is_animating());
1716 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
1718 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1719 gfx::Rect(0, 0, 1000, 1000));
1721 this->VisitLayer(topmost
, &occlusion
);
1722 this->EnterLayer(parent2
, &occlusion
);
1723 // This occlusion will affect all surfaces.
1724 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1725 occlusion
.occlusion_from_inside_target().ToString());
1726 EXPECT_EQ(gfx::Rect().ToString(),
1727 occlusion
.occlusion_from_outside_target().ToString());
1729 this->LeaveLayer(parent2
, &occlusion
);
1730 this->VisitLayer(surface_child2
, &occlusion
);
1731 this->EnterLayer(surface_child
, &occlusion
);
1732 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1733 occlusion
.occlusion_from_inside_target().ToString());
1734 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1735 occlusion
.occlusion_from_outside_target().ToString());
1737 this->LeaveLayer(surface_child
, &occlusion
);
1738 this->EnterLayer(surface
, &occlusion
);
1739 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1740 occlusion
.occlusion_from_inside_target().ToString());
1741 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1742 occlusion
.occlusion_from_outside_target().ToString());
1744 this->LeaveLayer(surface
, &occlusion
);
1745 this->EnterContributingSurface(surface
, &occlusion
);
1746 // Occlusion within the surface is lost when leaving the animating surface.
1747 EXPECT_EQ(gfx::Rect().ToString(),
1748 occlusion
.occlusion_from_inside_target().ToString());
1749 EXPECT_EQ(gfx::Rect().ToString(),
1750 occlusion
.occlusion_from_outside_target().ToString());
1752 this->LeaveContributingSurface(surface
, &occlusion
);
1753 // Occlusion from outside the animating surface still exists.
1754 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1755 occlusion
.occlusion_from_inside_target().ToString());
1756 EXPECT_EQ(gfx::Rect().ToString(),
1757 occlusion
.occlusion_from_outside_target().ToString());
1759 this->VisitLayer(layer
, &occlusion
);
1760 this->EnterLayer(parent
, &occlusion
);
1762 // Occlusion is not added for the animating |layer|.
1763 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1764 occlusion
.occlusion_from_inside_target().ToString());
1765 EXPECT_EQ(gfx::Rect().ToString(),
1766 occlusion
.occlusion_from_outside_target().ToString());
1770 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
1772 template <class Types
>
1773 class OcclusionTrackerTestAnimationTranslateOnMainThread
1774 : public OcclusionTrackerTest
<Types
> {
1776 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
1778 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1779 void RunMyTest() override
{
1780 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1781 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1782 typename
Types::ContentLayerType
* layer
=
1783 this->CreateDrawingLayer(parent
,
1784 this->identity_matrix
,
1786 gfx::Size(300, 300),
1788 typename
Types::ContentLayerType
* surface
=
1789 this->CreateDrawingSurface(parent
,
1790 this->identity_matrix
,
1792 gfx::Size(300, 300),
1794 typename
Types::ContentLayerType
* surface_child
=
1795 this->CreateDrawingLayer(surface
,
1796 this->identity_matrix
,
1798 gfx::Size(200, 300),
1800 typename
Types::ContentLayerType
* surface_child2
=
1801 this->CreateDrawingLayer(surface
,
1802 this->identity_matrix
,
1804 gfx::Size(100, 300),
1806 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
1807 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
1809 AddAnimatedTransformToController(
1810 layer
->layer_animation_controller(), 10.0, 30, 0);
1811 AddAnimatedTransformToController(
1812 surface
->layer_animation_controller(), 10.0, 30, 0);
1813 AddAnimatedTransformToController(
1814 surface_child
->layer_animation_controller(), 10.0, 30, 0);
1815 this->CalcDrawEtc(parent
);
1817 EXPECT_TRUE(layer
->draw_transform_is_animating());
1818 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
1820 surface
->render_surface()->target_surface_transforms_are_animating());
1822 surface
->render_surface()->screen_space_transforms_are_animating());
1823 // The surface owning layer doesn't animate against its own surface.
1824 EXPECT_FALSE(surface
->draw_transform_is_animating());
1825 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
1826 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
1827 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
1829 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1830 gfx::Rect(0, 0, 1000, 1000));
1832 this->VisitLayer(surface2
, &occlusion
);
1833 this->EnterContributingSurface(surface2
, &occlusion
);
1835 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1836 occlusion
.occlusion_from_inside_target().ToString());
1838 this->LeaveContributingSurface(surface2
, &occlusion
);
1839 this->EnterLayer(surface_child2
, &occlusion
);
1840 // surface_child2 is moving in screen space but not relative to its target,
1841 // so occlusion should happen in its target space only. It also means that
1842 // things occluding from outside the target (e.g. surface2) cannot occlude
1844 EXPECT_EQ(gfx::Rect().ToString(),
1845 occlusion
.occlusion_from_outside_target().ToString());
1846 EXPECT_EQ(gfx::Rect().ToString(),
1847 occlusion
.occlusion_from_inside_target().ToString());
1849 this->LeaveLayer(surface_child2
, &occlusion
);
1850 this->EnterLayer(surface_child
, &occlusion
);
1851 // surface_child2 added to the occlusion since it is not moving relative
1853 EXPECT_EQ(gfx::Rect().ToString(),
1854 occlusion
.occlusion_from_outside_target().ToString());
1855 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1856 occlusion
.occlusion_from_inside_target().ToString());
1858 this->LeaveLayer(surface_child
, &occlusion
);
1859 // surface_child is moving relative to its target, so it does not add
1861 EXPECT_EQ(gfx::Rect().ToString(),
1862 occlusion
.occlusion_from_outside_target().ToString());
1863 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1864 occlusion
.occlusion_from_inside_target().ToString());
1866 this->EnterLayer(surface
, &occlusion
);
1867 EXPECT_EQ(gfx::Rect().ToString(),
1868 occlusion
.occlusion_from_outside_target().ToString());
1869 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1870 occlusion
.occlusion_from_inside_target().ToString());
1872 this->LeaveLayer(surface
, &occlusion
);
1873 // The surface's owning layer is moving in screen space but not relative to
1874 // its target, so it adds to the occlusion.
1875 EXPECT_EQ(gfx::Rect().ToString(),
1876 occlusion
.occlusion_from_outside_target().ToString());
1877 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
1878 occlusion
.occlusion_from_inside_target().ToString());
1880 this->EnterContributingSurface(surface
, &occlusion
);
1881 this->LeaveContributingSurface(surface
, &occlusion
);
1882 // The |surface| is moving in the screen and in its target, so all occlusion
1883 // within the surface is lost when leaving it. Only the |surface2| occlusion
1885 EXPECT_EQ(gfx::Rect().ToString(),
1886 occlusion
.occlusion_from_outside_target().ToString());
1887 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1888 occlusion
.occlusion_from_inside_target().ToString());
1890 this->VisitLayer(layer
, &occlusion
);
1891 // The |layer| is animating in the screen and in its target, so no occlusion
1893 EXPECT_EQ(gfx::Rect().ToString(),
1894 occlusion
.occlusion_from_outside_target().ToString());
1895 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1896 occlusion
.occlusion_from_inside_target().ToString());
1900 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
1902 template <class Types
>
1903 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1904 : public OcclusionTrackerTest
<Types
> {
1906 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1908 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1909 void RunMyTest() override
{
1910 gfx::Transform surface_transform
;
1911 surface_transform
.Translate(300.0, 300.0);
1912 surface_transform
.Scale(2.0, 2.0);
1913 surface_transform
.Translate(-150.0, -150.0);
1915 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1916 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
1917 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
1918 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
1919 typename
Types::ContentLayerType
* surface2
=
1920 this->CreateDrawingSurface(parent
,
1921 this->identity_matrix
,
1922 gfx::PointF(50.f
, 50.f
),
1923 gfx::Size(300, 300),
1925 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1926 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1927 this->CalcDrawEtc(parent
);
1929 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1930 gfx::Rect(0, 0, 1000, 1000));
1932 this->VisitLayer(surface2
, &occlusion
);
1933 this->VisitContributingSurface(surface2
, &occlusion
);
1935 EXPECT_EQ(gfx::Rect().ToString(),
1936 occlusion
.occlusion_from_outside_target().ToString());
1937 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1938 occlusion
.occlusion_from_inside_target().ToString());
1940 // Clear any stored occlusion.
1941 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1942 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1944 this->VisitLayer(surface
, &occlusion
);
1945 this->VisitContributingSurface(surface
, &occlusion
);
1947 EXPECT_EQ(gfx::Rect().ToString(),
1948 occlusion
.occlusion_from_outside_target().ToString());
1949 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1950 occlusion
.occlusion_from_inside_target().ToString());
1954 MAIN_AND_IMPL_THREAD_TEST(
1955 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
1957 template <class Types
>
1958 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1959 : public OcclusionTrackerTest
<Types
> {
1961 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
1963 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1964 void RunMyTest() override
{
1965 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1966 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1967 parent
->SetMasksToBounds(true);
1968 typename
Types::ContentLayerType
* surface
=
1969 this->CreateDrawingSurface(parent
,
1970 this->identity_matrix
,
1972 gfx::Size(500, 300),
1974 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
1975 this->CalcDrawEtc(parent
);
1977 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1978 gfx::Rect(0, 0, 1000, 1000));
1980 this->VisitLayer(surface
, &occlusion
);
1981 this->VisitContributingSurface(surface
, &occlusion
);
1983 EXPECT_EQ(gfx::Rect().ToString(),
1984 occlusion
.occlusion_from_outside_target().ToString());
1985 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
1986 occlusion
.occlusion_from_inside_target().ToString());
1990 MAIN_AND_IMPL_THREAD_TEST(
1991 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
1993 template <class Types
>
1994 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
1995 : public OcclusionTrackerTest
<Types
> {
1997 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
1998 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1999 void RunMyTest() override
{
2000 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2001 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2002 typename
Types::LayerType
* surface
=
2003 this->CreateDrawingSurface(parent
,
2004 this->identity_matrix
,
2006 gfx::Size(100, 100),
2008 this->CreateReplicaLayer(surface
,
2009 this->identity_matrix
,
2010 gfx::PointF(0.f
, 100.f
),
2011 gfx::Size(100, 100));
2012 typename
Types::LayerType
* topmost
=
2013 this->CreateDrawingLayer(parent
,
2014 this->identity_matrix
,
2016 gfx::Size(100, 110),
2018 this->CalcDrawEtc(parent
);
2020 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2021 gfx::Rect(0, 0, 1000, 1000));
2023 // |topmost| occludes the surface, but not the entire surface's replica.
2024 this->VisitLayer(topmost
, &occlusion
);
2026 EXPECT_EQ(gfx::Rect().ToString(),
2027 occlusion
.occlusion_from_outside_target().ToString());
2028 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2029 occlusion
.occlusion_from_inside_target().ToString());
2031 this->VisitLayer(surface
, &occlusion
);
2033 // Render target with replica ignores occlusion from outside.
2034 EXPECT_EQ(gfx::Rect().ToString(),
2035 occlusion
.occlusion_from_outside_target().ToString());
2036 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2037 occlusion
.occlusion_from_inside_target().ToString());
2039 this->EnterContributingSurface(surface
, &occlusion
);
2041 // Only occlusion from outside the surface occludes the surface/replica.
2042 EXPECT_EQ(gfx::Rect().ToString(),
2043 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2045 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2046 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2051 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2053 template <class Types
>
2054 class OcclusionTrackerTestSurfaceChildOfSurface
2055 : public OcclusionTrackerTest
<Types
> {
2057 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
2058 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2059 void RunMyTest() override
{
2060 // This test verifies that the surface cliprect does not end up empty and
2061 // clip away the entire unoccluded rect.
2063 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2064 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2065 typename
Types::LayerType
* surface
=
2066 this->CreateDrawingSurface(parent
,
2067 this->identity_matrix
,
2069 gfx::Size(100, 100),
2071 typename
Types::LayerType
* surface_child
=
2072 this->CreateDrawingSurface(surface
,
2073 this->identity_matrix
,
2074 gfx::PointF(0.f
, 10.f
),
2077 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
2078 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
2079 this->CalcDrawEtc(parent
);
2081 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2082 gfx::Rect(-100, -100, 1000, 1000));
2084 // |topmost| occludes everything partially so we know occlusion is happening
2086 this->VisitLayer(topmost
, &occlusion
);
2088 EXPECT_EQ(gfx::Rect().ToString(),
2089 occlusion
.occlusion_from_outside_target().ToString());
2090 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2091 occlusion
.occlusion_from_inside_target().ToString());
2093 this->VisitLayer(surface_child
, &occlusion
);
2095 // surface_child increases the occlusion in the screen by a narrow sliver.
2096 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2097 occlusion
.occlusion_from_outside_target().ToString());
2098 // In its own surface, surface_child is at 0,0 as is its occlusion.
2099 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2100 occlusion
.occlusion_from_inside_target().ToString());
2102 // The root layer always has a clip rect. So the parent of |surface| has a
2103 // clip rect. However, the owning layer for |surface| does not mask to
2104 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2105 // |surface_child| exercises different code paths as its parent does not
2106 // have a clip rect.
2108 this->EnterContributingSurface(surface_child
, &occlusion
);
2109 // The |surface_child| can't occlude its own surface, but occlusion from
2111 EXPECT_EQ(gfx::Rect().ToString(),
2112 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2114 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2115 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2117 this->LeaveContributingSurface(surface_child
, &occlusion
);
2119 // When the surface_child's occlusion is transformed up to its parent, make
2120 // sure it is not clipped away inappropriately.
2121 this->EnterLayer(surface
, &occlusion
);
2122 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2123 occlusion
.occlusion_from_outside_target().ToString());
2124 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2125 occlusion
.occlusion_from_inside_target().ToString());
2126 this->LeaveLayer(surface
, &occlusion
);
2128 this->EnterContributingSurface(surface
, &occlusion
);
2129 // The occlusion from inside |surface| can't affect the surface, but
2131 EXPECT_EQ(gfx::Rect().ToString(),
2132 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2134 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2135 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2138 this->LeaveContributingSurface(surface
, &occlusion
);
2139 this->EnterLayer(parent
, &occlusion
);
2140 // The occlusion in |surface| and without are merged into the parent.
2141 EXPECT_EQ(gfx::Rect().ToString(),
2142 occlusion
.occlusion_from_outside_target().ToString());
2143 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
2144 occlusion
.occlusion_from_inside_target().ToString());
2148 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2150 template <class Types
>
2151 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2152 : public OcclusionTrackerTest
<Types
> {
2154 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2156 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2157 void RunMyTest() override
{
2158 gfx::Transform scale_by_half
;
2159 scale_by_half
.Scale(0.5, 0.5);
2161 FilterOperations filters
;
2162 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
2164 // Save the distance of influence for the blur effect.
2165 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2167 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2174 LAST_DIRECTION
= BOTTOM
,
2177 for (int i
= 0; i
<= LAST_DIRECTION
; ++i
) {
2180 // Make a 50x50 filtered surface that is adjacent to occluding layers
2181 // which are above it in the z-order in various configurations. The
2182 // surface is scaled to test that the pixel moving is done in the target
2183 // space, where the background filter is applied.
2184 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2185 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
2186 typename
Types::LayerType
* filtered_surface
=
2187 this->CreateDrawingLayer(parent
,
2189 gfx::PointF(50.f
, 50.f
),
2190 gfx::Size(100, 100),
2192 Types::SetForceRenderSurface(filtered_surface
, true);
2193 filtered_surface
->SetBackgroundFilters(filters
);
2194 gfx::Rect occlusion_rect
;
2197 occlusion_rect
= gfx::Rect(0, 0, 50, 200);
2200 occlusion_rect
= gfx::Rect(100, 0, 50, 200);
2203 occlusion_rect
= gfx::Rect(0, 0, 200, 50);
2206 occlusion_rect
= gfx::Rect(0, 100, 200, 50);
2210 typename
Types::LayerType
* occluding_layer
=
2211 this->CreateDrawingLayer(parent
,
2212 this->identity_matrix
,
2213 occlusion_rect
.origin(),
2214 occlusion_rect
.size(),
2216 this->CalcDrawEtc(parent
);
2218 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2219 gfx::Rect(0, 0, 200, 200));
2221 // This layer occludes pixels directly beside the filtered_surface.
2222 // Because filtered surface blends pixels in a radius, it will need to see
2223 // some of the pixels (up to radius far) underneath the occluding layers.
2224 this->VisitLayer(occluding_layer
, &occlusion
);
2226 EXPECT_EQ(occlusion_rect
.ToString(),
2227 occlusion
.occlusion_from_inside_target().ToString());
2228 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2230 this->VisitLayer(filtered_surface
, &occlusion
);
2232 // The occlusion is used fully inside the surface.
2233 gfx::Rect occlusion_inside_surface
=
2234 occlusion_rect
- gfx::Vector2d(50, 50);
2235 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2236 EXPECT_EQ(occlusion_inside_surface
.ToString(),
2237 occlusion
.occlusion_from_outside_target().ToString());
2239 // The surface has a background blur, so it needs pixels that are
2240 // currently considered occluded in order to be drawn. So the pixels it
2241 // needs should be removed some the occluded area so that when we get to
2242 // the parent they are drawn.
2243 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2244 this->EnterLayer(parent
, &occlusion
);
2246 gfx::Rect expected_occlusion
= occlusion_rect
;
2249 expected_occlusion
.Inset(0, 0, outset_right
, 0);
2252 expected_occlusion
.Inset(outset_right
, 0, 0, 0);
2255 expected_occlusion
.Inset(0, 0, 0, outset_right
);
2258 expected_occlusion
.Inset(0, outset_right
, 0, 0);
2262 EXPECT_EQ(expected_occlusion
.ToString(),
2263 occlusion
.occlusion_from_inside_target().ToString());
2264 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2266 this->DestroyLayers();
2271 ALL_OCCLUSIONTRACKER_TEST(
2272 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
2274 template <class Types
>
2275 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
2276 : public OcclusionTrackerTest
<Types
> {
2278 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
2280 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2281 void RunMyTest() override
{
2282 gfx::Transform scale_by_half
;
2283 scale_by_half
.Scale(0.5, 0.5);
2285 // Makes two surfaces that completely cover |parent|. The occlusion both
2286 // above and below the filters will be reduced by each of them.
2287 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2288 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
2289 typename
Types::LayerType
* parent
= this->CreateSurface(
2290 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
2291 parent
->SetMasksToBounds(true);
2292 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
2293 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
2294 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
2295 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
2296 typename
Types::LayerType
* occluding_layer_above
=
2297 this->CreateDrawingLayer(parent
,
2298 this->identity_matrix
,
2299 gfx::PointF(100.f
, 100.f
),
2303 // Filters make the layers own surfaces.
2304 Types::SetForceRenderSurface(filtered_surface1
, true);
2305 Types::SetForceRenderSurface(filtered_surface2
, true);
2306 FilterOperations filters
;
2307 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
2308 filtered_surface1
->SetBackgroundFilters(filters
);
2309 filtered_surface2
->SetBackgroundFilters(filters
);
2311 // Save the distance of influence for the blur effect.
2312 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2314 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2316 this->CalcDrawEtc(root
);
2318 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2319 gfx::Rect(0, 0, 1000, 1000));
2321 this->VisitLayer(occluding_layer_above
, &occlusion
);
2322 EXPECT_EQ(gfx::Rect().ToString(),
2323 occlusion
.occlusion_from_outside_target().ToString());
2324 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
2325 occlusion
.occlusion_from_inside_target().ToString());
2327 this->VisitLayer(filtered_surface2
, &occlusion
);
2328 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
2329 this->VisitLayer(filtered_surface1
, &occlusion
);
2330 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
2332 // Test expectations in the target.
2333 gfx::Rect expected_occlusion
=
2334 gfx::Rect(100 / 2 + outset_right
* 2,
2335 100 / 2 + outset_bottom
* 2,
2336 50 / 2 - (outset_left
+ outset_right
) * 2,
2337 50 / 2 - (outset_top
+ outset_bottom
) * 2);
2338 EXPECT_EQ(expected_occlusion
.ToString(),
2339 occlusion
.occlusion_from_inside_target().ToString());
2341 // Test expectations in the screen are the same as in the target, as the
2342 // render surface is 1:1 with the screen.
2343 EXPECT_EQ(expected_occlusion
.ToString(),
2344 occlusion
.occlusion_from_outside_target().ToString());
2348 ALL_OCCLUSIONTRACKER_TEST(
2349 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
2351 template <class Types
>
2352 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
2353 : public OcclusionTrackerTest
<Types
> {
2355 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
2357 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2358 void RunMyTest() override
{
2359 gfx::Transform scale_by_half
;
2360 scale_by_half
.Scale(0.5, 0.5);
2362 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
2363 // centered below each. The surface is scaled to test that the pixel moving
2364 // is done in the target space, where the background filter is applied, but
2365 // the surface appears at 50, 50 and the replica at 200, 50.
2366 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2367 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
2368 typename
Types::LayerType
* behind_surface_layer
=
2369 this->CreateDrawingLayer(parent
,
2370 this->identity_matrix
,
2371 gfx::PointF(60.f
, 60.f
),
2374 typename
Types::LayerType
* behind_replica_layer
=
2375 this->CreateDrawingLayer(parent
,
2376 this->identity_matrix
,
2377 gfx::PointF(210.f
, 60.f
),
2380 typename
Types::LayerType
* filtered_surface
=
2381 this->CreateDrawingLayer(parent
,
2383 gfx::PointF(50.f
, 50.f
),
2384 gfx::Size(100, 100),
2386 this->CreateReplicaLayer(filtered_surface
,
2387 this->identity_matrix
,
2388 gfx::PointF(300.f
, 0.f
),
2391 // Filters make the layer own a surface.
2392 Types::SetForceRenderSurface(filtered_surface
, true);
2393 FilterOperations filters
;
2394 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2395 filtered_surface
->SetBackgroundFilters(filters
);
2397 this->CalcDrawEtc(parent
);
2399 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2400 gfx::Rect(0, 0, 1000, 1000));
2402 // The surface has a background blur, so it blurs non-opaque pixels below
2404 this->VisitLayer(filtered_surface
, &occlusion
);
2405 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2407 this->VisitLayer(behind_replica_layer
, &occlusion
);
2409 // The layers behind the surface are not blurred, and their occlusion does
2410 // not change, until we leave the surface. So it should not be modified by
2412 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
2413 EXPECT_EQ(occlusion_behind_replica
.ToString(),
2414 occlusion
.occlusion_from_inside_target().ToString());
2415 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2417 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
2418 // without existing occlusion interfering.
2419 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2421 this->VisitLayer(behind_surface_layer
, &occlusion
);
2423 // The layers behind the surface are not blurred, and their occlusion does
2424 // not change, until we leave the surface. So it should not be modified by
2426 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
2427 EXPECT_EQ(occlusion_behind_surface
.ToString(),
2428 occlusion
.occlusion_from_inside_target().ToString());
2429 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2433 ALL_OCCLUSIONTRACKER_TEST(
2434 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
2436 template <class Types
>
2437 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
2438 : public OcclusionTrackerTest
<Types
> {
2440 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
2442 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2443 void RunMyTest() override
{
2444 gfx::Transform scale_by_half
;
2445 scale_by_half
.Scale(0.5, 0.5);
2447 // Make a 50x50 filtered surface that is completely occluded by an opaque
2448 // layer which is above it in the z-order. The surface is
2449 // scaled to test that the pixel moving is done in the target space, where
2450 // the background filter is applied, but the surface appears at 50, 50.
2451 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2452 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
2453 typename
Types::LayerType
* filtered_surface
=
2454 this->CreateDrawingLayer(parent
,
2456 gfx::PointF(50.f
, 50.f
),
2457 gfx::Size(100, 100),
2459 typename
Types::LayerType
* occluding_layer
=
2460 this->CreateDrawingLayer(parent
,
2461 this->identity_matrix
,
2462 gfx::PointF(50.f
, 50.f
),
2466 // Filters make the layer own a surface.
2467 Types::SetForceRenderSurface(filtered_surface
, true);
2468 FilterOperations filters
;
2469 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2470 filtered_surface
->SetBackgroundFilters(filters
);
2472 this->CalcDrawEtc(parent
);
2474 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2475 gfx::Rect(0, 0, 1000, 1000));
2477 this->VisitLayer(occluding_layer
, &occlusion
);
2479 this->VisitLayer(filtered_surface
, &occlusion
);
2481 // The layers above the filtered surface occlude from outside.
2482 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
2484 EXPECT_EQ(gfx::Rect().ToString(),
2485 occlusion
.occlusion_from_inside_target().ToString());
2486 EXPECT_EQ(occlusion_above_surface
.ToString(),
2487 occlusion
.occlusion_from_outside_target().ToString());
2490 // The surface has a background blur, so it blurs non-opaque pixels below
2492 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2494 // The filter is completely occluded, so it should not blur anything and
2495 // reduce any occlusion.
2496 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
2498 EXPECT_EQ(occlusion_above_surface
.ToString(),
2499 occlusion
.occlusion_from_inside_target().ToString());
2500 EXPECT_EQ(gfx::Rect().ToString(),
2501 occlusion
.occlusion_from_outside_target().ToString());
2506 ALL_OCCLUSIONTRACKER_TEST(
2507 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
2509 template <class Types
>
2510 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
2511 : public OcclusionTrackerTest
<Types
> {
2514 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
2516 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2517 void RunMyTest() override
{
2518 gfx::Transform scale_by_half
;
2519 scale_by_half
.Scale(0.5, 0.5);
2521 // Make a surface and its replica, each 50x50, that are partially occluded
2522 // by opaque layers which are above them in the z-order. The surface is
2523 // scaled to test that the pixel moving is done in the target space, where
2524 // the background filter is applied, but the surface appears at 50, 50 and
2525 // the replica at 200, 50.
2526 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2527 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
2528 typename
Types::LayerType
* filtered_surface
=
2529 this->CreateDrawingLayer(parent
,
2531 gfx::PointF(50.f
, 50.f
),
2532 gfx::Size(100, 100),
2534 this->CreateReplicaLayer(filtered_surface
,
2535 this->identity_matrix
,
2536 gfx::PointF(300.f
, 0.f
),
2538 typename
Types::LayerType
* above_surface_layer
=
2539 this->CreateDrawingLayer(parent
,
2540 this->identity_matrix
,
2541 gfx::PointF(70.f
, 50.f
),
2544 typename
Types::LayerType
* above_replica_layer
=
2545 this->CreateDrawingLayer(parent
,
2546 this->identity_matrix
,
2547 gfx::PointF(200.f
, 50.f
),
2550 typename
Types::LayerType
* beside_surface_layer
=
2551 this->CreateDrawingLayer(parent
,
2552 this->identity_matrix
,
2553 gfx::PointF(90.f
, 40.f
),
2556 typename
Types::LayerType
* beside_replica_layer
=
2557 this->CreateDrawingLayer(parent
,
2558 this->identity_matrix
,
2559 gfx::PointF(200.f
, 40.f
),
2563 // Filters make the layer own a surface.
2564 Types::SetForceRenderSurface(filtered_surface
, true);
2565 FilterOperations filters
;
2566 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2567 filtered_surface
->SetBackgroundFilters(filters
);
2569 // Save the distance of influence for the blur effect.
2570 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2572 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2574 this->CalcDrawEtc(parent
);
2576 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2577 gfx::Rect(0, 0, 1000, 1000));
2579 this->VisitLayer(beside_replica_layer
, &occlusion
);
2580 this->VisitLayer(beside_surface_layer
, &occlusion
);
2581 this->VisitLayer(above_replica_layer
, &occlusion
);
2582 this->VisitLayer(above_surface_layer
, &occlusion
);
2584 // The surface has a background blur, so it blurs non-opaque pixels below
2586 this->VisitLayer(filtered_surface
, &occlusion
);
2587 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2589 // The filter in the surface and replica are partially unoccluded. Only the
2590 // unoccluded parts should reduce occlusion. This means it will push back
2591 // the occlusion that touches the unoccluded part (occlusion_above___), but
2592 // it will not touch occlusion_beside____ since that is not beside the
2593 // unoccluded part of the surface, even though it is beside the occluded
2594 // part of the surface.
2595 gfx::Rect occlusion_above_surface
=
2596 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
2597 gfx::Rect occlusion_above_replica
=
2598 gfx::Rect(200, 50, 30 - outset_left
, 50);
2599 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
2600 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
2602 SimpleEnclosedRegion expected_occlusion
;
2603 expected_occlusion
.Union(occlusion_beside_replica
);
2604 expected_occlusion
.Union(occlusion_beside_surface
);
2605 expected_occlusion
.Union(occlusion_above_replica
);
2606 expected_occlusion
.Union(occlusion_above_surface
);
2608 EXPECT_EQ(expected_occlusion
.ToString(),
2609 occlusion
.occlusion_from_inside_target().ToString());
2610 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2612 const SimpleEnclosedRegion
& actual_occlusion
=
2613 occlusion
.occlusion_from_inside_target();
2614 for (size_t i
= 0; i
< expected_occlusion
.GetRegionComplexity(); ++i
) {
2615 ASSERT_LT(i
, actual_occlusion
.GetRegionComplexity());
2616 EXPECT_EQ(expected_occlusion
.GetRect(i
), actual_occlusion
.GetRect(i
));
2621 ALL_OCCLUSIONTRACKER_TEST(
2622 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
2624 template <class Types
>
2625 class OcclusionTrackerTestBlendModeDoesNotOcclude
2626 : public OcclusionTrackerTest
<Types
> {
2628 explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers
)
2629 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2630 void RunMyTest() override
{
2631 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2632 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2633 typename
Types::LayerType
* blend_mode_layer
= this->CreateDrawingLayer(
2634 parent
, this->identity_matrix
, gfx::PointF(0.f
, 0.f
),
2635 gfx::Size(100, 100), true);
2636 typename
Types::LayerType
* top_layer
= this->CreateDrawingLayer(
2637 parent
, this->identity_matrix
, gfx::PointF(10.f
, 12.f
),
2638 gfx::Size(20, 22), true);
2640 // Blend mode makes the layer own a surface.
2641 Types::SetForceRenderSurface(blend_mode_layer
, true);
2642 blend_mode_layer
->SetBlendMode(SkXfermode::kMultiply_Mode
);
2644 this->CalcDrawEtc(parent
);
2646 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2647 gfx::Rect(0, 0, 1000, 1000));
2649 this->VisitLayer(top_layer
, &occlusion
);
2650 // |top_layer| occludes.
2651 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2652 occlusion
.occlusion_from_inside_target().ToString());
2653 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2655 this->VisitLayer(blend_mode_layer
, &occlusion
);
2656 // |top_layer| occludes but not |blend_mode_layer|.
2657 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2658 occlusion
.occlusion_from_outside_target().ToString());
2659 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2661 this->VisitContributingSurface(blend_mode_layer
, &occlusion
);
2662 // |top_layer| occludes but not |blend_mode_layer|.
2663 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2664 occlusion
.occlusion_from_inside_target().ToString());
2665 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2669 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude
);
2671 template <class Types
>
2672 class OcclusionTrackerTestMinimumTrackingSize
2673 : public OcclusionTrackerTest
<Types
> {
2675 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
2676 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2677 void RunMyTest() override
{
2678 gfx::Size
tracking_size(100, 100);
2679 gfx::Size
below_tracking_size(99, 99);
2681 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2682 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2683 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
2684 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
2685 typename
Types::LayerType
* small
=
2686 this->CreateDrawingLayer(parent
,
2687 this->identity_matrix
,
2689 below_tracking_size
,
2691 this->CalcDrawEtc(parent
);
2693 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2694 gfx::Rect(0, 0, 1000, 1000));
2695 occlusion
.set_minimum_tracking_size(tracking_size
);
2697 // The small layer is not tracked because it is too small.
2698 this->VisitLayer(small
, &occlusion
);
2700 EXPECT_EQ(gfx::Rect().ToString(),
2701 occlusion
.occlusion_from_outside_target().ToString());
2702 EXPECT_EQ(gfx::Rect().ToString(),
2703 occlusion
.occlusion_from_inside_target().ToString());
2705 // The large layer is tracked as it is large enough.
2706 this->VisitLayer(large
, &occlusion
);
2708 EXPECT_EQ(gfx::Rect().ToString(),
2709 occlusion
.occlusion_from_outside_target().ToString());
2710 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
2711 occlusion
.occlusion_from_inside_target().ToString());
2715 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
2717 template <class Types
>
2718 class OcclusionTrackerTestScaledLayerIsClipped
2719 : public OcclusionTrackerTest
<Types
> {
2721 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
2722 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2723 void RunMyTest() override
{
2724 gfx::Transform scale_transform
;
2725 scale_transform
.Scale(512.0, 512.0);
2727 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2728 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2729 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
2730 this->identity_matrix
,
2731 gfx::PointF(10.f
, 10.f
),
2733 clip
->SetMasksToBounds(true);
2734 typename
Types::LayerType
* scale
= this->CreateLayer(
2735 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
2736 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
2737 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
2738 this->CalcDrawEtc(parent
);
2740 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2741 gfx::Rect(0, 0, 1000, 1000));
2743 this->VisitLayer(scaled
, &occlusion
);
2745 EXPECT_EQ(gfx::Rect().ToString(),
2746 occlusion
.occlusion_from_outside_target().ToString());
2747 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2748 occlusion
.occlusion_from_inside_target().ToString());
2752 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
2754 template <class Types
>
2755 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
2756 : public OcclusionTrackerTest
<Types
> {
2758 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
2759 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2760 void RunMyTest() override
{
2761 gfx::Transform scale_transform
;
2762 scale_transform
.Scale(512.0, 512.0);
2764 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2765 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2766 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
2767 this->identity_matrix
,
2768 gfx::PointF(10.f
, 10.f
),
2770 clip
->SetMasksToBounds(true);
2771 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
2772 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
2773 typename
Types::LayerType
* scale
= this->CreateLayer(
2774 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
2775 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
2776 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
2777 this->CalcDrawEtc(parent
);
2779 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2780 gfx::Rect(0, 0, 1000, 1000));
2782 this->VisitLayer(scaled
, &occlusion
);
2783 this->VisitLayer(surface
, &occlusion
);
2784 this->VisitContributingSurface(surface
, &occlusion
);
2786 EXPECT_EQ(gfx::Rect().ToString(),
2787 occlusion
.occlusion_from_outside_target().ToString());
2788 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2789 occlusion
.occlusion_from_inside_target().ToString());
2793 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
2795 template <class Types
>
2796 class OcclusionTrackerTestCopyRequestDoesOcclude
2797 : public OcclusionTrackerTest
<Types
> {
2799 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
2800 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2801 void RunMyTest() override
{
2802 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2803 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2804 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
2805 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2806 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
2807 this->identity_matrix
,
2809 gfx::Size(200, 400));
2810 this->AddCopyRequest(copy
);
2811 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
2813 this->identity_matrix
,
2815 gfx::Size(200, 400),
2817 typename
Types::LayerType
* top_layer
=
2818 this->CreateDrawingLayer(root
, this->identity_matrix
,
2819 gfx::PointF(50, 0), gfx::Size(50, 400), true);
2820 this->CalcDrawEtc(root
);
2822 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2823 gfx::Rect(0, 0, 1000, 1000));
2825 this->VisitLayer(top_layer
, &occlusion
);
2826 EXPECT_EQ(gfx::Rect().ToString(),
2827 occlusion
.occlusion_from_outside_target().ToString());
2828 EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(),
2829 occlusion
.occlusion_from_inside_target().ToString());
2831 this->VisitLayer(copy_child
, &occlusion
);
2832 // Layers outside the copy request do not occlude.
2833 EXPECT_EQ(gfx::Rect().ToString(),
2834 occlusion
.occlusion_from_outside_target().ToString());
2835 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2836 occlusion
.occlusion_from_inside_target().ToString());
2838 // CopyRequests cause the layer to own a surface.
2839 this->VisitContributingSurface(copy
, &occlusion
);
2841 // The occlusion from the copy should be kept.
2842 EXPECT_EQ(gfx::Rect().ToString(),
2843 occlusion
.occlusion_from_outside_target().ToString());
2844 EXPECT_EQ(gfx::Rect(50, 0, 250, 400).ToString(),
2845 occlusion
.occlusion_from_inside_target().ToString());
2849 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
2851 template <class Types
>
2852 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2853 : public OcclusionTrackerTest
<Types
> {
2855 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2857 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2858 void RunMyTest() override
{
2859 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2860 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2861 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
2862 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2863 typename
Types::LayerType
* hide
= this->CreateLayer(
2864 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
2865 typename
Types::LayerType
* copy
= this->CreateLayer(
2866 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
2867 this->AddCopyRequest(copy
);
2868 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
2869 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
2871 // The |copy| layer is hidden but since it is being copied, it will be
2873 hide
->SetHideLayerAndSubtree(true);
2875 this->CalcDrawEtc(root
);
2877 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2878 gfx::Rect(0, 0, 1000, 1000));
2880 this->VisitLayer(copy_child
, &occlusion
);
2881 EXPECT_EQ(gfx::Rect().ToString(),
2882 occlusion
.occlusion_from_outside_target().ToString());
2883 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2884 occlusion
.occlusion_from_inside_target().ToString());
2886 // CopyRequests cause the layer to own a surface.
2887 this->VisitContributingSurface(copy
, &occlusion
);
2889 // The occlusion from the copy should be dropped since it is hidden.
2890 EXPECT_EQ(gfx::Rect().ToString(),
2891 occlusion
.occlusion_from_outside_target().ToString());
2892 EXPECT_EQ(gfx::Rect().ToString(),
2893 occlusion
.occlusion_from_inside_target().ToString());
2897 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
2899 template <class Types
>
2900 class OcclusionTrackerTestOccludedLayer
: public OcclusionTrackerTest
<Types
> {
2902 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers
)
2903 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2904 void RunMyTest() override
{
2905 gfx::Transform translate
;
2906 translate
.Translate(10.0, 20.0);
2907 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2908 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2909 typename
Types::LayerType
* surface
= this->CreateSurface(
2910 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2911 typename
Types::LayerType
* layer
= this->CreateDrawingLayer(
2912 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2913 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
2914 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2915 this->CalcDrawEtc(root
);
2917 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2918 gfx::Rect(0, 0, 200, 200));
2919 this->VisitLayer(outside_layer
, &occlusion
);
2920 this->EnterLayer(layer
, &occlusion
);
2922 // No occlusion, is not occluded.
2923 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2924 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2925 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100)));
2927 // Partial occlusion from outside, is not occluded.
2928 occlusion
.set_occlusion_from_outside_target(
2929 SimpleEnclosedRegion(50, 50, 100, 100));
2930 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2931 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2932 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2933 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2934 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2935 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2936 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2937 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2938 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2940 // Full occlusion from outside, is occluded.
2941 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2942 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2943 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2944 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2946 // Partial occlusion from inside, is not occluded.
2947 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2948 occlusion
.set_occlusion_from_inside_target(
2949 SimpleEnclosedRegion(50, 50, 100, 100));
2950 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2951 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2952 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2953 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2954 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2955 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2956 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2957 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2959 // Full occlusion from inside, is occluded.
2960 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2961 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2962 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2963 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2965 // Partial occlusion from both, is not occluded.
2966 occlusion
.set_occlusion_from_outside_target(
2967 SimpleEnclosedRegion(50, 50, 100, 50));
2968 occlusion
.set_occlusion_from_inside_target(
2969 SimpleEnclosedRegion(50, 100, 100, 50));
2970 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2971 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2972 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2973 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2974 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2975 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2976 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2977 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2979 // Full occlusion from both, is occluded.
2980 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2981 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2982 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2983 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2987 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer
)
2989 template <class Types
>
2990 class OcclusionTrackerTestUnoccludedLayerQuery
2991 : public OcclusionTrackerTest
<Types
> {
2993 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers
)
2994 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2995 void RunMyTest() override
{
2996 gfx::Transform translate
;
2997 translate
.Translate(10.0, 20.0);
2998 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2999 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
3000 typename
Types::LayerType
* surface
= this->CreateSurface(
3001 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
3002 typename
Types::LayerType
* layer
= this->CreateDrawingLayer(
3003 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
3004 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
3005 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
3006 this->CalcDrawEtc(root
);
3008 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3009 gfx::Rect(0, 0, 200, 200));
3010 this->VisitLayer(outside_layer
, &occlusion
);
3011 this->EnterLayer(layer
, &occlusion
);
3013 // No occlusion, is not occluded.
3014 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3015 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3016 EXPECT_EQ(gfx::Rect(100, 100),
3017 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(100, 100)));
3019 // Partial occlusion from outside.
3020 occlusion
.set_occlusion_from_outside_target(
3021 SimpleEnclosedRegion(50, 50, 100, 100));
3022 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3024 gfx::Rect(0, 0, 100, 100),
3025 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3026 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3027 occlusion
.UnoccludedLayerContentRect(
3028 layer
, gfx::Rect(90, 30, 100, 100)));
3029 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3030 occlusion
.UnoccludedLayerContentRect(layer
,
3031 gfx::Rect(40, 0, 100, 100)));
3032 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3033 occlusion
.UnoccludedLayerContentRect(
3034 layer
, gfx::Rect(40, 80, 100, 100)));
3036 gfx::Rect(0, 0, 80, 100),
3037 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3038 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3039 occlusion
.UnoccludedLayerContentRect(
3040 layer
, gfx::Rect(90, 80, 100, 100)));
3041 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3042 occlusion
.UnoccludedLayerContentRect(layer
,
3043 gfx::Rect(0, 80, 100, 100)));
3044 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3045 occlusion
.UnoccludedLayerContentRect(layer
,
3046 gfx::Rect(90, 0, 100, 100)));
3048 // Full occlusion from outside, is occluded.
3049 EXPECT_EQ(gfx::Rect(),
3050 occlusion
.UnoccludedLayerContentRect(
3051 layer
, gfx::Rect(40, 30, 100, 100)));
3054 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3055 EXPECT_EQ(gfx::Rect(),
3056 occlusion
.UnoccludedLayerContentRect(
3057 layer
, gfx::Rect(130, 120, 10, 10)));
3060 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3062 // Partial occlusion from inside, is not occluded.
3063 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3064 occlusion
.set_occlusion_from_inside_target(
3065 SimpleEnclosedRegion(50, 50, 100, 100));
3067 gfx::Rect(0, 0, 100, 100),
3068 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3069 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3070 occlusion
.UnoccludedLayerContentRect(
3071 layer
, gfx::Rect(90, 30, 100, 100)));
3072 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3073 occlusion
.UnoccludedLayerContentRect(layer
,
3074 gfx::Rect(40, 0, 100, 100)));
3075 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3076 occlusion
.UnoccludedLayerContentRect(
3077 layer
, gfx::Rect(40, 80, 100, 100)));
3079 gfx::Rect(0, 0, 80, 100),
3080 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3081 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3082 occlusion
.UnoccludedLayerContentRect(
3083 layer
, gfx::Rect(90, 80, 100, 100)));
3084 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3085 occlusion
.UnoccludedLayerContentRect(layer
,
3086 gfx::Rect(0, 80, 100, 100)));
3087 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3088 occlusion
.UnoccludedLayerContentRect(layer
,
3089 gfx::Rect(90, 0, 100, 100)));
3091 // Full occlusion from inside, is occluded.
3092 EXPECT_EQ(gfx::Rect(),
3093 occlusion
.UnoccludedLayerContentRect(
3094 layer
, gfx::Rect(40, 30, 100, 100)));
3097 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3098 EXPECT_EQ(gfx::Rect(),
3099 occlusion
.UnoccludedLayerContentRect(
3100 layer
, gfx::Rect(130, 120, 10, 10)));
3103 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3105 // Partial occlusion from both, is not occluded.
3106 occlusion
.set_occlusion_from_outside_target(
3107 SimpleEnclosedRegion(50, 50, 100, 50));
3108 occlusion
.set_occlusion_from_inside_target(
3109 SimpleEnclosedRegion(50, 100, 100, 50));
3111 gfx::Rect(0, 0, 100, 100),
3112 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3113 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3115 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3116 occlusion
.UnoccludedLayerContentRect(
3117 layer
, gfx::Rect(90, 30, 100, 100)));
3118 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3119 occlusion
.UnoccludedLayerContentRect(layer
,
3120 gfx::Rect(40, 0, 100, 100)));
3121 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3122 occlusion
.UnoccludedLayerContentRect(
3123 layer
, gfx::Rect(40, 80, 100, 100)));
3125 gfx::Rect(0, 0, 80, 100),
3126 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3127 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3128 occlusion
.UnoccludedLayerContentRect(
3129 layer
, gfx::Rect(90, 80, 100, 100)));
3130 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3131 occlusion
.UnoccludedLayerContentRect(layer
,
3132 gfx::Rect(0, 80, 100, 100)));
3133 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3134 occlusion
.UnoccludedLayerContentRect(layer
,
3135 gfx::Rect(90, 0, 100, 100)));
3137 // Full occlusion from both, is occluded.
3138 EXPECT_EQ(gfx::Rect(),
3139 occlusion
.UnoccludedLayerContentRect(
3140 layer
, gfx::Rect(40, 30, 100, 100)));
3143 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3144 EXPECT_EQ(gfx::Rect(),
3145 occlusion
.UnoccludedLayerContentRect(
3146 layer
, gfx::Rect(130, 120, 10, 10)));
3149 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3153 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery
)
3155 template <class Types
>
3156 class OcclusionTrackerTestUnoccludedSurfaceQuery
3157 : public OcclusionTrackerTest
<Types
> {
3159 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers
)
3160 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3161 void RunMyTest() override
{
3162 gfx::Transform translate
;
3163 translate
.Translate(10.0, 20.0);
3164 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3165 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
3166 typename
Types::LayerType
* surface
=
3167 this->CreateSurface(root
, translate
, gfx::Point(), gfx::Size(200, 200));
3168 typename
Types::LayerType
* layer
=
3169 this->CreateDrawingLayer(surface
,
3170 this->identity_matrix
,
3172 gfx::Size(200, 200),
3174 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
3175 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
3176 this->CalcDrawEtc(root
);
3178 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3179 gfx::Rect(0, 0, 200, 200));
3180 this->VisitLayer(outside_layer
, &occlusion
);
3181 this->VisitLayer(layer
, &occlusion
);
3182 this->EnterContributingSurface(surface
, &occlusion
);
3184 // No occlusion, is not occluded.
3185 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3186 SimpleEnclosedRegion());
3187 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3188 SimpleEnclosedRegion());
3190 gfx::Rect(100, 100),
3191 occlusion
.UnoccludedSurfaceContentRect(surface
, gfx::Rect(100, 100)));
3193 // Partial occlusion from outside.
3194 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3195 SimpleEnclosedRegion(50, 50, 100, 100));
3196 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3197 SimpleEnclosedRegion());
3198 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3199 occlusion
.UnoccludedSurfaceContentRect(
3200 surface
, gfx::Rect(0, 0, 100, 100)));
3201 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3202 occlusion
.UnoccludedSurfaceContentRect(
3203 surface
, gfx::Rect(90, 30, 100, 100)));
3204 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3205 occlusion
.UnoccludedSurfaceContentRect(
3206 surface
, gfx::Rect(40, 0, 100, 100)));
3207 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3208 occlusion
.UnoccludedSurfaceContentRect(
3209 surface
, gfx::Rect(40, 80, 100, 100)));
3210 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3211 occlusion
.UnoccludedSurfaceContentRect(surface
,
3212 gfx::Rect(0, 0, 80, 100)));
3213 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3214 occlusion
.UnoccludedSurfaceContentRect(
3215 surface
, gfx::Rect(90, 80, 100, 100)));
3216 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3217 occlusion
.UnoccludedSurfaceContentRect(
3218 surface
, gfx::Rect(0, 80, 100, 100)));
3219 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3220 occlusion
.UnoccludedSurfaceContentRect(
3221 surface
, gfx::Rect(90, 0, 100, 100)));
3223 // Full occlusion from outside, is occluded.
3224 EXPECT_EQ(gfx::Rect(),
3225 occlusion
.UnoccludedSurfaceContentRect(
3226 surface
, gfx::Rect(40, 30, 100, 100)));
3227 EXPECT_EQ(gfx::Rect(),
3228 occlusion
.UnoccludedSurfaceContentRect(
3229 surface
, gfx::Rect(40, 30, 10, 10)));
3230 EXPECT_EQ(gfx::Rect(),
3231 occlusion
.UnoccludedSurfaceContentRect(
3232 surface
, gfx::Rect(130, 120, 10, 10)));
3233 EXPECT_EQ(gfx::Rect(),
3234 occlusion
.UnoccludedSurfaceContentRect(
3235 surface
, gfx::Rect(80, 70, 50, 50)));
3237 // Partial occlusion from inside, is not occluded.
3238 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3239 SimpleEnclosedRegion());
3240 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3241 SimpleEnclosedRegion(50, 50, 100, 100));
3242 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3243 occlusion
.UnoccludedSurfaceContentRect(
3244 surface
, gfx::Rect(0, 0, 100, 100)));
3245 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3246 occlusion
.UnoccludedSurfaceContentRect(
3247 surface
, gfx::Rect(90, 30, 100, 100)));
3248 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3249 occlusion
.UnoccludedSurfaceContentRect(
3250 surface
, gfx::Rect(40, 0, 100, 100)));
3251 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3252 occlusion
.UnoccludedSurfaceContentRect(
3253 surface
, gfx::Rect(40, 80, 100, 100)));
3254 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3255 occlusion
.UnoccludedSurfaceContentRect(surface
,
3256 gfx::Rect(0, 0, 80, 100)));
3257 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3258 occlusion
.UnoccludedSurfaceContentRect(
3259 surface
, gfx::Rect(90, 80, 100, 100)));
3260 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3261 occlusion
.UnoccludedSurfaceContentRect(
3262 surface
, gfx::Rect(0, 80, 100, 100)));
3263 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3264 occlusion
.UnoccludedSurfaceContentRect(
3265 surface
, gfx::Rect(90, 0, 100, 100)));
3267 // Full occlusion from inside, is occluded.
3268 EXPECT_EQ(gfx::Rect(),
3269 occlusion
.UnoccludedSurfaceContentRect(
3270 surface
, gfx::Rect(40, 30, 100, 100)));
3271 EXPECT_EQ(gfx::Rect(),
3272 occlusion
.UnoccludedSurfaceContentRect(
3273 surface
, gfx::Rect(40, 30, 10, 10)));
3274 EXPECT_EQ(gfx::Rect(),
3275 occlusion
.UnoccludedSurfaceContentRect(
3276 surface
, gfx::Rect(130, 120, 10, 10)));
3277 EXPECT_EQ(gfx::Rect(),
3278 occlusion
.UnoccludedSurfaceContentRect(
3279 surface
, gfx::Rect(80, 70, 50, 50)));
3281 // Partial occlusion from both, is not occluded.
3282 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3283 SimpleEnclosedRegion(50, 50, 100, 50));
3284 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3285 SimpleEnclosedRegion(50, 100, 100, 50));
3286 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3287 occlusion
.UnoccludedSurfaceContentRect(
3288 surface
, gfx::Rect(0, 0, 100, 100)));
3289 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3291 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3292 occlusion
.UnoccludedSurfaceContentRect(
3293 surface
, gfx::Rect(90, 30, 100, 100)));
3294 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3295 occlusion
.UnoccludedSurfaceContentRect(
3296 surface
, gfx::Rect(40, 0, 100, 100)));
3297 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3298 occlusion
.UnoccludedSurfaceContentRect(
3299 surface
, gfx::Rect(40, 80, 100, 100)));
3300 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3301 occlusion
.UnoccludedSurfaceContentRect(surface
,
3302 gfx::Rect(0, 0, 80, 100)));
3303 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3304 occlusion
.UnoccludedSurfaceContentRect(
3305 surface
, gfx::Rect(90, 80, 100, 100)));
3306 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3307 occlusion
.UnoccludedSurfaceContentRect(
3308 surface
, gfx::Rect(0, 80, 100, 100)));
3309 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3310 occlusion
.UnoccludedSurfaceContentRect(
3311 surface
, gfx::Rect(90, 0, 100, 100)));
3313 // Full occlusion from both, is occluded.
3314 EXPECT_EQ(gfx::Rect(),
3315 occlusion
.UnoccludedSurfaceContentRect(
3316 surface
, gfx::Rect(40, 30, 100, 100)));
3317 EXPECT_EQ(gfx::Rect(),
3318 occlusion
.UnoccludedSurfaceContentRect(
3319 surface
, gfx::Rect(40, 30, 10, 10)));
3320 EXPECT_EQ(gfx::Rect(),
3321 occlusion
.UnoccludedSurfaceContentRect(
3322 surface
, gfx::Rect(130, 120, 10, 10)));
3323 EXPECT_EQ(gfx::Rect(),
3324 occlusion
.UnoccludedSurfaceContentRect(
3325 surface
, gfx::Rect(80, 70, 50, 50)));
3329 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery
)