1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/occlusion_tracker.h"
7 #include "cc/animation/layer_animation_controller.h"
8 #include "cc/base/math_util.h"
9 #include "cc/layers/layer.h"
10 #include "cc/layers/layer_impl.h"
11 #include "cc/output/copy_output_request.h"
12 #include "cc/output/copy_output_result.h"
13 #include "cc/output/filter_operation.h"
14 #include "cc/output/filter_operations.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_impl_proxy.h"
17 #include "cc/test/fake_layer_tree_host.h"
18 #include "cc/test/fake_layer_tree_host_impl.h"
19 #include "cc/test/geometry_test_utils.h"
20 #include "cc/test/test_occlusion_tracker.h"
21 #include "cc/trees/layer_tree_host_common.h"
22 #include "cc/trees/single_thread_proxy.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/gfx/transform.h"
30 class TestContentLayer
: public Layer
{
32 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
36 virtual Region
VisibleContentOpaqueRegion() const OVERRIDE
{
37 if (override_opaque_contents_rect_
)
38 return gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect());
39 return Layer::VisibleContentOpaqueRegion();
41 void SetOpaqueContentsRect(const gfx::Rect
& opaque_contents_rect
) {
42 override_opaque_contents_rect_
= true;
43 opaque_contents_rect_
= opaque_contents_rect
;
47 virtual ~TestContentLayer() {}
49 bool override_opaque_contents_rect_
;
50 gfx::Rect opaque_contents_rect_
;
53 class TestContentLayerImpl
: public LayerImpl
{
55 TestContentLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
56 : LayerImpl(tree_impl
, id
), override_opaque_contents_rect_(false) {
57 SetDrawsContent(true);
60 virtual Region
VisibleContentOpaqueRegion() const OVERRIDE
{
61 if (override_opaque_contents_rect_
)
62 return gfx::IntersectRects(opaque_contents_rect_
, visible_content_rect());
63 return LayerImpl::VisibleContentOpaqueRegion();
65 void SetOpaqueContentsRect(const gfx::Rect
& opaque_contents_rect
) {
66 override_opaque_contents_rect_
= true;
67 opaque_contents_rect_
= opaque_contents_rect
;
71 bool override_opaque_contents_rect_
;
72 gfx::Rect opaque_contents_rect_
;
75 template <typename LayerType
>
76 class TestOcclusionTrackerWithClip
: public TestOcclusionTracker
<LayerType
> {
78 explicit TestOcclusionTrackerWithClip(const gfx::Rect
& viewport_rect
)
79 : TestOcclusionTracker
<LayerType
>(viewport_rect
) {}
81 bool OccludedLayer(const LayerType
* layer
,
82 const gfx::Rect
& content_rect
) const {
83 DCHECK(layer
->visible_content_rect().Contains(content_rect
));
84 return this->Occluded(
85 layer
->render_target(), content_rect
, layer
->draw_transform());
88 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
89 // layer. Simple wrapper around UnoccludedContentRect.
90 gfx::Rect
UnoccludedLayerContentRect(const LayerType
* layer
,
91 const gfx::Rect
& content_rect
) const {
92 DCHECK(layer
->visible_content_rect().Contains(content_rect
));
93 return this->UnoccludedContentRect(content_rect
, layer
->draw_transform());
96 gfx::Rect
UnoccludedSurfaceContentRect(const LayerType
* layer
,
98 const gfx::Rect
& content_rect
) const {
99 typename
LayerType::RenderSurfaceType
* surface
= layer
->render_surface();
100 gfx::Transform draw_transform
= for_replica
101 ? surface
->replica_draw_transform()
102 : surface
->draw_transform();
103 return this->UnoccludedContributingSurfaceContentRect(content_rect
,
108 struct OcclusionTrackerTestMainThreadTypes
{
109 typedef Layer LayerType
;
110 typedef FakeLayerTreeHost HostType
;
111 typedef RenderSurface RenderSurfaceType
;
112 typedef TestContentLayer ContentLayerType
;
113 typedef scoped_refptr
<Layer
> LayerPtrType
;
114 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
115 typedef LayerIterator
<Layer
> TestLayerIterator
;
116 typedef OcclusionTracker
<Layer
> OcclusionTrackerType
;
118 static LayerPtrType
CreateLayer(HostType
* host
) { return Layer::Create(); }
119 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
120 return make_scoped_refptr(new ContentLayerType());
123 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
124 LayerPtrType
ref(*layer
);
129 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
130 LayerPtrType
ref(*layer
);
135 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
138 struct OcclusionTrackerTestImplThreadTypes
{
139 typedef LayerImpl LayerType
;
140 typedef LayerTreeImpl HostType
;
141 typedef RenderSurfaceImpl RenderSurfaceType
;
142 typedef TestContentLayerImpl ContentLayerType
;
143 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
144 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
145 typedef LayerIterator
<LayerImpl
> TestLayerIterator
;
146 typedef OcclusionTracker
<LayerImpl
> OcclusionTrackerType
;
148 static LayerPtrType
CreateLayer(HostType
* host
) {
149 return LayerImpl::Create(host
, next_layer_impl_id
++);
151 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
152 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
154 static int next_layer_impl_id
;
156 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
157 return layer
->Pass();
160 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
161 return layer
->PassAs
<LayerType
>();
164 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
167 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
169 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
171 explicit OcclusionTrackerTest(bool opaque_layers
)
172 : opaque_layers_(opaque_layers
), host_(FakeLayerTreeHost::Create()) {}
174 virtual void RunMyTest() = 0;
176 virtual void TearDown() {
177 Types::DestroyLayer(&root_
);
178 render_surface_layer_list_
.reset();
179 render_surface_layer_list_impl_
.clear();
180 replica_layers_
.clear();
181 mask_layers_
.clear();
184 typename
Types::HostType
* GetHost();
186 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
187 const gfx::PointF
& position
,
188 const gfx::Size
& bounds
) {
189 typename
Types::ContentLayerPtrType
layer(
190 Types::CreateContentLayer(GetHost()));
191 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
192 SetProperties(layer_ptr
, transform
, position
, bounds
);
194 DCHECK(!root_
.get());
195 root_
= Types::PassLayerPtr(&layer
);
197 SetRootLayerOnMainThread(layer_ptr
);
202 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
203 const gfx::Transform
& transform
,
204 const gfx::PointF
& position
,
205 const gfx::Size
& bounds
) {
206 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
207 typename
Types::LayerType
* layer_ptr
= layer
.get();
208 SetProperties(layer_ptr
, transform
, position
, bounds
);
209 parent
->AddChild(Types::PassLayerPtr(&layer
));
213 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
214 const gfx::Transform
& transform
,
215 const gfx::PointF
& position
,
216 const gfx::Size
& bounds
) {
217 typename
Types::LayerType
* layer
=
218 CreateLayer(parent
, transform
, position
, bounds
);
219 layer
->SetForceRenderSurface(true);
223 typename
Types::ContentLayerType
* CreateDrawingLayer(
224 typename
Types::LayerType
* parent
,
225 const gfx::Transform
& transform
,
226 const gfx::PointF
& position
,
227 const gfx::Size
& bounds
,
229 typename
Types::ContentLayerPtrType
layer(
230 Types::CreateContentLayer(GetHost()));
231 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
232 SetProperties(layer_ptr
, transform
, position
, bounds
);
234 if (opaque_layers_
) {
235 layer_ptr
->SetContentsOpaque(opaque
);
237 layer_ptr
->SetContentsOpaque(false);
239 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
241 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
244 parent
->AddChild(Types::PassLayerPtr(&layer
));
248 typename
Types::LayerType
* CreateReplicaLayer(
249 typename
Types::LayerType
* owning_layer
,
250 const gfx::Transform
& transform
,
251 const gfx::PointF
& position
,
252 const gfx::Size
& bounds
) {
253 typename
Types::ContentLayerPtrType
layer(
254 Types::CreateContentLayer(GetHost()));
255 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
256 SetProperties(layer_ptr
, transform
, position
, bounds
);
257 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
261 typename
Types::LayerType
* CreateMaskLayer(
262 typename
Types::LayerType
* owning_layer
,
263 const gfx::Size
& bounds
) {
264 typename
Types::ContentLayerPtrType
layer(
265 Types::CreateContentLayer(GetHost()));
266 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
267 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
268 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
272 typename
Types::ContentLayerType
* CreateDrawingSurface(
273 typename
Types::LayerType
* parent
,
274 const gfx::Transform
& transform
,
275 const gfx::PointF
& position
,
276 const gfx::Size
& bounds
,
278 typename
Types::ContentLayerType
* layer
=
279 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
280 layer
->SetForceRenderSurface(true);
285 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
287 void AddCopyRequest(Layer
* layer
) {
288 layer
->RequestCopyOfOutput(
289 CopyOutputRequest::CreateBitmapRequest(base::Bind(
290 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
291 base::Unretained(this))));
294 void AddCopyRequest(LayerImpl
* layer
) {
295 ScopedPtrVector
<CopyOutputRequest
> requests
;
297 CopyOutputRequest::CreateBitmapRequest(base::Bind(
298 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
299 base::Unretained(this))));
300 layer
->PassCopyRequests(&requests
);
303 void CalcDrawEtc(TestContentLayerImpl
* root
) {
304 DCHECK(root
== root_
.get());
305 DCHECK(!root
->render_surface());
307 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
308 root
, root
->bounds(), &render_surface_layer_list_impl_
);
309 inputs
.can_adjust_raster_scales
= true;
310 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
312 layer_iterator_
= layer_iterator_begin_
=
313 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
316 void CalcDrawEtc(TestContentLayer
* root
) {
317 DCHECK(root
== root_
.get());
318 DCHECK(!root
->render_surface());
320 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
321 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
322 root
, root
->bounds(), render_surface_layer_list_
.get());
323 inputs
.can_adjust_raster_scales
= true;
324 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
326 layer_iterator_
= layer_iterator_begin_
=
327 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
330 void EnterLayer(typename
Types::LayerType
* layer
,
331 typename
Types::OcclusionTrackerType
* occlusion
) {
332 ASSERT_EQ(layer
, *layer_iterator_
);
333 ASSERT_TRUE(layer_iterator_
.represents_itself());
334 occlusion
->EnterLayer(layer_iterator_
);
337 void LeaveLayer(typename
Types::LayerType
* layer
,
338 typename
Types::OcclusionTrackerType
* occlusion
) {
339 ASSERT_EQ(layer
, *layer_iterator_
);
340 ASSERT_TRUE(layer_iterator_
.represents_itself());
341 occlusion
->LeaveLayer(layer_iterator_
);
345 void VisitLayer(typename
Types::LayerType
* layer
,
346 typename
Types::OcclusionTrackerType
* occlusion
) {
347 EnterLayer(layer
, occlusion
);
348 LeaveLayer(layer
, occlusion
);
351 void EnterContributingSurface(
352 typename
Types::LayerType
* layer
,
353 typename
Types::OcclusionTrackerType
* occlusion
) {
354 ASSERT_EQ(layer
, *layer_iterator_
);
355 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
356 occlusion
->EnterLayer(layer_iterator_
);
357 occlusion
->LeaveLayer(layer_iterator_
);
359 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
360 occlusion
->EnterLayer(layer_iterator_
);
363 void LeaveContributingSurface(
364 typename
Types::LayerType
* layer
,
365 typename
Types::OcclusionTrackerType
* occlusion
) {
366 ASSERT_EQ(layer
, *layer_iterator_
);
367 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
368 occlusion
->LeaveLayer(layer_iterator_
);
372 void VisitContributingSurface(
373 typename
Types::LayerType
* layer
,
374 typename
Types::OcclusionTrackerType
* occlusion
) {
375 EnterContributingSurface(layer
, occlusion
);
376 LeaveContributingSurface(layer
, occlusion
);
379 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
381 const gfx::Transform identity_matrix
;
384 void SetRootLayerOnMainThread(Layer
* root
) {
385 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
388 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
390 void SetBaseProperties(typename
Types::LayerType
* layer
,
391 const gfx::Transform
& transform
,
392 const gfx::PointF
& position
,
393 const gfx::Size
& bounds
) {
394 layer
->SetTransform(transform
);
395 layer
->SetPosition(position
);
396 layer
->SetBounds(bounds
);
399 void SetProperties(Layer
* layer
,
400 const gfx::Transform
& transform
,
401 const gfx::PointF
& position
,
402 const gfx::Size
& bounds
) {
403 SetBaseProperties(layer
, transform
, position
, bounds
);
406 void SetProperties(LayerImpl
* layer
,
407 const gfx::Transform
& transform
,
408 const gfx::PointF
& position
,
409 const gfx::Size
& bounds
) {
410 SetBaseProperties(layer
, transform
, position
, bounds
);
412 layer
->SetContentBounds(layer
->bounds());
415 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
416 owning_layer
->SetReplicaLayer(layer
.get());
417 replica_layers_
.push_back(layer
);
420 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
421 owning_layer
->SetReplicaLayer(layer
.Pass());
424 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
425 owning_layer
->SetMaskLayer(layer
.get());
426 mask_layers_
.push_back(layer
);
429 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
430 owning_layer
->SetMaskLayer(layer
.Pass());
434 scoped_ptr
<FakeLayerTreeHost
> host_
;
435 // These hold ownership of the layers for the duration of the test.
436 typename
Types::LayerPtrType root_
;
437 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
438 LayerImplList render_surface_layer_list_impl_
;
439 typename
Types::TestLayerIterator layer_iterator_begin_
;
440 typename
Types::TestLayerIterator layer_iterator_
;
441 typename
Types::LayerType
* last_layer_visited_
;
442 LayerList replica_layers_
;
443 LayerList mask_layers_
;
448 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
454 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
455 return host_
->host_impl()->active_tree();
458 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
459 class ClassName##MainThreadOpaqueLayers \
460 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
461 public: /* NOLINT(whitespace/indent) */ \
462 ClassName##MainThreadOpaqueLayers() \
463 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
465 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
466 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
467 class ClassName##MainThreadOpaquePaints \
468 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
469 public: /* NOLINT(whitespace/indent) */ \
470 ClassName##MainThreadOpaquePaints() \
471 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
473 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
475 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
476 class ClassName##ImplThreadOpaqueLayers \
477 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
478 public: /* NOLINT(whitespace/indent) */ \
479 ClassName##ImplThreadOpaqueLayers() \
480 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
482 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
483 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
484 class ClassName##ImplThreadOpaquePaints \
485 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
486 public: /* NOLINT(whitespace/indent) */ \
487 ClassName##ImplThreadOpaquePaints() \
488 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
490 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
492 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
493 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
494 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
495 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
496 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
498 #define MAIN_THREAD_TEST(ClassName) \
499 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
501 #define IMPL_THREAD_TEST(ClassName) \
502 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
504 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
505 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
506 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
508 template <class Types
>
509 class OcclusionTrackerTestIdentityTransforms
510 : public OcclusionTrackerTest
<Types
> {
512 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
513 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
516 typename
Types::ContentLayerType
* root
= this->CreateRoot(
517 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
518 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
519 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
520 typename
Types::ContentLayerType
* layer
=
521 this->CreateDrawingLayer(parent
,
522 this->identity_matrix
,
523 gfx::PointF(30.f
, 30.f
),
526 parent
->SetMasksToBounds(true);
527 this->CalcDrawEtc(root
);
529 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
530 gfx::Rect(0, 0, 1000, 1000));
532 this->VisitLayer(layer
, &occlusion
);
533 this->EnterLayer(parent
, &occlusion
);
535 EXPECT_EQ(gfx::Rect().ToString(),
536 occlusion
.occlusion_from_outside_target().ToString());
537 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
538 occlusion
.occlusion_from_inside_target().ToString());
540 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
541 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
542 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
543 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
544 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
546 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
547 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
548 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
549 occlusion
.UnoccludedLayerContentRect(
550 parent
, gfx::Rect(29, 30, 70, 70)));
551 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
552 occlusion
.UnoccludedLayerContentRect(
553 parent
, gfx::Rect(29, 29, 70, 70)));
554 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
555 occlusion
.UnoccludedLayerContentRect(
556 parent
, gfx::Rect(30, 29, 70, 70)));
557 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
558 occlusion
.UnoccludedLayerContentRect(
559 parent
, gfx::Rect(31, 29, 69, 70)));
560 EXPECT_RECT_EQ(gfx::Rect(),
561 occlusion
.UnoccludedLayerContentRect(
562 parent
, gfx::Rect(31, 30, 69, 70)));
563 EXPECT_RECT_EQ(gfx::Rect(),
564 occlusion
.UnoccludedLayerContentRect(
565 parent
, gfx::Rect(31, 31, 69, 69)));
566 EXPECT_RECT_EQ(gfx::Rect(),
567 occlusion
.UnoccludedLayerContentRect(
568 parent
, gfx::Rect(30, 31, 70, 69)));
569 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
570 occlusion
.UnoccludedLayerContentRect(
571 parent
, gfx::Rect(29, 31, 70, 69)));
575 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
577 template <class Types
>
578 class OcclusionTrackerTestQuadsMismatchLayer
579 : public OcclusionTrackerTest
<Types
> {
581 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers
)
582 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
584 gfx::Transform layer_transform
;
585 layer_transform
.Translate(10.0, 10.0);
587 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
588 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(100, 100));
589 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
590 parent
, layer_transform
, gfx::PointF(), gfx::Size(90, 90), true);
591 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
592 layer1
, layer_transform
, gfx::PointF(), gfx::Size(50, 50), true);
593 this->CalcDrawEtc(parent
);
595 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
596 gfx::Rect(0, 0, 1000, 1000));
598 this->VisitLayer(layer2
, &occlusion
);
599 this->EnterLayer(layer1
, &occlusion
);
601 EXPECT_EQ(gfx::Rect().ToString(),
602 occlusion
.occlusion_from_outside_target().ToString());
603 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
604 occlusion
.occlusion_from_inside_target().ToString());
606 // This checks cases where the quads don't match their "containing"
607 // layers, e.g. in terms of transforms or clip rect. This is typical for
608 // DelegatedRendererLayer.
610 gfx::Transform quad_transform
;
611 quad_transform
.Translate(30.0, 30.0);
613 EXPECT_TRUE(occlusion
.UnoccludedContentRect(gfx::Rect(0, 0, 10, 10),
614 quad_transform
).IsEmpty());
615 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
616 occlusion
.UnoccludedContentRect(gfx::Rect(40, 40, 10, 10),
618 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
619 occlusion
.UnoccludedContentRect(gfx::Rect(35, 30, 10, 10),
624 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
626 template <class Types
>
627 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
629 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
630 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
632 gfx::Transform layer_transform
;
633 layer_transform
.Translate(250.0, 250.0);
634 layer_transform
.Rotate(90.0);
635 layer_transform
.Translate(-250.0, -250.0);
637 typename
Types::ContentLayerType
* root
= this->CreateRoot(
638 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
639 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
640 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
641 typename
Types::ContentLayerType
* layer
=
642 this->CreateDrawingLayer(parent
,
644 gfx::PointF(30.f
, 30.f
),
647 parent
->SetMasksToBounds(true);
648 this->CalcDrawEtc(root
);
650 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
651 gfx::Rect(0, 0, 1000, 1000));
653 this->VisitLayer(layer
, &occlusion
);
654 this->EnterLayer(parent
, &occlusion
);
656 EXPECT_EQ(gfx::Rect().ToString(),
657 occlusion
.occlusion_from_outside_target().ToString());
658 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
659 occlusion
.occlusion_from_inside_target().ToString());
661 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
662 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
663 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
664 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
665 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
667 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
668 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
669 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
670 occlusion
.UnoccludedLayerContentRect(
671 parent
, gfx::Rect(29, 30, 69, 70)));
672 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
673 occlusion
.UnoccludedLayerContentRect(
674 parent
, gfx::Rect(29, 29, 70, 70)));
675 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
676 occlusion
.UnoccludedLayerContentRect(
677 parent
, gfx::Rect(30, 29, 70, 70)));
678 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
679 occlusion
.UnoccludedLayerContentRect(
680 parent
, gfx::Rect(31, 29, 69, 70)));
681 EXPECT_RECT_EQ(gfx::Rect(),
682 occlusion
.UnoccludedLayerContentRect(
683 parent
, gfx::Rect(31, 30, 69, 70)));
684 EXPECT_RECT_EQ(gfx::Rect(),
685 occlusion
.UnoccludedLayerContentRect(
686 parent
, gfx::Rect(31, 31, 69, 69)));
687 EXPECT_RECT_EQ(gfx::Rect(),
688 occlusion
.UnoccludedLayerContentRect(
689 parent
, gfx::Rect(30, 31, 70, 69)));
690 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
691 occlusion
.UnoccludedLayerContentRect(
692 parent
, gfx::Rect(29, 31, 70, 69)));
696 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
698 template <class Types
>
699 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
701 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
702 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
704 gfx::Transform layer_transform
;
705 layer_transform
.Translate(20.0, 20.0);
707 typename
Types::ContentLayerType
* root
= this->CreateRoot(
708 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
709 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
710 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
711 typename
Types::ContentLayerType
* layer
=
712 this->CreateDrawingLayer(parent
,
714 gfx::PointF(30.f
, 30.f
),
717 parent
->SetMasksToBounds(true);
718 this->CalcDrawEtc(root
);
720 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
721 gfx::Rect(0, 0, 1000, 1000));
723 this->VisitLayer(layer
, &occlusion
);
724 this->EnterLayer(parent
, &occlusion
);
726 EXPECT_EQ(gfx::Rect().ToString(),
727 occlusion
.occlusion_from_outside_target().ToString());
728 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
729 occlusion
.occlusion_from_inside_target().ToString());
731 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
732 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
733 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
734 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(51, 50, 49, 50)));
735 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 51, 50, 49)));
737 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
738 parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
739 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
740 occlusion
.UnoccludedLayerContentRect(
741 parent
, gfx::Rect(49, 50, 50, 50)));
742 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
743 occlusion
.UnoccludedLayerContentRect(
744 parent
, gfx::Rect(49, 49, 50, 50)));
745 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
746 occlusion
.UnoccludedLayerContentRect(
747 parent
, gfx::Rect(50, 49, 50, 50)));
748 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
749 occlusion
.UnoccludedLayerContentRect(
750 parent
, gfx::Rect(51, 49, 49, 50)));
751 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
752 parent
, gfx::Rect(51, 50, 49, 50)).IsEmpty());
753 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
754 parent
, gfx::Rect(51, 51, 49, 49)).IsEmpty());
755 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
756 parent
, gfx::Rect(50, 51, 50, 49)).IsEmpty());
757 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
758 occlusion
.UnoccludedLayerContentRect(
759 parent
, gfx::Rect(49, 51, 50, 49)));
763 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
765 template <class Types
>
766 class OcclusionTrackerTestChildInRotatedChild
767 : public OcclusionTrackerTest
<Types
> {
769 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
770 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
772 gfx::Transform child_transform
;
773 child_transform
.Translate(250.0, 250.0);
774 child_transform
.Rotate(90.0);
775 child_transform
.Translate(-250.0, -250.0);
777 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
778 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
779 parent
->SetMasksToBounds(true);
780 typename
Types::LayerType
* child
= this->CreateSurface(
781 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
782 child
->SetMasksToBounds(true);
783 typename
Types::ContentLayerType
* layer
=
784 this->CreateDrawingLayer(child
,
785 this->identity_matrix
,
786 gfx::PointF(10.f
, 10.f
),
789 this->CalcDrawEtc(parent
);
791 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
792 gfx::Rect(0, 0, 1000, 1000));
794 this->VisitLayer(layer
, &occlusion
);
795 this->EnterContributingSurface(child
, &occlusion
);
797 EXPECT_EQ(gfx::Rect().ToString(),
798 occlusion
.occlusion_from_outside_target().ToString());
799 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
800 occlusion
.occlusion_from_inside_target().ToString());
802 this->LeaveContributingSurface(child
, &occlusion
);
803 this->EnterLayer(parent
, &occlusion
);
805 EXPECT_EQ(gfx::Rect().ToString(),
806 occlusion
.occlusion_from_outside_target().ToString());
807 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
808 occlusion
.occlusion_from_inside_target().ToString());
810 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
811 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
812 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
813 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 40, 69, 60)));
814 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 41, 70, 59)));
816 /* Justification for the above occlusion from |layer|:
818 +---------------------+
821 | 30 + ---------------------------------+
823 | |10+---------------------------------+
827 +----|--|-------------+ | |
835 +--|-------------------------------+ |
837 +---------------------------------+
840 +---------------------+
841 | |30 Visible region of |layer|: /////
843 | +---------------------------------+
845 | +---------------------------------+ |
846 | | |///////////////| 420 | |
847 | | |///////////////|60 | |
848 | | |///////////////| | |
849 +--|--|---------------+ | |
857 | +------------------------------|--+
859 +---------------------------------+
866 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
868 template <class Types
>
869 class OcclusionTrackerTestScaledRenderSurface
870 : public OcclusionTrackerTest
<Types
> {
872 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
873 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
876 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
877 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
879 gfx::Transform layer1_matrix
;
880 layer1_matrix
.Scale(2.0, 2.0);
881 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
882 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
883 layer1
->SetForceRenderSurface(true);
885 gfx::Transform layer2_matrix
;
886 layer2_matrix
.Translate(25.0, 25.0);
887 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
888 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
889 typename
Types::ContentLayerType
* occluder
=
890 this->CreateDrawingLayer(parent
,
891 this->identity_matrix
,
892 gfx::PointF(100.f
, 100.f
),
895 this->CalcDrawEtc(parent
);
897 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
898 gfx::Rect(0, 0, 1000, 1000));
900 this->VisitLayer(occluder
, &occlusion
);
901 this->EnterLayer(layer2
, &occlusion
);
903 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
904 occlusion
.occlusion_from_outside_target().ToString());
905 EXPECT_EQ(gfx::Rect().ToString(),
906 occlusion
.occlusion_from_inside_target().ToString());
909 gfx::Rect(0, 0, 25, 25),
910 occlusion
.UnoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
911 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
912 occlusion
.UnoccludedLayerContentRect(
913 layer2
, gfx::Rect(10, 25, 25, 25)));
914 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
915 occlusion
.UnoccludedLayerContentRect(
916 layer2
, gfx::Rect(25, 10, 25, 25)));
917 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
918 layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
922 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
924 template <class Types
>
925 class OcclusionTrackerTestVisitTargetTwoTimes
926 : public OcclusionTrackerTest
<Types
> {
928 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
929 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
931 gfx::Transform child_transform
;
932 child_transform
.Translate(250.0, 250.0);
933 child_transform
.Rotate(90.0);
934 child_transform
.Translate(-250.0, -250.0);
936 typename
Types::ContentLayerType
* root
= this->CreateRoot(
937 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
938 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
939 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
940 parent
->SetMasksToBounds(true);
941 typename
Types::LayerType
* child
= this->CreateSurface(
942 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
943 child
->SetMasksToBounds(true);
944 typename
Types::ContentLayerType
* layer
=
945 this->CreateDrawingLayer(child
,
946 this->identity_matrix
,
947 gfx::PointF(10.f
, 10.f
),
950 // |child2| makes |parent|'s surface get considered by OcclusionTracker
951 // first, instead of |child|'s. This exercises different code in
952 // LeaveToRenderTarget, as the target surface has already been seen.
953 typename
Types::ContentLayerType
* child2
=
954 this->CreateDrawingLayer(parent
,
955 this->identity_matrix
,
956 gfx::PointF(30.f
, 30.f
),
959 this->CalcDrawEtc(root
);
961 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
962 gfx::Rect(0, 0, 1000, 1000));
964 this->VisitLayer(child2
, &occlusion
);
966 EXPECT_EQ(gfx::Rect().ToString(),
967 occlusion
.occlusion_from_outside_target().ToString());
968 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
969 occlusion
.occlusion_from_inside_target().ToString());
971 this->VisitLayer(layer
, &occlusion
);
973 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
974 occlusion
.occlusion_from_outside_target().ToString());
975 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
976 occlusion
.occlusion_from_inside_target().ToString());
978 this->EnterContributingSurface(child
, &occlusion
);
980 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
981 occlusion
.occlusion_from_outside_target().ToString());
982 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
983 occlusion
.occlusion_from_inside_target().ToString());
985 // Occlusion in |child2| should get merged with the |child| surface we are
987 this->LeaveContributingSurface(child
, &occlusion
);
988 this->EnterLayer(parent
, &occlusion
);
990 EXPECT_EQ(gfx::Rect().ToString(),
991 occlusion
.occlusion_from_outside_target().ToString());
992 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
994 occlusion
.occlusion_from_inside_target().ToString());
996 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
997 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
998 occlusion
.UnoccludedLayerContentRect(
999 parent
, gfx::Rect(30, 30, 70, 70)));
1001 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
1002 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
1003 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
1004 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
1005 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
1007 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1008 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1009 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1011 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1012 parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1013 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1014 occlusion
.UnoccludedLayerContentRect(
1015 parent
, gfx::Rect(29, 30, 60, 10)));
1016 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1017 occlusion
.UnoccludedLayerContentRect(
1018 parent
, gfx::Rect(30, 29, 60, 10)));
1019 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1020 occlusion
.UnoccludedLayerContentRect(
1021 parent
, gfx::Rect(31, 30, 60, 10)));
1022 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1023 parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1025 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1026 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1027 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1028 occlusion
.UnoccludedLayerContentRect(
1029 parent
, gfx::Rect(29, 40, 70, 60)));
1030 // This rect is mostly occluded by |child2|.
1031 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1032 occlusion
.UnoccludedLayerContentRect(
1033 parent
, gfx::Rect(30, 39, 70, 60)));
1034 // This rect extends past top/right ends of |child2|.
1035 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1036 occlusion
.UnoccludedLayerContentRect(
1037 parent
, gfx::Rect(30, 29, 70, 70)));
1038 // This rect extends past left/right ends of |child2|.
1039 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1040 occlusion
.UnoccludedLayerContentRect(
1041 parent
, gfx::Rect(20, 39, 80, 60)));
1042 EXPECT_RECT_EQ(gfx::Rect(),
1043 occlusion
.UnoccludedLayerContentRect(
1044 parent
, gfx::Rect(31, 40, 69, 60)));
1045 EXPECT_RECT_EQ(gfx::Rect(),
1046 occlusion
.UnoccludedLayerContentRect(
1047 parent
, gfx::Rect(30, 41, 70, 59)));
1049 /* Justification for the above occlusion from |layer|:
1051 +---------------------+
1054 | 30 + ------------+--------------------+
1055 100 | | 10 | | | ==>
1056 | |10+----------|----------------------+
1057 | + ------------+ | | |
1060 +----|--|-------------+ | |
1068 +--|-------------------------------+ |
1070 +---------------------------------+
1074 +---------------------+
1075 | |30 Visible region of |layer|: /////
1076 | 30 60 | |child2|: \\\\\
1077 | 30 +------------+--------------------+
1078 | |\\\\\\\\\\\\| |10 |
1079 | +--|\\\\\\\\\\\\|-----------------+ |
1080 | | +------------+//| 420 | |
1081 | | |///////////////|60 | |
1082 | | |///////////////| | |
1083 +--|--|---------------+ | |
1091 | +------------------------------|--+
1093 +---------------------------------+
1099 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
1101 template <class Types
>
1102 class OcclusionTrackerTestSurfaceRotatedOffAxis
1103 : public OcclusionTrackerTest
<Types
> {
1105 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
1106 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1108 gfx::Transform child_transform
;
1109 child_transform
.Translate(250.0, 250.0);
1110 child_transform
.Rotate(95.0);
1111 child_transform
.Translate(-250.0, -250.0);
1113 gfx::Transform layer_transform
;
1114 layer_transform
.Translate(10.0, 10.0);
1116 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1117 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1118 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1119 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1120 typename
Types::LayerType
* child
= this->CreateLayer(
1121 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1122 child
->SetMasksToBounds(true);
1123 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1124 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
1125 this->CalcDrawEtc(root
);
1127 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1128 gfx::Rect(0, 0, 1000, 1000));
1130 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
1131 layer_transform
, layer
->visible_content_rect());
1133 this->VisitLayer(layer
, &occlusion
);
1134 this->EnterContributingSurface(child
, &occlusion
);
1136 EXPECT_EQ(gfx::Rect().ToString(),
1137 occlusion
.occlusion_from_outside_target().ToString());
1138 EXPECT_EQ(clipped_layer_in_child
.ToString(),
1139 occlusion
.occlusion_from_inside_target().ToString());
1141 this->LeaveContributingSurface(child
, &occlusion
);
1142 this->EnterLayer(parent
, &occlusion
);
1144 EXPECT_EQ(gfx::Rect().ToString(),
1145 occlusion
.occlusion_from_outside_target().ToString());
1146 EXPECT_EQ(gfx::Rect().ToString(),
1147 occlusion
.occlusion_from_inside_target().ToString());
1149 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
1151 gfx::Rect(75, 55, 1, 1),
1152 occlusion
.UnoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
1156 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
1158 template <class Types
>
1159 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1160 : public OcclusionTrackerTest
<Types
> {
1162 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
1163 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1165 gfx::Transform child_transform
;
1166 child_transform
.Translate(250.0, 250.0);
1167 child_transform
.Rotate(90.0);
1168 child_transform
.Translate(-250.0, -250.0);
1170 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1171 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1172 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1173 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1174 parent
->SetMasksToBounds(true);
1175 typename
Types::ContentLayerType
* child
=
1176 this->CreateDrawingSurface(parent
,
1178 gfx::PointF(30.f
, 30.f
),
1179 gfx::Size(500, 500),
1181 child
->SetMasksToBounds(true);
1182 typename
Types::ContentLayerType
* layer1
=
1183 this->CreateDrawingLayer(child
,
1184 this->identity_matrix
,
1185 gfx::PointF(10.f
, 10.f
),
1186 gfx::Size(500, 500),
1188 typename
Types::ContentLayerType
* layer2
=
1189 this->CreateDrawingLayer(child
,
1190 this->identity_matrix
,
1191 gfx::PointF(10.f
, 450.f
),
1194 this->CalcDrawEtc(root
);
1196 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1197 gfx::Rect(0, 0, 1000, 1000));
1199 this->VisitLayer(layer2
, &occlusion
);
1200 this->VisitLayer(layer1
, &occlusion
);
1201 this->VisitLayer(child
, &occlusion
);
1202 this->EnterContributingSurface(child
, &occlusion
);
1204 EXPECT_EQ(gfx::Rect().ToString(),
1205 occlusion
.occlusion_from_outside_target().ToString());
1206 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1207 occlusion
.occlusion_from_inside_target().ToString());
1209 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
1210 EXPECT_FALSE(occlusion
.OccludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
1211 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(11, 430, 59, 70)));
1212 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 431, 60, 69)));
1214 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1215 child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1217 gfx::Rect(9, 430, 1, 70),
1218 occlusion
.UnoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
1219 EXPECT_RECT_EQ(gfx::Rect(),
1220 occlusion
.UnoccludedLayerContentRect(
1221 child
, gfx::Rect(11, 430, 59, 70)));
1222 EXPECT_RECT_EQ(gfx::Rect(),
1223 occlusion
.UnoccludedLayerContentRect(
1224 child
, gfx::Rect(10, 431, 60, 69)));
1226 this->LeaveContributingSurface(child
, &occlusion
);
1227 this->EnterLayer(parent
, &occlusion
);
1229 EXPECT_EQ(gfx::Rect().ToString(),
1230 occlusion
.occlusion_from_outside_target().ToString());
1231 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1232 occlusion
.occlusion_from_inside_target().ToString());
1234 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1235 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1236 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1238 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1239 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1240 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1241 occlusion
.UnoccludedLayerContentRect(
1242 parent
, gfx::Rect(29, 40, 70, 60)));
1243 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1244 occlusion
.UnoccludedLayerContentRect(
1245 parent
, gfx::Rect(30, 39, 70, 60)));
1246 EXPECT_RECT_EQ(gfx::Rect(),
1247 occlusion
.UnoccludedLayerContentRect(
1248 parent
, gfx::Rect(31, 40, 69, 60)));
1249 EXPECT_RECT_EQ(gfx::Rect(),
1250 occlusion
.UnoccludedLayerContentRect(
1251 parent
, gfx::Rect(30, 41, 70, 59)));
1253 /* Justification for the above occlusion from |layer1| and |layer2|:
1255 +---------------------+
1256 | |30 Visible region of |layer1|: /////
1257 | | Visible region of |layer2|: \\\\\
1258 | +---------------------------------+
1260 | +---------------+-----------------+ |
1261 | | |\\\\\\\\\\\\|//| 420 | |
1262 | | |\\\\\\\\\\\\|//|60 | |
1263 | | |\\\\\\\\\\\\|//| | |
1264 +--|--|------------|--+ | |
1272 | +------------|-----------------|--+
1274 +---------------+-----------------+
1280 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1282 template <class Types
>
1283 class OcclusionTrackerTestOverlappingSurfaceSiblings
1284 : public OcclusionTrackerTest
<Types
> {
1286 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
1287 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1289 gfx::Transform child_transform
;
1290 child_transform
.Translate(250.0, 250.0);
1291 child_transform
.Rotate(90.0);
1292 child_transform
.Translate(-250.0, -250.0);
1294 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1295 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1296 parent
->SetMasksToBounds(true);
1297 typename
Types::LayerType
* child1
= this->CreateSurface(
1298 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(10, 10));
1299 typename
Types::LayerType
* child2
= this->CreateSurface(
1300 parent
, child_transform
, gfx::PointF(20.f
, 40.f
), gfx::Size(10, 10));
1301 typename
Types::ContentLayerType
* layer1
=
1302 this->CreateDrawingLayer(child1
,
1303 this->identity_matrix
,
1304 gfx::PointF(-10.f
, -10.f
),
1305 gfx::Size(510, 510),
1307 typename
Types::ContentLayerType
* layer2
=
1308 this->CreateDrawingLayer(child2
,
1309 this->identity_matrix
,
1310 gfx::PointF(-10.f
, -10.f
),
1311 gfx::Size(510, 510),
1313 this->CalcDrawEtc(parent
);
1315 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1316 gfx::Rect(0, 0, 1000, 1000));
1318 this->VisitLayer(layer2
, &occlusion
);
1319 this->EnterContributingSurface(child2
, &occlusion
);
1321 EXPECT_EQ(gfx::Rect().ToString(),
1322 occlusion
.occlusion_from_outside_target().ToString());
1323 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1324 occlusion
.occlusion_from_inside_target().ToString());
1326 // There is nothing above child2's surface in the z-order.
1327 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1328 occlusion
.UnoccludedSurfaceContentRect(
1329 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1331 this->LeaveContributingSurface(child2
, &occlusion
);
1332 this->VisitLayer(layer1
, &occlusion
);
1333 this->EnterContributingSurface(child1
, &occlusion
);
1335 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1336 occlusion
.occlusion_from_outside_target().ToString());
1337 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1338 occlusion
.occlusion_from_inside_target().ToString());
1340 // child2's contents will occlude child1 below it.
1341 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1342 occlusion
.UnoccludedSurfaceContentRect(
1343 child1
, false, gfx::Rect(-10, 430, 80, 70)));
1345 this->LeaveContributingSurface(child1
, &occlusion
);
1346 this->EnterLayer(parent
, &occlusion
);
1348 EXPECT_EQ(gfx::Rect().ToString(),
1349 occlusion
.occlusion_from_outside_target().ToString());
1350 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1352 occlusion
.occlusion_from_inside_target().ToString());
1354 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1356 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1357 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1358 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1360 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1361 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1362 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1364 /* Justification for the above occlusion:
1366 +---------------------+
1368 | 30+ ---------------------------------+
1369 100 | 30| | layer2 |
1370 |20+----------------------------------+ |
1374 +--|-|----------------+ | |
1382 | +--------------------------------|-+
1384 +----------------------------------+
1390 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1392 template <class Types
>
1393 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1394 : public OcclusionTrackerTest
<Types
> {
1396 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1398 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1400 gfx::Transform child1_transform
;
1401 child1_transform
.Translate(250.0, 250.0);
1402 child1_transform
.Rotate(-90.0);
1403 child1_transform
.Translate(-250.0, -250.0);
1405 gfx::Transform child2_transform
;
1406 child2_transform
.Translate(250.0, 250.0);
1407 child2_transform
.Rotate(90.0);
1408 child2_transform
.Translate(-250.0, -250.0);
1410 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1411 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1412 parent
->SetMasksToBounds(true);
1413 typename
Types::LayerType
* child1
= this->CreateSurface(
1414 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1415 typename
Types::LayerType
* child2
=
1416 this->CreateDrawingSurface(parent
,
1418 gfx::PointF(20.f
, 40.f
),
1421 typename
Types::ContentLayerType
* layer1
=
1422 this->CreateDrawingLayer(child1
,
1423 this->identity_matrix
,
1424 gfx::PointF(-10.f
, -20.f
),
1425 gfx::Size(510, 510),
1427 typename
Types::ContentLayerType
* layer2
=
1428 this->CreateDrawingLayer(child2
,
1429 this->identity_matrix
,
1430 gfx::PointF(-10.f
, -10.f
),
1431 gfx::Size(510, 510),
1433 this->CalcDrawEtc(parent
);
1435 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1436 gfx::Rect(0, 0, 1000, 1000));
1438 this->VisitLayer(layer2
, &occlusion
);
1439 this->EnterLayer(child2
, &occlusion
);
1441 EXPECT_EQ(gfx::Rect().ToString(),
1442 occlusion
.occlusion_from_outside_target().ToString());
1443 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1444 occlusion
.occlusion_from_inside_target().ToString());
1446 this->LeaveLayer(child2
, &occlusion
);
1447 this->EnterContributingSurface(child2
, &occlusion
);
1449 // There is nothing above child2's surface in the z-order.
1450 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1451 occlusion
.UnoccludedSurfaceContentRect(
1452 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1454 this->LeaveContributingSurface(child2
, &occlusion
);
1455 this->VisitLayer(layer1
, &occlusion
);
1456 this->EnterContributingSurface(child1
, &occlusion
);
1458 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1459 occlusion
.occlusion_from_outside_target().ToString());
1460 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1461 occlusion
.occlusion_from_inside_target().ToString());
1463 // child2's contents will occlude child1 below it.
1464 EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(),
1465 occlusion
.occlusion_on_contributing_surface_from_inside_target()
1467 EXPECT_EQ(gfx::Rect().ToString(),
1468 occlusion
.occlusion_on_contributing_surface_from_outside_target()
1471 this->LeaveContributingSurface(child1
, &occlusion
);
1472 this->EnterLayer(parent
, &occlusion
);
1474 EXPECT_EQ(gfx::Rect().ToString(),
1475 occlusion
.occlusion_from_outside_target().ToString());
1476 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1477 occlusion
.occlusion_from_inside_target().ToString());
1479 /* Justification for the above occlusion:
1481 +---------------------+
1483 10+----------------------------------+
1484 100 || 30 | layer2 |
1485 |20+----------------------------------+
1489 +|-|------------------+ | |
1497 +----------------------------------+ |
1499 +----------------------------------+
1505 ALL_OCCLUSIONTRACKER_TEST(
1506 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1508 template <class Types
>
1509 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1511 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1512 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1514 gfx::Transform layer_transform
;
1515 layer_transform
.Translate(250.0, 250.0);
1516 layer_transform
.Rotate(90.0);
1517 layer_transform
.Translate(-250.0, -250.0);
1519 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1520 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1521 parent
->SetMasksToBounds(true);
1522 typename
Types::ContentLayerType
* blur_layer
=
1523 this->CreateDrawingLayer(parent
,
1525 gfx::PointF(30.f
, 30.f
),
1526 gfx::Size(500, 500),
1528 typename
Types::ContentLayerType
* opaque_layer
=
1529 this->CreateDrawingLayer(parent
,
1531 gfx::PointF(30.f
, 30.f
),
1532 gfx::Size(500, 500),
1534 typename
Types::ContentLayerType
* opacity_layer
=
1535 this->CreateDrawingLayer(parent
,
1537 gfx::PointF(30.f
, 30.f
),
1538 gfx::Size(500, 500),
1541 FilterOperations filters
;
1542 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1543 blur_layer
->SetFilters(filters
);
1546 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1547 opaque_layer
->SetFilters(filters
);
1550 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1551 opacity_layer
->SetFilters(filters
);
1553 this->CalcDrawEtc(parent
);
1555 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1556 gfx::Rect(0, 0, 1000, 1000));
1558 // Opacity layer won't contribute to occlusion.
1559 this->VisitLayer(opacity_layer
, &occlusion
);
1560 this->EnterContributingSurface(opacity_layer
, &occlusion
);
1562 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1563 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1565 // And has nothing to contribute to its parent surface.
1566 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1567 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1568 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1570 // Opaque layer will contribute to occlusion.
1571 this->VisitLayer(opaque_layer
, &occlusion
);
1572 this->EnterContributingSurface(opaque_layer
, &occlusion
);
1574 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1575 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1576 occlusion
.occlusion_from_inside_target().ToString());
1578 // And it gets translated to the parent surface.
1579 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1580 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1581 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1582 occlusion
.occlusion_from_inside_target().ToString());
1584 // The blur layer needs to throw away any occlusion from outside its
1586 this->EnterLayer(blur_layer
, &occlusion
);
1587 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1588 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1590 // And it won't contribute to occlusion.
1591 this->LeaveLayer(blur_layer
, &occlusion
);
1592 this->EnterContributingSurface(blur_layer
, &occlusion
);
1593 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1594 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1596 // But the opaque layer's occlusion is preserved on the parent.
1597 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1598 this->EnterLayer(parent
, &occlusion
);
1599 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1600 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1601 occlusion
.occlusion_from_inside_target().ToString());
1605 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1607 template <class Types
>
1608 class OcclusionTrackerTestReplicaDoesOcclude
1609 : public OcclusionTrackerTest
<Types
> {
1611 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1612 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1614 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1615 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1616 typename
Types::LayerType
* surface
=
1617 this->CreateDrawingSurface(parent
,
1618 this->identity_matrix
,
1619 gfx::PointF(0.f
, 100.f
),
1622 this->CreateReplicaLayer(
1623 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1624 this->CalcDrawEtc(parent
);
1626 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1627 gfx::Rect(0, 0, 1000, 1000));
1629 this->VisitLayer(surface
, &occlusion
);
1631 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1632 occlusion
.occlusion_from_inside_target().ToString());
1634 this->VisitContributingSurface(surface
, &occlusion
);
1635 this->EnterLayer(parent
, &occlusion
);
1637 // The surface and replica should both be occluding the parent.
1639 UnionRegions(gfx::Rect(0, 100, 50, 50),
1640 gfx::Rect(50, 150, 50, 50)).ToString(),
1641 occlusion
.occlusion_from_inside_target().ToString());
1645 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1647 template <class Types
>
1648 class OcclusionTrackerTestReplicaWithClipping
1649 : public OcclusionTrackerTest
<Types
> {
1651 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1652 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1654 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1655 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1656 parent
->SetMasksToBounds(true);
1657 typename
Types::LayerType
* surface
=
1658 this->CreateDrawingSurface(parent
,
1659 this->identity_matrix
,
1660 gfx::PointF(0.f
, 100.f
),
1663 this->CreateReplicaLayer(
1664 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1665 this->CalcDrawEtc(parent
);
1667 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1668 gfx::Rect(0, 0, 1000, 1000));
1670 this->VisitLayer(surface
, &occlusion
);
1672 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1673 occlusion
.occlusion_from_inside_target().ToString());
1675 this->VisitContributingSurface(surface
, &occlusion
);
1676 this->EnterLayer(parent
, &occlusion
);
1678 // The surface and replica should both be occluding the parent.
1680 UnionRegions(gfx::Rect(0, 100, 50, 50),
1681 gfx::Rect(50, 150, 50, 20)).ToString(),
1682 occlusion
.occlusion_from_inside_target().ToString());
1686 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1688 template <class Types
>
1689 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1691 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1692 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1694 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1695 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1696 typename
Types::LayerType
* surface
=
1697 this->CreateDrawingSurface(parent
,
1698 this->identity_matrix
,
1699 gfx::PointF(0.f
, 100.f
),
1702 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1703 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1704 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1705 this->CalcDrawEtc(parent
);
1707 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1708 gfx::Rect(0, 0, 1000, 1000));
1710 this->VisitLayer(surface
, &occlusion
);
1712 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1713 occlusion
.occlusion_from_inside_target().ToString());
1715 this->VisitContributingSurface(surface
, &occlusion
);
1716 this->EnterLayer(parent
, &occlusion
);
1718 // The replica should not be occluding the parent, since it has a mask
1720 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1721 occlusion
.occlusion_from_inside_target().ToString());
1725 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1727 template <class Types
>
1728 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1729 : public OcclusionTrackerTest
<Types
> {
1731 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1732 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1734 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1735 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1736 typename
Types::ContentLayerType
* layer
=
1737 this->CreateDrawingSurface(parent
,
1738 this->identity_matrix
,
1740 gfx::Size(200, 200),
1742 this->CalcDrawEtc(parent
);
1744 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1745 gfx::Rect(0, 0, 1000, 1000));
1746 this->EnterLayer(layer
, &occlusion
);
1748 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1749 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1750 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1751 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1753 this->LeaveLayer(layer
, &occlusion
);
1754 this->VisitContributingSurface(layer
, &occlusion
);
1755 this->EnterLayer(parent
, &occlusion
);
1757 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1761 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1763 template <class Types
>
1764 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1765 : public OcclusionTrackerTest
<Types
> {
1767 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1768 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1770 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1771 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1772 typename
Types::ContentLayerType
* layer
=
1773 this->CreateDrawingLayer(parent
,
1774 this->identity_matrix
,
1775 gfx::PointF(100.f
, 100.f
),
1776 gfx::Size(200, 200),
1778 this->CalcDrawEtc(parent
);
1780 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1781 gfx::Rect(0, 0, 1000, 1000));
1782 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1784 this->ResetLayerIterator();
1785 this->VisitLayer(layer
, &occlusion
);
1786 this->EnterLayer(parent
, &occlusion
);
1788 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1789 occlusion
.occlusion_from_inside_target().ToString());
1792 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1794 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1796 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1799 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1800 gfx::Rect(0, 0, 1000, 1000));
1801 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1803 this->ResetLayerIterator();
1804 this->VisitLayer(layer
, &occlusion
);
1805 this->EnterLayer(parent
, &occlusion
);
1807 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1808 occlusion
.occlusion_from_inside_target().ToString());
1811 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1813 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1815 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1818 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1819 gfx::Rect(0, 0, 1000, 1000));
1820 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1822 this->ResetLayerIterator();
1823 this->VisitLayer(layer
, &occlusion
);
1824 this->EnterLayer(parent
, &occlusion
);
1826 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1827 occlusion
.occlusion_from_inside_target().ToString());
1830 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1832 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1834 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1839 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1841 template <class Types
>
1842 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
1844 explicit OcclusionTrackerTest3dTransform(bool opaque_layers
)
1845 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1847 gfx::Transform transform
;
1848 transform
.RotateAboutYAxis(30.0);
1850 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1851 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1852 typename
Types::LayerType
* container
= this->CreateLayer(
1853 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1854 typename
Types::ContentLayerType
* layer
=
1855 this->CreateDrawingLayer(container
,
1857 gfx::PointF(100.f
, 100.f
),
1858 gfx::Size(200, 200),
1860 this->CalcDrawEtc(parent
);
1862 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1863 gfx::Rect(0, 0, 1000, 1000));
1864 this->EnterLayer(layer
, &occlusion
);
1866 // The layer is rotated in 3d but without preserving 3d, so it only gets
1869 gfx::Rect(0, 0, 200, 200),
1870 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1874 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
1876 template <class Types
>
1877 class OcclusionTrackerTestUnsorted3dLayers
1878 : public OcclusionTrackerTest
<Types
> {
1880 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
1881 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1883 // Currently, The main thread layer iterator does not iterate over 3d items
1884 // in sorted order, because layer sorting is not performed on the main
1885 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1886 // layer occludes other layers that have not yet been iterated over. For
1887 // now, the expected behavior is that a 3d layer simply does not add any
1888 // occlusion to the occlusion tracker.
1890 gfx::Transform translation_to_front
;
1891 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
1892 gfx::Transform translation_to_back
;
1893 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
1895 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1896 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1897 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
1898 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
1899 typename
Types::ContentLayerType
* child2
=
1900 this->CreateDrawingLayer(parent
,
1901 translation_to_front
,
1902 gfx::PointF(50.f
, 50.f
),
1903 gfx::Size(100, 100),
1905 parent
->SetShouldFlattenTransform(false);
1906 parent
->Set3dSortingContextId(1);
1907 child1
->Set3dSortingContextId(1);
1908 child2
->Set3dSortingContextId(1);
1910 this->CalcDrawEtc(parent
);
1912 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1913 gfx::Rect(0, 0, 1000, 1000));
1914 this->VisitLayer(child2
, &occlusion
);
1915 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1916 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1918 this->VisitLayer(child1
, &occlusion
);
1919 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1920 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1924 // This test will have different layer ordering on the impl thread; the test
1925 // will only work on the main thread.
1926 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1928 template <class Types
>
1929 class OcclusionTrackerTestPerspectiveTransform
1930 : public OcclusionTrackerTest
<Types
> {
1932 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers
)
1933 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1935 gfx::Transform transform
;
1936 transform
.Translate(150.0, 150.0);
1937 transform
.ApplyPerspectiveDepth(400.0);
1938 transform
.RotateAboutXAxis(-30.0);
1939 transform
.Translate(-150.0, -150.0);
1941 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1942 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1943 typename
Types::LayerType
* container
= this->CreateLayer(
1944 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1945 typename
Types::ContentLayerType
* layer
=
1946 this->CreateDrawingLayer(container
,
1948 gfx::PointF(100.f
, 100.f
),
1949 gfx::Size(200, 200),
1951 container
->SetShouldFlattenTransform(false);
1952 container
->Set3dSortingContextId(1);
1953 layer
->Set3dSortingContextId(1);
1954 layer
->SetShouldFlattenTransform(false);
1956 this->CalcDrawEtc(parent
);
1958 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1959 gfx::Rect(0, 0, 1000, 1000));
1960 this->EnterLayer(layer
, &occlusion
);
1963 gfx::Rect(0, 0, 200, 200),
1964 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1968 // This test requires accumulating occlusion of 3d layers, which are skipped by
1969 // the occlusion tracker on the main thread. So this test should run on the impl
1971 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
1972 template <class Types
>
1973 class OcclusionTrackerTestPerspectiveTransformBehindCamera
1974 : public OcclusionTrackerTest
<Types
> {
1976 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
1978 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1980 // This test is based on the platform/chromium/compositing/3d-corners.html
1982 gfx::Transform transform
;
1983 transform
.Translate(250.0, 50.0);
1984 transform
.ApplyPerspectiveDepth(10.0);
1985 transform
.Translate(-250.0, -50.0);
1986 transform
.Translate(250.0, 50.0);
1987 transform
.RotateAboutXAxis(-167.0);
1988 transform
.Translate(-250.0, -50.0);
1990 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1991 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 100));
1992 typename
Types::LayerType
* container
= this->CreateLayer(
1993 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
1994 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1995 container
, transform
, gfx::PointF(), gfx::Size(500, 500), true);
1996 container
->SetShouldFlattenTransform(false);
1997 container
->Set3dSortingContextId(1);
1998 layer
->SetShouldFlattenTransform(false);
1999 layer
->Set3dSortingContextId(1);
2000 this->CalcDrawEtc(parent
);
2002 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2003 gfx::Rect(0, 0, 1000, 1000));
2004 this->EnterLayer(layer
, &occlusion
);
2006 // The bottom 11 pixel rows of this layer remain visible inside the
2007 // container, after translation to the target surface. When translated back,
2008 // this will include many more pixels but must include at least the bottom
2010 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2011 layer
, gfx::Rect(0, 26, 500, 474)).
2012 Contains(gfx::Rect(0, 489, 500, 11)));
2016 // This test requires accumulating occlusion of 3d layers, which are skipped by
2017 // the occlusion tracker on the main thread. So this test should run on the impl
2019 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
2021 template <class Types
>
2022 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2023 : public OcclusionTrackerTest
<Types
> {
2025 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2027 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2029 gfx::Transform transform
;
2030 transform
.Translate(50.0, 50.0);
2031 transform
.ApplyPerspectiveDepth(100.0);
2032 transform
.Translate3d(0.0, 0.0, 110.0);
2033 transform
.Translate(-50.0, -50.0);
2035 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2036 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2037 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2038 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2039 parent
->SetShouldFlattenTransform(false);
2040 parent
->Set3dSortingContextId(1);
2041 layer
->SetShouldFlattenTransform(false);
2042 layer
->Set3dSortingContextId(1);
2043 this->CalcDrawEtc(parent
);
2045 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2046 gfx::Rect(0, 0, 1000, 1000));
2048 // The |layer| is entirely behind the camera and should not occlude.
2049 this->VisitLayer(layer
, &occlusion
);
2050 this->EnterLayer(parent
, &occlusion
);
2051 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2052 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2056 // This test requires accumulating occlusion of 3d layers, which are skipped by
2057 // the occlusion tracker on the main thread. So this test should run on the impl
2059 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2061 template <class Types
>
2062 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2063 : public OcclusionTrackerTest
<Types
> {
2065 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2067 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2069 gfx::Transform transform
;
2070 transform
.Translate(50.0, 50.0);
2071 transform
.ApplyPerspectiveDepth(100.0);
2072 transform
.Translate3d(0.0, 0.0, 99.0);
2073 transform
.Translate(-50.0, -50.0);
2075 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2076 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2077 parent
->SetMasksToBounds(true);
2078 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2079 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2080 parent
->SetShouldFlattenTransform(false);
2081 parent
->Set3dSortingContextId(1);
2082 layer
->SetShouldFlattenTransform(false);
2083 layer
->Set3dSortingContextId(1);
2084 this->CalcDrawEtc(parent
);
2086 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2087 gfx::Rect(0, 0, 1000, 1000));
2089 // This is very close to the camera, so pixels in its visible_content_rect()
2090 // will actually go outside of the layer's clip rect. Ensure that those
2091 // pixels don't occlude things outside the clip rect.
2092 this->VisitLayer(layer
, &occlusion
);
2093 this->EnterLayer(parent
, &occlusion
);
2094 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2095 occlusion
.occlusion_from_inside_target().ToString());
2096 EXPECT_EQ(gfx::Rect().ToString(),
2097 occlusion
.occlusion_from_outside_target().ToString());
2101 // This test requires accumulating occlusion of 3d layers, which are skipped by
2102 // the occlusion tracker on the main thread. So this test should run on the impl
2104 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2106 template <class Types
>
2107 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2108 : public OcclusionTrackerTest
<Types
> {
2110 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
2111 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2116 // | +--surface_child
2117 // | +--surface_child2
2121 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2122 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2123 typename
Types::ContentLayerType
* layer
=
2124 this->CreateDrawingLayer(parent
,
2125 this->identity_matrix
,
2127 gfx::Size(300, 300),
2129 typename
Types::ContentLayerType
* surface
=
2130 this->CreateDrawingSurface(parent
,
2131 this->identity_matrix
,
2133 gfx::Size(300, 300),
2135 typename
Types::ContentLayerType
* surface_child
=
2136 this->CreateDrawingLayer(surface
,
2137 this->identity_matrix
,
2139 gfx::Size(200, 300),
2141 typename
Types::ContentLayerType
* surface_child2
=
2142 this->CreateDrawingLayer(surface
,
2143 this->identity_matrix
,
2145 gfx::Size(100, 300),
2147 typename
Types::ContentLayerType
* parent2
=
2148 this->CreateDrawingLayer(parent
,
2149 this->identity_matrix
,
2151 gfx::Size(300, 300),
2153 typename
Types::ContentLayerType
* topmost
=
2154 this->CreateDrawingLayer(parent
,
2155 this->identity_matrix
,
2156 gfx::PointF(250.f
, 0.f
),
2160 AddOpacityTransitionToController(
2161 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2162 AddOpacityTransitionToController(
2163 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2164 this->CalcDrawEtc(parent
);
2166 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2167 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2168 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2170 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2171 gfx::Rect(0, 0, 1000, 1000));
2173 this->VisitLayer(topmost
, &occlusion
);
2174 this->EnterLayer(parent2
, &occlusion
);
2175 // This occlusion will affect all surfaces.
2176 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2177 occlusion
.occlusion_from_inside_target().ToString());
2178 EXPECT_EQ(gfx::Rect().ToString(),
2179 occlusion
.occlusion_from_outside_target().ToString());
2180 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2181 occlusion
.UnoccludedLayerContentRect(
2182 parent2
, gfx::Rect(0, 0, 300, 300)).ToString());
2183 this->LeaveLayer(parent2
, &occlusion
);
2185 this->VisitLayer(surface_child2
, &occlusion
);
2186 this->EnterLayer(surface_child
, &occlusion
);
2187 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2188 occlusion
.occlusion_from_inside_target().ToString());
2189 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2190 occlusion
.occlusion_from_outside_target().ToString());
2191 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2192 occlusion
.UnoccludedLayerContentRect(
2193 surface_child
, gfx::Rect(0, 0, 200, 300)));
2194 this->LeaveLayer(surface_child
, &occlusion
);
2195 this->EnterLayer(surface
, &occlusion
);
2196 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2197 occlusion
.occlusion_from_inside_target().ToString());
2198 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2199 occlusion
.occlusion_from_outside_target().ToString());
2200 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2201 occlusion
.UnoccludedLayerContentRect(
2202 surface
, gfx::Rect(0, 0, 300, 300)));
2203 this->LeaveLayer(surface
, &occlusion
);
2205 this->EnterContributingSurface(surface
, &occlusion
);
2206 // Occlusion within the surface is lost when leaving the animating surface.
2207 EXPECT_EQ(gfx::Rect().ToString(),
2208 occlusion
.occlusion_from_inside_target().ToString());
2209 EXPECT_EQ(gfx::Rect().ToString(),
2210 occlusion
.occlusion_from_outside_target().ToString());
2211 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2212 occlusion
.UnoccludedSurfaceContentRect(
2213 surface
, false, gfx::Rect(0, 0, 300, 300)));
2214 this->LeaveContributingSurface(surface
, &occlusion
);
2216 // Occlusion from outside the animating surface still exists.
2217 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2218 occlusion
.occlusion_from_inside_target().ToString());
2219 EXPECT_EQ(gfx::Rect().ToString(),
2220 occlusion
.occlusion_from_outside_target().ToString());
2222 this->VisitLayer(layer
, &occlusion
);
2223 this->EnterLayer(parent
, &occlusion
);
2225 // Occlusion is not added for the animating |layer|.
2226 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2227 occlusion
.UnoccludedLayerContentRect(
2228 parent
, gfx::Rect(0, 0, 300, 300)));
2232 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2234 template <class Types
>
2235 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2236 : public OcclusionTrackerTest
<Types
> {
2238 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
2239 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2241 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2242 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2243 typename
Types::ContentLayerType
* layer
=
2244 this->CreateDrawingLayer(parent
,
2245 this->identity_matrix
,
2247 gfx::Size(300, 300),
2249 typename
Types::ContentLayerType
* surface
=
2250 this->CreateDrawingSurface(parent
,
2251 this->identity_matrix
,
2253 gfx::Size(300, 300),
2255 typename
Types::ContentLayerType
* surface_child
=
2256 this->CreateDrawingLayer(surface
,
2257 this->identity_matrix
,
2259 gfx::Size(200, 300),
2261 typename
Types::ContentLayerType
* surface_child2
=
2262 this->CreateDrawingLayer(surface
,
2263 this->identity_matrix
,
2265 gfx::Size(100, 300),
2267 typename
Types::ContentLayerType
* parent2
=
2268 this->CreateDrawingLayer(parent
,
2269 this->identity_matrix
,
2271 gfx::Size(300, 300),
2273 typename
Types::ContentLayerType
* topmost
=
2274 this->CreateDrawingLayer(parent
,
2275 this->identity_matrix
,
2276 gfx::PointF(250.f
, 0.f
),
2280 AddOpacityTransitionToController(
2281 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2282 AddOpacityTransitionToController(
2283 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2284 this->CalcDrawEtc(parent
);
2286 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2287 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2288 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2290 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2291 gfx::Rect(0, 0, 1000, 1000));
2293 this->VisitLayer(topmost
, &occlusion
);
2294 this->EnterLayer(parent2
, &occlusion
);
2295 // This occlusion will affect all surfaces.
2296 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2297 occlusion
.occlusion_from_inside_target().ToString());
2298 EXPECT_EQ(gfx::Rect().ToString(),
2299 occlusion
.occlusion_from_outside_target().ToString());
2300 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2301 occlusion
.UnoccludedLayerContentRect(
2302 parent
, gfx::Rect(0, 0, 300, 300)));
2303 this->LeaveLayer(parent2
, &occlusion
);
2305 this->VisitLayer(surface_child2
, &occlusion
);
2306 this->EnterLayer(surface_child
, &occlusion
);
2307 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2308 occlusion
.occlusion_from_inside_target().ToString());
2309 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2310 occlusion
.occlusion_from_outside_target().ToString());
2311 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2312 occlusion
.UnoccludedLayerContentRect(
2313 surface_child
, gfx::Rect(0, 0, 200, 300)));
2314 this->LeaveLayer(surface_child
, &occlusion
);
2315 this->EnterLayer(surface
, &occlusion
);
2316 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2317 occlusion
.occlusion_from_inside_target().ToString());
2318 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2319 occlusion
.occlusion_from_outside_target().ToString());
2320 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2321 occlusion
.UnoccludedLayerContentRect(
2322 surface
, gfx::Rect(0, 0, 300, 300)));
2323 this->LeaveLayer(surface
, &occlusion
);
2325 this->EnterContributingSurface(surface
, &occlusion
);
2326 // Occlusion within the surface is lost when leaving the animating surface.
2327 EXPECT_EQ(gfx::Rect().ToString(),
2328 occlusion
.occlusion_from_inside_target().ToString());
2329 EXPECT_EQ(gfx::Rect().ToString(),
2330 occlusion
.occlusion_from_outside_target().ToString());
2331 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2332 occlusion
.UnoccludedSurfaceContentRect(
2333 surface
, false, gfx::Rect(0, 0, 300, 300)));
2334 this->LeaveContributingSurface(surface
, &occlusion
);
2336 // Occlusion from outside the animating surface still exists.
2337 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2338 occlusion
.occlusion_from_inside_target().ToString());
2339 EXPECT_EQ(gfx::Rect().ToString(),
2340 occlusion
.occlusion_from_outside_target().ToString());
2342 this->VisitLayer(layer
, &occlusion
);
2343 this->EnterLayer(parent
, &occlusion
);
2345 // Occlusion is not added for the animating |layer|.
2346 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2347 occlusion
.UnoccludedLayerContentRect(
2348 parent
, gfx::Rect(0, 0, 300, 300)));
2352 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2354 template <class Types
>
2355 class OcclusionTrackerTestAnimationTranslateOnMainThread
2356 : public OcclusionTrackerTest
<Types
> {
2358 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2360 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2362 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2363 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2364 typename
Types::ContentLayerType
* layer
=
2365 this->CreateDrawingLayer(parent
,
2366 this->identity_matrix
,
2368 gfx::Size(300, 300),
2370 typename
Types::ContentLayerType
* surface
=
2371 this->CreateDrawingSurface(parent
,
2372 this->identity_matrix
,
2374 gfx::Size(300, 300),
2376 typename
Types::ContentLayerType
* surface_child
=
2377 this->CreateDrawingLayer(surface
,
2378 this->identity_matrix
,
2380 gfx::Size(200, 300),
2382 typename
Types::ContentLayerType
* surface_child2
=
2383 this->CreateDrawingLayer(surface
,
2384 this->identity_matrix
,
2386 gfx::Size(100, 300),
2388 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
2389 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
2391 AddAnimatedTransformToController(
2392 layer
->layer_animation_controller(), 10.0, 30, 0);
2393 AddAnimatedTransformToController(
2394 surface
->layer_animation_controller(), 10.0, 30, 0);
2395 AddAnimatedTransformToController(
2396 surface_child
->layer_animation_controller(), 10.0, 30, 0);
2397 this->CalcDrawEtc(parent
);
2399 EXPECT_TRUE(layer
->draw_transform_is_animating());
2400 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
2402 surface
->render_surface()->target_surface_transforms_are_animating());
2404 surface
->render_surface()->screen_space_transforms_are_animating());
2405 // The surface owning layer doesn't animate against its own surface.
2406 EXPECT_FALSE(surface
->draw_transform_is_animating());
2407 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
2408 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
2409 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
2411 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2412 gfx::Rect(0, 0, 1000, 1000));
2414 this->VisitLayer(surface2
, &occlusion
);
2415 this->EnterContributingSurface(surface2
, &occlusion
);
2417 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2418 occlusion
.occlusion_from_inside_target().ToString());
2420 this->LeaveContributingSurface(surface2
, &occlusion
);
2421 this->EnterLayer(surface_child2
, &occlusion
);
2422 // surface_child2 is moving in screen space but not relative to its target,
2423 // so occlusion should happen in its target space only. It also means that
2424 // things occluding from outside the target (e.g. surface2) cannot occlude
2426 EXPECT_EQ(gfx::Rect().ToString(),
2427 occlusion
.occlusion_from_outside_target().ToString());
2428 EXPECT_EQ(gfx::Rect().ToString(),
2429 occlusion
.occlusion_from_inside_target().ToString());
2431 this->LeaveLayer(surface_child2
, &occlusion
);
2432 this->EnterLayer(surface_child
, &occlusion
);
2433 // surface_child2 added to the occlusion since it is not moving relative
2435 EXPECT_EQ(gfx::Rect().ToString(),
2436 occlusion
.occlusion_from_outside_target().ToString());
2437 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2438 occlusion
.occlusion_from_inside_target().ToString());
2440 this->LeaveLayer(surface_child
, &occlusion
);
2441 // surface_child is moving relative to its target, so it does not add
2443 EXPECT_EQ(gfx::Rect().ToString(),
2444 occlusion
.occlusion_from_outside_target().ToString());
2445 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2446 occlusion
.occlusion_from_inside_target().ToString());
2448 this->EnterLayer(surface
, &occlusion
);
2449 EXPECT_EQ(gfx::Rect().ToString(),
2450 occlusion
.occlusion_from_outside_target().ToString());
2451 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2452 occlusion
.occlusion_from_inside_target().ToString());
2454 this->LeaveLayer(surface
, &occlusion
);
2455 // The surface's owning layer is moving in screen space but not relative to
2456 // its target, so it adds to the occlusion.
2457 EXPECT_EQ(gfx::Rect().ToString(),
2458 occlusion
.occlusion_from_outside_target().ToString());
2459 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2460 occlusion
.occlusion_from_inside_target().ToString());
2462 this->EnterContributingSurface(surface
, &occlusion
);
2463 this->LeaveContributingSurface(surface
, &occlusion
);
2464 // The |surface| is moving in the screen and in its target, so all occlusion
2465 // within the surface is lost when leaving it. Only the |surface2| occlusion
2467 EXPECT_EQ(gfx::Rect().ToString(),
2468 occlusion
.occlusion_from_outside_target().ToString());
2469 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2470 occlusion
.occlusion_from_inside_target().ToString());
2472 this->VisitLayer(layer
, &occlusion
);
2473 // The |layer| is animating in the screen and in its target, so no occlusion
2475 EXPECT_EQ(gfx::Rect().ToString(),
2476 occlusion
.occlusion_from_outside_target().ToString());
2477 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2478 occlusion
.occlusion_from_inside_target().ToString());
2482 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
2484 template <class Types
>
2485 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2486 : public OcclusionTrackerTest
<Types
> {
2488 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2490 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2492 gfx::Transform surface_transform
;
2493 surface_transform
.Translate(300.0, 300.0);
2494 surface_transform
.Scale(2.0, 2.0);
2495 surface_transform
.Translate(-150.0, -150.0);
2497 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2498 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2499 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
2500 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
2501 typename
Types::ContentLayerType
* surface2
=
2502 this->CreateDrawingSurface(parent
,
2503 this->identity_matrix
,
2504 gfx::PointF(50.f
, 50.f
),
2505 gfx::Size(300, 300),
2507 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2508 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2509 this->CalcDrawEtc(parent
);
2511 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2512 gfx::Rect(0, 0, 1000, 1000));
2514 this->VisitLayer(surface2
, &occlusion
);
2515 this->VisitContributingSurface(surface2
, &occlusion
);
2517 EXPECT_EQ(gfx::Rect().ToString(),
2518 occlusion
.occlusion_from_outside_target().ToString());
2519 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2520 occlusion
.occlusion_from_inside_target().ToString());
2522 // Clear any stored occlusion.
2523 occlusion
.set_occlusion_from_outside_target(Region());
2524 occlusion
.set_occlusion_from_inside_target(Region());
2526 this->VisitLayer(surface
, &occlusion
);
2527 this->VisitContributingSurface(surface
, &occlusion
);
2529 EXPECT_EQ(gfx::Rect().ToString(),
2530 occlusion
.occlusion_from_outside_target().ToString());
2531 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2532 occlusion
.occlusion_from_inside_target().ToString());
2536 MAIN_AND_IMPL_THREAD_TEST(
2537 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
2539 template <class Types
>
2540 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2541 : public OcclusionTrackerTest
<Types
> {
2543 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2545 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2547 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2548 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2549 parent
->SetMasksToBounds(true);
2550 typename
Types::ContentLayerType
* surface
=
2551 this->CreateDrawingSurface(parent
,
2552 this->identity_matrix
,
2554 gfx::Size(500, 300),
2556 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2557 this->CalcDrawEtc(parent
);
2559 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2560 gfx::Rect(0, 0, 1000, 1000));
2562 this->VisitLayer(surface
, &occlusion
);
2563 this->VisitContributingSurface(surface
, &occlusion
);
2565 EXPECT_EQ(gfx::Rect().ToString(),
2566 occlusion
.occlusion_from_outside_target().ToString());
2567 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2568 occlusion
.occlusion_from_inside_target().ToString());
2572 MAIN_AND_IMPL_THREAD_TEST(
2573 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2575 template <class Types
>
2576 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
2578 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers
)
2579 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2581 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2582 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2583 typename
Types::LayerType
* surface
=
2584 this->CreateDrawingSurface(parent
,
2585 this->identity_matrix
,
2587 gfx::Size(100, 100),
2589 this->CreateReplicaLayer(surface
,
2590 this->identity_matrix
,
2591 gfx::PointF(0.f
, 100.f
),
2592 gfx::Size(100, 100));
2593 typename
Types::LayerType
* topmost
=
2594 this->CreateDrawingLayer(parent
,
2595 this->identity_matrix
,
2596 gfx::PointF(0.f
, 100.f
),
2597 gfx::Size(100, 100),
2599 this->CalcDrawEtc(parent
);
2601 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2602 gfx::Rect(0, 0, 1000, 1000));
2604 // |topmost| occludes the replica, but not the surface itself.
2605 this->VisitLayer(topmost
, &occlusion
);
2607 EXPECT_EQ(gfx::Rect().ToString(),
2608 occlusion
.occlusion_from_outside_target().ToString());
2609 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2610 occlusion
.occlusion_from_inside_target().ToString());
2612 this->VisitLayer(surface
, &occlusion
);
2614 // Render target with replica ignores occlusion from outside.
2615 EXPECT_EQ(gfx::Rect().ToString(),
2616 occlusion
.occlusion_from_outside_target().ToString());
2617 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2618 occlusion
.occlusion_from_inside_target().ToString());
2620 this->EnterContributingSurface(surface
, &occlusion
);
2622 // Surface is not occluded so it shouldn't think it is.
2623 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2624 occlusion
.UnoccludedSurfaceContentRect(
2625 surface
, false, gfx::Rect(0, 0, 100, 100)));
2629 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
2631 template <class Types
>
2632 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2633 : public OcclusionTrackerTest
<Types
> {
2635 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
2636 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2638 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2639 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2640 typename
Types::LayerType
* surface
=
2641 this->CreateDrawingSurface(parent
,
2642 this->identity_matrix
,
2644 gfx::Size(100, 100),
2646 this->CreateReplicaLayer(surface
,
2647 this->identity_matrix
,
2648 gfx::PointF(0.f
, 100.f
),
2649 gfx::Size(100, 100));
2650 typename
Types::LayerType
* topmost
=
2651 this->CreateDrawingLayer(parent
,
2652 this->identity_matrix
,
2654 gfx::Size(100, 110),
2656 this->CalcDrawEtc(parent
);
2658 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2659 gfx::Rect(0, 0, 1000, 1000));
2661 // |topmost| occludes the surface, but not the entire surface's replica.
2662 this->VisitLayer(topmost
, &occlusion
);
2664 EXPECT_EQ(gfx::Rect().ToString(),
2665 occlusion
.occlusion_from_outside_target().ToString());
2666 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2667 occlusion
.occlusion_from_inside_target().ToString());
2669 this->VisitLayer(surface
, &occlusion
);
2671 // Render target with replica ignores occlusion from outside.
2672 EXPECT_EQ(gfx::Rect().ToString(),
2673 occlusion
.occlusion_from_outside_target().ToString());
2674 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2675 occlusion
.occlusion_from_inside_target().ToString());
2677 this->EnterContributingSurface(surface
, &occlusion
);
2679 // Surface is occluded, but only the top 10px of the replica.
2680 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2681 occlusion
.UnoccludedSurfaceContentRect(
2682 surface
, false, gfx::Rect(0, 0, 100, 100)));
2683 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2684 occlusion
.UnoccludedSurfaceContentRect(
2685 surface
, true, gfx::Rect(0, 0, 100, 100)));
2689 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2691 template <class Types
>
2692 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
2693 : public OcclusionTrackerTest
<Types
> {
2695 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
2697 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2699 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2700 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2701 typename
Types::LayerType
* surface
=
2702 this->CreateDrawingSurface(parent
,
2703 this->identity_matrix
,
2705 gfx::Size(100, 100),
2707 this->CreateReplicaLayer(surface
,
2708 this->identity_matrix
,
2709 gfx::PointF(0.f
, 100.f
),
2710 gfx::Size(100, 100));
2711 typename
Types::LayerType
* over_surface
= this->CreateDrawingLayer(
2712 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 100), true);
2713 typename
Types::LayerType
* over_replica
=
2714 this->CreateDrawingLayer(parent
,
2715 this->identity_matrix
,
2716 gfx::PointF(0.f
, 100.f
),
2719 this->CalcDrawEtc(parent
);
2721 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2722 gfx::Rect(0, 0, 1000, 1000));
2724 // These occlude the surface and replica differently, so we can test each
2726 this->VisitLayer(over_replica
, &occlusion
);
2727 this->VisitLayer(over_surface
, &occlusion
);
2729 EXPECT_EQ(gfx::Rect().ToString(),
2730 occlusion
.occlusion_from_outside_target().ToString());
2731 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2733 occlusion
.occlusion_from_inside_target().ToString());
2735 this->VisitLayer(surface
, &occlusion
);
2737 // Render target with replica ignores occlusion from outside.
2738 EXPECT_EQ(gfx::Rect().ToString(),
2739 occlusion
.occlusion_from_outside_target().ToString());
2740 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2741 occlusion
.occlusion_from_inside_target().ToString());
2743 this->EnterContributingSurface(surface
, &occlusion
);
2745 // Surface and replica are occluded different amounts.
2746 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
2747 occlusion
.UnoccludedSurfaceContentRect(
2748 surface
, false, gfx::Rect(0, 0, 100, 100)));
2749 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2750 occlusion
.UnoccludedSurfaceContentRect(
2751 surface
, true, gfx::Rect(0, 0, 100, 100)));
2755 ALL_OCCLUSIONTRACKER_TEST(
2756 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
2758 template <class Types
>
2759 class OcclusionTrackerTestSurfaceChildOfSurface
2760 : public OcclusionTrackerTest
<Types
> {
2762 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
2763 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2765 // This test verifies that the surface cliprect does not end up empty and
2766 // clip away the entire unoccluded rect.
2768 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2769 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2770 typename
Types::LayerType
* surface
=
2771 this->CreateDrawingSurface(parent
,
2772 this->identity_matrix
,
2774 gfx::Size(100, 100),
2776 typename
Types::LayerType
* surface_child
=
2777 this->CreateDrawingSurface(surface
,
2778 this->identity_matrix
,
2779 gfx::PointF(0.f
, 10.f
),
2782 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
2783 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
2784 this->CalcDrawEtc(parent
);
2786 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2787 gfx::Rect(-100, -100, 1000, 1000));
2789 // |topmost| occludes everything partially so we know occlusion is happening
2791 this->VisitLayer(topmost
, &occlusion
);
2793 EXPECT_EQ(gfx::Rect().ToString(),
2794 occlusion
.occlusion_from_outside_target().ToString());
2795 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2796 occlusion
.occlusion_from_inside_target().ToString());
2798 this->VisitLayer(surface_child
, &occlusion
);
2800 // surface_child increases the occlusion in the screen by a narrow sliver.
2801 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2802 occlusion
.occlusion_from_outside_target().ToString());
2803 // In its own surface, surface_child is at 0,0 as is its occlusion.
2804 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2805 occlusion
.occlusion_from_inside_target().ToString());
2807 // The root layer always has a clip rect. So the parent of |surface| has a
2808 // clip rect. However, the owning layer for |surface| does not mask to
2809 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2810 // |surface_child| exercises different code paths as its parent does not
2811 // have a clip rect.
2813 this->EnterContributingSurface(surface_child
, &occlusion
);
2814 // The surface_child's parent does not have a clip rect as it owns a render
2815 // surface. Make sure the unoccluded rect does not get clipped away
2817 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
2818 occlusion
.UnoccludedSurfaceContentRect(
2819 surface_child
, false, gfx::Rect(0, 0, 100, 50)));
2820 this->LeaveContributingSurface(surface_child
, &occlusion
);
2822 // When the surface_child's occlusion is transformed up to its parent, make
2823 // sure it is not clipped away inappropriately also.
2824 this->EnterLayer(surface
, &occlusion
);
2825 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2826 occlusion
.occlusion_from_outside_target().ToString());
2827 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2828 occlusion
.occlusion_from_inside_target().ToString());
2829 this->LeaveLayer(surface
, &occlusion
);
2831 this->EnterContributingSurface(surface
, &occlusion
);
2832 // The surface's parent does have a clip rect as it is the root layer.
2833 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
2834 occlusion
.UnoccludedSurfaceContentRect(
2835 surface
, false, gfx::Rect(0, 0, 100, 100)));
2839 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2841 template <class Types
>
2842 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2843 : public OcclusionTrackerTest
<Types
> {
2845 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2847 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2849 gfx::Transform scale_by_half
;
2850 scale_by_half
.Scale(0.5, 0.5);
2852 // Make a 50x50 filtered surface that is completely surrounded by opaque
2853 // layers which are above it in the z-order. The surface is scaled to test
2854 // that the pixel moving is done in the target space, where the background
2855 // filter is applied.
2856 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2857 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
2858 typename
Types::LayerType
* filtered_surface
=
2859 this->CreateDrawingLayer(parent
,
2861 gfx::PointF(50.f
, 50.f
),
2862 gfx::Size(100, 100),
2864 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
2865 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 50), true);
2866 typename
Types::LayerType
* occluding_layer2
=
2867 this->CreateDrawingLayer(parent
,
2868 this->identity_matrix
,
2869 gfx::PointF(0.f
, 100.f
),
2872 typename
Types::LayerType
* occluding_layer3
=
2873 this->CreateDrawingLayer(parent
,
2874 this->identity_matrix
,
2875 gfx::PointF(0.f
, 50.f
),
2878 typename
Types::LayerType
* occluding_layer4
=
2879 this->CreateDrawingLayer(parent
,
2880 this->identity_matrix
,
2881 gfx::PointF(100.f
, 50.f
),
2885 // Filters make the layer own a surface.
2886 FilterOperations filters
;
2887 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
2888 filtered_surface
->SetBackgroundFilters(filters
);
2890 // Save the distance of influence for the blur effect.
2891 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2893 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2895 this->CalcDrawEtc(parent
);
2897 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2898 gfx::Rect(0, 0, 1000, 1000));
2900 // These layers occlude pixels directly beside the filtered_surface. Because
2901 // filtered surface blends pixels in a radius, it will need to see some of
2902 // the pixels (up to radius far) underneath the occluding layers.
2903 this->VisitLayer(occluding_layer4
, &occlusion
);
2904 this->VisitLayer(occluding_layer3
, &occlusion
);
2905 this->VisitLayer(occluding_layer2
, &occlusion
);
2906 this->VisitLayer(occluding_layer1
, &occlusion
);
2908 Region expected_occlusion
;
2909 expected_occlusion
.Union(gfx::Rect(0, 0, 200, 50));
2910 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
2911 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
2912 expected_occlusion
.Union(gfx::Rect(0, 100, 200, 50));
2914 EXPECT_EQ(expected_occlusion
.ToString(),
2915 occlusion
.occlusion_from_inside_target().ToString());
2916 EXPECT_EQ(gfx::Rect().ToString(),
2917 occlusion
.occlusion_from_outside_target().ToString());
2919 this->VisitLayer(filtered_surface
, &occlusion
);
2921 // The filtered layer does not occlude.
2922 Region expected_occlusion_outside_surface
;
2923 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 200, 50));
2924 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
2925 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
2926 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 200, 50));
2928 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
2929 occlusion
.occlusion_from_outside_target().ToString());
2930 EXPECT_EQ(gfx::Rect().ToString(),
2931 occlusion
.occlusion_from_inside_target().ToString());
2933 // The surface has a background blur, so it needs pixels that are currently
2934 // considered occluded in order to be drawn. So the pixels it needs should
2935 // be removed some the occluded area so that when we get to the parent they
2937 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2939 this->EnterLayer(parent
, &occlusion
);
2941 Region expected_blurred_occlusion
;
2942 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 200, 50 - outset_top
));
2943 expected_blurred_occlusion
.Union(gfx::Rect(
2944 0, 50 - outset_top
, 50 - outset_left
, 50 + outset_top
+ outset_bottom
));
2945 expected_blurred_occlusion
.Union(
2946 gfx::Rect(100 + outset_right
,
2949 50 + outset_top
+ outset_bottom
));
2950 expected_blurred_occlusion
.Union(
2951 gfx::Rect(0, 100 + outset_bottom
, 200, 50 - outset_bottom
));
2953 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
2954 occlusion
.occlusion_from_inside_target().ToString());
2955 EXPECT_EQ(gfx::Rect().ToString(),
2956 occlusion
.occlusion_from_outside_target().ToString());
2958 gfx::Rect outset_rect
;
2959 gfx::Rect test_rect
;
2961 // Nothing in the blur outsets for the filtered_surface is occluded.
2962 outset_rect
= gfx::Rect(50 - outset_left
,
2964 50 + outset_left
+ outset_right
,
2965 50 + outset_top
+ outset_bottom
);
2966 test_rect
= outset_rect
;
2968 outset_rect
.ToString(),
2969 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2971 // Stuff outside the blur outsets is still occluded though.
2972 test_rect
= outset_rect
;
2973 test_rect
.Inset(0, 0, -1, 0);
2975 outset_rect
.ToString(),
2976 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2977 test_rect
= outset_rect
;
2978 test_rect
.Inset(0, 0, 0, -1);
2980 outset_rect
.ToString(),
2981 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2982 test_rect
= outset_rect
;
2983 test_rect
.Inset(-1, 0, 0, 0);
2985 outset_rect
.ToString(),
2986 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2987 test_rect
= outset_rect
;
2988 test_rect
.Inset(0, -1, 0, 0);
2990 outset_rect
.ToString(),
2991 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2995 ALL_OCCLUSIONTRACKER_TEST(
2996 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
2998 template <class Types
>
2999 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3000 : public OcclusionTrackerTest
<Types
> {
3002 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3004 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3006 gfx::Transform scale_by_half
;
3007 scale_by_half
.Scale(0.5, 0.5);
3009 // Makes two surfaces that completely cover |parent|. The occlusion both
3010 // above and below the filters will be reduced by each of them.
3011 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3012 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
3013 typename
Types::LayerType
* parent
= this->CreateSurface(
3014 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
3015 parent
->SetMasksToBounds(true);
3016 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
3017 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3018 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
3019 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3020 typename
Types::LayerType
* occluding_layer_above
=
3021 this->CreateDrawingLayer(parent
,
3022 this->identity_matrix
,
3023 gfx::PointF(100.f
, 100.f
),
3027 // Filters make the layers own surfaces.
3028 FilterOperations filters
;
3029 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
3030 filtered_surface1
->SetBackgroundFilters(filters
);
3031 filtered_surface2
->SetBackgroundFilters(filters
);
3033 // Save the distance of influence for the blur effect.
3034 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3036 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3038 this->CalcDrawEtc(root
);
3040 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3041 gfx::Rect(0, 0, 1000, 1000));
3043 this->VisitLayer(occluding_layer_above
, &occlusion
);
3044 EXPECT_EQ(gfx::Rect().ToString(),
3045 occlusion
.occlusion_from_outside_target().ToString());
3046 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3047 occlusion
.occlusion_from_inside_target().ToString());
3049 this->VisitLayer(filtered_surface2
, &occlusion
);
3050 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
3051 this->VisitLayer(filtered_surface1
, &occlusion
);
3052 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
3054 // Test expectations in the target.
3055 gfx::Rect expected_occlusion
=
3056 gfx::Rect(100 / 2 + outset_right
* 2,
3057 100 / 2 + outset_bottom
* 2,
3058 50 / 2 - (outset_left
+ outset_right
) * 2,
3059 50 / 2 - (outset_top
+ outset_bottom
) * 2);
3060 EXPECT_EQ(expected_occlusion
.ToString(),
3061 occlusion
.occlusion_from_inside_target().ToString());
3063 // Test expectations in the screen are the same as in the target, as the
3064 // render surface is 1:1 with the screen.
3065 EXPECT_EQ(expected_occlusion
.ToString(),
3066 occlusion
.occlusion_from_outside_target().ToString());
3070 ALL_OCCLUSIONTRACKER_TEST(
3071 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
3073 template <class Types
>
3074 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3075 : public OcclusionTrackerTest
<Types
> {
3077 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3079 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3081 gfx::Transform scale_by_half
;
3082 scale_by_half
.Scale(0.5, 0.5);
3084 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3085 // centered below each. The surface is scaled to test that the pixel moving
3086 // is done in the target space, where the background filter is applied, but
3087 // the surface appears at 50, 50 and the replica at 200, 50.
3088 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3089 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3090 typename
Types::LayerType
* behind_surface_layer
=
3091 this->CreateDrawingLayer(parent
,
3092 this->identity_matrix
,
3093 gfx::PointF(60.f
, 60.f
),
3096 typename
Types::LayerType
* behind_replica_layer
=
3097 this->CreateDrawingLayer(parent
,
3098 this->identity_matrix
,
3099 gfx::PointF(210.f
, 60.f
),
3102 typename
Types::LayerType
* filtered_surface
=
3103 this->CreateDrawingLayer(parent
,
3105 gfx::PointF(50.f
, 50.f
),
3106 gfx::Size(100, 100),
3108 this->CreateReplicaLayer(filtered_surface
,
3109 this->identity_matrix
,
3110 gfx::PointF(300.f
, 0.f
),
3113 // Filters make the layer own a surface.
3114 FilterOperations filters
;
3115 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3116 filtered_surface
->SetBackgroundFilters(filters
);
3118 this->CalcDrawEtc(parent
);
3120 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3121 gfx::Rect(0, 0, 1000, 1000));
3123 // The surface has a background blur, so it blurs non-opaque pixels below
3125 this->VisitLayer(filtered_surface
, &occlusion
);
3126 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3128 this->VisitLayer(behind_replica_layer
, &occlusion
);
3129 this->VisitLayer(behind_surface_layer
, &occlusion
);
3131 // The layers behind the surface are not blurred, and their occlusion does
3132 // not change, until we leave the surface. So it should not be modified by
3134 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
3135 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
3137 Region expected_opaque_bounds
=
3138 UnionRegions(occlusion_behind_surface
, occlusion_behind_replica
);
3139 EXPECT_EQ(expected_opaque_bounds
.ToString(),
3140 occlusion
.occlusion_from_inside_target().ToString());
3142 EXPECT_EQ(gfx::Rect().ToString(),
3143 occlusion
.occlusion_from_outside_target().ToString());
3147 ALL_OCCLUSIONTRACKER_TEST(
3148 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
3150 template <class Types
>
3151 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3152 : public OcclusionTrackerTest
<Types
> {
3154 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3156 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3158 gfx::Transform scale_by_half
;
3159 scale_by_half
.Scale(0.5, 0.5);
3161 // Make a 50x50 filtered surface that is completely occluded by an opaque
3162 // layer which is above it in the z-order. The surface is
3163 // scaled to test that the pixel moving is done in the target space, where
3164 // the background filter is applied, but the surface appears at 50, 50.
3165 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3166 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
3167 typename
Types::LayerType
* filtered_surface
=
3168 this->CreateDrawingLayer(parent
,
3170 gfx::PointF(50.f
, 50.f
),
3171 gfx::Size(100, 100),
3173 typename
Types::LayerType
* occluding_layer
=
3174 this->CreateDrawingLayer(parent
,
3175 this->identity_matrix
,
3176 gfx::PointF(50.f
, 50.f
),
3180 // Filters make the layer own a surface.
3181 FilterOperations filters
;
3182 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3183 filtered_surface
->SetBackgroundFilters(filters
);
3185 this->CalcDrawEtc(parent
);
3187 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3188 gfx::Rect(0, 0, 1000, 1000));
3190 this->VisitLayer(occluding_layer
, &occlusion
);
3192 this->VisitLayer(filtered_surface
, &occlusion
);
3194 // The layers above the filtered surface occlude from outside.
3195 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
3197 EXPECT_EQ(gfx::Rect().ToString(),
3198 occlusion
.occlusion_from_inside_target().ToString());
3199 EXPECT_EQ(occlusion_above_surface
.ToString(),
3200 occlusion
.occlusion_from_outside_target().ToString());
3203 // The surface has a background blur, so it blurs non-opaque pixels below
3205 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3207 // The filter is completely occluded, so it should not blur anything and
3208 // reduce any occlusion.
3209 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
3211 EXPECT_EQ(occlusion_above_surface
.ToString(),
3212 occlusion
.occlusion_from_inside_target().ToString());
3213 EXPECT_EQ(gfx::Rect().ToString(),
3214 occlusion
.occlusion_from_outside_target().ToString());
3219 ALL_OCCLUSIONTRACKER_TEST(
3220 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
3222 template <class Types
>
3223 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3224 : public OcclusionTrackerTest
<Types
> {
3227 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3229 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3231 gfx::Transform scale_by_half
;
3232 scale_by_half
.Scale(0.5, 0.5);
3234 // Make a surface and its replica, each 50x50, that are partially occluded
3235 // by opaque layers which are above them in the z-order. The surface is
3236 // scaled to test that the pixel moving is done in the target space, where
3237 // the background filter is applied, but the surface appears at 50, 50 and
3238 // the replica at 200, 50.
3239 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3240 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3241 typename
Types::LayerType
* filtered_surface
=
3242 this->CreateDrawingLayer(parent
,
3244 gfx::PointF(50.f
, 50.f
),
3245 gfx::Size(100, 100),
3247 this->CreateReplicaLayer(filtered_surface
,
3248 this->identity_matrix
,
3249 gfx::PointF(300.f
, 0.f
),
3251 typename
Types::LayerType
* above_surface_layer
=
3252 this->CreateDrawingLayer(parent
,
3253 this->identity_matrix
,
3254 gfx::PointF(70.f
, 50.f
),
3257 typename
Types::LayerType
* above_replica_layer
=
3258 this->CreateDrawingLayer(parent
,
3259 this->identity_matrix
,
3260 gfx::PointF(200.f
, 50.f
),
3263 typename
Types::LayerType
* beside_surface_layer
=
3264 this->CreateDrawingLayer(parent
,
3265 this->identity_matrix
,
3266 gfx::PointF(90.f
, 40.f
),
3269 typename
Types::LayerType
* beside_replica_layer
=
3270 this->CreateDrawingLayer(parent
,
3271 this->identity_matrix
,
3272 gfx::PointF(200.f
, 40.f
),
3276 // Filters make the layer own a surface.
3277 FilterOperations filters
;
3278 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3279 filtered_surface
->SetBackgroundFilters(filters
);
3281 // Save the distance of influence for the blur effect.
3282 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3284 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3286 this->CalcDrawEtc(parent
);
3288 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3289 gfx::Rect(0, 0, 1000, 1000));
3291 this->VisitLayer(beside_replica_layer
, &occlusion
);
3292 this->VisitLayer(beside_surface_layer
, &occlusion
);
3293 this->VisitLayer(above_replica_layer
, &occlusion
);
3294 this->VisitLayer(above_surface_layer
, &occlusion
);
3296 // The surface has a background blur, so it blurs non-opaque pixels below
3298 this->VisitLayer(filtered_surface
, &occlusion
);
3299 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3301 // The filter in the surface and replica are partially unoccluded. Only the
3302 // unoccluded parts should reduce occlusion. This means it will push back
3303 // the occlusion that touches the unoccluded part (occlusion_above___), but
3304 // it will not touch occlusion_beside____ since that is not beside the
3305 // unoccluded part of the surface, even though it is beside the occluded
3306 // part of the surface.
3307 gfx::Rect occlusion_above_surface
=
3308 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
3309 gfx::Rect occlusion_above_replica
=
3310 gfx::Rect(200, 50, 30 - outset_left
, 50);
3311 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
3312 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
3314 Region expected_occlusion
;
3315 expected_occlusion
.Union(occlusion_above_surface
);
3316 expected_occlusion
.Union(occlusion_above_replica
);
3317 expected_occlusion
.Union(occlusion_beside_surface
);
3318 expected_occlusion
.Union(occlusion_beside_replica
);
3320 ASSERT_EQ(expected_occlusion
.ToString(),
3321 occlusion
.occlusion_from_inside_target().ToString());
3322 EXPECT_EQ(gfx::Rect().ToString(),
3323 occlusion
.occlusion_from_outside_target().ToString());
3325 Region::Iterator
expected_rects(expected_occlusion
);
3326 Region::Iterator
target_surface_rects(
3327 occlusion
.occlusion_from_inside_target());
3328 for (; expected_rects
.has_rect();
3329 expected_rects
.next(), target_surface_rects
.next()) {
3330 ASSERT_TRUE(target_surface_rects
.has_rect());
3331 EXPECT_EQ(expected_rects
.rect(), target_surface_rects
.rect());
3336 ALL_OCCLUSIONTRACKER_TEST(
3337 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
3339 template <class Types
>
3340 class OcclusionTrackerTestMinimumTrackingSize
3341 : public OcclusionTrackerTest
<Types
> {
3343 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
3344 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3346 gfx::Size
tracking_size(100, 100);
3347 gfx::Size
below_tracking_size(99, 99);
3349 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3350 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3351 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
3352 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
3353 typename
Types::LayerType
* small
=
3354 this->CreateDrawingLayer(parent
,
3355 this->identity_matrix
,
3357 below_tracking_size
,
3359 this->CalcDrawEtc(parent
);
3361 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3362 gfx::Rect(0, 0, 1000, 1000));
3363 occlusion
.set_minimum_tracking_size(tracking_size
);
3365 // The small layer is not tracked because it is too small.
3366 this->VisitLayer(small
, &occlusion
);
3368 EXPECT_EQ(gfx::Rect().ToString(),
3369 occlusion
.occlusion_from_outside_target().ToString());
3370 EXPECT_EQ(gfx::Rect().ToString(),
3371 occlusion
.occlusion_from_inside_target().ToString());
3373 // The large layer is tracked as it is large enough.
3374 this->VisitLayer(large
, &occlusion
);
3376 EXPECT_EQ(gfx::Rect().ToString(),
3377 occlusion
.occlusion_from_outside_target().ToString());
3378 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
3379 occlusion
.occlusion_from_inside_target().ToString());
3383 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
3385 template <class Types
>
3386 class OcclusionTrackerTestScaledLayerIsClipped
3387 : public OcclusionTrackerTest
<Types
> {
3389 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
3390 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3392 gfx::Transform scale_transform
;
3393 scale_transform
.Scale(512.0, 512.0);
3395 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3396 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3397 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3398 this->identity_matrix
,
3399 gfx::PointF(10.f
, 10.f
),
3401 clip
->SetMasksToBounds(true);
3402 typename
Types::LayerType
* scale
= this->CreateLayer(
3403 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3404 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3405 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3406 this->CalcDrawEtc(parent
);
3408 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3409 gfx::Rect(0, 0, 1000, 1000));
3411 this->VisitLayer(scaled
, &occlusion
);
3413 EXPECT_EQ(gfx::Rect().ToString(),
3414 occlusion
.occlusion_from_outside_target().ToString());
3415 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3416 occlusion
.occlusion_from_inside_target().ToString());
3420 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
3422 template <class Types
>
3423 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3424 : public OcclusionTrackerTest
<Types
> {
3426 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
3427 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3429 gfx::Transform scale_transform
;
3430 scale_transform
.Scale(512.0, 512.0);
3432 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3433 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3434 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3435 this->identity_matrix
,
3436 gfx::PointF(10.f
, 10.f
),
3438 clip
->SetMasksToBounds(true);
3439 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
3440 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
3441 typename
Types::LayerType
* scale
= this->CreateLayer(
3442 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3443 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3444 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3445 this->CalcDrawEtc(parent
);
3447 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3448 gfx::Rect(0, 0, 1000, 1000));
3450 this->VisitLayer(scaled
, &occlusion
);
3451 this->VisitLayer(surface
, &occlusion
);
3452 this->VisitContributingSurface(surface
, &occlusion
);
3454 EXPECT_EQ(gfx::Rect().ToString(),
3455 occlusion
.occlusion_from_outside_target().ToString());
3456 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3457 occlusion
.occlusion_from_inside_target().ToString());
3461 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
3463 template <class Types
>
3464 class OcclusionTrackerTestCopyRequestDoesOcclude
3465 : public OcclusionTrackerTest
<Types
> {
3467 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
3468 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3470 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3471 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3472 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3473 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3474 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
3475 this->identity_matrix
,
3477 gfx::Size(200, 400));
3478 this->AddCopyRequest(copy
);
3479 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3481 this->identity_matrix
,
3483 gfx::Size(200, 400),
3485 this->CalcDrawEtc(root
);
3487 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3488 gfx::Rect(0, 0, 1000, 1000));
3490 this->VisitLayer(copy_child
, &occlusion
);
3491 EXPECT_EQ(gfx::Rect().ToString(),
3492 occlusion
.occlusion_from_outside_target().ToString());
3493 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3494 occlusion
.occlusion_from_inside_target().ToString());
3496 // CopyRequests cause the layer to own a surface.
3497 this->VisitContributingSurface(copy
, &occlusion
);
3499 // The occlusion from the copy should be kept.
3500 EXPECT_EQ(gfx::Rect().ToString(),
3501 occlusion
.occlusion_from_outside_target().ToString());
3502 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3503 occlusion
.occlusion_from_inside_target().ToString());
3507 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
3509 template <class Types
>
3510 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3511 : public OcclusionTrackerTest
<Types
> {
3513 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3515 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3517 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3518 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3519 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3520 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3521 typename
Types::LayerType
* hide
= this->CreateLayer(
3522 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
3523 typename
Types::LayerType
* copy
= this->CreateLayer(
3524 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
3525 this->AddCopyRequest(copy
);
3526 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3527 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
3529 // The |copy| layer is hidden but since it is being copied, it will be
3531 hide
->SetHideLayerAndSubtree(true);
3533 this->CalcDrawEtc(root
);
3535 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3536 gfx::Rect(0, 0, 1000, 1000));
3538 this->VisitLayer(copy_child
, &occlusion
);
3539 EXPECT_EQ(gfx::Rect().ToString(),
3540 occlusion
.occlusion_from_outside_target().ToString());
3541 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3542 occlusion
.occlusion_from_inside_target().ToString());
3544 // CopyRequests cause the layer to own a surface.
3545 this->VisitContributingSurface(copy
, &occlusion
);
3547 // The occlusion from the copy should be dropped since it is hidden.
3548 EXPECT_EQ(gfx::Rect().ToString(),
3549 occlusion
.occlusion_from_outside_target().ToString());
3550 EXPECT_EQ(gfx::Rect().ToString(),
3551 occlusion
.occlusion_from_inside_target().ToString());
3555 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)