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 explicit TestContentLayer(const LayerSettings
& settings
)
33 : Layer(settings
), override_opaque_contents_rect_(false) {
37 SimpleEnclosedRegion
VisibleContentOpaqueRegion() const override
{
38 if (override_opaque_contents_rect_
) {
39 return SimpleEnclosedRegion(
40 gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect()));
42 return Layer::VisibleContentOpaqueRegion();
44 void SetOpaqueContentsRect(const gfx::Rect
& opaque_contents_rect
) {
45 override_opaque_contents_rect_
= true;
46 opaque_contents_rect_
= opaque_contents_rect
;
50 ~TestContentLayer() override
{}
52 bool override_opaque_contents_rect_
;
53 gfx::Rect opaque_contents_rect_
;
56 class TestContentLayerImpl
: public LayerImpl
{
58 TestContentLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
59 : LayerImpl(tree_impl
, id
), override_opaque_contents_rect_(false) {
60 SetDrawsContent(true);
63 SimpleEnclosedRegion
VisibleContentOpaqueRegion() const override
{
64 if (override_opaque_contents_rect_
) {
65 return SimpleEnclosedRegion(
66 gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect()));
68 return LayerImpl::VisibleContentOpaqueRegion();
70 void SetOpaqueContentsRect(const gfx::Rect
& opaque_contents_rect
) {
71 override_opaque_contents_rect_
= true;
72 opaque_contents_rect_
= opaque_contents_rect
;
76 bool override_opaque_contents_rect_
;
77 gfx::Rect opaque_contents_rect_
;
80 template <typename LayerType
>
81 class TestOcclusionTrackerWithClip
: public TestOcclusionTracker
<LayerType
> {
83 explicit TestOcclusionTrackerWithClip(const gfx::Rect
& viewport_rect
)
84 : TestOcclusionTracker
<LayerType
>(viewport_rect
) {}
86 bool OccludedLayer(const LayerType
* layer
,
87 const gfx::Rect
& content_rect
) const {
88 DCHECK(layer
->visible_content_rect().Contains(content_rect
));
89 return this->GetCurrentOcclusionForLayer(layer
->draw_transform())
90 .IsOccluded(content_rect
);
93 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
94 // layer. Simple wrapper around GetUnoccludedContentRect.
95 gfx::Rect
UnoccludedLayerContentRect(const LayerType
* layer
,
96 const gfx::Rect
& content_rect
) const {
97 DCHECK(layer
->visible_content_rect().Contains(content_rect
));
98 return this->GetCurrentOcclusionForLayer(layer
->draw_transform())
99 .GetUnoccludedContentRect(content_rect
);
102 gfx::Rect
UnoccludedSurfaceContentRect(const LayerType
* layer
,
103 const gfx::Rect
& content_rect
) const {
104 typename
LayerType::RenderSurfaceType
* surface
= layer
->render_surface();
105 return this->GetCurrentOcclusionForContributingSurface(
106 surface
->draw_transform())
107 .GetUnoccludedContentRect(content_rect
);
111 struct OcclusionTrackerTestMainThreadTypes
{
112 typedef Layer LayerType
;
113 typedef FakeLayerTreeHost HostType
;
114 typedef RenderSurface RenderSurfaceType
;
115 typedef TestContentLayer ContentLayerType
;
116 typedef scoped_refptr
<Layer
> LayerPtrType
;
117 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
118 typedef LayerIterator
<Layer
> TestLayerIterator
;
119 typedef OcclusionTracker
<Layer
> OcclusionTrackerType
;
121 static LayerPtrType
CreateLayer(HostType
* host
) {
122 return Layer::Create(LayerSettings());
124 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
125 return make_scoped_refptr(new ContentLayerType(LayerSettings()));
128 template <typename T
>
129 static LayerPtrType
PassLayerPtr(T
* layer
) {
130 LayerPtrType
ref(*layer
);
134 static void SetForceRenderSurface(LayerType
* layer
, bool force
) {
135 layer
->SetForceRenderSurface(force
);
138 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
140 static void RecursiveUpdateNumChildren(LayerType
* layerType
) {}
143 struct OcclusionTrackerTestImplThreadTypes
{
144 typedef LayerImpl LayerType
;
145 typedef LayerTreeImpl HostType
;
146 typedef RenderSurfaceImpl RenderSurfaceType
;
147 typedef TestContentLayerImpl ContentLayerType
;
148 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
149 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
150 typedef LayerIterator
<LayerImpl
> TestLayerIterator
;
151 typedef OcclusionTracker
<LayerImpl
> OcclusionTrackerType
;
153 static LayerPtrType
CreateLayer(HostType
* host
) {
154 return LayerImpl::Create(host
, next_layer_impl_id
++);
156 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
157 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
159 static int next_layer_impl_id
;
161 template <typename T
>
162 static LayerPtrType
PassLayerPtr(T
* layer
) {
163 return layer
->Pass();
166 static void SetForceRenderSurface(LayerType
* layer
, bool force
) {
167 layer
->SetHasRenderSurface(force
);
169 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
171 static void RecursiveUpdateNumChildren(LayerType
* layer
) {
172 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer
);
176 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
178 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
180 explicit OcclusionTrackerTest(bool opaque_layers
)
181 : opaque_layers_(opaque_layers
),
182 client_(FakeLayerTreeHostClient::DIRECT_3D
),
183 host_(FakeLayerTreeHost::Create(&client_
)) {}
185 virtual void RunMyTest() = 0;
187 void TearDown() override
{ DestroyLayers(); }
189 typename
Types::HostType
* GetHost();
191 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
192 const gfx::PointF
& position
,
193 const gfx::Size
& bounds
) {
194 typename
Types::ContentLayerPtrType
layer(
195 Types::CreateContentLayer(GetHost()));
196 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
197 SetProperties(layer_ptr
, transform
, position
, bounds
);
199 DCHECK(!root_
.get());
200 root_
= Types::PassLayerPtr(&layer
);
202 Types::SetForceRenderSurface(layer_ptr
, true);
203 SetRootLayerOnMainThread(layer_ptr
);
208 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
209 const gfx::Transform
& transform
,
210 const gfx::PointF
& position
,
211 const gfx::Size
& bounds
) {
212 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
213 typename
Types::LayerType
* layer_ptr
= layer
.get();
214 SetProperties(layer_ptr
, transform
, position
, bounds
);
215 parent
->AddChild(Types::PassLayerPtr(&layer
));
219 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
220 const gfx::Transform
& transform
,
221 const gfx::PointF
& position
,
222 const gfx::Size
& bounds
) {
223 typename
Types::LayerType
* layer
=
224 CreateLayer(parent
, transform
, position
, bounds
);
225 Types::SetForceRenderSurface(layer
, true);
229 typename
Types::ContentLayerType
* CreateDrawingLayer(
230 typename
Types::LayerType
* parent
,
231 const gfx::Transform
& transform
,
232 const gfx::PointF
& position
,
233 const gfx::Size
& bounds
,
235 typename
Types::ContentLayerPtrType
layer(
236 Types::CreateContentLayer(GetHost()));
237 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
238 SetProperties(layer_ptr
, transform
, position
, bounds
);
240 if (opaque_layers_
) {
241 layer_ptr
->SetContentsOpaque(opaque
);
243 layer_ptr
->SetContentsOpaque(false);
245 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
247 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
250 parent
->AddChild(Types::PassLayerPtr(&layer
));
254 typename
Types::LayerType
* CreateReplicaLayer(
255 typename
Types::LayerType
* owning_layer
,
256 const gfx::Transform
& transform
,
257 const gfx::PointF
& position
,
258 const gfx::Size
& bounds
) {
259 typename
Types::ContentLayerPtrType
layer(
260 Types::CreateContentLayer(GetHost()));
261 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
262 SetProperties(layer_ptr
, transform
, position
, bounds
);
263 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
267 typename
Types::LayerType
* CreateMaskLayer(
268 typename
Types::LayerType
* owning_layer
,
269 const gfx::Size
& bounds
) {
270 typename
Types::ContentLayerPtrType
layer(
271 Types::CreateContentLayer(GetHost()));
272 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
273 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
274 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
278 typename
Types::ContentLayerType
* CreateDrawingSurface(
279 typename
Types::LayerType
* parent
,
280 const gfx::Transform
& transform
,
281 const gfx::PointF
& position
,
282 const gfx::Size
& bounds
,
284 typename
Types::ContentLayerType
* layer
=
285 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
286 Types::SetForceRenderSurface(layer
, true);
290 void DestroyLayers() {
291 Types::DestroyLayer(&root_
);
292 render_surface_layer_list_
= nullptr;
293 render_surface_layer_list_impl_
.clear();
294 replica_layers_
.clear();
295 mask_layers_
.clear();
296 ResetLayerIterator();
299 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
301 void AddCopyRequest(Layer
* layer
) {
302 layer
->RequestCopyOfOutput(
303 CopyOutputRequest::CreateBitmapRequest(base::Bind(
304 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
305 base::Unretained(this))));
308 void AddCopyRequest(LayerImpl
* layer
) {
309 ScopedPtrVector
<CopyOutputRequest
> requests
;
311 CopyOutputRequest::CreateBitmapRequest(base::Bind(
312 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
313 base::Unretained(this))));
314 layer
->SetHasRenderSurface(true);
315 layer
->PassCopyRequests(&requests
);
318 void CalcDrawEtc(TestContentLayerImpl
* root
) {
319 DCHECK(root
== root_
.get());
321 Types::RecursiveUpdateNumChildren(root
);
322 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
323 root
, root
->bounds(), &render_surface_layer_list_impl_
);
324 inputs
.can_adjust_raster_scales
= true;
325 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
327 layer_iterator_
= layer_iterator_begin_
=
328 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
331 void CalcDrawEtc(TestContentLayer
* root
) {
332 DCHECK(root
== root_
.get());
333 DCHECK(!root
->render_surface());
335 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
336 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
337 root
, root
->bounds(), render_surface_layer_list_
.get());
338 inputs
.can_adjust_raster_scales
= true;
339 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
341 layer_iterator_
= layer_iterator_begin_
=
342 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
345 void EnterLayer(typename
Types::LayerType
* layer
,
346 typename
Types::OcclusionTrackerType
* occlusion
) {
347 ASSERT_EQ(*layer_iterator_
, layer
);
348 ASSERT_TRUE(layer_iterator_
.represents_itself());
349 occlusion
->EnterLayer(layer_iterator_
);
352 void LeaveLayer(typename
Types::LayerType
* layer
,
353 typename
Types::OcclusionTrackerType
* occlusion
) {
354 ASSERT_EQ(*layer_iterator_
, layer
);
355 ASSERT_TRUE(layer_iterator_
.represents_itself());
356 occlusion
->LeaveLayer(layer_iterator_
);
360 void VisitLayer(typename
Types::LayerType
* layer
,
361 typename
Types::OcclusionTrackerType
* occlusion
) {
362 EnterLayer(layer
, occlusion
);
363 LeaveLayer(layer
, occlusion
);
366 void EnterContributingSurface(
367 typename
Types::LayerType
* layer
,
368 typename
Types::OcclusionTrackerType
* occlusion
) {
369 ASSERT_EQ(*layer_iterator_
, layer
);
370 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
371 occlusion
->EnterLayer(layer_iterator_
);
372 occlusion
->LeaveLayer(layer_iterator_
);
374 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
375 occlusion
->EnterLayer(layer_iterator_
);
378 void LeaveContributingSurface(
379 typename
Types::LayerType
* layer
,
380 typename
Types::OcclusionTrackerType
* occlusion
) {
381 ASSERT_EQ(*layer_iterator_
, layer
);
382 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
383 occlusion
->LeaveLayer(layer_iterator_
);
387 void VisitContributingSurface(
388 typename
Types::LayerType
* layer
,
389 typename
Types::OcclusionTrackerType
* occlusion
) {
390 EnterContributingSurface(layer
, occlusion
);
391 LeaveContributingSurface(layer
, occlusion
);
394 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
396 const gfx::Transform identity_matrix
;
399 void SetRootLayerOnMainThread(Layer
* root
) {
400 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
403 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
405 void SetBaseProperties(typename
Types::LayerType
* layer
,
406 const gfx::Transform
& transform
,
407 const gfx::PointF
& position
,
408 const gfx::Size
& bounds
) {
409 layer
->SetTransform(transform
);
410 layer
->SetPosition(position
);
411 layer
->SetBounds(bounds
);
414 void SetProperties(Layer
* layer
,
415 const gfx::Transform
& transform
,
416 const gfx::PointF
& position
,
417 const gfx::Size
& bounds
) {
418 SetBaseProperties(layer
, transform
, position
, bounds
);
421 void SetProperties(LayerImpl
* layer
,
422 const gfx::Transform
& transform
,
423 const gfx::PointF
& position
,
424 const gfx::Size
& bounds
) {
425 SetBaseProperties(layer
, transform
, position
, bounds
);
427 layer
->SetContentBounds(layer
->bounds());
430 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
431 owning_layer
->SetReplicaLayer(layer
.get());
432 replica_layers_
.push_back(layer
);
435 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
436 owning_layer
->SetReplicaLayer(layer
.Pass());
439 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
440 owning_layer
->SetMaskLayer(layer
.get());
441 mask_layers_
.push_back(layer
);
444 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
445 owning_layer
->SetMaskLayer(layer
.Pass());
449 FakeLayerTreeHostClient client_
;
450 scoped_ptr
<FakeLayerTreeHost
> host_
;
451 // These hold ownership of the layers for the duration of the test.
452 typename
Types::LayerPtrType root_
;
453 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
454 LayerImplList render_surface_layer_list_impl_
;
455 typename
Types::TestLayerIterator layer_iterator_begin_
;
456 typename
Types::TestLayerIterator layer_iterator_
;
457 typename
Types::LayerType
* last_layer_visited_
;
458 LayerList replica_layers_
;
459 LayerList mask_layers_
;
464 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
470 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
471 return host_
->host_impl()->active_tree();
474 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
475 class ClassName##MainThreadOpaqueLayers \
476 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
477 public: /* NOLINT(whitespace/indent) */ \
478 ClassName##MainThreadOpaqueLayers() \
479 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
481 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
482 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
483 class ClassName##MainThreadOpaquePaints \
484 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
485 public: /* NOLINT(whitespace/indent) */ \
486 ClassName##MainThreadOpaquePaints() \
487 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
489 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
491 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
492 class ClassName##ImplThreadOpaqueLayers \
493 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
494 public: /* NOLINT(whitespace/indent) */ \
495 ClassName##ImplThreadOpaqueLayers() \
496 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
498 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
499 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
500 class ClassName##ImplThreadOpaquePaints \
501 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
502 public: /* NOLINT(whitespace/indent) */ \
503 ClassName##ImplThreadOpaquePaints() \
504 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
506 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
508 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
509 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
510 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
511 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
512 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
514 #define MAIN_THREAD_TEST(ClassName) \
515 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
517 #define IMPL_THREAD_TEST(ClassName) \
518 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
520 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
521 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
522 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
524 template <class Types
>
525 class OcclusionTrackerTestIdentityTransforms
526 : public OcclusionTrackerTest
<Types
> {
528 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
529 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
531 void RunMyTest() override
{
532 typename
Types::ContentLayerType
* root
= this->CreateRoot(
533 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
534 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
535 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
536 typename
Types::ContentLayerType
* layer
=
537 this->CreateDrawingLayer(parent
,
538 this->identity_matrix
,
539 gfx::PointF(30.f
, 30.f
),
542 parent
->SetMasksToBounds(true);
543 this->CalcDrawEtc(root
);
545 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
546 gfx::Rect(0, 0, 1000, 1000));
548 this->VisitLayer(layer
, &occlusion
);
549 this->EnterLayer(parent
, &occlusion
);
551 EXPECT_EQ(gfx::Rect().ToString(),
552 occlusion
.occlusion_from_outside_target().ToString());
553 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
554 occlusion
.occlusion_from_inside_target().ToString());
558 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
560 template <class Types
>
561 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
563 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
564 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
565 void RunMyTest() override
{
566 gfx::Transform layer_transform
;
567 layer_transform
.Translate(250.0, 250.0);
568 layer_transform
.Rotate(90.0);
569 layer_transform
.Translate(-250.0, -250.0);
571 typename
Types::ContentLayerType
* root
= this->CreateRoot(
572 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
573 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
574 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
575 typename
Types::ContentLayerType
* layer
=
576 this->CreateDrawingLayer(parent
,
578 gfx::PointF(30.f
, 30.f
),
581 parent
->SetMasksToBounds(true);
582 this->CalcDrawEtc(root
);
584 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
585 gfx::Rect(0, 0, 1000, 1000));
587 this->VisitLayer(layer
, &occlusion
);
588 this->EnterLayer(parent
, &occlusion
);
590 EXPECT_EQ(gfx::Rect().ToString(),
591 occlusion
.occlusion_from_outside_target().ToString());
592 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
593 occlusion
.occlusion_from_inside_target().ToString());
597 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
599 template <class Types
>
600 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
602 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
603 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
604 void RunMyTest() override
{
605 gfx::Transform layer_transform
;
606 layer_transform
.Translate(20.0, 20.0);
608 typename
Types::ContentLayerType
* root
= this->CreateRoot(
609 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
610 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
611 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
612 typename
Types::ContentLayerType
* layer
=
613 this->CreateDrawingLayer(parent
,
615 gfx::PointF(30.f
, 30.f
),
618 parent
->SetMasksToBounds(true);
619 this->CalcDrawEtc(root
);
621 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
622 gfx::Rect(0, 0, 1000, 1000));
624 this->VisitLayer(layer
, &occlusion
);
625 this->EnterLayer(parent
, &occlusion
);
627 EXPECT_EQ(gfx::Rect().ToString(),
628 occlusion
.occlusion_from_outside_target().ToString());
629 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
630 occlusion
.occlusion_from_inside_target().ToString());
634 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
636 template <class Types
>
637 class OcclusionTrackerTestChildInRotatedChild
638 : public OcclusionTrackerTest
<Types
> {
640 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
641 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
642 void RunMyTest() override
{
643 gfx::Transform child_transform
;
644 child_transform
.Translate(250.0, 250.0);
645 child_transform
.Rotate(90.0);
646 child_transform
.Translate(-250.0, -250.0);
648 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
649 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
650 parent
->SetMasksToBounds(true);
651 typename
Types::LayerType
* child
= this->CreateSurface(
652 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
653 child
->SetMasksToBounds(true);
654 typename
Types::ContentLayerType
* layer
=
655 this->CreateDrawingLayer(child
,
656 this->identity_matrix
,
657 gfx::PointF(10.f
, 10.f
),
660 this->CalcDrawEtc(parent
);
662 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
663 gfx::Rect(0, 0, 1000, 1000));
665 this->VisitLayer(layer
, &occlusion
);
666 this->EnterContributingSurface(child
, &occlusion
);
668 EXPECT_EQ(gfx::Rect().ToString(),
669 occlusion
.occlusion_from_outside_target().ToString());
670 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
671 occlusion
.occlusion_from_inside_target().ToString());
673 this->LeaveContributingSurface(child
, &occlusion
);
674 this->EnterLayer(parent
, &occlusion
);
676 EXPECT_EQ(gfx::Rect().ToString(),
677 occlusion
.occlusion_from_outside_target().ToString());
678 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
679 occlusion
.occlusion_from_inside_target().ToString());
681 /* Justification for the above occlusion from |layer|:
683 +---------------------+
686 | 30 + ---------------------------------+
688 | |10+---------------------------------+
692 +----|--|-------------+ | |
700 +--|-------------------------------+ |
702 +---------------------------------+
705 +---------------------+
706 | |30 Visible region of |layer|: /////
708 | +---------------------------------+
710 | +---------------------------------+ |
711 | | |///////////////| 420 | |
712 | | |///////////////|60 | |
713 | | |///////////////| | |
714 +--|--|---------------+ | |
722 | +------------------------------|--+
724 +---------------------------------+
731 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
733 template <class Types
>
734 class OcclusionTrackerTestScaledRenderSurface
735 : public OcclusionTrackerTest
<Types
> {
737 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
738 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
740 void RunMyTest() override
{
741 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
742 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
744 gfx::Transform layer1_matrix
;
745 layer1_matrix
.Scale(2.0, 2.0);
746 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
747 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
748 Types::SetForceRenderSurface(layer1
, true);
750 gfx::Transform layer2_matrix
;
751 layer2_matrix
.Translate(25.0, 25.0);
752 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
753 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
754 typename
Types::ContentLayerType
* occluder
=
755 this->CreateDrawingLayer(parent
,
756 this->identity_matrix
,
757 gfx::PointF(100.f
, 100.f
),
760 this->CalcDrawEtc(parent
);
762 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
763 gfx::Rect(0, 0, 1000, 1000));
765 this->VisitLayer(occluder
, &occlusion
);
766 this->EnterLayer(layer2
, &occlusion
);
768 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
769 occlusion
.occlusion_from_outside_target().ToString());
770 EXPECT_EQ(gfx::Rect().ToString(),
771 occlusion
.occlusion_from_inside_target().ToString());
775 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
777 template <class Types
>
778 class OcclusionTrackerTestVisitTargetTwoTimes
779 : public OcclusionTrackerTest
<Types
> {
781 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
782 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
783 void RunMyTest() override
{
784 typename
Types::ContentLayerType
* root
= this->CreateRoot(
785 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
786 typename
Types::LayerType
* surface
= this->CreateSurface(
787 root
, this->identity_matrix
, gfx::PointF(30.f
, 30.f
), gfx::Size());
788 typename
Types::ContentLayerType
* surface_child
=
789 this->CreateDrawingLayer(surface
,
790 this->identity_matrix
,
791 gfx::PointF(10.f
, 10.f
),
794 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
795 // first, instead of |surface|'s. This exercises different code in
796 // LeaveToRenderTarget, as the target surface has already been seen when
797 // leaving |surface| later.
798 typename
Types::ContentLayerType
* top_layer
=
799 this->CreateDrawingLayer(root
,
800 this->identity_matrix
,
801 gfx::PointF(40.f
, 90.f
),
804 this->CalcDrawEtc(root
);
806 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
807 gfx::Rect(0, 0, 1000, 1000));
809 this->VisitLayer(top_layer
, &occlusion
);
811 EXPECT_EQ(gfx::Rect().ToString(),
812 occlusion
.occlusion_from_outside_target().ToString());
813 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
814 occlusion
.occlusion_from_inside_target().ToString());
816 this->VisitLayer(surface_child
, &occlusion
);
818 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
819 occlusion
.occlusion_from_outside_target().ToString());
820 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
821 occlusion
.occlusion_from_inside_target().ToString());
823 this->EnterContributingSurface(surface
, &occlusion
);
825 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
826 occlusion
.occlusion_from_outside_target().ToString());
827 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
828 occlusion
.occlusion_from_inside_target().ToString());
830 // Occlusion from |top_layer| already in the root target should get merged
831 // with the occlusion from the |surface| we are leaving now.
832 this->LeaveContributingSurface(surface
, &occlusion
);
833 this->EnterLayer(root
, &occlusion
);
835 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
836 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
837 occlusion
.occlusion_from_inside_target().ToString());
841 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
843 template <class Types
>
844 class OcclusionTrackerTestSurfaceRotatedOffAxis
845 : public OcclusionTrackerTest
<Types
> {
847 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
848 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
849 void RunMyTest() override
{
850 gfx::Transform child_transform
;
851 child_transform
.Translate(250.0, 250.0);
852 child_transform
.Rotate(95.0);
853 child_transform
.Translate(-250.0, -250.0);
855 gfx::Transform layer_transform
;
856 layer_transform
.Translate(10.0, 10.0);
858 typename
Types::ContentLayerType
* root
= this->CreateRoot(
859 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
860 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
861 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
862 typename
Types::LayerType
* child
= this->CreateSurface(
863 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
864 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
865 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
866 this->CalcDrawEtc(root
);
868 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
869 gfx::Rect(0, 0, 1000, 1000));
871 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
872 layer_transform
, layer
->visible_content_rect());
874 this->VisitLayer(layer
, &occlusion
);
875 this->EnterContributingSurface(child
, &occlusion
);
877 EXPECT_EQ(gfx::Rect().ToString(),
878 occlusion
.occlusion_from_outside_target().ToString());
879 EXPECT_EQ(clipped_layer_in_child
.ToString(),
880 occlusion
.occlusion_from_inside_target().ToString());
882 this->LeaveContributingSurface(child
, &occlusion
);
883 this->EnterLayer(parent
, &occlusion
);
885 EXPECT_EQ(gfx::Rect().ToString(),
886 occlusion
.occlusion_from_outside_target().ToString());
887 EXPECT_EQ(gfx::Rect().ToString(),
888 occlusion
.occlusion_from_inside_target().ToString());
892 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
894 template <class Types
>
895 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
896 : public OcclusionTrackerTest
<Types
> {
898 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
899 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
900 void RunMyTest() override
{
901 gfx::Transform child_transform
;
902 child_transform
.Translate(250.0, 250.0);
903 child_transform
.Rotate(90.0);
904 child_transform
.Translate(-250.0, -250.0);
906 typename
Types::ContentLayerType
* root
= this->CreateRoot(
907 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
908 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
909 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
910 parent
->SetMasksToBounds(true);
911 typename
Types::ContentLayerType
* child
=
912 this->CreateDrawingSurface(parent
,
914 gfx::PointF(30.f
, 30.f
),
917 child
->SetMasksToBounds(true);
918 typename
Types::ContentLayerType
* layer1
=
919 this->CreateDrawingLayer(child
,
920 this->identity_matrix
,
921 gfx::PointF(10.f
, 10.f
),
924 typename
Types::ContentLayerType
* layer2
=
925 this->CreateDrawingLayer(child
,
926 this->identity_matrix
,
927 gfx::PointF(10.f
, 450.f
),
930 this->CalcDrawEtc(root
);
932 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
933 gfx::Rect(0, 0, 1000, 1000));
935 this->VisitLayer(layer2
, &occlusion
);
936 this->VisitLayer(layer1
, &occlusion
);
937 this->VisitLayer(child
, &occlusion
);
938 this->EnterContributingSurface(child
, &occlusion
);
940 EXPECT_EQ(gfx::Rect().ToString(),
941 occlusion
.occlusion_from_outside_target().ToString());
942 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
943 occlusion
.occlusion_from_inside_target().ToString());
945 this->LeaveContributingSurface(child
, &occlusion
);
946 this->EnterLayer(parent
, &occlusion
);
948 EXPECT_EQ(gfx::Rect().ToString(),
949 occlusion
.occlusion_from_outside_target().ToString());
950 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
951 occlusion
.occlusion_from_inside_target().ToString());
953 /* Justification for the above occlusion from |layer1| and |layer2|:
955 +---------------------+
956 | |30 Visible region of |layer1|: /////
957 | | Visible region of |layer2|: \\\\\
958 | +---------------------------------+
960 | +---------------+-----------------+ |
961 | | |\\\\\\\\\\\\|//| 420 | |
962 | | |\\\\\\\\\\\\|//|60 | |
963 | | |\\\\\\\\\\\\|//| | |
964 +--|--|------------|--+ | |
972 | +------------|-----------------|--+
974 +---------------+-----------------+
980 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
982 template <class Types
>
983 class OcclusionTrackerTestOverlappingSurfaceSiblings
984 : public OcclusionTrackerTest
<Types
> {
986 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
987 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
988 void RunMyTest() override
{
989 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
990 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
991 parent
->SetMasksToBounds(true);
992 typename
Types::LayerType
* child1
= this->CreateSurface(
993 parent
, this->identity_matrix
, gfx::PointF(10.f
, 0.f
), gfx::Size());
994 typename
Types::LayerType
* child2
= this->CreateSurface(
995 parent
, this->identity_matrix
, gfx::PointF(30.f
, 0.f
), gfx::Size());
996 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
997 child1
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 50), true);
998 typename
Types::ContentLayerType
* layer2
=
999 this->CreateDrawingLayer(child2
,
1000 this->identity_matrix
,
1001 gfx::PointF(10.f
, 0.f
),
1004 this->CalcDrawEtc(parent
);
1006 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1007 gfx::Rect(0, 0, 1000, 1000));
1009 this->VisitLayer(layer2
, &occlusion
);
1010 this->EnterContributingSurface(child2
, &occlusion
);
1012 // layer2's occlusion.
1013 EXPECT_EQ(gfx::Rect().ToString(),
1014 occlusion
.occlusion_from_outside_target().ToString());
1015 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
1016 occlusion
.occlusion_from_inside_target().ToString());
1018 this->LeaveContributingSurface(child2
, &occlusion
);
1019 this->VisitLayer(layer1
, &occlusion
);
1020 this->EnterContributingSurface(child1
, &occlusion
);
1022 // layer2's occlusion in the target space of layer1.
1023 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
1024 occlusion
.occlusion_from_outside_target().ToString());
1025 // layer1's occlusion.
1026 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
1027 occlusion
.occlusion_from_inside_target().ToString());
1029 this->LeaveContributingSurface(child1
, &occlusion
);
1030 this->EnterLayer(parent
, &occlusion
);
1032 // The occlusion from from layer1 and layer2 is merged.
1033 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1034 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
1035 occlusion
.occlusion_from_inside_target().ToString());
1039 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1041 template <class Types
>
1042 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1043 : public OcclusionTrackerTest
<Types
> {
1045 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1047 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1048 void RunMyTest() override
{
1049 gfx::Transform child1_transform
;
1050 child1_transform
.Translate(250.0, 250.0);
1051 child1_transform
.Rotate(-90.0);
1052 child1_transform
.Translate(-250.0, -250.0);
1054 gfx::Transform child2_transform
;
1055 child2_transform
.Translate(250.0, 250.0);
1056 child2_transform
.Rotate(90.0);
1057 child2_transform
.Translate(-250.0, -250.0);
1059 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1060 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1061 parent
->SetMasksToBounds(true);
1062 typename
Types::LayerType
* child1
= this->CreateSurface(
1063 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1064 typename
Types::LayerType
* child2
=
1065 this->CreateDrawingSurface(parent
,
1067 gfx::PointF(20.f
, 40.f
),
1070 typename
Types::ContentLayerType
* layer1
=
1071 this->CreateDrawingLayer(child1
,
1072 this->identity_matrix
,
1073 gfx::PointF(-10.f
, -20.f
),
1074 gfx::Size(510, 510),
1076 typename
Types::ContentLayerType
* layer2
=
1077 this->CreateDrawingLayer(child2
,
1078 this->identity_matrix
,
1079 gfx::PointF(-10.f
, -10.f
),
1080 gfx::Size(510, 510),
1082 this->CalcDrawEtc(parent
);
1084 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1085 gfx::Rect(0, 0, 1000, 1000));
1087 this->VisitLayer(layer2
, &occlusion
);
1088 this->EnterLayer(child2
, &occlusion
);
1090 EXPECT_EQ(gfx::Rect().ToString(),
1091 occlusion
.occlusion_from_outside_target().ToString());
1092 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1093 occlusion
.occlusion_from_inside_target().ToString());
1095 this->LeaveLayer(child2
, &occlusion
);
1096 this->EnterContributingSurface(child2
, &occlusion
);
1098 EXPECT_EQ(gfx::Rect().ToString(),
1099 occlusion
.occlusion_from_outside_target().ToString());
1100 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1101 occlusion
.occlusion_from_inside_target().ToString());
1103 this->LeaveContributingSurface(child2
, &occlusion
);
1104 this->VisitLayer(layer1
, &occlusion
);
1105 this->EnterContributingSurface(child1
, &occlusion
);
1107 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1108 occlusion
.occlusion_from_outside_target().ToString());
1109 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1110 occlusion
.occlusion_from_inside_target().ToString());
1112 this->LeaveContributingSurface(child1
, &occlusion
);
1113 this->EnterLayer(parent
, &occlusion
);
1115 EXPECT_EQ(gfx::Rect().ToString(),
1116 occlusion
.occlusion_from_outside_target().ToString());
1117 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1118 occlusion
.occlusion_from_inside_target().ToString());
1120 /* Justification for the above occlusion:
1122 +---------------------+
1124 10+----------------------------------+
1125 100 || 30 | layer2 |
1126 |20+----------------------------------+
1130 +|-|------------------+ | |
1138 +----------------------------------+ |
1140 +----------------------------------+
1146 ALL_OCCLUSIONTRACKER_TEST(
1147 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1149 template <class Types
>
1150 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1152 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1153 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1154 void RunMyTest() override
{
1155 gfx::Transform layer_transform
;
1156 layer_transform
.Translate(250.0, 250.0);
1157 layer_transform
.Rotate(90.0);
1158 layer_transform
.Translate(-250.0, -250.0);
1160 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1161 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1162 parent
->SetMasksToBounds(true);
1163 typename
Types::ContentLayerType
* blur_layer
=
1164 this->CreateDrawingLayer(parent
,
1166 gfx::PointF(30.f
, 30.f
),
1167 gfx::Size(500, 500),
1169 typename
Types::ContentLayerType
* opaque_layer
=
1170 this->CreateDrawingLayer(parent
,
1172 gfx::PointF(30.f
, 30.f
),
1173 gfx::Size(500, 500),
1175 typename
Types::ContentLayerType
* opacity_layer
=
1176 this->CreateDrawingLayer(parent
,
1178 gfx::PointF(30.f
, 30.f
),
1179 gfx::Size(500, 500),
1182 Types::SetForceRenderSurface(blur_layer
, true);
1183 FilterOperations filters
;
1184 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1185 blur_layer
->SetFilters(filters
);
1187 Types::SetForceRenderSurface(opaque_layer
, true);
1189 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1190 opaque_layer
->SetFilters(filters
);
1192 Types::SetForceRenderSurface(opacity_layer
, true);
1194 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1195 opacity_layer
->SetFilters(filters
);
1197 this->CalcDrawEtc(parent
);
1199 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1200 gfx::Rect(0, 0, 1000, 1000));
1202 // Opacity layer won't contribute to occlusion.
1203 this->VisitLayer(opacity_layer
, &occlusion
);
1204 this->EnterContributingSurface(opacity_layer
, &occlusion
);
1206 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1207 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1209 // And has nothing to contribute to its parent surface.
1210 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1211 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1212 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1214 // Opaque layer will contribute to occlusion.
1215 this->VisitLayer(opaque_layer
, &occlusion
);
1216 this->EnterContributingSurface(opaque_layer
, &occlusion
);
1218 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1219 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1220 occlusion
.occlusion_from_inside_target().ToString());
1222 // And it gets translated to the parent surface.
1223 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1224 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1225 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1226 occlusion
.occlusion_from_inside_target().ToString());
1228 // The blur layer needs to throw away any occlusion from outside its
1230 this->EnterLayer(blur_layer
, &occlusion
);
1231 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1232 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1234 // And it won't contribute to occlusion.
1235 this->LeaveLayer(blur_layer
, &occlusion
);
1236 this->EnterContributingSurface(blur_layer
, &occlusion
);
1237 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1238 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1240 // But the opaque layer's occlusion is preserved on the parent.
1241 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1242 this->EnterLayer(parent
, &occlusion
);
1243 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1244 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1245 occlusion
.occlusion_from_inside_target().ToString());
1249 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1251 template <class Types
>
1252 class OcclusionTrackerTestReplicaDoesOcclude
1253 : public OcclusionTrackerTest
<Types
> {
1255 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1256 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1257 void RunMyTest() override
{
1258 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1259 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1260 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
1261 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
1262 this->CreateReplicaLayer(
1263 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1264 this->CalcDrawEtc(parent
);
1266 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1267 gfx::Rect(0, 0, 1000, 1000));
1269 this->VisitLayer(surface
, &occlusion
);
1271 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1272 occlusion
.occlusion_from_inside_target().ToString());
1274 this->VisitContributingSurface(surface
, &occlusion
);
1275 this->EnterLayer(parent
, &occlusion
);
1277 // The surface and replica should both be occluding the parent.
1278 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1279 occlusion
.occlusion_from_inside_target().ToString());
1283 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1285 template <class Types
>
1286 class OcclusionTrackerTestReplicaWithClipping
1287 : public OcclusionTrackerTest
<Types
> {
1289 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1290 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1291 void RunMyTest() override
{
1292 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1293 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1294 parent
->SetMasksToBounds(true);
1295 typename
Types::LayerType
* surface
=
1296 this->CreateDrawingSurface(parent
,
1297 this->identity_matrix
,
1298 gfx::PointF(0.f
, 100.f
),
1301 this->CreateReplicaLayer(
1302 surface
, this->identity_matrix
, gfx::PointF(0.f
, 50.f
), gfx::Size());
1303 this->CalcDrawEtc(parent
);
1305 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1306 gfx::Rect(0, 0, 1000, 1000));
1308 this->VisitLayer(surface
, &occlusion
);
1310 // The surface layer's occlusion in its own space.
1311 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1312 occlusion
.occlusion_from_inside_target().ToString());
1313 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1315 this->VisitContributingSurface(surface
, &occlusion
);
1316 this->EnterLayer(parent
, &occlusion
);
1318 // The surface and replica should both be occluding the parent, the
1319 // replica's occlusion is clipped by the parent.
1320 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1321 occlusion
.occlusion_from_inside_target().ToString());
1322 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1326 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1328 template <class Types
>
1329 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1331 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1332 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1333 void RunMyTest() override
{
1334 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1335 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1336 typename
Types::LayerType
* surface
=
1337 this->CreateDrawingSurface(parent
,
1338 this->identity_matrix
,
1339 gfx::PointF(0.f
, 100.f
),
1342 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1343 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1344 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1345 this->CalcDrawEtc(parent
);
1347 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1348 gfx::Rect(0, 0, 1000, 1000));
1350 this->VisitLayer(surface
, &occlusion
);
1352 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1353 occlusion
.occlusion_from_inside_target().ToString());
1355 this->VisitContributingSurface(surface
, &occlusion
);
1356 this->EnterLayer(parent
, &occlusion
);
1358 // The replica should not be occluding the parent, since it has a mask
1360 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1361 occlusion
.occlusion_from_inside_target().ToString());
1365 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1367 template <class Types
>
1368 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1369 : public OcclusionTrackerTest
<Types
> {
1371 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1372 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1373 void RunMyTest() override
{
1374 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1375 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1376 typename
Types::ContentLayerType
* layer
=
1377 this->CreateDrawingSurface(parent
,
1378 this->identity_matrix
,
1380 gfx::Size(200, 200),
1382 this->CalcDrawEtc(parent
);
1384 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1385 gfx::Rect(0, 0, 1000, 1000));
1386 this->EnterLayer(layer
, &occlusion
);
1388 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1389 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1391 this->LeaveLayer(layer
, &occlusion
);
1392 this->VisitContributingSurface(layer
, &occlusion
);
1393 this->EnterLayer(parent
, &occlusion
);
1395 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1396 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1400 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1402 template <class Types
>
1403 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1404 : public OcclusionTrackerTest
<Types
> {
1406 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1407 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1408 void RunMyTest() override
{
1409 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1410 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1411 typename
Types::ContentLayerType
* layer
=
1412 this->CreateDrawingLayer(parent
,
1413 this->identity_matrix
,
1414 gfx::PointF(100.f
, 100.f
),
1415 gfx::Size(200, 200),
1417 this->CalcDrawEtc(parent
);
1419 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1420 gfx::Rect(0, 0, 1000, 1000));
1421 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1423 this->ResetLayerIterator();
1424 this->VisitLayer(layer
, &occlusion
);
1425 this->EnterLayer(parent
, &occlusion
);
1427 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1428 occlusion
.occlusion_from_inside_target().ToString());
1431 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1432 gfx::Rect(0, 0, 1000, 1000));
1433 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1435 this->ResetLayerIterator();
1436 this->VisitLayer(layer
, &occlusion
);
1437 this->EnterLayer(parent
, &occlusion
);
1439 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1440 occlusion
.occlusion_from_inside_target().ToString());
1443 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1444 gfx::Rect(0, 0, 1000, 1000));
1445 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1447 this->ResetLayerIterator();
1448 this->VisitLayer(layer
, &occlusion
);
1449 this->EnterLayer(parent
, &occlusion
);
1451 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1452 occlusion
.occlusion_from_inside_target().ToString());
1457 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1459 template <class Types
>
1460 class OcclusionTrackerTestUnsorted3dLayers
1461 : public OcclusionTrackerTest
<Types
> {
1463 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
1464 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1465 void RunMyTest() override
{
1466 // Currently, The main thread layer iterator does not iterate over 3d items
1467 // in sorted order, because layer sorting is not performed on the main
1468 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1469 // layer occludes other layers that have not yet been iterated over. For
1470 // now, the expected behavior is that a 3d layer simply does not add any
1471 // occlusion to the occlusion tracker.
1473 gfx::Transform translation_to_front
;
1474 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
1475 gfx::Transform translation_to_back
;
1476 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
1478 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1479 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1480 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
1481 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
1482 typename
Types::ContentLayerType
* child2
=
1483 this->CreateDrawingLayer(parent
,
1484 translation_to_front
,
1485 gfx::PointF(50.f
, 50.f
),
1486 gfx::Size(100, 100),
1488 parent
->SetShouldFlattenTransform(false);
1489 parent
->Set3dSortingContextId(1);
1490 child1
->Set3dSortingContextId(1);
1491 child2
->Set3dSortingContextId(1);
1493 this->CalcDrawEtc(parent
);
1495 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1496 gfx::Rect(0, 0, 1000, 1000));
1497 this->VisitLayer(child2
, &occlusion
);
1498 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1499 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1501 this->VisitLayer(child1
, &occlusion
);
1502 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1503 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1507 // This test will have different layer ordering on the impl thread; the test
1508 // will only work on the main thread.
1509 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1511 template <class Types
>
1512 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1513 : public OcclusionTrackerTest
<Types
> {
1515 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1517 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1518 void RunMyTest() override
{
1519 gfx::Transform transform
;
1520 transform
.Translate(50.0, 50.0);
1521 transform
.ApplyPerspectiveDepth(100.0);
1522 transform
.Translate3d(0.0, 0.0, 110.0);
1523 transform
.Translate(-50.0, -50.0);
1525 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1526 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1527 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1528 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
1529 parent
->SetShouldFlattenTransform(false);
1530 parent
->Set3dSortingContextId(1);
1531 layer
->SetShouldFlattenTransform(false);
1532 layer
->Set3dSortingContextId(1);
1533 this->CalcDrawEtc(parent
);
1535 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1536 gfx::Rect(0, 0, 1000, 1000));
1538 // The |layer| is entirely behind the camera and should not occlude.
1539 this->VisitLayer(layer
, &occlusion
);
1540 this->EnterLayer(parent
, &occlusion
);
1541 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1542 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1546 template <class Types
>
1547 class OcclusionTrackerTestAnimationOpacity1OnMainThread
1548 : public OcclusionTrackerTest
<Types
> {
1550 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
1551 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1552 void RunMyTest() override
{
1556 // | +--surface_child
1557 // | +--surface_child2
1561 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1562 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1563 typename
Types::ContentLayerType
* layer
=
1564 this->CreateDrawingLayer(parent
,
1565 this->identity_matrix
,
1567 gfx::Size(300, 300),
1569 typename
Types::ContentLayerType
* surface
=
1570 this->CreateDrawingSurface(parent
,
1571 this->identity_matrix
,
1573 gfx::Size(300, 300),
1575 typename
Types::ContentLayerType
* surface_child
=
1576 this->CreateDrawingLayer(surface
,
1577 this->identity_matrix
,
1579 gfx::Size(200, 300),
1581 typename
Types::ContentLayerType
* surface_child2
=
1582 this->CreateDrawingLayer(surface
,
1583 this->identity_matrix
,
1585 gfx::Size(100, 300),
1587 typename
Types::ContentLayerType
* parent2
=
1588 this->CreateDrawingLayer(parent
,
1589 this->identity_matrix
,
1591 gfx::Size(300, 300),
1593 typename
Types::ContentLayerType
* topmost
=
1594 this->CreateDrawingLayer(parent
,
1595 this->identity_matrix
,
1596 gfx::PointF(250.f
, 0.f
),
1600 AddOpacityTransitionToController(
1601 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
1602 AddOpacityTransitionToController(
1603 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
1604 this->CalcDrawEtc(parent
);
1606 EXPECT_TRUE(layer
->draw_opacity_is_animating());
1607 EXPECT_FALSE(surface
->draw_opacity_is_animating());
1608 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
1610 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1611 gfx::Rect(0, 0, 1000, 1000));
1613 this->VisitLayer(topmost
, &occlusion
);
1614 this->EnterLayer(parent2
, &occlusion
);
1616 // This occlusion will affect all surfaces.
1617 EXPECT_EQ(gfx::Rect().ToString(),
1618 occlusion
.occlusion_from_outside_target().ToString());
1619 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1620 occlusion
.occlusion_from_inside_target().ToString());
1622 this->LeaveLayer(parent2
, &occlusion
);
1623 this->VisitLayer(surface_child2
, &occlusion
);
1624 this->EnterLayer(surface_child
, &occlusion
);
1625 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1626 occlusion
.occlusion_from_outside_target().ToString());
1627 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1628 occlusion
.occlusion_from_inside_target().ToString());
1630 this->LeaveLayer(surface_child
, &occlusion
);
1631 this->EnterLayer(surface
, &occlusion
);
1632 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1633 occlusion
.occlusion_from_outside_target().ToString());
1634 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1635 occlusion
.occlusion_from_inside_target().ToString());
1637 this->LeaveLayer(surface
, &occlusion
);
1638 this->EnterContributingSurface(surface
, &occlusion
);
1639 // Occlusion within the surface is lost when leaving the animating surface.
1640 EXPECT_EQ(gfx::Rect().ToString(),
1641 occlusion
.occlusion_from_outside_target().ToString());
1642 EXPECT_EQ(gfx::Rect().ToString(),
1643 occlusion
.occlusion_from_inside_target().ToString());
1645 this->LeaveContributingSurface(surface
, &occlusion
);
1646 // Occlusion from outside the animating surface still exists.
1647 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1648 occlusion
.occlusion_from_inside_target().ToString());
1649 EXPECT_EQ(gfx::Rect().ToString(),
1650 occlusion
.occlusion_from_outside_target().ToString());
1652 this->VisitLayer(layer
, &occlusion
);
1653 this->EnterLayer(parent
, &occlusion
);
1655 // Occlusion is not added for the animating |layer|.
1656 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1657 occlusion
.occlusion_from_inside_target().ToString());
1658 EXPECT_EQ(gfx::Rect().ToString(),
1659 occlusion
.occlusion_from_outside_target().ToString());
1663 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
1665 template <class Types
>
1666 class OcclusionTrackerTestAnimationOpacity0OnMainThread
1667 : public OcclusionTrackerTest
<Types
> {
1669 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
1670 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1671 void RunMyTest() override
{
1672 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1673 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1674 typename
Types::ContentLayerType
* layer
=
1675 this->CreateDrawingLayer(parent
,
1676 this->identity_matrix
,
1678 gfx::Size(300, 300),
1680 typename
Types::ContentLayerType
* surface
=
1681 this->CreateDrawingSurface(parent
,
1682 this->identity_matrix
,
1684 gfx::Size(300, 300),
1686 typename
Types::ContentLayerType
* surface_child
=
1687 this->CreateDrawingLayer(surface
,
1688 this->identity_matrix
,
1690 gfx::Size(200, 300),
1692 typename
Types::ContentLayerType
* surface_child2
=
1693 this->CreateDrawingLayer(surface
,
1694 this->identity_matrix
,
1696 gfx::Size(100, 300),
1698 typename
Types::ContentLayerType
* parent2
=
1699 this->CreateDrawingLayer(parent
,
1700 this->identity_matrix
,
1702 gfx::Size(300, 300),
1704 typename
Types::ContentLayerType
* topmost
=
1705 this->CreateDrawingLayer(parent
,
1706 this->identity_matrix
,
1707 gfx::PointF(250.f
, 0.f
),
1711 AddOpacityTransitionToController(
1712 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
1713 AddOpacityTransitionToController(
1714 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
1715 this->CalcDrawEtc(parent
);
1717 EXPECT_TRUE(layer
->draw_opacity_is_animating());
1718 EXPECT_FALSE(surface
->draw_opacity_is_animating());
1719 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
1721 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1722 gfx::Rect(0, 0, 1000, 1000));
1724 this->VisitLayer(topmost
, &occlusion
);
1725 this->EnterLayer(parent2
, &occlusion
);
1726 // This occlusion will affect all surfaces.
1727 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1728 occlusion
.occlusion_from_inside_target().ToString());
1729 EXPECT_EQ(gfx::Rect().ToString(),
1730 occlusion
.occlusion_from_outside_target().ToString());
1732 this->LeaveLayer(parent2
, &occlusion
);
1733 this->VisitLayer(surface_child2
, &occlusion
);
1734 this->EnterLayer(surface_child
, &occlusion
);
1735 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1736 occlusion
.occlusion_from_inside_target().ToString());
1737 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1738 occlusion
.occlusion_from_outside_target().ToString());
1740 this->LeaveLayer(surface_child
, &occlusion
);
1741 this->EnterLayer(surface
, &occlusion
);
1742 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1743 occlusion
.occlusion_from_inside_target().ToString());
1744 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1745 occlusion
.occlusion_from_outside_target().ToString());
1747 this->LeaveLayer(surface
, &occlusion
);
1748 this->EnterContributingSurface(surface
, &occlusion
);
1749 // Occlusion within the surface is lost when leaving the animating surface.
1750 EXPECT_EQ(gfx::Rect().ToString(),
1751 occlusion
.occlusion_from_inside_target().ToString());
1752 EXPECT_EQ(gfx::Rect().ToString(),
1753 occlusion
.occlusion_from_outside_target().ToString());
1755 this->LeaveContributingSurface(surface
, &occlusion
);
1756 // Occlusion from outside the animating surface still exists.
1757 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1758 occlusion
.occlusion_from_inside_target().ToString());
1759 EXPECT_EQ(gfx::Rect().ToString(),
1760 occlusion
.occlusion_from_outside_target().ToString());
1762 this->VisitLayer(layer
, &occlusion
);
1763 this->EnterLayer(parent
, &occlusion
);
1765 // Occlusion is not added for the animating |layer|.
1766 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1767 occlusion
.occlusion_from_inside_target().ToString());
1768 EXPECT_EQ(gfx::Rect().ToString(),
1769 occlusion
.occlusion_from_outside_target().ToString());
1773 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
1775 template <class Types
>
1776 class OcclusionTrackerTestAnimationTranslateOnMainThread
1777 : public OcclusionTrackerTest
<Types
> {
1779 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
1781 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1782 void RunMyTest() override
{
1783 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1784 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1785 typename
Types::ContentLayerType
* layer
=
1786 this->CreateDrawingLayer(parent
,
1787 this->identity_matrix
,
1789 gfx::Size(300, 300),
1791 typename
Types::ContentLayerType
* surface
=
1792 this->CreateDrawingSurface(parent
,
1793 this->identity_matrix
,
1795 gfx::Size(300, 300),
1797 typename
Types::ContentLayerType
* surface_child
=
1798 this->CreateDrawingLayer(surface
,
1799 this->identity_matrix
,
1801 gfx::Size(200, 300),
1803 typename
Types::ContentLayerType
* surface_child2
=
1804 this->CreateDrawingLayer(surface
,
1805 this->identity_matrix
,
1807 gfx::Size(100, 300),
1809 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
1810 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
1812 AddAnimatedTransformToController(
1813 layer
->layer_animation_controller(), 10.0, 30, 0);
1814 AddAnimatedTransformToController(
1815 surface
->layer_animation_controller(), 10.0, 30, 0);
1816 AddAnimatedTransformToController(
1817 surface_child
->layer_animation_controller(), 10.0, 30, 0);
1818 this->CalcDrawEtc(parent
);
1820 EXPECT_TRUE(layer
->draw_transform_is_animating());
1821 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
1823 surface
->render_surface()->target_surface_transforms_are_animating());
1825 surface
->render_surface()->screen_space_transforms_are_animating());
1826 // The surface owning layer doesn't animate against its own surface.
1827 EXPECT_FALSE(surface
->draw_transform_is_animating());
1828 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
1829 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
1830 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
1832 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1833 gfx::Rect(0, 0, 1000, 1000));
1835 this->VisitLayer(surface2
, &occlusion
);
1836 this->EnterContributingSurface(surface2
, &occlusion
);
1838 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1839 occlusion
.occlusion_from_inside_target().ToString());
1841 this->LeaveContributingSurface(surface2
, &occlusion
);
1842 this->EnterLayer(surface_child2
, &occlusion
);
1843 // surface_child2 is moving in screen space but not relative to its target,
1844 // so occlusion should happen in its target space only. It also means that
1845 // things occluding from outside the target (e.g. surface2) cannot occlude
1847 EXPECT_EQ(gfx::Rect().ToString(),
1848 occlusion
.occlusion_from_outside_target().ToString());
1849 EXPECT_EQ(gfx::Rect().ToString(),
1850 occlusion
.occlusion_from_inside_target().ToString());
1852 this->LeaveLayer(surface_child2
, &occlusion
);
1853 this->EnterLayer(surface_child
, &occlusion
);
1854 // surface_child2 added to the occlusion since it is not moving relative
1856 EXPECT_EQ(gfx::Rect().ToString(),
1857 occlusion
.occlusion_from_outside_target().ToString());
1858 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1859 occlusion
.occlusion_from_inside_target().ToString());
1861 this->LeaveLayer(surface_child
, &occlusion
);
1862 // surface_child is moving relative to its target, so it does not add
1864 EXPECT_EQ(gfx::Rect().ToString(),
1865 occlusion
.occlusion_from_outside_target().ToString());
1866 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1867 occlusion
.occlusion_from_inside_target().ToString());
1869 this->EnterLayer(surface
, &occlusion
);
1870 EXPECT_EQ(gfx::Rect().ToString(),
1871 occlusion
.occlusion_from_outside_target().ToString());
1872 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1873 occlusion
.occlusion_from_inside_target().ToString());
1875 this->LeaveLayer(surface
, &occlusion
);
1876 // The surface's owning layer is moving in screen space but not relative to
1877 // its target, so it adds to the occlusion.
1878 EXPECT_EQ(gfx::Rect().ToString(),
1879 occlusion
.occlusion_from_outside_target().ToString());
1880 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
1881 occlusion
.occlusion_from_inside_target().ToString());
1883 this->EnterContributingSurface(surface
, &occlusion
);
1884 this->LeaveContributingSurface(surface
, &occlusion
);
1885 // The |surface| is moving in the screen and in its target, so all occlusion
1886 // within the surface is lost when leaving it. Only the |surface2| occlusion
1888 EXPECT_EQ(gfx::Rect().ToString(),
1889 occlusion
.occlusion_from_outside_target().ToString());
1890 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1891 occlusion
.occlusion_from_inside_target().ToString());
1893 this->VisitLayer(layer
, &occlusion
);
1894 // The |layer| is animating in the screen and in its target, so no occlusion
1896 EXPECT_EQ(gfx::Rect().ToString(),
1897 occlusion
.occlusion_from_outside_target().ToString());
1898 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1899 occlusion
.occlusion_from_inside_target().ToString());
1903 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
1905 template <class Types
>
1906 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1907 : public OcclusionTrackerTest
<Types
> {
1909 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1911 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1912 void RunMyTest() override
{
1913 gfx::Transform surface_transform
;
1914 surface_transform
.Translate(300.0, 300.0);
1915 surface_transform
.Scale(2.0, 2.0);
1916 surface_transform
.Translate(-150.0, -150.0);
1918 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1919 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
1920 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
1921 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
1922 typename
Types::ContentLayerType
* surface2
=
1923 this->CreateDrawingSurface(parent
,
1924 this->identity_matrix
,
1925 gfx::PointF(50.f
, 50.f
),
1926 gfx::Size(300, 300),
1928 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1929 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1930 this->CalcDrawEtc(parent
);
1932 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1933 gfx::Rect(0, 0, 1000, 1000));
1935 this->VisitLayer(surface2
, &occlusion
);
1936 this->VisitContributingSurface(surface2
, &occlusion
);
1938 EXPECT_EQ(gfx::Rect().ToString(),
1939 occlusion
.occlusion_from_outside_target().ToString());
1940 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1941 occlusion
.occlusion_from_inside_target().ToString());
1943 // Clear any stored occlusion.
1944 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1945 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1947 this->VisitLayer(surface
, &occlusion
);
1948 this->VisitContributingSurface(surface
, &occlusion
);
1950 EXPECT_EQ(gfx::Rect().ToString(),
1951 occlusion
.occlusion_from_outside_target().ToString());
1952 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1953 occlusion
.occlusion_from_inside_target().ToString());
1957 MAIN_AND_IMPL_THREAD_TEST(
1958 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
1960 template <class Types
>
1961 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1962 : public OcclusionTrackerTest
<Types
> {
1964 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
1966 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1967 void RunMyTest() override
{
1968 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1969 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1970 parent
->SetMasksToBounds(true);
1971 typename
Types::ContentLayerType
* surface
=
1972 this->CreateDrawingSurface(parent
,
1973 this->identity_matrix
,
1975 gfx::Size(500, 300),
1977 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
1978 this->CalcDrawEtc(parent
);
1980 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1981 gfx::Rect(0, 0, 1000, 1000));
1983 this->VisitLayer(surface
, &occlusion
);
1984 this->VisitContributingSurface(surface
, &occlusion
);
1986 EXPECT_EQ(gfx::Rect().ToString(),
1987 occlusion
.occlusion_from_outside_target().ToString());
1988 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
1989 occlusion
.occlusion_from_inside_target().ToString());
1993 MAIN_AND_IMPL_THREAD_TEST(
1994 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
1996 template <class Types
>
1997 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
1998 : public OcclusionTrackerTest
<Types
> {
2000 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
2001 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2002 void RunMyTest() override
{
2003 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2004 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2005 typename
Types::LayerType
* surface
=
2006 this->CreateDrawingSurface(parent
,
2007 this->identity_matrix
,
2009 gfx::Size(100, 100),
2011 this->CreateReplicaLayer(surface
,
2012 this->identity_matrix
,
2013 gfx::PointF(0.f
, 100.f
),
2014 gfx::Size(100, 100));
2015 typename
Types::LayerType
* topmost
=
2016 this->CreateDrawingLayer(parent
,
2017 this->identity_matrix
,
2019 gfx::Size(100, 110),
2021 this->CalcDrawEtc(parent
);
2023 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2024 gfx::Rect(0, 0, 1000, 1000));
2026 // |topmost| occludes the surface, but not the entire surface's replica.
2027 this->VisitLayer(topmost
, &occlusion
);
2029 EXPECT_EQ(gfx::Rect().ToString(),
2030 occlusion
.occlusion_from_outside_target().ToString());
2031 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2032 occlusion
.occlusion_from_inside_target().ToString());
2034 this->VisitLayer(surface
, &occlusion
);
2036 // Render target with replica ignores occlusion from outside.
2037 EXPECT_EQ(gfx::Rect().ToString(),
2038 occlusion
.occlusion_from_outside_target().ToString());
2039 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2040 occlusion
.occlusion_from_inside_target().ToString());
2042 this->EnterContributingSurface(surface
, &occlusion
);
2044 // Only occlusion from outside the surface occludes the surface/replica.
2045 EXPECT_EQ(gfx::Rect().ToString(),
2046 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2048 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2049 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2054 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2056 template <class Types
>
2057 class OcclusionTrackerTestSurfaceChildOfSurface
2058 : public OcclusionTrackerTest
<Types
> {
2060 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
2061 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2062 void RunMyTest() override
{
2063 // This test verifies that the surface cliprect does not end up empty and
2064 // clip away the entire unoccluded rect.
2066 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2067 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2068 typename
Types::LayerType
* surface
=
2069 this->CreateDrawingSurface(parent
,
2070 this->identity_matrix
,
2072 gfx::Size(100, 100),
2074 typename
Types::LayerType
* surface_child
=
2075 this->CreateDrawingSurface(surface
,
2076 this->identity_matrix
,
2077 gfx::PointF(0.f
, 10.f
),
2080 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
2081 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
2082 this->CalcDrawEtc(parent
);
2084 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2085 gfx::Rect(-100, -100, 1000, 1000));
2087 // |topmost| occludes everything partially so we know occlusion is happening
2089 this->VisitLayer(topmost
, &occlusion
);
2091 EXPECT_EQ(gfx::Rect().ToString(),
2092 occlusion
.occlusion_from_outside_target().ToString());
2093 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2094 occlusion
.occlusion_from_inside_target().ToString());
2096 this->VisitLayer(surface_child
, &occlusion
);
2098 // surface_child increases the occlusion in the screen by a narrow sliver.
2099 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2100 occlusion
.occlusion_from_outside_target().ToString());
2101 // In its own surface, surface_child is at 0,0 as is its occlusion.
2102 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2103 occlusion
.occlusion_from_inside_target().ToString());
2105 // The root layer always has a clip rect. So the parent of |surface| has a
2106 // clip rect. However, the owning layer for |surface| does not mask to
2107 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2108 // |surface_child| exercises different code paths as its parent does not
2109 // have a clip rect.
2111 this->EnterContributingSurface(surface_child
, &occlusion
);
2112 // The |surface_child| can't occlude its own surface, but occlusion from
2114 EXPECT_EQ(gfx::Rect().ToString(),
2115 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2117 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2118 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2120 this->LeaveContributingSurface(surface_child
, &occlusion
);
2122 // When the surface_child's occlusion is transformed up to its parent, make
2123 // sure it is not clipped away inappropriately.
2124 this->EnterLayer(surface
, &occlusion
);
2125 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2126 occlusion
.occlusion_from_outside_target().ToString());
2127 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2128 occlusion
.occlusion_from_inside_target().ToString());
2129 this->LeaveLayer(surface
, &occlusion
);
2131 this->EnterContributingSurface(surface
, &occlusion
);
2132 // The occlusion from inside |surface| can't affect the surface, but
2134 EXPECT_EQ(gfx::Rect().ToString(),
2135 occlusion
.occlusion_on_contributing_surface_from_outside_target()
2137 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2138 occlusion
.occlusion_on_contributing_surface_from_inside_target()
2141 this->LeaveContributingSurface(surface
, &occlusion
);
2142 this->EnterLayer(parent
, &occlusion
);
2143 // The occlusion in |surface| and without are merged into the parent.
2144 EXPECT_EQ(gfx::Rect().ToString(),
2145 occlusion
.occlusion_from_outside_target().ToString());
2146 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
2147 occlusion
.occlusion_from_inside_target().ToString());
2151 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2153 template <class Types
>
2154 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2155 : public OcclusionTrackerTest
<Types
> {
2157 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2159 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2160 void RunMyTest() override
{
2161 gfx::Transform scale_by_half
;
2162 scale_by_half
.Scale(0.5, 0.5);
2164 FilterOperations filters
;
2165 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
2167 // Save the distance of influence for the blur effect.
2168 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2170 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2177 LAST_DIRECTION
= BOTTOM
,
2180 for (int i
= 0; i
<= LAST_DIRECTION
; ++i
) {
2183 // Make a 50x50 filtered surface that is adjacent to occluding layers
2184 // which are above it in the z-order in various configurations. The
2185 // surface is scaled to test that the pixel moving is done in the target
2186 // space, where the background filter is applied.
2187 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2188 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
2189 typename
Types::LayerType
* filtered_surface
=
2190 this->CreateDrawingLayer(parent
,
2192 gfx::PointF(50.f
, 50.f
),
2193 gfx::Size(100, 100),
2195 Types::SetForceRenderSurface(filtered_surface
, true);
2196 filtered_surface
->SetBackgroundFilters(filters
);
2197 gfx::Rect occlusion_rect
;
2200 occlusion_rect
= gfx::Rect(0, 0, 50, 200);
2203 occlusion_rect
= gfx::Rect(100, 0, 50, 200);
2206 occlusion_rect
= gfx::Rect(0, 0, 200, 50);
2209 occlusion_rect
= gfx::Rect(0, 100, 200, 50);
2213 typename
Types::LayerType
* occluding_layer
=
2214 this->CreateDrawingLayer(parent
,
2215 this->identity_matrix
,
2216 occlusion_rect
.origin(),
2217 occlusion_rect
.size(),
2219 this->CalcDrawEtc(parent
);
2221 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2222 gfx::Rect(0, 0, 200, 200));
2224 // This layer occludes pixels directly beside the filtered_surface.
2225 // Because filtered surface blends pixels in a radius, it will need to see
2226 // some of the pixels (up to radius far) underneath the occluding layers.
2227 this->VisitLayer(occluding_layer
, &occlusion
);
2229 EXPECT_EQ(occlusion_rect
.ToString(),
2230 occlusion
.occlusion_from_inside_target().ToString());
2231 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2233 this->VisitLayer(filtered_surface
, &occlusion
);
2235 // The occlusion is used fully inside the surface.
2236 gfx::Rect occlusion_inside_surface
=
2237 occlusion_rect
- gfx::Vector2d(50, 50);
2238 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2239 EXPECT_EQ(occlusion_inside_surface
.ToString(),
2240 occlusion
.occlusion_from_outside_target().ToString());
2242 // The surface has a background blur, so it needs pixels that are
2243 // currently considered occluded in order to be drawn. So the pixels it
2244 // needs should be removed some the occluded area so that when we get to
2245 // the parent they are drawn.
2246 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2247 this->EnterLayer(parent
, &occlusion
);
2249 gfx::Rect expected_occlusion
= occlusion_rect
;
2252 expected_occlusion
.Inset(0, 0, outset_right
, 0);
2255 expected_occlusion
.Inset(outset_right
, 0, 0, 0);
2258 expected_occlusion
.Inset(0, 0, 0, outset_right
);
2261 expected_occlusion
.Inset(0, outset_right
, 0, 0);
2265 EXPECT_EQ(expected_occlusion
.ToString(),
2266 occlusion
.occlusion_from_inside_target().ToString());
2267 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2269 this->DestroyLayers();
2274 ALL_OCCLUSIONTRACKER_TEST(
2275 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
2277 template <class Types
>
2278 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
2279 : public OcclusionTrackerTest
<Types
> {
2281 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
2283 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2284 void RunMyTest() override
{
2285 gfx::Transform scale_by_half
;
2286 scale_by_half
.Scale(0.5, 0.5);
2288 // Makes two surfaces that completely cover |parent|. The occlusion both
2289 // above and below the filters will be reduced by each of them.
2290 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2291 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
2292 typename
Types::LayerType
* parent
= this->CreateSurface(
2293 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
2294 parent
->SetMasksToBounds(true);
2295 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
2296 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
2297 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
2298 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
2299 typename
Types::LayerType
* occluding_layer_above
=
2300 this->CreateDrawingLayer(parent
,
2301 this->identity_matrix
,
2302 gfx::PointF(100.f
, 100.f
),
2306 // Filters make the layers own surfaces.
2307 Types::SetForceRenderSurface(filtered_surface1
, true);
2308 Types::SetForceRenderSurface(filtered_surface2
, true);
2309 FilterOperations filters
;
2310 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
2311 filtered_surface1
->SetBackgroundFilters(filters
);
2312 filtered_surface2
->SetBackgroundFilters(filters
);
2314 // Save the distance of influence for the blur effect.
2315 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2317 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2319 this->CalcDrawEtc(root
);
2321 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2322 gfx::Rect(0, 0, 1000, 1000));
2324 this->VisitLayer(occluding_layer_above
, &occlusion
);
2325 EXPECT_EQ(gfx::Rect().ToString(),
2326 occlusion
.occlusion_from_outside_target().ToString());
2327 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
2328 occlusion
.occlusion_from_inside_target().ToString());
2330 this->VisitLayer(filtered_surface2
, &occlusion
);
2331 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
2332 this->VisitLayer(filtered_surface1
, &occlusion
);
2333 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
2335 // Test expectations in the target.
2336 gfx::Rect expected_occlusion
=
2337 gfx::Rect(100 / 2 + outset_right
* 2,
2338 100 / 2 + outset_bottom
* 2,
2339 50 / 2 - (outset_left
+ outset_right
) * 2,
2340 50 / 2 - (outset_top
+ outset_bottom
) * 2);
2341 EXPECT_EQ(expected_occlusion
.ToString(),
2342 occlusion
.occlusion_from_inside_target().ToString());
2344 // Test expectations in the screen are the same as in the target, as the
2345 // render surface is 1:1 with the screen.
2346 EXPECT_EQ(expected_occlusion
.ToString(),
2347 occlusion
.occlusion_from_outside_target().ToString());
2351 ALL_OCCLUSIONTRACKER_TEST(
2352 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
2354 template <class Types
>
2355 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
2356 : public OcclusionTrackerTest
<Types
> {
2358 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
2360 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2361 void RunMyTest() override
{
2362 gfx::Transform scale_by_half
;
2363 scale_by_half
.Scale(0.5, 0.5);
2365 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
2366 // centered below each. The surface is scaled to test that the pixel moving
2367 // is done in the target space, where the background filter is applied, but
2368 // the surface appears at 50, 50 and the replica at 200, 50.
2369 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2370 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
2371 typename
Types::LayerType
* behind_surface_layer
=
2372 this->CreateDrawingLayer(parent
,
2373 this->identity_matrix
,
2374 gfx::PointF(60.f
, 60.f
),
2377 typename
Types::LayerType
* behind_replica_layer
=
2378 this->CreateDrawingLayer(parent
,
2379 this->identity_matrix
,
2380 gfx::PointF(210.f
, 60.f
),
2383 typename
Types::LayerType
* filtered_surface
=
2384 this->CreateDrawingLayer(parent
,
2386 gfx::PointF(50.f
, 50.f
),
2387 gfx::Size(100, 100),
2389 this->CreateReplicaLayer(filtered_surface
,
2390 this->identity_matrix
,
2391 gfx::PointF(300.f
, 0.f
),
2394 // Filters make the layer own a surface.
2395 Types::SetForceRenderSurface(filtered_surface
, true);
2396 FilterOperations filters
;
2397 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2398 filtered_surface
->SetBackgroundFilters(filters
);
2400 this->CalcDrawEtc(parent
);
2402 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2403 gfx::Rect(0, 0, 1000, 1000));
2405 // The surface has a background blur, so it blurs non-opaque pixels below
2407 this->VisitLayer(filtered_surface
, &occlusion
);
2408 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2410 this->VisitLayer(behind_replica_layer
, &occlusion
);
2412 // The layers behind the surface are not blurred, and their occlusion does
2413 // not change, until we leave the surface. So it should not be modified by
2415 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
2416 EXPECT_EQ(occlusion_behind_replica
.ToString(),
2417 occlusion
.occlusion_from_inside_target().ToString());
2418 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2420 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
2421 // without existing occlusion interfering.
2422 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2424 this->VisitLayer(behind_surface_layer
, &occlusion
);
2426 // The layers behind the surface are not blurred, and their occlusion does
2427 // not change, until we leave the surface. So it should not be modified by
2429 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
2430 EXPECT_EQ(occlusion_behind_surface
.ToString(),
2431 occlusion
.occlusion_from_inside_target().ToString());
2432 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2436 ALL_OCCLUSIONTRACKER_TEST(
2437 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
2439 template <class Types
>
2440 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
2441 : public OcclusionTrackerTest
<Types
> {
2443 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
2445 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2446 void RunMyTest() override
{
2447 gfx::Transform scale_by_half
;
2448 scale_by_half
.Scale(0.5, 0.5);
2450 // Make a 50x50 filtered surface that is completely occluded by an opaque
2451 // layer which is above it in the z-order. The surface is
2452 // scaled to test that the pixel moving is done in the target space, where
2453 // the background filter is applied, but the surface appears at 50, 50.
2454 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2455 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
2456 typename
Types::LayerType
* filtered_surface
=
2457 this->CreateDrawingLayer(parent
,
2459 gfx::PointF(50.f
, 50.f
),
2460 gfx::Size(100, 100),
2462 typename
Types::LayerType
* occluding_layer
=
2463 this->CreateDrawingLayer(parent
,
2464 this->identity_matrix
,
2465 gfx::PointF(50.f
, 50.f
),
2469 // Filters make the layer own a surface.
2470 Types::SetForceRenderSurface(filtered_surface
, true);
2471 FilterOperations filters
;
2472 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2473 filtered_surface
->SetBackgroundFilters(filters
);
2475 this->CalcDrawEtc(parent
);
2477 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2478 gfx::Rect(0, 0, 1000, 1000));
2480 this->VisitLayer(occluding_layer
, &occlusion
);
2482 this->VisitLayer(filtered_surface
, &occlusion
);
2484 // The layers above the filtered surface occlude from outside.
2485 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
2487 EXPECT_EQ(gfx::Rect().ToString(),
2488 occlusion
.occlusion_from_inside_target().ToString());
2489 EXPECT_EQ(occlusion_above_surface
.ToString(),
2490 occlusion
.occlusion_from_outside_target().ToString());
2493 // The surface has a background blur, so it blurs non-opaque pixels below
2495 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2497 // The filter is completely occluded, so it should not blur anything and
2498 // reduce any occlusion.
2499 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
2501 EXPECT_EQ(occlusion_above_surface
.ToString(),
2502 occlusion
.occlusion_from_inside_target().ToString());
2503 EXPECT_EQ(gfx::Rect().ToString(),
2504 occlusion
.occlusion_from_outside_target().ToString());
2509 ALL_OCCLUSIONTRACKER_TEST(
2510 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
2512 template <class Types
>
2513 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
2514 : public OcclusionTrackerTest
<Types
> {
2517 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
2519 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2520 void RunMyTest() override
{
2521 gfx::Transform scale_by_half
;
2522 scale_by_half
.Scale(0.5, 0.5);
2524 // Make a surface and its replica, each 50x50, that are partially occluded
2525 // by opaque layers which are above them in the z-order. The surface is
2526 // scaled to test that the pixel moving is done in the target space, where
2527 // the background filter is applied, but the surface appears at 50, 50 and
2528 // the replica at 200, 50.
2529 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2530 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
2531 typename
Types::LayerType
* filtered_surface
=
2532 this->CreateDrawingLayer(parent
,
2534 gfx::PointF(50.f
, 50.f
),
2535 gfx::Size(100, 100),
2537 this->CreateReplicaLayer(filtered_surface
,
2538 this->identity_matrix
,
2539 gfx::PointF(300.f
, 0.f
),
2541 typename
Types::LayerType
* above_surface_layer
=
2542 this->CreateDrawingLayer(parent
,
2543 this->identity_matrix
,
2544 gfx::PointF(70.f
, 50.f
),
2547 typename
Types::LayerType
* above_replica_layer
=
2548 this->CreateDrawingLayer(parent
,
2549 this->identity_matrix
,
2550 gfx::PointF(200.f
, 50.f
),
2553 typename
Types::LayerType
* beside_surface_layer
=
2554 this->CreateDrawingLayer(parent
,
2555 this->identity_matrix
,
2556 gfx::PointF(90.f
, 40.f
),
2559 typename
Types::LayerType
* beside_replica_layer
=
2560 this->CreateDrawingLayer(parent
,
2561 this->identity_matrix
,
2562 gfx::PointF(200.f
, 40.f
),
2566 // Filters make the layer own a surface.
2567 Types::SetForceRenderSurface(filtered_surface
, true);
2568 FilterOperations filters
;
2569 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
2570 filtered_surface
->SetBackgroundFilters(filters
);
2572 // Save the distance of influence for the blur effect.
2573 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2575 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2577 this->CalcDrawEtc(parent
);
2579 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2580 gfx::Rect(0, 0, 1000, 1000));
2582 this->VisitLayer(beside_replica_layer
, &occlusion
);
2583 this->VisitLayer(beside_surface_layer
, &occlusion
);
2584 this->VisitLayer(above_replica_layer
, &occlusion
);
2585 this->VisitLayer(above_surface_layer
, &occlusion
);
2587 // The surface has a background blur, so it blurs non-opaque pixels below
2589 this->VisitLayer(filtered_surface
, &occlusion
);
2590 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2592 // The filter in the surface and replica are partially unoccluded. Only the
2593 // unoccluded parts should reduce occlusion. This means it will push back
2594 // the occlusion that touches the unoccluded part (occlusion_above___), but
2595 // it will not touch occlusion_beside____ since that is not beside the
2596 // unoccluded part of the surface, even though it is beside the occluded
2597 // part of the surface.
2598 gfx::Rect occlusion_above_surface
=
2599 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
2600 gfx::Rect occlusion_above_replica
=
2601 gfx::Rect(200, 50, 30 - outset_left
, 50);
2602 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
2603 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
2605 SimpleEnclosedRegion expected_occlusion
;
2606 expected_occlusion
.Union(occlusion_beside_replica
);
2607 expected_occlusion
.Union(occlusion_beside_surface
);
2608 expected_occlusion
.Union(occlusion_above_replica
);
2609 expected_occlusion
.Union(occlusion_above_surface
);
2611 EXPECT_EQ(expected_occlusion
.ToString(),
2612 occlusion
.occlusion_from_inside_target().ToString());
2613 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2615 const SimpleEnclosedRegion
& actual_occlusion
=
2616 occlusion
.occlusion_from_inside_target();
2617 for (size_t i
= 0; i
< expected_occlusion
.GetRegionComplexity(); ++i
) {
2618 ASSERT_LT(i
, actual_occlusion
.GetRegionComplexity());
2619 EXPECT_EQ(expected_occlusion
.GetRect(i
), actual_occlusion
.GetRect(i
));
2624 ALL_OCCLUSIONTRACKER_TEST(
2625 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
2627 template <class Types
>
2628 class OcclusionTrackerTestBlendModeDoesNotOcclude
2629 : public OcclusionTrackerTest
<Types
> {
2631 explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers
)
2632 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2633 void RunMyTest() override
{
2634 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2635 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2636 typename
Types::LayerType
* blend_mode_layer
= this->CreateDrawingLayer(
2637 parent
, this->identity_matrix
, gfx::PointF(0.f
, 0.f
),
2638 gfx::Size(100, 100), true);
2639 typename
Types::LayerType
* top_layer
= this->CreateDrawingLayer(
2640 parent
, this->identity_matrix
, gfx::PointF(10.f
, 12.f
),
2641 gfx::Size(20, 22), true);
2643 // Blend mode makes the layer own a surface.
2644 Types::SetForceRenderSurface(blend_mode_layer
, true);
2645 blend_mode_layer
->SetBlendMode(SkXfermode::kMultiply_Mode
);
2647 this->CalcDrawEtc(parent
);
2649 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2650 gfx::Rect(0, 0, 1000, 1000));
2652 this->VisitLayer(top_layer
, &occlusion
);
2653 // |top_layer| occludes.
2654 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2655 occlusion
.occlusion_from_inside_target().ToString());
2656 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2658 this->VisitLayer(blend_mode_layer
, &occlusion
);
2659 // |top_layer| occludes but not |blend_mode_layer|.
2660 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2661 occlusion
.occlusion_from_outside_target().ToString());
2662 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2664 this->VisitContributingSurface(blend_mode_layer
, &occlusion
);
2665 // |top_layer| occludes but not |blend_mode_layer|.
2666 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2667 occlusion
.occlusion_from_inside_target().ToString());
2668 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2672 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude
);
2674 template <class Types
>
2675 class OcclusionTrackerTestMinimumTrackingSize
2676 : public OcclusionTrackerTest
<Types
> {
2678 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
2679 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2680 void RunMyTest() override
{
2681 gfx::Size
tracking_size(100, 100);
2682 gfx::Size
below_tracking_size(99, 99);
2684 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2685 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2686 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
2687 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
2688 typename
Types::LayerType
* small
=
2689 this->CreateDrawingLayer(parent
,
2690 this->identity_matrix
,
2692 below_tracking_size
,
2694 this->CalcDrawEtc(parent
);
2696 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2697 gfx::Rect(0, 0, 1000, 1000));
2698 occlusion
.set_minimum_tracking_size(tracking_size
);
2700 // The small layer is not tracked because it is too small.
2701 this->VisitLayer(small
, &occlusion
);
2703 EXPECT_EQ(gfx::Rect().ToString(),
2704 occlusion
.occlusion_from_outside_target().ToString());
2705 EXPECT_EQ(gfx::Rect().ToString(),
2706 occlusion
.occlusion_from_inside_target().ToString());
2708 // The large layer is tracked as it is large enough.
2709 this->VisitLayer(large
, &occlusion
);
2711 EXPECT_EQ(gfx::Rect().ToString(),
2712 occlusion
.occlusion_from_outside_target().ToString());
2713 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
2714 occlusion
.occlusion_from_inside_target().ToString());
2718 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
2720 template <class Types
>
2721 class OcclusionTrackerTestScaledLayerIsClipped
2722 : public OcclusionTrackerTest
<Types
> {
2724 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
2725 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2726 void RunMyTest() override
{
2727 gfx::Transform scale_transform
;
2728 scale_transform
.Scale(512.0, 512.0);
2730 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2731 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2732 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
2733 this->identity_matrix
,
2734 gfx::PointF(10.f
, 10.f
),
2736 clip
->SetMasksToBounds(true);
2737 typename
Types::LayerType
* scale
= this->CreateLayer(
2738 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
2739 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
2740 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
2741 this->CalcDrawEtc(parent
);
2743 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2744 gfx::Rect(0, 0, 1000, 1000));
2746 this->VisitLayer(scaled
, &occlusion
);
2748 EXPECT_EQ(gfx::Rect().ToString(),
2749 occlusion
.occlusion_from_outside_target().ToString());
2750 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2751 occlusion
.occlusion_from_inside_target().ToString());
2755 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
2757 template <class Types
>
2758 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
2759 : public OcclusionTrackerTest
<Types
> {
2761 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
2762 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2763 void RunMyTest() override
{
2764 gfx::Transform scale_transform
;
2765 scale_transform
.Scale(512.0, 512.0);
2767 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2768 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
2769 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
2770 this->identity_matrix
,
2771 gfx::PointF(10.f
, 10.f
),
2773 clip
->SetMasksToBounds(true);
2774 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
2775 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
2776 typename
Types::LayerType
* scale
= this->CreateLayer(
2777 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
2778 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
2779 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
2780 this->CalcDrawEtc(parent
);
2782 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2783 gfx::Rect(0, 0, 1000, 1000));
2785 this->VisitLayer(scaled
, &occlusion
);
2786 this->VisitLayer(surface
, &occlusion
);
2787 this->VisitContributingSurface(surface
, &occlusion
);
2789 EXPECT_EQ(gfx::Rect().ToString(),
2790 occlusion
.occlusion_from_outside_target().ToString());
2791 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2792 occlusion
.occlusion_from_inside_target().ToString());
2796 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
2798 template <class Types
>
2799 class OcclusionTrackerTestCopyRequestDoesOcclude
2800 : public OcclusionTrackerTest
<Types
> {
2802 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
2803 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2804 void RunMyTest() override
{
2805 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2806 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2807 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
2808 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2809 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
2810 this->identity_matrix
,
2812 gfx::Size(200, 400));
2813 this->AddCopyRequest(copy
);
2814 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
2816 this->identity_matrix
,
2818 gfx::Size(200, 400),
2820 typename
Types::LayerType
* top_layer
=
2821 this->CreateDrawingLayer(root
, this->identity_matrix
,
2822 gfx::PointF(50, 0), gfx::Size(50, 400), true);
2823 this->CalcDrawEtc(root
);
2825 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2826 gfx::Rect(0, 0, 1000, 1000));
2828 this->VisitLayer(top_layer
, &occlusion
);
2829 EXPECT_EQ(gfx::Rect().ToString(),
2830 occlusion
.occlusion_from_outside_target().ToString());
2831 EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(),
2832 occlusion
.occlusion_from_inside_target().ToString());
2834 this->VisitLayer(copy_child
, &occlusion
);
2835 // Layers outside the copy request do not occlude.
2836 EXPECT_EQ(gfx::Rect().ToString(),
2837 occlusion
.occlusion_from_outside_target().ToString());
2838 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2839 occlusion
.occlusion_from_inside_target().ToString());
2841 // CopyRequests cause the layer to own a surface.
2842 this->VisitContributingSurface(copy
, &occlusion
);
2844 // The occlusion from the copy should be kept.
2845 EXPECT_EQ(gfx::Rect().ToString(),
2846 occlusion
.occlusion_from_outside_target().ToString());
2847 EXPECT_EQ(gfx::Rect(50, 0, 250, 400).ToString(),
2848 occlusion
.occlusion_from_inside_target().ToString());
2852 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
2854 template <class Types
>
2855 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2856 : public OcclusionTrackerTest
<Types
> {
2858 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2860 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2861 void RunMyTest() override
{
2862 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2863 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
2864 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
2865 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
2866 typename
Types::LayerType
* hide
= this->CreateLayer(
2867 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
2868 typename
Types::LayerType
* copy
= this->CreateLayer(
2869 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
2870 this->AddCopyRequest(copy
);
2871 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
2872 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
2874 // The |copy| layer is hidden but since it is being copied, it will be
2876 hide
->SetHideLayerAndSubtree(true);
2878 this->CalcDrawEtc(root
);
2880 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2881 gfx::Rect(0, 0, 1000, 1000));
2883 this->VisitLayer(copy_child
, &occlusion
);
2884 EXPECT_EQ(gfx::Rect().ToString(),
2885 occlusion
.occlusion_from_outside_target().ToString());
2886 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2887 occlusion
.occlusion_from_inside_target().ToString());
2889 // CopyRequests cause the layer to own a surface.
2890 this->VisitContributingSurface(copy
, &occlusion
);
2892 // The occlusion from the copy should be dropped since it is hidden.
2893 EXPECT_EQ(gfx::Rect().ToString(),
2894 occlusion
.occlusion_from_outside_target().ToString());
2895 EXPECT_EQ(gfx::Rect().ToString(),
2896 occlusion
.occlusion_from_inside_target().ToString());
2900 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
2902 template <class Types
>
2903 class OcclusionTrackerTestOccludedLayer
: public OcclusionTrackerTest
<Types
> {
2905 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers
)
2906 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2907 void RunMyTest() override
{
2908 gfx::Transform translate
;
2909 translate
.Translate(10.0, 20.0);
2910 typename
Types::ContentLayerType
* root
= this->CreateRoot(
2911 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2912 typename
Types::LayerType
* surface
= this->CreateSurface(
2913 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
2914 typename
Types::LayerType
* layer
= this->CreateDrawingLayer(
2915 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
2916 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
2917 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
2918 this->CalcDrawEtc(root
);
2920 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2921 gfx::Rect(0, 0, 200, 200));
2922 this->VisitLayer(outside_layer
, &occlusion
);
2923 this->EnterLayer(layer
, &occlusion
);
2925 // No occlusion, is not occluded.
2926 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2927 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2928 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100)));
2930 // Partial occlusion from outside, is not occluded.
2931 occlusion
.set_occlusion_from_outside_target(
2932 SimpleEnclosedRegion(50, 50, 100, 100));
2933 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2934 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2935 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2936 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2937 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2938 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2939 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2940 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2941 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2943 // Full occlusion from outside, is occluded.
2944 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2945 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2946 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2947 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2949 // Partial occlusion from inside, is not occluded.
2950 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2951 occlusion
.set_occlusion_from_inside_target(
2952 SimpleEnclosedRegion(50, 50, 100, 100));
2953 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2954 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2955 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2956 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2957 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2958 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2959 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2960 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2962 // Full occlusion from inside, is occluded.
2963 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2964 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2965 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2966 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2968 // Partial occlusion from both, is not occluded.
2969 occlusion
.set_occlusion_from_outside_target(
2970 SimpleEnclosedRegion(50, 50, 100, 50));
2971 occlusion
.set_occlusion_from_inside_target(
2972 SimpleEnclosedRegion(50, 100, 100, 50));
2973 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
2974 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 30, 100, 100)));
2975 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 0, 100, 100)));
2976 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 80, 100, 100)));
2977 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 80, 100)));
2978 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 80, 100, 100)));
2979 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 80, 100, 100)));
2980 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(90, 0, 100, 100)));
2982 // Full occlusion from both, is occluded.
2983 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 100, 100)));
2984 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(40, 30, 10, 10)));
2985 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(130, 120, 10, 10)));
2986 EXPECT_TRUE(occlusion
.OccludedLayer(layer
, gfx::Rect(80, 70, 50, 50)));
2990 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer
)
2992 template <class Types
>
2993 class OcclusionTrackerTestUnoccludedLayerQuery
2994 : public OcclusionTrackerTest
<Types
> {
2996 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers
)
2997 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2998 void RunMyTest() override
{
2999 gfx::Transform translate
;
3000 translate
.Translate(10.0, 20.0);
3001 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3002 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
3003 typename
Types::LayerType
* surface
= this->CreateSurface(
3004 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
3005 typename
Types::LayerType
* layer
= this->CreateDrawingLayer(
3006 surface
, translate
, gfx::Point(), gfx::Size(200, 200), false);
3007 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
3008 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
3009 this->CalcDrawEtc(root
);
3011 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3012 gfx::Rect(0, 0, 200, 200));
3013 this->VisitLayer(outside_layer
, &occlusion
);
3014 this->EnterLayer(layer
, &occlusion
);
3016 // No occlusion, is not occluded.
3017 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3018 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3019 EXPECT_EQ(gfx::Rect(100, 100),
3020 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(100, 100)));
3022 // Partial occlusion from outside.
3023 occlusion
.set_occlusion_from_outside_target(
3024 SimpleEnclosedRegion(50, 50, 100, 100));
3025 occlusion
.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3027 gfx::Rect(0, 0, 100, 100),
3028 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3029 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3030 occlusion
.UnoccludedLayerContentRect(
3031 layer
, gfx::Rect(90, 30, 100, 100)));
3032 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3033 occlusion
.UnoccludedLayerContentRect(layer
,
3034 gfx::Rect(40, 0, 100, 100)));
3035 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3036 occlusion
.UnoccludedLayerContentRect(
3037 layer
, gfx::Rect(40, 80, 100, 100)));
3039 gfx::Rect(0, 0, 80, 100),
3040 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3041 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3042 occlusion
.UnoccludedLayerContentRect(
3043 layer
, gfx::Rect(90, 80, 100, 100)));
3044 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3045 occlusion
.UnoccludedLayerContentRect(layer
,
3046 gfx::Rect(0, 80, 100, 100)));
3047 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3048 occlusion
.UnoccludedLayerContentRect(layer
,
3049 gfx::Rect(90, 0, 100, 100)));
3051 // Full occlusion from outside, is occluded.
3052 EXPECT_EQ(gfx::Rect(),
3053 occlusion
.UnoccludedLayerContentRect(
3054 layer
, gfx::Rect(40, 30, 100, 100)));
3057 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3058 EXPECT_EQ(gfx::Rect(),
3059 occlusion
.UnoccludedLayerContentRect(
3060 layer
, gfx::Rect(130, 120, 10, 10)));
3063 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3065 // Partial occlusion from inside, is not occluded.
3066 occlusion
.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3067 occlusion
.set_occlusion_from_inside_target(
3068 SimpleEnclosedRegion(50, 50, 100, 100));
3070 gfx::Rect(0, 0, 100, 100),
3071 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3072 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3073 occlusion
.UnoccludedLayerContentRect(
3074 layer
, gfx::Rect(90, 30, 100, 100)));
3075 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3076 occlusion
.UnoccludedLayerContentRect(layer
,
3077 gfx::Rect(40, 0, 100, 100)));
3078 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3079 occlusion
.UnoccludedLayerContentRect(
3080 layer
, gfx::Rect(40, 80, 100, 100)));
3082 gfx::Rect(0, 0, 80, 100),
3083 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3084 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3085 occlusion
.UnoccludedLayerContentRect(
3086 layer
, gfx::Rect(90, 80, 100, 100)));
3087 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3088 occlusion
.UnoccludedLayerContentRect(layer
,
3089 gfx::Rect(0, 80, 100, 100)));
3090 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3091 occlusion
.UnoccludedLayerContentRect(layer
,
3092 gfx::Rect(90, 0, 100, 100)));
3094 // Full occlusion from inside, is occluded.
3095 EXPECT_EQ(gfx::Rect(),
3096 occlusion
.UnoccludedLayerContentRect(
3097 layer
, gfx::Rect(40, 30, 100, 100)));
3100 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3101 EXPECT_EQ(gfx::Rect(),
3102 occlusion
.UnoccludedLayerContentRect(
3103 layer
, gfx::Rect(130, 120, 10, 10)));
3106 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3108 // Partial occlusion from both, is not occluded.
3109 occlusion
.set_occlusion_from_outside_target(
3110 SimpleEnclosedRegion(50, 50, 100, 50));
3111 occlusion
.set_occlusion_from_inside_target(
3112 SimpleEnclosedRegion(50, 100, 100, 50));
3114 gfx::Rect(0, 0, 100, 100),
3115 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 100, 100)));
3116 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3118 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3119 occlusion
.UnoccludedLayerContentRect(
3120 layer
, gfx::Rect(90, 30, 100, 100)));
3121 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3122 occlusion
.UnoccludedLayerContentRect(layer
,
3123 gfx::Rect(40, 0, 100, 100)));
3124 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3125 occlusion
.UnoccludedLayerContentRect(
3126 layer
, gfx::Rect(40, 80, 100, 100)));
3128 gfx::Rect(0, 0, 80, 100),
3129 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 80, 100)));
3130 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3131 occlusion
.UnoccludedLayerContentRect(
3132 layer
, gfx::Rect(90, 80, 100, 100)));
3133 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3134 occlusion
.UnoccludedLayerContentRect(layer
,
3135 gfx::Rect(0, 80, 100, 100)));
3136 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3137 occlusion
.UnoccludedLayerContentRect(layer
,
3138 gfx::Rect(90, 0, 100, 100)));
3140 // Full occlusion from both, is occluded.
3141 EXPECT_EQ(gfx::Rect(),
3142 occlusion
.UnoccludedLayerContentRect(
3143 layer
, gfx::Rect(40, 30, 100, 100)));
3146 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(40, 30, 10, 10)));
3147 EXPECT_EQ(gfx::Rect(),
3148 occlusion
.UnoccludedLayerContentRect(
3149 layer
, gfx::Rect(130, 120, 10, 10)));
3152 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(80, 70, 50, 50)));
3156 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery
)
3158 template <class Types
>
3159 class OcclusionTrackerTestUnoccludedSurfaceQuery
3160 : public OcclusionTrackerTest
<Types
> {
3162 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers
)
3163 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3164 void RunMyTest() override
{
3165 gfx::Transform translate
;
3166 translate
.Translate(10.0, 20.0);
3167 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3168 this->identity_matrix
, gfx::Point(), gfx::Size(200, 200));
3169 typename
Types::LayerType
* surface
=
3170 this->CreateSurface(root
, translate
, gfx::Point(), gfx::Size(200, 200));
3171 typename
Types::LayerType
* layer
=
3172 this->CreateDrawingLayer(surface
,
3173 this->identity_matrix
,
3175 gfx::Size(200, 200),
3177 typename
Types::ContentLayerType
* outside_layer
= this->CreateDrawingLayer(
3178 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), false);
3179 this->CalcDrawEtc(root
);
3181 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3182 gfx::Rect(0, 0, 200, 200));
3183 this->VisitLayer(outside_layer
, &occlusion
);
3184 this->VisitLayer(layer
, &occlusion
);
3185 this->EnterContributingSurface(surface
, &occlusion
);
3187 // No occlusion, is not occluded.
3188 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3189 SimpleEnclosedRegion());
3190 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3191 SimpleEnclosedRegion());
3193 gfx::Rect(100, 100),
3194 occlusion
.UnoccludedSurfaceContentRect(surface
, gfx::Rect(100, 100)));
3196 // Partial occlusion from outside.
3197 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3198 SimpleEnclosedRegion(50, 50, 100, 100));
3199 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3200 SimpleEnclosedRegion());
3201 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3202 occlusion
.UnoccludedSurfaceContentRect(
3203 surface
, gfx::Rect(0, 0, 100, 100)));
3204 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3205 occlusion
.UnoccludedSurfaceContentRect(
3206 surface
, gfx::Rect(90, 30, 100, 100)));
3207 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3208 occlusion
.UnoccludedSurfaceContentRect(
3209 surface
, gfx::Rect(40, 0, 100, 100)));
3210 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3211 occlusion
.UnoccludedSurfaceContentRect(
3212 surface
, gfx::Rect(40, 80, 100, 100)));
3213 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3214 occlusion
.UnoccludedSurfaceContentRect(surface
,
3215 gfx::Rect(0, 0, 80, 100)));
3216 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3217 occlusion
.UnoccludedSurfaceContentRect(
3218 surface
, gfx::Rect(90, 80, 100, 100)));
3219 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3220 occlusion
.UnoccludedSurfaceContentRect(
3221 surface
, gfx::Rect(0, 80, 100, 100)));
3222 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3223 occlusion
.UnoccludedSurfaceContentRect(
3224 surface
, gfx::Rect(90, 0, 100, 100)));
3226 // Full occlusion from outside, is occluded.
3227 EXPECT_EQ(gfx::Rect(),
3228 occlusion
.UnoccludedSurfaceContentRect(
3229 surface
, gfx::Rect(40, 30, 100, 100)));
3230 EXPECT_EQ(gfx::Rect(),
3231 occlusion
.UnoccludedSurfaceContentRect(
3232 surface
, gfx::Rect(40, 30, 10, 10)));
3233 EXPECT_EQ(gfx::Rect(),
3234 occlusion
.UnoccludedSurfaceContentRect(
3235 surface
, gfx::Rect(130, 120, 10, 10)));
3236 EXPECT_EQ(gfx::Rect(),
3237 occlusion
.UnoccludedSurfaceContentRect(
3238 surface
, gfx::Rect(80, 70, 50, 50)));
3240 // Partial occlusion from inside, is not occluded.
3241 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3242 SimpleEnclosedRegion());
3243 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3244 SimpleEnclosedRegion(50, 50, 100, 100));
3245 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3246 occlusion
.UnoccludedSurfaceContentRect(
3247 surface
, gfx::Rect(0, 0, 100, 100)));
3248 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3249 occlusion
.UnoccludedSurfaceContentRect(
3250 surface
, gfx::Rect(90, 30, 100, 100)));
3251 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3252 occlusion
.UnoccludedSurfaceContentRect(
3253 surface
, gfx::Rect(40, 0, 100, 100)));
3254 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3255 occlusion
.UnoccludedSurfaceContentRect(
3256 surface
, gfx::Rect(40, 80, 100, 100)));
3257 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3258 occlusion
.UnoccludedSurfaceContentRect(surface
,
3259 gfx::Rect(0, 0, 80, 100)));
3260 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3261 occlusion
.UnoccludedSurfaceContentRect(
3262 surface
, gfx::Rect(90, 80, 100, 100)));
3263 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3264 occlusion
.UnoccludedSurfaceContentRect(
3265 surface
, gfx::Rect(0, 80, 100, 100)));
3266 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3267 occlusion
.UnoccludedSurfaceContentRect(
3268 surface
, gfx::Rect(90, 0, 100, 100)));
3270 // Full occlusion from inside, is occluded.
3271 EXPECT_EQ(gfx::Rect(),
3272 occlusion
.UnoccludedSurfaceContentRect(
3273 surface
, gfx::Rect(40, 30, 100, 100)));
3274 EXPECT_EQ(gfx::Rect(),
3275 occlusion
.UnoccludedSurfaceContentRect(
3276 surface
, gfx::Rect(40, 30, 10, 10)));
3277 EXPECT_EQ(gfx::Rect(),
3278 occlusion
.UnoccludedSurfaceContentRect(
3279 surface
, gfx::Rect(130, 120, 10, 10)));
3280 EXPECT_EQ(gfx::Rect(),
3281 occlusion
.UnoccludedSurfaceContentRect(
3282 surface
, gfx::Rect(80, 70, 50, 50)));
3284 // Partial occlusion from both, is not occluded.
3285 occlusion
.set_occlusion_on_contributing_surface_from_outside_target(
3286 SimpleEnclosedRegion(50, 50, 100, 50));
3287 occlusion
.set_occlusion_on_contributing_surface_from_inside_target(
3288 SimpleEnclosedRegion(50, 100, 100, 50));
3289 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3290 occlusion
.UnoccludedSurfaceContentRect(
3291 surface
, gfx::Rect(0, 0, 100, 100)));
3292 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3294 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3295 occlusion
.UnoccludedSurfaceContentRect(
3296 surface
, gfx::Rect(90, 30, 100, 100)));
3297 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3298 occlusion
.UnoccludedSurfaceContentRect(
3299 surface
, gfx::Rect(40, 0, 100, 100)));
3300 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3301 occlusion
.UnoccludedSurfaceContentRect(
3302 surface
, gfx::Rect(40, 80, 100, 100)));
3303 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3304 occlusion
.UnoccludedSurfaceContentRect(surface
,
3305 gfx::Rect(0, 0, 80, 100)));
3306 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3307 occlusion
.UnoccludedSurfaceContentRect(
3308 surface
, gfx::Rect(90, 80, 100, 100)));
3309 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3310 occlusion
.UnoccludedSurfaceContentRect(
3311 surface
, gfx::Rect(0, 80, 100, 100)));
3312 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3313 occlusion
.UnoccludedSurfaceContentRect(
3314 surface
, gfx::Rect(90, 0, 100, 100)));
3316 // Full occlusion from both, is occluded.
3317 EXPECT_EQ(gfx::Rect(),
3318 occlusion
.UnoccludedSurfaceContentRect(
3319 surface
, gfx::Rect(40, 30, 100, 100)));
3320 EXPECT_EQ(gfx::Rect(),
3321 occlusion
.UnoccludedSurfaceContentRect(
3322 surface
, gfx::Rect(40, 30, 10, 10)));
3323 EXPECT_EQ(gfx::Rect(),
3324 occlusion
.UnoccludedSurfaceContentRect(
3325 surface
, gfx::Rect(130, 120, 10, 10)));
3326 EXPECT_EQ(gfx::Rect(),
3327 occlusion
.UnoccludedSurfaceContentRect(
3328 surface
, gfx::Rect(80, 70, 50, 50)));
3332 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery
)