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(
94 layer
->render_target(), content_rect
, layer
->draw_transform());
97 gfx::Rect
UnoccludedSurfaceContentRect(const LayerType
* layer
,
99 const gfx::Rect
& content_rect
) const {
100 typename
LayerType::RenderSurfaceType
* surface
= layer
->render_surface();
101 gfx::Transform draw_transform
= for_replica
102 ? surface
->replica_draw_transform()
103 : surface
->draw_transform();
104 return this->UnoccludedContributingSurfaceContentRect(
105 layer
, content_rect
, draw_transform
);
109 struct OcclusionTrackerTestMainThreadTypes
{
110 typedef Layer LayerType
;
111 typedef FakeLayerTreeHost HostType
;
112 typedef RenderSurface RenderSurfaceType
;
113 typedef TestContentLayer ContentLayerType
;
114 typedef scoped_refptr
<Layer
> LayerPtrType
;
115 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
116 typedef LayerIterator
<Layer
> TestLayerIterator
;
117 typedef OcclusionTracker
<Layer
> OcclusionTrackerType
;
119 static LayerPtrType
CreateLayer(HostType
* host
) { return Layer::Create(); }
120 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
121 return make_scoped_refptr(new ContentLayerType());
124 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
125 LayerPtrType
ref(*layer
);
130 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
131 LayerPtrType
ref(*layer
);
136 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
139 struct OcclusionTrackerTestImplThreadTypes
{
140 typedef LayerImpl LayerType
;
141 typedef LayerTreeImpl HostType
;
142 typedef RenderSurfaceImpl RenderSurfaceType
;
143 typedef TestContentLayerImpl ContentLayerType
;
144 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
145 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
146 typedef LayerIterator
<LayerImpl
> TestLayerIterator
;
147 typedef OcclusionTracker
<LayerImpl
> OcclusionTrackerType
;
149 static LayerPtrType
CreateLayer(HostType
* host
) {
150 return LayerImpl::Create(host
, next_layer_impl_id
++);
152 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
153 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
155 static int next_layer_impl_id
;
157 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
158 return layer
->Pass();
161 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
162 return layer
->PassAs
<LayerType
>();
165 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
168 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
170 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
172 explicit OcclusionTrackerTest(bool opaque_layers
)
173 : opaque_layers_(opaque_layers
), host_(FakeLayerTreeHost::Create()) {}
175 virtual void RunMyTest() = 0;
177 virtual void TearDown() {
178 Types::DestroyLayer(&root_
);
179 render_surface_layer_list_
.reset();
180 render_surface_layer_list_impl_
.clear();
181 replica_layers_
.clear();
182 mask_layers_
.clear();
185 typename
Types::HostType
* GetHost();
187 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
188 const gfx::PointF
& position
,
189 const gfx::Size
& bounds
) {
190 typename
Types::ContentLayerPtrType
layer(
191 Types::CreateContentLayer(GetHost()));
192 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
193 SetProperties(layer_ptr
, transform
, position
, bounds
);
195 DCHECK(!root_
.get());
196 root_
= Types::PassLayerPtr(&layer
);
198 SetRootLayerOnMainThread(layer_ptr
);
203 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
204 const gfx::Transform
& transform
,
205 const gfx::PointF
& position
,
206 const gfx::Size
& bounds
) {
207 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
208 typename
Types::LayerType
* layer_ptr
= layer
.get();
209 SetProperties(layer_ptr
, transform
, position
, bounds
);
210 parent
->AddChild(Types::PassLayerPtr(&layer
));
214 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
215 const gfx::Transform
& transform
,
216 const gfx::PointF
& position
,
217 const gfx::Size
& bounds
) {
218 typename
Types::LayerType
* layer
=
219 CreateLayer(parent
, transform
, position
, bounds
);
220 layer
->SetForceRenderSurface(true);
224 typename
Types::ContentLayerType
* CreateDrawingLayer(
225 typename
Types::LayerType
* parent
,
226 const gfx::Transform
& transform
,
227 const gfx::PointF
& position
,
228 const gfx::Size
& bounds
,
230 typename
Types::ContentLayerPtrType
layer(
231 Types::CreateContentLayer(GetHost()));
232 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
233 SetProperties(layer_ptr
, transform
, position
, bounds
);
235 if (opaque_layers_
) {
236 layer_ptr
->SetContentsOpaque(opaque
);
238 layer_ptr
->SetContentsOpaque(false);
240 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
242 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
245 parent
->AddChild(Types::PassLayerPtr(&layer
));
249 typename
Types::LayerType
* CreateReplicaLayer(
250 typename
Types::LayerType
* owning_layer
,
251 const gfx::Transform
& transform
,
252 const gfx::PointF
& position
,
253 const gfx::Size
& bounds
) {
254 typename
Types::ContentLayerPtrType
layer(
255 Types::CreateContentLayer(GetHost()));
256 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
257 SetProperties(layer_ptr
, transform
, position
, bounds
);
258 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
262 typename
Types::LayerType
* CreateMaskLayer(
263 typename
Types::LayerType
* owning_layer
,
264 const gfx::Size
& bounds
) {
265 typename
Types::ContentLayerPtrType
layer(
266 Types::CreateContentLayer(GetHost()));
267 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
268 SetProperties(layer_ptr
, identity_matrix
, gfx::PointF(), bounds
);
269 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
273 typename
Types::ContentLayerType
* CreateDrawingSurface(
274 typename
Types::LayerType
* parent
,
275 const gfx::Transform
& transform
,
276 const gfx::PointF
& position
,
277 const gfx::Size
& bounds
,
279 typename
Types::ContentLayerType
* layer
=
280 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
281 layer
->SetForceRenderSurface(true);
286 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
288 void AddCopyRequest(Layer
* layer
) {
289 layer
->RequestCopyOfOutput(
290 CopyOutputRequest::CreateBitmapRequest(base::Bind(
291 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
292 base::Unretained(this))));
295 void AddCopyRequest(LayerImpl
* layer
) {
296 ScopedPtrVector
<CopyOutputRequest
> requests
;
298 CopyOutputRequest::CreateBitmapRequest(base::Bind(
299 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
300 base::Unretained(this))));
301 layer
->PassCopyRequests(&requests
);
304 void CalcDrawEtc(TestContentLayerImpl
* root
) {
305 DCHECK(root
== root_
.get());
306 DCHECK(!root
->render_surface());
308 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
309 root
, root
->bounds(), &render_surface_layer_list_impl_
);
310 inputs
.can_adjust_raster_scales
= true;
311 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
313 layer_iterator_
= layer_iterator_begin_
=
314 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
317 void CalcDrawEtc(TestContentLayer
* root
) {
318 DCHECK(root
== root_
.get());
319 DCHECK(!root
->render_surface());
321 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
322 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
323 root
, root
->bounds(), render_surface_layer_list_
.get());
324 inputs
.can_adjust_raster_scales
= true;
325 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
327 layer_iterator_
= layer_iterator_begin_
=
328 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
331 void EnterLayer(typename
Types::LayerType
* layer
,
332 typename
Types::OcclusionTrackerType
* occlusion
) {
333 ASSERT_EQ(layer
, *layer_iterator_
);
334 ASSERT_TRUE(layer_iterator_
.represents_itself());
335 occlusion
->EnterLayer(layer_iterator_
);
338 void LeaveLayer(typename
Types::LayerType
* layer
,
339 typename
Types::OcclusionTrackerType
* occlusion
) {
340 ASSERT_EQ(layer
, *layer_iterator_
);
341 ASSERT_TRUE(layer_iterator_
.represents_itself());
342 occlusion
->LeaveLayer(layer_iterator_
);
346 void VisitLayer(typename
Types::LayerType
* layer
,
347 typename
Types::OcclusionTrackerType
* occlusion
) {
348 EnterLayer(layer
, occlusion
);
349 LeaveLayer(layer
, occlusion
);
352 void EnterContributingSurface(
353 typename
Types::LayerType
* layer
,
354 typename
Types::OcclusionTrackerType
* occlusion
) {
355 ASSERT_EQ(layer
, *layer_iterator_
);
356 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
357 occlusion
->EnterLayer(layer_iterator_
);
358 occlusion
->LeaveLayer(layer_iterator_
);
360 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
361 occlusion
->EnterLayer(layer_iterator_
);
364 void LeaveContributingSurface(
365 typename
Types::LayerType
* layer
,
366 typename
Types::OcclusionTrackerType
* occlusion
) {
367 ASSERT_EQ(layer
, *layer_iterator_
);
368 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
369 occlusion
->LeaveLayer(layer_iterator_
);
373 void VisitContributingSurface(
374 typename
Types::LayerType
* layer
,
375 typename
Types::OcclusionTrackerType
* occlusion
) {
376 EnterContributingSurface(layer
, occlusion
);
377 LeaveContributingSurface(layer
, occlusion
);
380 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
382 const gfx::Transform identity_matrix
;
385 void SetRootLayerOnMainThread(Layer
* root
) {
386 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
389 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
391 void SetBaseProperties(typename
Types::LayerType
* layer
,
392 const gfx::Transform
& transform
,
393 const gfx::PointF
& position
,
394 const gfx::Size
& bounds
) {
395 layer
->SetTransform(transform
);
396 layer
->SetAnchorPoint(gfx::PointF());
397 layer
->SetPosition(position
);
398 layer
->SetBounds(bounds
);
401 void SetProperties(Layer
* layer
,
402 const gfx::Transform
& transform
,
403 const gfx::PointF
& position
,
404 const gfx::Size
& bounds
) {
405 SetBaseProperties(layer
, transform
, position
, bounds
);
408 void SetProperties(LayerImpl
* layer
,
409 const gfx::Transform
& transform
,
410 const gfx::PointF
& position
,
411 const gfx::Size
& bounds
) {
412 SetBaseProperties(layer
, transform
, position
, bounds
);
414 layer
->SetContentBounds(layer
->bounds());
417 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
418 owning_layer
->SetReplicaLayer(layer
.get());
419 replica_layers_
.push_back(layer
);
422 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
423 owning_layer
->SetReplicaLayer(layer
.Pass());
426 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
427 owning_layer
->SetMaskLayer(layer
.get());
428 mask_layers_
.push_back(layer
);
431 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
432 owning_layer
->SetMaskLayer(layer
.Pass());
436 scoped_ptr
<FakeLayerTreeHost
> host_
;
437 // These hold ownership of the layers for the duration of the test.
438 typename
Types::LayerPtrType root_
;
439 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
440 LayerImplList render_surface_layer_list_impl_
;
441 typename
Types::TestLayerIterator layer_iterator_begin_
;
442 typename
Types::TestLayerIterator layer_iterator_
;
443 typename
Types::LayerType
* last_layer_visited_
;
444 LayerList replica_layers_
;
445 LayerList mask_layers_
;
450 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
456 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
457 return host_
->host_impl()->active_tree();
460 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
461 class ClassName##MainThreadOpaqueLayers \
462 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
463 public: /* NOLINT(whitespace/indent) */ \
464 ClassName##MainThreadOpaqueLayers() \
465 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
467 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
468 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
469 class ClassName##MainThreadOpaquePaints \
470 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
471 public: /* NOLINT(whitespace/indent) */ \
472 ClassName##MainThreadOpaquePaints() \
473 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
475 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
477 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
478 class ClassName##ImplThreadOpaqueLayers \
479 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
480 public: /* NOLINT(whitespace/indent) */ \
481 ClassName##ImplThreadOpaqueLayers() \
482 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
484 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
485 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
486 class ClassName##ImplThreadOpaquePaints \
487 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
488 public: /* NOLINT(whitespace/indent) */ \
489 ClassName##ImplThreadOpaquePaints() \
490 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
492 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
494 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
495 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
496 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
497 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
498 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
500 #define MAIN_THREAD_TEST(ClassName) \
501 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
503 #define IMPL_THREAD_TEST(ClassName) \
504 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
506 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
507 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
508 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
510 template <class Types
>
511 class OcclusionTrackerTestIdentityTransforms
512 : public OcclusionTrackerTest
<Types
> {
514 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
515 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
518 typename
Types::ContentLayerType
* root
= this->CreateRoot(
519 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
520 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
521 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
522 typename
Types::ContentLayerType
* layer
=
523 this->CreateDrawingLayer(parent
,
524 this->identity_matrix
,
525 gfx::PointF(30.f
, 30.f
),
528 parent
->SetMasksToBounds(true);
529 this->CalcDrawEtc(root
);
531 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
532 gfx::Rect(0, 0, 1000, 1000));
534 this->VisitLayer(layer
, &occlusion
);
535 this->EnterLayer(parent
, &occlusion
);
537 EXPECT_EQ(gfx::Rect().ToString(),
538 occlusion
.occlusion_from_outside_target().ToString());
539 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
540 occlusion
.occlusion_from_inside_target().ToString());
542 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
543 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
544 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
545 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
546 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
548 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
549 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
550 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
551 occlusion
.UnoccludedLayerContentRect(
552 parent
, gfx::Rect(29, 30, 70, 70)));
553 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
554 occlusion
.UnoccludedLayerContentRect(
555 parent
, gfx::Rect(29, 29, 70, 70)));
556 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
557 occlusion
.UnoccludedLayerContentRect(
558 parent
, gfx::Rect(30, 29, 70, 70)));
559 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
560 occlusion
.UnoccludedLayerContentRect(
561 parent
, gfx::Rect(31, 29, 69, 70)));
562 EXPECT_RECT_EQ(gfx::Rect(),
563 occlusion
.UnoccludedLayerContentRect(
564 parent
, gfx::Rect(31, 30, 69, 70)));
565 EXPECT_RECT_EQ(gfx::Rect(),
566 occlusion
.UnoccludedLayerContentRect(
567 parent
, gfx::Rect(31, 31, 69, 69)));
568 EXPECT_RECT_EQ(gfx::Rect(),
569 occlusion
.UnoccludedLayerContentRect(
570 parent
, gfx::Rect(30, 31, 70, 69)));
571 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
572 occlusion
.UnoccludedLayerContentRect(
573 parent
, gfx::Rect(29, 31, 70, 69)));
577 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
579 template <class Types
>
580 class OcclusionTrackerTestQuadsMismatchLayer
581 : public OcclusionTrackerTest
<Types
> {
583 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers
)
584 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
586 gfx::Transform layer_transform
;
587 layer_transform
.Translate(10.0, 10.0);
589 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
590 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(100, 100));
591 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
592 parent
, layer_transform
, gfx::PointF(), gfx::Size(90, 90), true);
593 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
594 layer1
, layer_transform
, gfx::PointF(), gfx::Size(50, 50), true);
595 this->CalcDrawEtc(parent
);
597 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
598 gfx::Rect(0, 0, 1000, 1000));
600 this->VisitLayer(layer2
, &occlusion
);
601 this->EnterLayer(layer1
, &occlusion
);
603 EXPECT_EQ(gfx::Rect().ToString(),
604 occlusion
.occlusion_from_outside_target().ToString());
605 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
606 occlusion
.occlusion_from_inside_target().ToString());
608 // This checks cases where the quads don't match their "containing"
609 // layers, e.g. in terms of transforms or clip rect. This is typical for
610 // DelegatedRendererLayer.
612 gfx::Transform quad_transform
;
613 quad_transform
.Translate(30.0, 30.0);
615 EXPECT_TRUE(occlusion
.UnoccludedContentRect(parent
,
616 gfx::Rect(0, 0, 10, 10),
617 quad_transform
).IsEmpty());
618 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
619 occlusion
.UnoccludedContentRect(
620 parent
, gfx::Rect(40, 40, 10, 10), quad_transform
));
621 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
622 occlusion
.UnoccludedContentRect(
623 parent
, gfx::Rect(35, 30, 10, 10), quad_transform
));
627 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
629 template <class Types
>
630 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
632 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
633 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
635 gfx::Transform layer_transform
;
636 layer_transform
.Translate(250.0, 250.0);
637 layer_transform
.Rotate(90.0);
638 layer_transform
.Translate(-250.0, -250.0);
640 typename
Types::ContentLayerType
* root
= this->CreateRoot(
641 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
642 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
643 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
644 typename
Types::ContentLayerType
* layer
=
645 this->CreateDrawingLayer(parent
,
647 gfx::PointF(30.f
, 30.f
),
650 parent
->SetMasksToBounds(true);
651 this->CalcDrawEtc(root
);
653 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
654 gfx::Rect(0, 0, 1000, 1000));
656 this->VisitLayer(layer
, &occlusion
);
657 this->EnterLayer(parent
, &occlusion
);
659 EXPECT_EQ(gfx::Rect().ToString(),
660 occlusion
.occlusion_from_outside_target().ToString());
661 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
662 occlusion
.occlusion_from_inside_target().ToString());
664 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
665 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
666 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
667 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
668 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
670 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
671 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
672 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
673 occlusion
.UnoccludedLayerContentRect(
674 parent
, gfx::Rect(29, 30, 69, 70)));
675 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
676 occlusion
.UnoccludedLayerContentRect(
677 parent
, gfx::Rect(29, 29, 70, 70)));
678 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
679 occlusion
.UnoccludedLayerContentRect(
680 parent
, gfx::Rect(30, 29, 70, 70)));
681 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
682 occlusion
.UnoccludedLayerContentRect(
683 parent
, gfx::Rect(31, 29, 69, 70)));
684 EXPECT_RECT_EQ(gfx::Rect(),
685 occlusion
.UnoccludedLayerContentRect(
686 parent
, gfx::Rect(31, 30, 69, 70)));
687 EXPECT_RECT_EQ(gfx::Rect(),
688 occlusion
.UnoccludedLayerContentRect(
689 parent
, gfx::Rect(31, 31, 69, 69)));
690 EXPECT_RECT_EQ(gfx::Rect(),
691 occlusion
.UnoccludedLayerContentRect(
692 parent
, gfx::Rect(30, 31, 70, 69)));
693 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
694 occlusion
.UnoccludedLayerContentRect(
695 parent
, gfx::Rect(29, 31, 70, 69)));
699 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
701 template <class Types
>
702 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
704 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
705 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
707 gfx::Transform layer_transform
;
708 layer_transform
.Translate(20.0, 20.0);
710 typename
Types::ContentLayerType
* root
= this->CreateRoot(
711 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
712 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
713 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
714 typename
Types::ContentLayerType
* layer
=
715 this->CreateDrawingLayer(parent
,
717 gfx::PointF(30.f
, 30.f
),
720 parent
->SetMasksToBounds(true);
721 this->CalcDrawEtc(root
);
723 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
724 gfx::Rect(0, 0, 1000, 1000));
726 this->VisitLayer(layer
, &occlusion
);
727 this->EnterLayer(parent
, &occlusion
);
729 EXPECT_EQ(gfx::Rect().ToString(),
730 occlusion
.occlusion_from_outside_target().ToString());
731 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
732 occlusion
.occlusion_from_inside_target().ToString());
734 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
735 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
736 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
737 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(51, 50, 49, 50)));
738 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 51, 50, 49)));
740 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
741 parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
742 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
743 occlusion
.UnoccludedLayerContentRect(
744 parent
, gfx::Rect(49, 50, 50, 50)));
745 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
746 occlusion
.UnoccludedLayerContentRect(
747 parent
, gfx::Rect(49, 49, 50, 50)));
748 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
749 occlusion
.UnoccludedLayerContentRect(
750 parent
, gfx::Rect(50, 49, 50, 50)));
751 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
752 occlusion
.UnoccludedLayerContentRect(
753 parent
, gfx::Rect(51, 49, 49, 50)));
754 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
755 parent
, gfx::Rect(51, 50, 49, 50)).IsEmpty());
756 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
757 parent
, gfx::Rect(51, 51, 49, 49)).IsEmpty());
758 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
759 parent
, gfx::Rect(50, 51, 50, 49)).IsEmpty());
760 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
761 occlusion
.UnoccludedLayerContentRect(
762 parent
, gfx::Rect(49, 51, 50, 49)));
766 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
768 template <class Types
>
769 class OcclusionTrackerTestChildInRotatedChild
770 : public OcclusionTrackerTest
<Types
> {
772 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
773 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
775 gfx::Transform child_transform
;
776 child_transform
.Translate(250.0, 250.0);
777 child_transform
.Rotate(90.0);
778 child_transform
.Translate(-250.0, -250.0);
780 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
781 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
782 parent
->SetMasksToBounds(true);
783 typename
Types::LayerType
* child
= this->CreateSurface(
784 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
785 child
->SetMasksToBounds(true);
786 typename
Types::ContentLayerType
* layer
=
787 this->CreateDrawingLayer(child
,
788 this->identity_matrix
,
789 gfx::PointF(10.f
, 10.f
),
792 this->CalcDrawEtc(parent
);
794 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
795 gfx::Rect(0, 0, 1000, 1000));
797 this->VisitLayer(layer
, &occlusion
);
798 this->EnterContributingSurface(child
, &occlusion
);
800 EXPECT_EQ(gfx::Rect().ToString(),
801 occlusion
.occlusion_from_outside_target().ToString());
802 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
803 occlusion
.occlusion_from_inside_target().ToString());
805 this->LeaveContributingSurface(child
, &occlusion
);
806 this->EnterLayer(parent
, &occlusion
);
808 EXPECT_EQ(gfx::Rect().ToString(),
809 occlusion
.occlusion_from_outside_target().ToString());
810 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
811 occlusion
.occlusion_from_inside_target().ToString());
813 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
814 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
815 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
816 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 40, 69, 60)));
817 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 41, 70, 59)));
819 /* Justification for the above occlusion from |layer|:
821 +---------------------+
824 | 30 + ---------------------------------+
826 | |10+---------------------------------+
830 +----|--|-------------+ | |
838 +--|-------------------------------+ |
840 +---------------------------------+
843 +---------------------+
844 | |30 Visible region of |layer|: /////
846 | +---------------------------------+
848 | +---------------------------------+ |
849 | | |///////////////| 420 | |
850 | | |///////////////|60 | |
851 | | |///////////////| | |
852 +--|--|---------------+ | |
860 | +------------------------------|--+
862 +---------------------------------+
869 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
871 template <class Types
>
872 class OcclusionTrackerTestScaledRenderSurface
873 : public OcclusionTrackerTest
<Types
> {
875 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
876 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
879 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
880 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
882 gfx::Transform layer1_matrix
;
883 layer1_matrix
.Scale(2.0, 2.0);
884 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
885 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
886 layer1
->SetForceRenderSurface(true);
888 gfx::Transform layer2_matrix
;
889 layer2_matrix
.Translate(25.0, 25.0);
890 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
891 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
892 typename
Types::ContentLayerType
* occluder
=
893 this->CreateDrawingLayer(parent
,
894 this->identity_matrix
,
895 gfx::PointF(100.f
, 100.f
),
898 this->CalcDrawEtc(parent
);
900 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
901 gfx::Rect(0, 0, 1000, 1000));
903 this->VisitLayer(occluder
, &occlusion
);
904 this->EnterLayer(layer2
, &occlusion
);
906 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
907 occlusion
.occlusion_from_outside_target().ToString());
908 EXPECT_EQ(gfx::Rect().ToString(),
909 occlusion
.occlusion_from_inside_target().ToString());
912 gfx::Rect(0, 0, 25, 25),
913 occlusion
.UnoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
914 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
915 occlusion
.UnoccludedLayerContentRect(
916 layer2
, gfx::Rect(10, 25, 25, 25)));
917 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
918 occlusion
.UnoccludedLayerContentRect(
919 layer2
, gfx::Rect(25, 10, 25, 25)));
920 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
921 layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
925 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
927 template <class Types
>
928 class OcclusionTrackerTestVisitTargetTwoTimes
929 : public OcclusionTrackerTest
<Types
> {
931 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
932 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
934 gfx::Transform child_transform
;
935 child_transform
.Translate(250.0, 250.0);
936 child_transform
.Rotate(90.0);
937 child_transform
.Translate(-250.0, -250.0);
939 typename
Types::ContentLayerType
* root
= this->CreateRoot(
940 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
941 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
942 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
943 parent
->SetMasksToBounds(true);
944 typename
Types::LayerType
* child
= this->CreateSurface(
945 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
946 child
->SetMasksToBounds(true);
947 typename
Types::ContentLayerType
* layer
=
948 this->CreateDrawingLayer(child
,
949 this->identity_matrix
,
950 gfx::PointF(10.f
, 10.f
),
953 // |child2| makes |parent|'s surface get considered by OcclusionTracker
954 // first, instead of |child|'s. This exercises different code in
955 // LeaveToRenderTarget, as the target surface has already been seen.
956 typename
Types::ContentLayerType
* child2
=
957 this->CreateDrawingLayer(parent
,
958 this->identity_matrix
,
959 gfx::PointF(30.f
, 30.f
),
962 this->CalcDrawEtc(root
);
964 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
965 gfx::Rect(0, 0, 1000, 1000));
967 this->VisitLayer(child2
, &occlusion
);
969 EXPECT_EQ(gfx::Rect().ToString(),
970 occlusion
.occlusion_from_outside_target().ToString());
971 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
972 occlusion
.occlusion_from_inside_target().ToString());
974 this->VisitLayer(layer
, &occlusion
);
976 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
977 occlusion
.occlusion_from_outside_target().ToString());
978 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
979 occlusion
.occlusion_from_inside_target().ToString());
981 this->EnterContributingSurface(child
, &occlusion
);
983 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
984 occlusion
.occlusion_from_outside_target().ToString());
985 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
986 occlusion
.occlusion_from_inside_target().ToString());
988 // Occlusion in |child2| should get merged with the |child| surface we are
990 this->LeaveContributingSurface(child
, &occlusion
);
991 this->EnterLayer(parent
, &occlusion
);
993 EXPECT_EQ(gfx::Rect().ToString(),
994 occlusion
.occlusion_from_outside_target().ToString());
995 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
997 occlusion
.occlusion_from_inside_target().ToString());
999 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
1000 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1001 occlusion
.UnoccludedLayerContentRect(
1002 parent
, gfx::Rect(30, 30, 70, 70)));
1004 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
1005 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
1006 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
1007 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
1008 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
1010 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1011 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1012 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1014 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1015 parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1016 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1017 occlusion
.UnoccludedLayerContentRect(
1018 parent
, gfx::Rect(29, 30, 60, 10)));
1019 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1020 occlusion
.UnoccludedLayerContentRect(
1021 parent
, gfx::Rect(30, 29, 60, 10)));
1022 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1023 occlusion
.UnoccludedLayerContentRect(
1024 parent
, gfx::Rect(31, 30, 60, 10)));
1025 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1026 parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1028 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1029 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1030 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1031 occlusion
.UnoccludedLayerContentRect(
1032 parent
, gfx::Rect(29, 40, 70, 60)));
1033 // This rect is mostly occluded by |child2|.
1034 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1035 occlusion
.UnoccludedLayerContentRect(
1036 parent
, gfx::Rect(30, 39, 70, 60)));
1037 // This rect extends past top/right ends of |child2|.
1038 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1039 occlusion
.UnoccludedLayerContentRect(
1040 parent
, gfx::Rect(30, 29, 70, 70)));
1041 // This rect extends past left/right ends of |child2|.
1042 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1043 occlusion
.UnoccludedLayerContentRect(
1044 parent
, gfx::Rect(20, 39, 80, 60)));
1045 EXPECT_RECT_EQ(gfx::Rect(),
1046 occlusion
.UnoccludedLayerContentRect(
1047 parent
, gfx::Rect(31, 40, 69, 60)));
1048 EXPECT_RECT_EQ(gfx::Rect(),
1049 occlusion
.UnoccludedLayerContentRect(
1050 parent
, gfx::Rect(30, 41, 70, 59)));
1052 /* Justification for the above occlusion from |layer|:
1054 +---------------------+
1057 | 30 + ------------+--------------------+
1058 100 | | 10 | | | ==>
1059 | |10+----------|----------------------+
1060 | + ------------+ | | |
1063 +----|--|-------------+ | |
1071 +--|-------------------------------+ |
1073 +---------------------------------+
1077 +---------------------+
1078 | |30 Visible region of |layer|: /////
1079 | 30 60 | |child2|: \\\\\
1080 | 30 +------------+--------------------+
1081 | |\\\\\\\\\\\\| |10 |
1082 | +--|\\\\\\\\\\\\|-----------------+ |
1083 | | +------------+//| 420 | |
1084 | | |///////////////|60 | |
1085 | | |///////////////| | |
1086 +--|--|---------------+ | |
1094 | +------------------------------|--+
1096 +---------------------------------+
1102 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
1104 template <class Types
>
1105 class OcclusionTrackerTestSurfaceRotatedOffAxis
1106 : public OcclusionTrackerTest
<Types
> {
1108 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
1109 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1111 gfx::Transform child_transform
;
1112 child_transform
.Translate(250.0, 250.0);
1113 child_transform
.Rotate(95.0);
1114 child_transform
.Translate(-250.0, -250.0);
1116 gfx::Transform layer_transform
;
1117 layer_transform
.Translate(10.0, 10.0);
1119 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1120 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1121 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1122 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1123 typename
Types::LayerType
* child
= this->CreateLayer(
1124 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1125 child
->SetMasksToBounds(true);
1126 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1127 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
1128 this->CalcDrawEtc(root
);
1130 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1131 gfx::Rect(0, 0, 1000, 1000));
1133 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
1134 layer_transform
, layer
->visible_content_rect());
1136 this->VisitLayer(layer
, &occlusion
);
1137 this->EnterContributingSurface(child
, &occlusion
);
1139 EXPECT_EQ(gfx::Rect().ToString(),
1140 occlusion
.occlusion_from_outside_target().ToString());
1141 EXPECT_EQ(clipped_layer_in_child
.ToString(),
1142 occlusion
.occlusion_from_inside_target().ToString());
1144 this->LeaveContributingSurface(child
, &occlusion
);
1145 this->EnterLayer(parent
, &occlusion
);
1147 EXPECT_EQ(gfx::Rect().ToString(),
1148 occlusion
.occlusion_from_outside_target().ToString());
1149 EXPECT_EQ(gfx::Rect().ToString(),
1150 occlusion
.occlusion_from_inside_target().ToString());
1152 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
1154 gfx::Rect(75, 55, 1, 1),
1155 occlusion
.UnoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
1159 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
1161 template <class Types
>
1162 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1163 : public OcclusionTrackerTest
<Types
> {
1165 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
1166 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1168 gfx::Transform child_transform
;
1169 child_transform
.Translate(250.0, 250.0);
1170 child_transform
.Rotate(90.0);
1171 child_transform
.Translate(-250.0, -250.0);
1173 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1174 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1175 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1176 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1177 parent
->SetMasksToBounds(true);
1178 typename
Types::ContentLayerType
* child
=
1179 this->CreateDrawingSurface(parent
,
1181 gfx::PointF(30.f
, 30.f
),
1182 gfx::Size(500, 500),
1184 child
->SetMasksToBounds(true);
1185 typename
Types::ContentLayerType
* layer1
=
1186 this->CreateDrawingLayer(child
,
1187 this->identity_matrix
,
1188 gfx::PointF(10.f
, 10.f
),
1189 gfx::Size(500, 500),
1191 typename
Types::ContentLayerType
* layer2
=
1192 this->CreateDrawingLayer(child
,
1193 this->identity_matrix
,
1194 gfx::PointF(10.f
, 450.f
),
1197 this->CalcDrawEtc(root
);
1199 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1200 gfx::Rect(0, 0, 1000, 1000));
1202 this->VisitLayer(layer2
, &occlusion
);
1203 this->VisitLayer(layer1
, &occlusion
);
1204 this->VisitLayer(child
, &occlusion
);
1205 this->EnterContributingSurface(child
, &occlusion
);
1207 EXPECT_EQ(gfx::Rect().ToString(),
1208 occlusion
.occlusion_from_outside_target().ToString());
1209 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1210 occlusion
.occlusion_from_inside_target().ToString());
1212 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
1213 EXPECT_FALSE(occlusion
.OccludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
1214 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(11, 430, 59, 70)));
1215 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 431, 60, 69)));
1217 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1218 child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1220 gfx::Rect(9, 430, 1, 70),
1221 occlusion
.UnoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
1222 EXPECT_RECT_EQ(gfx::Rect(),
1223 occlusion
.UnoccludedLayerContentRect(
1224 child
, gfx::Rect(11, 430, 59, 70)));
1225 EXPECT_RECT_EQ(gfx::Rect(),
1226 occlusion
.UnoccludedLayerContentRect(
1227 child
, gfx::Rect(10, 431, 60, 69)));
1229 this->LeaveContributingSurface(child
, &occlusion
);
1230 this->EnterLayer(parent
, &occlusion
);
1232 EXPECT_EQ(gfx::Rect().ToString(),
1233 occlusion
.occlusion_from_outside_target().ToString());
1234 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1235 occlusion
.occlusion_from_inside_target().ToString());
1237 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1238 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1239 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1241 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1242 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1243 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1244 occlusion
.UnoccludedLayerContentRect(
1245 parent
, gfx::Rect(29, 40, 70, 60)));
1246 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1247 occlusion
.UnoccludedLayerContentRect(
1248 parent
, gfx::Rect(30, 39, 70, 60)));
1249 EXPECT_RECT_EQ(gfx::Rect(),
1250 occlusion
.UnoccludedLayerContentRect(
1251 parent
, gfx::Rect(31, 40, 69, 60)));
1252 EXPECT_RECT_EQ(gfx::Rect(),
1253 occlusion
.UnoccludedLayerContentRect(
1254 parent
, gfx::Rect(30, 41, 70, 59)));
1256 /* Justification for the above occlusion from |layer1| and |layer2|:
1258 +---------------------+
1259 | |30 Visible region of |layer1|: /////
1260 | | Visible region of |layer2|: \\\\\
1261 | +---------------------------------+
1263 | +---------------+-----------------+ |
1264 | | |\\\\\\\\\\\\|//| 420 | |
1265 | | |\\\\\\\\\\\\|//|60 | |
1266 | | |\\\\\\\\\\\\|//| | |
1267 +--|--|------------|--+ | |
1275 | +------------|-----------------|--+
1277 +---------------+-----------------+
1283 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1285 template <class Types
>
1286 class OcclusionTrackerTestOverlappingSurfaceSiblings
1287 : public OcclusionTrackerTest
<Types
> {
1289 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
1290 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1292 gfx::Transform child_transform
;
1293 child_transform
.Translate(250.0, 250.0);
1294 child_transform
.Rotate(90.0);
1295 child_transform
.Translate(-250.0, -250.0);
1297 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1298 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1299 parent
->SetMasksToBounds(true);
1300 typename
Types::LayerType
* child1
= this->CreateSurface(
1301 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(10, 10));
1302 typename
Types::LayerType
* child2
= this->CreateSurface(
1303 parent
, child_transform
, gfx::PointF(20.f
, 40.f
), gfx::Size(10, 10));
1304 typename
Types::ContentLayerType
* layer1
=
1305 this->CreateDrawingLayer(child1
,
1306 this->identity_matrix
,
1307 gfx::PointF(-10.f
, -10.f
),
1308 gfx::Size(510, 510),
1310 typename
Types::ContentLayerType
* layer2
=
1311 this->CreateDrawingLayer(child2
,
1312 this->identity_matrix
,
1313 gfx::PointF(-10.f
, -10.f
),
1314 gfx::Size(510, 510),
1316 this->CalcDrawEtc(parent
);
1318 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1319 gfx::Rect(0, 0, 1000, 1000));
1321 this->VisitLayer(layer2
, &occlusion
);
1322 this->EnterContributingSurface(child2
, &occlusion
);
1324 EXPECT_EQ(gfx::Rect().ToString(),
1325 occlusion
.occlusion_from_outside_target().ToString());
1326 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1327 occlusion
.occlusion_from_inside_target().ToString());
1329 // There is nothing above child2's surface in the z-order.
1330 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1331 occlusion
.UnoccludedSurfaceContentRect(
1332 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1334 this->LeaveContributingSurface(child2
, &occlusion
);
1335 this->VisitLayer(layer1
, &occlusion
);
1336 this->EnterContributingSurface(child1
, &occlusion
);
1338 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1339 occlusion
.occlusion_from_outside_target().ToString());
1340 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1341 occlusion
.occlusion_from_inside_target().ToString());
1343 // child2's contents will occlude child1 below it.
1344 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1345 occlusion
.UnoccludedSurfaceContentRect(
1346 child1
, false, gfx::Rect(-10, 430, 80, 70)));
1348 this->LeaveContributingSurface(child1
, &occlusion
);
1349 this->EnterLayer(parent
, &occlusion
);
1351 EXPECT_EQ(gfx::Rect().ToString(),
1352 occlusion
.occlusion_from_outside_target().ToString());
1353 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1355 occlusion
.occlusion_from_inside_target().ToString());
1357 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1359 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1360 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1361 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1363 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1364 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1365 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1367 /* Justification for the above occlusion:
1369 +---------------------+
1371 | 30+ ---------------------------------+
1372 100 | 30| | layer2 |
1373 |20+----------------------------------+ |
1377 +--|-|----------------+ | |
1385 | +--------------------------------|-+
1387 +----------------------------------+
1393 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1395 template <class Types
>
1396 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1397 : public OcclusionTrackerTest
<Types
> {
1399 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1401 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1403 gfx::Transform child1_transform
;
1404 child1_transform
.Translate(250.0, 250.0);
1405 child1_transform
.Rotate(-90.0);
1406 child1_transform
.Translate(-250.0, -250.0);
1408 gfx::Transform child2_transform
;
1409 child2_transform
.Translate(250.0, 250.0);
1410 child2_transform
.Rotate(90.0);
1411 child2_transform
.Translate(-250.0, -250.0);
1413 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1414 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1415 parent
->SetMasksToBounds(true);
1416 typename
Types::LayerType
* child1
= this->CreateSurface(
1417 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1418 typename
Types::LayerType
* child2
=
1419 this->CreateDrawingSurface(parent
,
1421 gfx::PointF(20.f
, 40.f
),
1424 typename
Types::ContentLayerType
* layer1
=
1425 this->CreateDrawingLayer(child1
,
1426 this->identity_matrix
,
1427 gfx::PointF(-10.f
, -20.f
),
1428 gfx::Size(510, 510),
1430 typename
Types::ContentLayerType
* layer2
=
1431 this->CreateDrawingLayer(child2
,
1432 this->identity_matrix
,
1433 gfx::PointF(-10.f
, -10.f
),
1434 gfx::Size(510, 510),
1436 this->CalcDrawEtc(parent
);
1438 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1439 gfx::Rect(0, 0, 1000, 1000));
1441 this->VisitLayer(layer2
, &occlusion
);
1442 this->EnterLayer(child2
, &occlusion
);
1444 EXPECT_EQ(gfx::Rect().ToString(),
1445 occlusion
.occlusion_from_outside_target().ToString());
1446 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1447 occlusion
.occlusion_from_inside_target().ToString());
1449 this->LeaveLayer(child2
, &occlusion
);
1450 this->EnterContributingSurface(child2
, &occlusion
);
1452 // There is nothing above child2's surface in the z-order.
1453 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1454 occlusion
.UnoccludedSurfaceContentRect(
1455 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1457 this->LeaveContributingSurface(child2
, &occlusion
);
1458 this->VisitLayer(layer1
, &occlusion
);
1459 this->EnterContributingSurface(child1
, &occlusion
);
1461 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1462 occlusion
.occlusion_from_outside_target().ToString());
1463 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1464 occlusion
.occlusion_from_inside_target().ToString());
1466 // child2's contents will occlude child1 below it.
1467 EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(),
1468 occlusion
.occlusion_on_contributing_surface_from_inside_target()
1470 EXPECT_EQ(gfx::Rect().ToString(),
1471 occlusion
.occlusion_on_contributing_surface_from_outside_target()
1474 this->LeaveContributingSurface(child1
, &occlusion
);
1475 this->EnterLayer(parent
, &occlusion
);
1477 EXPECT_EQ(gfx::Rect().ToString(),
1478 occlusion
.occlusion_from_outside_target().ToString());
1479 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1480 occlusion
.occlusion_from_inside_target().ToString());
1482 /* Justification for the above occlusion:
1484 +---------------------+
1486 10+----------------------------------+
1487 100 || 30 | layer2 |
1488 |20+----------------------------------+
1492 +|-|------------------+ | |
1500 +----------------------------------+ |
1502 +----------------------------------+
1508 ALL_OCCLUSIONTRACKER_TEST(
1509 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1511 template <class Types
>
1512 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1514 explicit OcclusionTrackerTestFilters(bool opaque_layers
)
1515 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1517 gfx::Transform layer_transform
;
1518 layer_transform
.Translate(250.0, 250.0);
1519 layer_transform
.Rotate(90.0);
1520 layer_transform
.Translate(-250.0, -250.0);
1522 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1523 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1524 parent
->SetMasksToBounds(true);
1525 typename
Types::ContentLayerType
* blur_layer
=
1526 this->CreateDrawingLayer(parent
,
1528 gfx::PointF(30.f
, 30.f
),
1529 gfx::Size(500, 500),
1531 typename
Types::ContentLayerType
* opaque_layer
=
1532 this->CreateDrawingLayer(parent
,
1534 gfx::PointF(30.f
, 30.f
),
1535 gfx::Size(500, 500),
1537 typename
Types::ContentLayerType
* opacity_layer
=
1538 this->CreateDrawingLayer(parent
,
1540 gfx::PointF(30.f
, 30.f
),
1541 gfx::Size(500, 500),
1544 FilterOperations filters
;
1545 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
1546 blur_layer
->SetFilters(filters
);
1549 filters
.Append(FilterOperation::CreateGrayscaleFilter(0.5f
));
1550 opaque_layer
->SetFilters(filters
);
1553 filters
.Append(FilterOperation::CreateOpacityFilter(0.5f
));
1554 opacity_layer
->SetFilters(filters
);
1556 this->CalcDrawEtc(parent
);
1558 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1559 gfx::Rect(0, 0, 1000, 1000));
1561 // Opacity layer won't contribute to occlusion.
1562 this->VisitLayer(opacity_layer
, &occlusion
);
1563 this->EnterContributingSurface(opacity_layer
, &occlusion
);
1565 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1566 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1568 // And has nothing to contribute to its parent surface.
1569 this->LeaveContributingSurface(opacity_layer
, &occlusion
);
1570 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1571 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1573 // Opaque layer will contribute to occlusion.
1574 this->VisitLayer(opaque_layer
, &occlusion
);
1575 this->EnterContributingSurface(opaque_layer
, &occlusion
);
1577 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1578 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1579 occlusion
.occlusion_from_inside_target().ToString());
1581 // And it gets translated to the parent surface.
1582 this->LeaveContributingSurface(opaque_layer
, &occlusion
);
1583 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1584 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1585 occlusion
.occlusion_from_inside_target().ToString());
1587 // The blur layer needs to throw away any occlusion from outside its
1589 this->EnterLayer(blur_layer
, &occlusion
);
1590 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1591 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1593 // And it won't contribute to occlusion.
1594 this->LeaveLayer(blur_layer
, &occlusion
);
1595 this->EnterContributingSurface(blur_layer
, &occlusion
);
1596 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1597 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1599 // But the opaque layer's occlusion is preserved on the parent.
1600 this->LeaveContributingSurface(blur_layer
, &occlusion
);
1601 this->EnterLayer(parent
, &occlusion
);
1602 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1603 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1604 occlusion
.occlusion_from_inside_target().ToString());
1608 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1610 template <class Types
>
1611 class OcclusionTrackerTestReplicaDoesOcclude
1612 : public OcclusionTrackerTest
<Types
> {
1614 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers
)
1615 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1617 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1618 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1619 typename
Types::LayerType
* surface
=
1620 this->CreateDrawingSurface(parent
,
1621 this->identity_matrix
,
1622 gfx::PointF(0.f
, 100.f
),
1625 this->CreateReplicaLayer(
1626 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1627 this->CalcDrawEtc(parent
);
1629 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1630 gfx::Rect(0, 0, 1000, 1000));
1632 this->VisitLayer(surface
, &occlusion
);
1634 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1635 occlusion
.occlusion_from_inside_target().ToString());
1637 this->VisitContributingSurface(surface
, &occlusion
);
1638 this->EnterLayer(parent
, &occlusion
);
1640 // The surface and replica should both be occluding the parent.
1642 UnionRegions(gfx::Rect(0, 100, 50, 50),
1643 gfx::Rect(50, 150, 50, 50)).ToString(),
1644 occlusion
.occlusion_from_inside_target().ToString());
1648 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1650 template <class Types
>
1651 class OcclusionTrackerTestReplicaWithClipping
1652 : public OcclusionTrackerTest
<Types
> {
1654 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers
)
1655 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1657 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1658 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 170));
1659 parent
->SetMasksToBounds(true);
1660 typename
Types::LayerType
* surface
=
1661 this->CreateDrawingSurface(parent
,
1662 this->identity_matrix
,
1663 gfx::PointF(0.f
, 100.f
),
1666 this->CreateReplicaLayer(
1667 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1668 this->CalcDrawEtc(parent
);
1670 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1671 gfx::Rect(0, 0, 1000, 1000));
1673 this->VisitLayer(surface
, &occlusion
);
1675 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1676 occlusion
.occlusion_from_inside_target().ToString());
1678 this->VisitContributingSurface(surface
, &occlusion
);
1679 this->EnterLayer(parent
, &occlusion
);
1681 // The surface and replica should both be occluding the parent.
1683 UnionRegions(gfx::Rect(0, 100, 50, 50),
1684 gfx::Rect(50, 150, 50, 20)).ToString(),
1685 occlusion
.occlusion_from_inside_target().ToString());
1689 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1691 template <class Types
>
1692 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1694 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers
)
1695 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1697 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1698 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
1699 typename
Types::LayerType
* surface
=
1700 this->CreateDrawingSurface(parent
,
1701 this->identity_matrix
,
1702 gfx::PointF(0.f
, 100.f
),
1705 typename
Types::LayerType
* replica
= this->CreateReplicaLayer(
1706 surface
, this->identity_matrix
, gfx::PointF(50.f
, 50.f
), gfx::Size());
1707 this->CreateMaskLayer(replica
, gfx::Size(10, 10));
1708 this->CalcDrawEtc(parent
);
1710 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1711 gfx::Rect(0, 0, 1000, 1000));
1713 this->VisitLayer(surface
, &occlusion
);
1715 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1716 occlusion
.occlusion_from_inside_target().ToString());
1718 this->VisitContributingSurface(surface
, &occlusion
);
1719 this->EnterLayer(parent
, &occlusion
);
1721 // The replica should not be occluding the parent, since it has a mask
1723 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1724 occlusion
.occlusion_from_inside_target().ToString());
1728 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1730 template <class Types
>
1731 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1732 : public OcclusionTrackerTest
<Types
> {
1734 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers
)
1735 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1737 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1738 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1739 typename
Types::ContentLayerType
* layer
=
1740 this->CreateDrawingSurface(parent
,
1741 this->identity_matrix
,
1743 gfx::Size(200, 200),
1745 this->CalcDrawEtc(parent
);
1747 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1748 gfx::Rect(0, 0, 1000, 1000));
1749 this->EnterLayer(layer
, &occlusion
);
1751 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1752 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1753 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1754 EXPECT_FALSE(occlusion
.OccludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1756 this->LeaveLayer(layer
, &occlusion
);
1757 this->VisitContributingSurface(layer
, &occlusion
);
1758 this->EnterLayer(parent
, &occlusion
);
1760 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1764 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1766 template <class Types
>
1767 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1768 : public OcclusionTrackerTest
<Types
> {
1770 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers
)
1771 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1773 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1774 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1775 typename
Types::ContentLayerType
* layer
=
1776 this->CreateDrawingLayer(parent
,
1777 this->identity_matrix
,
1778 gfx::PointF(100.f
, 100.f
),
1779 gfx::Size(200, 200),
1781 this->CalcDrawEtc(parent
);
1783 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1784 gfx::Rect(0, 0, 1000, 1000));
1785 layer
->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1787 this->ResetLayerIterator();
1788 this->VisitLayer(layer
, &occlusion
);
1789 this->EnterLayer(parent
, &occlusion
);
1791 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1792 occlusion
.occlusion_from_inside_target().ToString());
1795 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1797 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1799 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1802 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1803 gfx::Rect(0, 0, 1000, 1000));
1804 layer
->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1806 this->ResetLayerIterator();
1807 this->VisitLayer(layer
, &occlusion
);
1808 this->EnterLayer(parent
, &occlusion
);
1810 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1811 occlusion
.occlusion_from_inside_target().ToString());
1814 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1816 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1818 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1821 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1822 gfx::Rect(0, 0, 1000, 1000));
1823 layer
->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1825 this->ResetLayerIterator();
1826 this->VisitLayer(layer
, &occlusion
);
1827 this->EnterLayer(parent
, &occlusion
);
1829 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1830 occlusion
.occlusion_from_inside_target().ToString());
1833 occlusion
.OccludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1835 occlusion
.OccludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1837 occlusion
.OccludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1842 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1844 template <class Types
>
1845 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
1847 explicit OcclusionTrackerTest3dTransform(bool opaque_layers
)
1848 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1850 gfx::Transform transform
;
1851 transform
.RotateAboutYAxis(30.0);
1853 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1854 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1855 typename
Types::LayerType
* container
= this->CreateLayer(
1856 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1857 typename
Types::ContentLayerType
* layer
=
1858 this->CreateDrawingLayer(container
,
1860 gfx::PointF(100.f
, 100.f
),
1861 gfx::Size(200, 200),
1863 this->CalcDrawEtc(parent
);
1865 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1866 gfx::Rect(0, 0, 1000, 1000));
1867 this->EnterLayer(layer
, &occlusion
);
1869 // The layer is rotated in 3d but without preserving 3d, so it only gets
1872 gfx::Rect(0, 0, 200, 200),
1873 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1877 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
1879 template <class Types
>
1880 class OcclusionTrackerTestUnsorted3dLayers
1881 : public OcclusionTrackerTest
<Types
> {
1883 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers
)
1884 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1886 // Currently, The main thread layer iterator does not iterate over 3d items
1887 // in sorted order, because layer sorting is not performed on the main
1888 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1889 // layer occludes other layers that have not yet been iterated over. For
1890 // now, the expected behavior is that a 3d layer simply does not add any
1891 // occlusion to the occlusion tracker.
1893 gfx::Transform translation_to_front
;
1894 translation_to_front
.Translate3d(0.0, 0.0, -10.0);
1895 gfx::Transform translation_to_back
;
1896 translation_to_front
.Translate3d(0.0, 0.0, -100.0);
1898 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1899 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1900 typename
Types::ContentLayerType
* child1
= this->CreateDrawingLayer(
1901 parent
, translation_to_back
, gfx::PointF(), gfx::Size(100, 100), true);
1902 typename
Types::ContentLayerType
* child2
=
1903 this->CreateDrawingLayer(parent
,
1904 translation_to_front
,
1905 gfx::PointF(50.f
, 50.f
),
1906 gfx::Size(100, 100),
1908 parent
->SetShouldFlattenTransform(false);
1909 parent
->SetIs3dSorted(true);
1910 child1
->SetIs3dSorted(true);
1911 child2
->SetIs3dSorted(true);
1913 this->CalcDrawEtc(parent
);
1915 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1916 gfx::Rect(0, 0, 1000, 1000));
1917 this->VisitLayer(child2
, &occlusion
);
1918 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1919 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1921 this->VisitLayer(child1
, &occlusion
);
1922 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
1923 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
1927 // This test will have different layer ordering on the impl thread; the test
1928 // will only work on the main thread.
1929 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1931 template <class Types
>
1932 class OcclusionTrackerTestPerspectiveTransform
1933 : public OcclusionTrackerTest
<Types
> {
1935 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers
)
1936 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1938 gfx::Transform transform
;
1939 transform
.Translate(150.0, 150.0);
1940 transform
.ApplyPerspectiveDepth(400.0);
1941 transform
.RotateAboutXAxis(-30.0);
1942 transform
.Translate(-150.0, -150.0);
1944 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1945 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1946 typename
Types::LayerType
* container
= this->CreateLayer(
1947 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
1948 typename
Types::ContentLayerType
* layer
=
1949 this->CreateDrawingLayer(container
,
1951 gfx::PointF(100.f
, 100.f
),
1952 gfx::Size(200, 200),
1954 container
->SetShouldFlattenTransform(false);
1955 container
->SetIs3dSorted(true);
1956 layer
->SetIs3dSorted(true);
1957 layer
->SetShouldFlattenTransform(false);
1959 this->CalcDrawEtc(parent
);
1961 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1962 gfx::Rect(0, 0, 1000, 1000));
1963 this->EnterLayer(layer
, &occlusion
);
1966 gfx::Rect(0, 0, 200, 200),
1967 occlusion
.UnoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1971 // This test requires accumulating occlusion of 3d layers, which are skipped by
1972 // the occlusion tracker on the main thread. So this test should run on the impl
1974 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
1975 template <class Types
>
1976 class OcclusionTrackerTestPerspectiveTransformBehindCamera
1977 : public OcclusionTrackerTest
<Types
> {
1979 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
1981 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1983 // This test is based on the platform/chromium/compositing/3d-corners.html
1985 gfx::Transform transform
;
1986 transform
.Translate(250.0, 50.0);
1987 transform
.ApplyPerspectiveDepth(10.0);
1988 transform
.Translate(-250.0, -50.0);
1989 transform
.Translate(250.0, 50.0);
1990 transform
.RotateAboutXAxis(-167.0);
1991 transform
.Translate(-250.0, -50.0);
1993 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1994 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 100));
1995 typename
Types::LayerType
* container
= this->CreateLayer(
1996 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
1997 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1998 container
, transform
, gfx::PointF(), gfx::Size(500, 500), true);
1999 container
->SetShouldFlattenTransform(false);
2000 container
->SetIs3dSorted(true);
2001 layer
->SetShouldFlattenTransform(false);
2002 layer
->SetIs3dSorted(true);
2003 this->CalcDrawEtc(parent
);
2005 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2006 gfx::Rect(0, 0, 1000, 1000));
2007 this->EnterLayer(layer
, &occlusion
);
2009 // The bottom 11 pixel rows of this layer remain visible inside the
2010 // container, after translation to the target surface. When translated back,
2011 // this will include many more pixels but must include at least the bottom
2013 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
2014 layer
, gfx::Rect(0, 26, 500, 474)).
2015 Contains(gfx::Rect(0, 489, 500, 11)));
2019 // This test requires accumulating occlusion of 3d layers, which are skipped by
2020 // the occlusion tracker on the main thread. So this test should run on the impl
2022 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
2024 template <class Types
>
2025 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2026 : public OcclusionTrackerTest
<Types
> {
2028 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2030 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2032 gfx::Transform transform
;
2033 transform
.Translate(50.0, 50.0);
2034 transform
.ApplyPerspectiveDepth(100.0);
2035 transform
.Translate3d(0.0, 0.0, 110.0);
2036 transform
.Translate(-50.0, -50.0);
2038 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2039 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2040 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2041 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2042 parent
->SetShouldFlattenTransform(false);
2043 parent
->SetIs3dSorted(true);
2044 layer
->SetShouldFlattenTransform(false);
2045 layer
->SetIs3dSorted(true);
2046 this->CalcDrawEtc(parent
);
2048 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2049 gfx::Rect(0, 0, 1000, 1000));
2051 // The |layer| is entirely behind the camera and should not occlude.
2052 this->VisitLayer(layer
, &occlusion
);
2053 this->EnterLayer(parent
, &occlusion
);
2054 EXPECT_TRUE(occlusion
.occlusion_from_inside_target().IsEmpty());
2055 EXPECT_TRUE(occlusion
.occlusion_from_outside_target().IsEmpty());
2059 // This test requires accumulating occlusion of 3d layers, which are skipped by
2060 // the occlusion tracker on the main thread. So this test should run on the impl
2062 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2064 template <class Types
>
2065 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2066 : public OcclusionTrackerTest
<Types
> {
2068 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2070 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2072 gfx::Transform transform
;
2073 transform
.Translate(50.0, 50.0);
2074 transform
.ApplyPerspectiveDepth(100.0);
2075 transform
.Translate3d(0.0, 0.0, 99.0);
2076 transform
.Translate(-50.0, -50.0);
2078 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2079 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
2080 parent
->SetMasksToBounds(true);
2081 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
2082 parent
, transform
, gfx::PointF(), gfx::Size(100, 100), true);
2083 parent
->SetShouldFlattenTransform(false);
2084 parent
->SetIs3dSorted(true);
2085 layer
->SetShouldFlattenTransform(false);
2086 layer
->SetIs3dSorted(true);
2087 this->CalcDrawEtc(parent
);
2089 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2090 gfx::Rect(0, 0, 1000, 1000));
2092 // This is very close to the camera, so pixels in its visible_content_rect()
2093 // will actually go outside of the layer's clip rect. Ensure that those
2094 // pixels don't occlude things outside the clip rect.
2095 this->VisitLayer(layer
, &occlusion
);
2096 this->EnterLayer(parent
, &occlusion
);
2097 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2098 occlusion
.occlusion_from_inside_target().ToString());
2099 EXPECT_EQ(gfx::Rect().ToString(),
2100 occlusion
.occlusion_from_outside_target().ToString());
2104 // This test requires accumulating occlusion of 3d layers, which are skipped by
2105 // the occlusion tracker on the main thread. So this test should run on the impl
2107 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2109 template <class Types
>
2110 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2111 : public OcclusionTrackerTest
<Types
> {
2113 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers
)
2114 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2119 // | +--surface_child
2120 // | +--surface_child2
2124 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2125 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2126 typename
Types::ContentLayerType
* layer
=
2127 this->CreateDrawingLayer(parent
,
2128 this->identity_matrix
,
2130 gfx::Size(300, 300),
2132 typename
Types::ContentLayerType
* surface
=
2133 this->CreateDrawingSurface(parent
,
2134 this->identity_matrix
,
2136 gfx::Size(300, 300),
2138 typename
Types::ContentLayerType
* surface_child
=
2139 this->CreateDrawingLayer(surface
,
2140 this->identity_matrix
,
2142 gfx::Size(200, 300),
2144 typename
Types::ContentLayerType
* surface_child2
=
2145 this->CreateDrawingLayer(surface
,
2146 this->identity_matrix
,
2148 gfx::Size(100, 300),
2150 typename
Types::ContentLayerType
* parent2
=
2151 this->CreateDrawingLayer(parent
,
2152 this->identity_matrix
,
2154 gfx::Size(300, 300),
2156 typename
Types::ContentLayerType
* topmost
=
2157 this->CreateDrawingLayer(parent
,
2158 this->identity_matrix
,
2159 gfx::PointF(250.f
, 0.f
),
2163 AddOpacityTransitionToController(
2164 layer
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2165 AddOpacityTransitionToController(
2166 surface
->layer_animation_controller(), 10.0, 0.f
, 1.f
, false);
2167 this->CalcDrawEtc(parent
);
2169 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2170 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2171 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2173 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2174 gfx::Rect(0, 0, 1000, 1000));
2176 this->VisitLayer(topmost
, &occlusion
);
2177 this->EnterLayer(parent2
, &occlusion
);
2178 // This occlusion will affect all surfaces.
2179 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2180 occlusion
.occlusion_from_inside_target().ToString());
2181 EXPECT_EQ(gfx::Rect().ToString(),
2182 occlusion
.occlusion_from_outside_target().ToString());
2183 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2184 occlusion
.UnoccludedLayerContentRect(
2185 parent2
, gfx::Rect(0, 0, 300, 300)).ToString());
2186 this->LeaveLayer(parent2
, &occlusion
);
2188 this->VisitLayer(surface_child2
, &occlusion
);
2189 this->EnterLayer(surface_child
, &occlusion
);
2190 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2191 occlusion
.occlusion_from_inside_target().ToString());
2192 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2193 occlusion
.occlusion_from_outside_target().ToString());
2194 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2195 occlusion
.UnoccludedLayerContentRect(
2196 surface_child
, gfx::Rect(0, 0, 200, 300)));
2197 this->LeaveLayer(surface_child
, &occlusion
);
2198 this->EnterLayer(surface
, &occlusion
);
2199 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2200 occlusion
.occlusion_from_inside_target().ToString());
2201 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2202 occlusion
.occlusion_from_outside_target().ToString());
2203 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2204 occlusion
.UnoccludedLayerContentRect(
2205 surface
, gfx::Rect(0, 0, 300, 300)));
2206 this->LeaveLayer(surface
, &occlusion
);
2208 this->EnterContributingSurface(surface
, &occlusion
);
2209 // Occlusion within the surface is lost when leaving the animating surface.
2210 EXPECT_EQ(gfx::Rect().ToString(),
2211 occlusion
.occlusion_from_inside_target().ToString());
2212 EXPECT_EQ(gfx::Rect().ToString(),
2213 occlusion
.occlusion_from_outside_target().ToString());
2214 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2215 occlusion
.UnoccludedSurfaceContentRect(
2216 surface
, false, gfx::Rect(0, 0, 300, 300)));
2217 this->LeaveContributingSurface(surface
, &occlusion
);
2219 // Occlusion from outside the animating surface still exists.
2220 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2221 occlusion
.occlusion_from_inside_target().ToString());
2222 EXPECT_EQ(gfx::Rect().ToString(),
2223 occlusion
.occlusion_from_outside_target().ToString());
2225 this->VisitLayer(layer
, &occlusion
);
2226 this->EnterLayer(parent
, &occlusion
);
2228 // Occlusion is not added for the animating |layer|.
2229 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2230 occlusion
.UnoccludedLayerContentRect(
2231 parent
, gfx::Rect(0, 0, 300, 300)));
2235 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2237 template <class Types
>
2238 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2239 : public OcclusionTrackerTest
<Types
> {
2241 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers
)
2242 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2244 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2245 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2246 typename
Types::ContentLayerType
* layer
=
2247 this->CreateDrawingLayer(parent
,
2248 this->identity_matrix
,
2250 gfx::Size(300, 300),
2252 typename
Types::ContentLayerType
* surface
=
2253 this->CreateDrawingSurface(parent
,
2254 this->identity_matrix
,
2256 gfx::Size(300, 300),
2258 typename
Types::ContentLayerType
* surface_child
=
2259 this->CreateDrawingLayer(surface
,
2260 this->identity_matrix
,
2262 gfx::Size(200, 300),
2264 typename
Types::ContentLayerType
* surface_child2
=
2265 this->CreateDrawingLayer(surface
,
2266 this->identity_matrix
,
2268 gfx::Size(100, 300),
2270 typename
Types::ContentLayerType
* parent2
=
2271 this->CreateDrawingLayer(parent
,
2272 this->identity_matrix
,
2274 gfx::Size(300, 300),
2276 typename
Types::ContentLayerType
* topmost
=
2277 this->CreateDrawingLayer(parent
,
2278 this->identity_matrix
,
2279 gfx::PointF(250.f
, 0.f
),
2283 AddOpacityTransitionToController(
2284 layer
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2285 AddOpacityTransitionToController(
2286 surface
->layer_animation_controller(), 10.0, 1.f
, 0.f
, false);
2287 this->CalcDrawEtc(parent
);
2289 EXPECT_TRUE(layer
->draw_opacity_is_animating());
2290 EXPECT_FALSE(surface
->draw_opacity_is_animating());
2291 EXPECT_TRUE(surface
->render_surface()->draw_opacity_is_animating());
2293 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2294 gfx::Rect(0, 0, 1000, 1000));
2296 this->VisitLayer(topmost
, &occlusion
);
2297 this->EnterLayer(parent2
, &occlusion
);
2298 // This occlusion will affect all surfaces.
2299 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2300 occlusion
.occlusion_from_inside_target().ToString());
2301 EXPECT_EQ(gfx::Rect().ToString(),
2302 occlusion
.occlusion_from_outside_target().ToString());
2303 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2304 occlusion
.UnoccludedLayerContentRect(
2305 parent
, gfx::Rect(0, 0, 300, 300)));
2306 this->LeaveLayer(parent2
, &occlusion
);
2308 this->VisitLayer(surface_child2
, &occlusion
);
2309 this->EnterLayer(surface_child
, &occlusion
);
2310 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2311 occlusion
.occlusion_from_inside_target().ToString());
2312 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2313 occlusion
.occlusion_from_outside_target().ToString());
2314 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2315 occlusion
.UnoccludedLayerContentRect(
2316 surface_child
, gfx::Rect(0, 0, 200, 300)));
2317 this->LeaveLayer(surface_child
, &occlusion
);
2318 this->EnterLayer(surface
, &occlusion
);
2319 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2320 occlusion
.occlusion_from_inside_target().ToString());
2321 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2322 occlusion
.occlusion_from_outside_target().ToString());
2323 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2324 occlusion
.UnoccludedLayerContentRect(
2325 surface
, gfx::Rect(0, 0, 300, 300)));
2326 this->LeaveLayer(surface
, &occlusion
);
2328 this->EnterContributingSurface(surface
, &occlusion
);
2329 // Occlusion within the surface is lost when leaving the animating surface.
2330 EXPECT_EQ(gfx::Rect().ToString(),
2331 occlusion
.occlusion_from_inside_target().ToString());
2332 EXPECT_EQ(gfx::Rect().ToString(),
2333 occlusion
.occlusion_from_outside_target().ToString());
2334 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2335 occlusion
.UnoccludedSurfaceContentRect(
2336 surface
, false, gfx::Rect(0, 0, 300, 300)));
2337 this->LeaveContributingSurface(surface
, &occlusion
);
2339 // Occlusion from outside the animating surface still exists.
2340 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2341 occlusion
.occlusion_from_inside_target().ToString());
2342 EXPECT_EQ(gfx::Rect().ToString(),
2343 occlusion
.occlusion_from_outside_target().ToString());
2345 this->VisitLayer(layer
, &occlusion
);
2346 this->EnterLayer(parent
, &occlusion
);
2348 // Occlusion is not added for the animating |layer|.
2349 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2350 occlusion
.UnoccludedLayerContentRect(
2351 parent
, gfx::Rect(0, 0, 300, 300)));
2355 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2357 template <class Types
>
2358 class OcclusionTrackerTestAnimationTranslateOnMainThread
2359 : public OcclusionTrackerTest
<Types
> {
2361 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2363 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2365 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2366 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2367 typename
Types::ContentLayerType
* layer
=
2368 this->CreateDrawingLayer(parent
,
2369 this->identity_matrix
,
2371 gfx::Size(300, 300),
2373 typename
Types::ContentLayerType
* surface
=
2374 this->CreateDrawingSurface(parent
,
2375 this->identity_matrix
,
2377 gfx::Size(300, 300),
2379 typename
Types::ContentLayerType
* surface_child
=
2380 this->CreateDrawingLayer(surface
,
2381 this->identity_matrix
,
2383 gfx::Size(200, 300),
2385 typename
Types::ContentLayerType
* surface_child2
=
2386 this->CreateDrawingLayer(surface
,
2387 this->identity_matrix
,
2389 gfx::Size(100, 300),
2391 typename
Types::ContentLayerType
* surface2
= this->CreateDrawingSurface(
2392 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(50, 300), true);
2394 AddAnimatedTransformToController(
2395 layer
->layer_animation_controller(), 10.0, 30, 0);
2396 AddAnimatedTransformToController(
2397 surface
->layer_animation_controller(), 10.0, 30, 0);
2398 AddAnimatedTransformToController(
2399 surface_child
->layer_animation_controller(), 10.0, 30, 0);
2400 this->CalcDrawEtc(parent
);
2402 EXPECT_TRUE(layer
->draw_transform_is_animating());
2403 EXPECT_TRUE(layer
->screen_space_transform_is_animating());
2405 surface
->render_surface()->target_surface_transforms_are_animating());
2407 surface
->render_surface()->screen_space_transforms_are_animating());
2408 // The surface owning layer doesn't animate against its own surface.
2409 EXPECT_FALSE(surface
->draw_transform_is_animating());
2410 EXPECT_TRUE(surface
->screen_space_transform_is_animating());
2411 EXPECT_TRUE(surface_child
->draw_transform_is_animating());
2412 EXPECT_TRUE(surface_child
->screen_space_transform_is_animating());
2414 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2415 gfx::Rect(0, 0, 1000, 1000));
2417 this->VisitLayer(surface2
, &occlusion
);
2418 this->EnterContributingSurface(surface2
, &occlusion
);
2420 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2421 occlusion
.occlusion_from_inside_target().ToString());
2423 this->LeaveContributingSurface(surface2
, &occlusion
);
2424 this->EnterLayer(surface_child2
, &occlusion
);
2425 // surface_child2 is moving in screen space but not relative to its target,
2426 // so occlusion should happen in its target space only. It also means that
2427 // things occluding from outside the target (e.g. surface2) cannot occlude
2429 EXPECT_EQ(gfx::Rect().ToString(),
2430 occlusion
.occlusion_from_outside_target().ToString());
2431 EXPECT_EQ(gfx::Rect().ToString(),
2432 occlusion
.occlusion_from_inside_target().ToString());
2434 this->LeaveLayer(surface_child2
, &occlusion
);
2435 this->EnterLayer(surface_child
, &occlusion
);
2436 // surface_child2 added to the occlusion since it is not moving relative
2438 EXPECT_EQ(gfx::Rect().ToString(),
2439 occlusion
.occlusion_from_outside_target().ToString());
2440 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2441 occlusion
.occlusion_from_inside_target().ToString());
2443 this->LeaveLayer(surface_child
, &occlusion
);
2444 // surface_child is moving relative to its target, so it does not add
2446 EXPECT_EQ(gfx::Rect().ToString(),
2447 occlusion
.occlusion_from_outside_target().ToString());
2448 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2449 occlusion
.occlusion_from_inside_target().ToString());
2451 this->EnterLayer(surface
, &occlusion
);
2452 EXPECT_EQ(gfx::Rect().ToString(),
2453 occlusion
.occlusion_from_outside_target().ToString());
2454 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2455 occlusion
.occlusion_from_inside_target().ToString());
2457 this->LeaveLayer(surface
, &occlusion
);
2458 // The surface's owning layer is moving in screen space but not relative to
2459 // its target, so it adds to the occlusion.
2460 EXPECT_EQ(gfx::Rect().ToString(),
2461 occlusion
.occlusion_from_outside_target().ToString());
2462 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2463 occlusion
.occlusion_from_inside_target().ToString());
2465 this->EnterContributingSurface(surface
, &occlusion
);
2466 this->LeaveContributingSurface(surface
, &occlusion
);
2467 // The |surface| is moving in the screen and in its target, so all occlusion
2468 // within the surface is lost when leaving it. Only the |surface2| occlusion
2470 EXPECT_EQ(gfx::Rect().ToString(),
2471 occlusion
.occlusion_from_outside_target().ToString());
2472 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2473 occlusion
.occlusion_from_inside_target().ToString());
2475 this->VisitLayer(layer
, &occlusion
);
2476 // The |layer| is animating in the screen and in its target, so no occlusion
2478 EXPECT_EQ(gfx::Rect().ToString(),
2479 occlusion
.occlusion_from_outside_target().ToString());
2480 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2481 occlusion
.occlusion_from_inside_target().ToString());
2485 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
2487 template <class Types
>
2488 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2489 : public OcclusionTrackerTest
<Types
> {
2491 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2493 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2495 gfx::Transform surface_transform
;
2496 surface_transform
.Translate(300.0, 300.0);
2497 surface_transform
.Scale(2.0, 2.0);
2498 surface_transform
.Translate(-150.0, -150.0);
2500 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2501 this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500));
2502 typename
Types::ContentLayerType
* surface
= this->CreateDrawingSurface(
2503 parent
, surface_transform
, gfx::PointF(), gfx::Size(300, 300), false);
2504 typename
Types::ContentLayerType
* surface2
=
2505 this->CreateDrawingSurface(parent
,
2506 this->identity_matrix
,
2507 gfx::PointF(50.f
, 50.f
),
2508 gfx::Size(300, 300),
2510 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2511 surface2
->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2512 this->CalcDrawEtc(parent
);
2514 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2515 gfx::Rect(0, 0, 1000, 1000));
2517 this->VisitLayer(surface2
, &occlusion
);
2518 this->VisitContributingSurface(surface2
, &occlusion
);
2520 EXPECT_EQ(gfx::Rect().ToString(),
2521 occlusion
.occlusion_from_outside_target().ToString());
2522 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2523 occlusion
.occlusion_from_inside_target().ToString());
2525 // Clear any stored occlusion.
2526 occlusion
.set_occlusion_from_outside_target(Region());
2527 occlusion
.set_occlusion_from_inside_target(Region());
2529 this->VisitLayer(surface
, &occlusion
);
2530 this->VisitContributingSurface(surface
, &occlusion
);
2532 EXPECT_EQ(gfx::Rect().ToString(),
2533 occlusion
.occlusion_from_outside_target().ToString());
2534 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2535 occlusion
.occlusion_from_inside_target().ToString());
2539 MAIN_AND_IMPL_THREAD_TEST(
2540 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
2542 template <class Types
>
2543 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2544 : public OcclusionTrackerTest
<Types
> {
2546 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2548 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2550 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2551 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 300));
2552 parent
->SetMasksToBounds(true);
2553 typename
Types::ContentLayerType
* surface
=
2554 this->CreateDrawingSurface(parent
,
2555 this->identity_matrix
,
2557 gfx::Size(500, 300),
2559 surface
->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2560 this->CalcDrawEtc(parent
);
2562 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2563 gfx::Rect(0, 0, 1000, 1000));
2565 this->VisitLayer(surface
, &occlusion
);
2566 this->VisitContributingSurface(surface
, &occlusion
);
2568 EXPECT_EQ(gfx::Rect().ToString(),
2569 occlusion
.occlusion_from_outside_target().ToString());
2570 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2571 occlusion
.occlusion_from_inside_target().ToString());
2575 MAIN_AND_IMPL_THREAD_TEST(
2576 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2578 template <class Types
>
2579 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
2581 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers
)
2582 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2584 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2585 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2586 typename
Types::LayerType
* surface
=
2587 this->CreateDrawingSurface(parent
,
2588 this->identity_matrix
,
2590 gfx::Size(100, 100),
2592 this->CreateReplicaLayer(surface
,
2593 this->identity_matrix
,
2594 gfx::PointF(0.f
, 100.f
),
2595 gfx::Size(100, 100));
2596 typename
Types::LayerType
* topmost
=
2597 this->CreateDrawingLayer(parent
,
2598 this->identity_matrix
,
2599 gfx::PointF(0.f
, 100.f
),
2600 gfx::Size(100, 100),
2602 this->CalcDrawEtc(parent
);
2604 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2605 gfx::Rect(0, 0, 1000, 1000));
2607 // |topmost| occludes the replica, but not the surface itself.
2608 this->VisitLayer(topmost
, &occlusion
);
2610 EXPECT_EQ(gfx::Rect().ToString(),
2611 occlusion
.occlusion_from_outside_target().ToString());
2612 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2613 occlusion
.occlusion_from_inside_target().ToString());
2615 this->VisitLayer(surface
, &occlusion
);
2617 // Render target with replica ignores occlusion from outside.
2618 EXPECT_EQ(gfx::Rect().ToString(),
2619 occlusion
.occlusion_from_outside_target().ToString());
2620 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2621 occlusion
.occlusion_from_inside_target().ToString());
2623 this->EnterContributingSurface(surface
, &occlusion
);
2625 // Surface is not occluded so it shouldn't think it is.
2626 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2627 occlusion
.UnoccludedSurfaceContentRect(
2628 surface
, false, gfx::Rect(0, 0, 100, 100)));
2632 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
2634 template <class Types
>
2635 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2636 : public OcclusionTrackerTest
<Types
> {
2638 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers
)
2639 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2641 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2642 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2643 typename
Types::LayerType
* surface
=
2644 this->CreateDrawingSurface(parent
,
2645 this->identity_matrix
,
2647 gfx::Size(100, 100),
2649 this->CreateReplicaLayer(surface
,
2650 this->identity_matrix
,
2651 gfx::PointF(0.f
, 100.f
),
2652 gfx::Size(100, 100));
2653 typename
Types::LayerType
* topmost
=
2654 this->CreateDrawingLayer(parent
,
2655 this->identity_matrix
,
2657 gfx::Size(100, 110),
2659 this->CalcDrawEtc(parent
);
2661 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2662 gfx::Rect(0, 0, 1000, 1000));
2664 // |topmost| occludes the surface, but not the entire surface's replica.
2665 this->VisitLayer(topmost
, &occlusion
);
2667 EXPECT_EQ(gfx::Rect().ToString(),
2668 occlusion
.occlusion_from_outside_target().ToString());
2669 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2670 occlusion
.occlusion_from_inside_target().ToString());
2672 this->VisitLayer(surface
, &occlusion
);
2674 // Render target with replica ignores occlusion from outside.
2675 EXPECT_EQ(gfx::Rect().ToString(),
2676 occlusion
.occlusion_from_outside_target().ToString());
2677 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2678 occlusion
.occlusion_from_inside_target().ToString());
2680 this->EnterContributingSurface(surface
, &occlusion
);
2682 // Surface is occluded, but only the top 10px of the replica.
2683 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2684 occlusion
.UnoccludedSurfaceContentRect(
2685 surface
, false, gfx::Rect(0, 0, 100, 100)));
2686 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2687 occlusion
.UnoccludedSurfaceContentRect(
2688 surface
, true, gfx::Rect(0, 0, 100, 100)));
2692 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2694 template <class Types
>
2695 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
2696 : public OcclusionTrackerTest
<Types
> {
2698 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
2700 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2702 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2703 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2704 typename
Types::LayerType
* surface
=
2705 this->CreateDrawingSurface(parent
,
2706 this->identity_matrix
,
2708 gfx::Size(100, 100),
2710 this->CreateReplicaLayer(surface
,
2711 this->identity_matrix
,
2712 gfx::PointF(0.f
, 100.f
),
2713 gfx::Size(100, 100));
2714 typename
Types::LayerType
* over_surface
= this->CreateDrawingLayer(
2715 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(40, 100), true);
2716 typename
Types::LayerType
* over_replica
=
2717 this->CreateDrawingLayer(parent
,
2718 this->identity_matrix
,
2719 gfx::PointF(0.f
, 100.f
),
2722 this->CalcDrawEtc(parent
);
2724 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2725 gfx::Rect(0, 0, 1000, 1000));
2727 // These occlude the surface and replica differently, so we can test each
2729 this->VisitLayer(over_replica
, &occlusion
);
2730 this->VisitLayer(over_surface
, &occlusion
);
2732 EXPECT_EQ(gfx::Rect().ToString(),
2733 occlusion
.occlusion_from_outside_target().ToString());
2734 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2736 occlusion
.occlusion_from_inside_target().ToString());
2738 this->VisitLayer(surface
, &occlusion
);
2740 // Render target with replica ignores occlusion from outside.
2741 EXPECT_EQ(gfx::Rect().ToString(),
2742 occlusion
.occlusion_from_outside_target().ToString());
2743 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2744 occlusion
.occlusion_from_inside_target().ToString());
2746 this->EnterContributingSurface(surface
, &occlusion
);
2748 // Surface and replica are occluded different amounts.
2749 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
2750 occlusion
.UnoccludedSurfaceContentRect(
2751 surface
, false, gfx::Rect(0, 0, 100, 100)));
2752 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2753 occlusion
.UnoccludedSurfaceContentRect(
2754 surface
, true, gfx::Rect(0, 0, 100, 100)));
2758 ALL_OCCLUSIONTRACKER_TEST(
2759 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
2761 template <class Types
>
2762 class OcclusionTrackerTestSurfaceChildOfSurface
2763 : public OcclusionTrackerTest
<Types
> {
2765 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers
)
2766 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2768 // This test verifies that the surface cliprect does not end up empty and
2769 // clip away the entire unoccluded rect.
2771 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2772 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2773 typename
Types::LayerType
* surface
=
2774 this->CreateDrawingSurface(parent
,
2775 this->identity_matrix
,
2777 gfx::Size(100, 100),
2779 typename
Types::LayerType
* surface_child
=
2780 this->CreateDrawingSurface(surface
,
2781 this->identity_matrix
,
2782 gfx::PointF(0.f
, 10.f
),
2785 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
2786 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
2787 this->CalcDrawEtc(parent
);
2789 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2790 gfx::Rect(-100, -100, 1000, 1000));
2792 // |topmost| occludes everything partially so we know occlusion is happening
2794 this->VisitLayer(topmost
, &occlusion
);
2796 EXPECT_EQ(gfx::Rect().ToString(),
2797 occlusion
.occlusion_from_outside_target().ToString());
2798 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2799 occlusion
.occlusion_from_inside_target().ToString());
2801 this->VisitLayer(surface_child
, &occlusion
);
2803 // surface_child increases the occlusion in the screen by a narrow sliver.
2804 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2805 occlusion
.occlusion_from_outside_target().ToString());
2806 // In its own surface, surface_child is at 0,0 as is its occlusion.
2807 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2808 occlusion
.occlusion_from_inside_target().ToString());
2810 // The root layer always has a clip rect. So the parent of |surface| has a
2811 // clip rect. However, the owning layer for |surface| does not mask to
2812 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2813 // |surface_child| exercises different code paths as its parent does not
2814 // have a clip rect.
2816 this->EnterContributingSurface(surface_child
, &occlusion
);
2817 // The surface_child's parent does not have a clip rect as it owns a render
2818 // surface. Make sure the unoccluded rect does not get clipped away
2820 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
2821 occlusion
.UnoccludedSurfaceContentRect(
2822 surface_child
, false, gfx::Rect(0, 0, 100, 50)));
2823 this->LeaveContributingSurface(surface_child
, &occlusion
);
2825 // When the surface_child's occlusion is transformed up to its parent, make
2826 // sure it is not clipped away inappropriately also.
2827 this->EnterLayer(surface
, &occlusion
);
2828 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2829 occlusion
.occlusion_from_outside_target().ToString());
2830 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2831 occlusion
.occlusion_from_inside_target().ToString());
2832 this->LeaveLayer(surface
, &occlusion
);
2834 this->EnterContributingSurface(surface
, &occlusion
);
2835 // The surface's parent does have a clip rect as it is the root layer.
2836 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
2837 occlusion
.UnoccludedSurfaceContentRect(
2838 surface
, false, gfx::Rect(0, 0, 100, 100)));
2842 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2844 template <class Types
>
2845 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2846 : public OcclusionTrackerTest
<Types
> {
2848 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2850 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2852 gfx::Transform scale_by_half
;
2853 scale_by_half
.Scale(0.5, 0.5);
2855 // Make a 50x50 filtered surface that is completely surrounded by opaque
2856 // layers which are above it in the z-order. The surface is scaled to test
2857 // that the pixel moving is done in the target space, where the background
2858 // filter is applied.
2859 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2860 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
2861 typename
Types::LayerType
* filtered_surface
=
2862 this->CreateDrawingLayer(parent
,
2864 gfx::PointF(50.f
, 50.f
),
2865 gfx::Size(100, 100),
2867 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
2868 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 50), true);
2869 typename
Types::LayerType
* occluding_layer2
=
2870 this->CreateDrawingLayer(parent
,
2871 this->identity_matrix
,
2872 gfx::PointF(0.f
, 100.f
),
2875 typename
Types::LayerType
* occluding_layer3
=
2876 this->CreateDrawingLayer(parent
,
2877 this->identity_matrix
,
2878 gfx::PointF(0.f
, 50.f
),
2881 typename
Types::LayerType
* occluding_layer4
=
2882 this->CreateDrawingLayer(parent
,
2883 this->identity_matrix
,
2884 gfx::PointF(100.f
, 50.f
),
2888 // Filters make the layer own a surface.
2889 FilterOperations filters
;
2890 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
2891 filtered_surface
->SetBackgroundFilters(filters
);
2893 // Save the distance of influence for the blur effect.
2894 int outset_top
, outset_right
, outset_bottom
, outset_left
;
2896 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
2898 this->CalcDrawEtc(parent
);
2900 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2901 gfx::Rect(0, 0, 1000, 1000));
2903 // These layers occlude pixels directly beside the filtered_surface. Because
2904 // filtered surface blends pixels in a radius, it will need to see some of
2905 // the pixels (up to radius far) underneath the occluding layers.
2906 this->VisitLayer(occluding_layer4
, &occlusion
);
2907 this->VisitLayer(occluding_layer3
, &occlusion
);
2908 this->VisitLayer(occluding_layer2
, &occlusion
);
2909 this->VisitLayer(occluding_layer1
, &occlusion
);
2911 Region expected_occlusion
;
2912 expected_occlusion
.Union(gfx::Rect(0, 0, 200, 50));
2913 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
2914 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
2915 expected_occlusion
.Union(gfx::Rect(0, 100, 200, 50));
2917 EXPECT_EQ(expected_occlusion
.ToString(),
2918 occlusion
.occlusion_from_inside_target().ToString());
2919 EXPECT_EQ(gfx::Rect().ToString(),
2920 occlusion
.occlusion_from_outside_target().ToString());
2922 this->VisitLayer(filtered_surface
, &occlusion
);
2924 // The filtered layer does not occlude.
2925 Region expected_occlusion_outside_surface
;
2926 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 200, 50));
2927 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
2928 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
2929 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 200, 50));
2931 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
2932 occlusion
.occlusion_from_outside_target().ToString());
2933 EXPECT_EQ(gfx::Rect().ToString(),
2934 occlusion
.occlusion_from_inside_target().ToString());
2936 // The surface has a background blur, so it needs pixels that are currently
2937 // considered occluded in order to be drawn. So the pixels it needs should
2938 // be removed some the occluded area so that when we get to the parent they
2940 this->VisitContributingSurface(filtered_surface
, &occlusion
);
2942 this->EnterLayer(parent
, &occlusion
);
2944 Region expected_blurred_occlusion
;
2945 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 200, 50 - outset_top
));
2946 expected_blurred_occlusion
.Union(gfx::Rect(
2947 0, 50 - outset_top
, 50 - outset_left
, 50 + outset_top
+ outset_bottom
));
2948 expected_blurred_occlusion
.Union(
2949 gfx::Rect(100 + outset_right
,
2952 50 + outset_top
+ outset_bottom
));
2953 expected_blurred_occlusion
.Union(
2954 gfx::Rect(0, 100 + outset_bottom
, 200, 50 - outset_bottom
));
2956 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
2957 occlusion
.occlusion_from_inside_target().ToString());
2958 EXPECT_EQ(gfx::Rect().ToString(),
2959 occlusion
.occlusion_from_outside_target().ToString());
2961 gfx::Rect outset_rect
;
2962 gfx::Rect test_rect
;
2964 // Nothing in the blur outsets for the filtered_surface is occluded.
2965 outset_rect
= gfx::Rect(50 - outset_left
,
2967 50 + outset_left
+ outset_right
,
2968 50 + outset_top
+ outset_bottom
);
2969 test_rect
= outset_rect
;
2971 outset_rect
.ToString(),
2972 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2974 // Stuff outside the blur outsets is still occluded though.
2975 test_rect
= outset_rect
;
2976 test_rect
.Inset(0, 0, -1, 0);
2978 outset_rect
.ToString(),
2979 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2980 test_rect
= outset_rect
;
2981 test_rect
.Inset(0, 0, 0, -1);
2983 outset_rect
.ToString(),
2984 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2985 test_rect
= outset_rect
;
2986 test_rect
.Inset(-1, 0, 0, 0);
2988 outset_rect
.ToString(),
2989 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2990 test_rect
= outset_rect
;
2991 test_rect
.Inset(0, -1, 0, 0);
2993 outset_rect
.ToString(),
2994 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
2998 ALL_OCCLUSIONTRACKER_TEST(
2999 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
3001 template <class Types
>
3002 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3003 : public OcclusionTrackerTest
<Types
> {
3005 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3007 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3009 gfx::Transform scale_by_half
;
3010 scale_by_half
.Scale(0.5, 0.5);
3012 // Makes two surfaces that completely cover |parent|. The occlusion both
3013 // above and below the filters will be reduced by each of them.
3014 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3015 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
3016 typename
Types::LayerType
* parent
= this->CreateSurface(
3017 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
3018 parent
->SetMasksToBounds(true);
3019 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
3020 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3021 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
3022 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3023 typename
Types::LayerType
* occluding_layer_above
=
3024 this->CreateDrawingLayer(parent
,
3025 this->identity_matrix
,
3026 gfx::PointF(100.f
, 100.f
),
3030 // Filters make the layers own surfaces.
3031 FilterOperations filters
;
3032 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
3033 filtered_surface1
->SetBackgroundFilters(filters
);
3034 filtered_surface2
->SetBackgroundFilters(filters
);
3036 // Save the distance of influence for the blur effect.
3037 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3039 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3041 this->CalcDrawEtc(root
);
3043 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3044 gfx::Rect(0, 0, 1000, 1000));
3046 this->VisitLayer(occluding_layer_above
, &occlusion
);
3047 EXPECT_EQ(gfx::Rect().ToString(),
3048 occlusion
.occlusion_from_outside_target().ToString());
3049 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3050 occlusion
.occlusion_from_inside_target().ToString());
3052 this->VisitLayer(filtered_surface2
, &occlusion
);
3053 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
3054 this->VisitLayer(filtered_surface1
, &occlusion
);
3055 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
3057 // Test expectations in the target.
3058 gfx::Rect expected_occlusion
=
3059 gfx::Rect(100 / 2 + outset_right
* 2,
3060 100 / 2 + outset_bottom
* 2,
3061 50 / 2 - (outset_left
+ outset_right
) * 2,
3062 50 / 2 - (outset_top
+ outset_bottom
) * 2);
3063 EXPECT_EQ(expected_occlusion
.ToString(),
3064 occlusion
.occlusion_from_inside_target().ToString());
3066 // Test expectations in the screen are the same as in the target, as the
3067 // render surface is 1:1 with the screen.
3068 EXPECT_EQ(expected_occlusion
.ToString(),
3069 occlusion
.occlusion_from_outside_target().ToString());
3073 ALL_OCCLUSIONTRACKER_TEST(
3074 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
3076 template <class Types
>
3077 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3078 : public OcclusionTrackerTest
<Types
> {
3080 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3082 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3084 gfx::Transform scale_by_half
;
3085 scale_by_half
.Scale(0.5, 0.5);
3087 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3088 // centered below each. The surface is scaled to test that the pixel moving
3089 // is done in the target space, where the background filter is applied, but
3090 // the surface appears at 50, 50 and the replica at 200, 50.
3091 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3092 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3093 typename
Types::LayerType
* behind_surface_layer
=
3094 this->CreateDrawingLayer(parent
,
3095 this->identity_matrix
,
3096 gfx::PointF(60.f
, 60.f
),
3099 typename
Types::LayerType
* behind_replica_layer
=
3100 this->CreateDrawingLayer(parent
,
3101 this->identity_matrix
,
3102 gfx::PointF(210.f
, 60.f
),
3105 typename
Types::LayerType
* filtered_surface
=
3106 this->CreateDrawingLayer(parent
,
3108 gfx::PointF(50.f
, 50.f
),
3109 gfx::Size(100, 100),
3111 this->CreateReplicaLayer(filtered_surface
,
3112 this->identity_matrix
,
3113 gfx::PointF(300.f
, 0.f
),
3116 // Filters make the layer own a surface.
3117 FilterOperations filters
;
3118 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3119 filtered_surface
->SetBackgroundFilters(filters
);
3121 this->CalcDrawEtc(parent
);
3123 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3124 gfx::Rect(0, 0, 1000, 1000));
3126 // The surface has a background blur, so it blurs non-opaque pixels below
3128 this->VisitLayer(filtered_surface
, &occlusion
);
3129 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3131 this->VisitLayer(behind_replica_layer
, &occlusion
);
3132 this->VisitLayer(behind_surface_layer
, &occlusion
);
3134 // The layers behind the surface are not blurred, and their occlusion does
3135 // not change, until we leave the surface. So it should not be modified by
3137 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
3138 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
3140 Region expected_opaque_bounds
=
3141 UnionRegions(occlusion_behind_surface
, occlusion_behind_replica
);
3142 EXPECT_EQ(expected_opaque_bounds
.ToString(),
3143 occlusion
.occlusion_from_inside_target().ToString());
3145 EXPECT_EQ(gfx::Rect().ToString(),
3146 occlusion
.occlusion_from_outside_target().ToString());
3150 ALL_OCCLUSIONTRACKER_TEST(
3151 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
3153 template <class Types
>
3154 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3155 : public OcclusionTrackerTest
<Types
> {
3157 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3159 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3161 gfx::Transform scale_by_half
;
3162 scale_by_half
.Scale(0.5, 0.5);
3164 // Make a 50x50 filtered surface that is completely occluded by an opaque
3165 // layer which is above it in the z-order. The surface is
3166 // scaled to test that the pixel moving is done in the target space, where
3167 // the background filter is applied, but the surface appears at 50, 50.
3168 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3169 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
3170 typename
Types::LayerType
* filtered_surface
=
3171 this->CreateDrawingLayer(parent
,
3173 gfx::PointF(50.f
, 50.f
),
3174 gfx::Size(100, 100),
3176 typename
Types::LayerType
* occluding_layer
=
3177 this->CreateDrawingLayer(parent
,
3178 this->identity_matrix
,
3179 gfx::PointF(50.f
, 50.f
),
3183 // Filters make the layer own a surface.
3184 FilterOperations filters
;
3185 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3186 filtered_surface
->SetBackgroundFilters(filters
);
3188 this->CalcDrawEtc(parent
);
3190 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3191 gfx::Rect(0, 0, 1000, 1000));
3193 this->VisitLayer(occluding_layer
, &occlusion
);
3195 this->VisitLayer(filtered_surface
, &occlusion
);
3197 // The layers above the filtered surface occlude from outside.
3198 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
3200 EXPECT_EQ(gfx::Rect().ToString(),
3201 occlusion
.occlusion_from_inside_target().ToString());
3202 EXPECT_EQ(occlusion_above_surface
.ToString(),
3203 occlusion
.occlusion_from_outside_target().ToString());
3206 // The surface has a background blur, so it blurs non-opaque pixels below
3208 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3210 // The filter is completely occluded, so it should not blur anything and
3211 // reduce any occlusion.
3212 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
3214 EXPECT_EQ(occlusion_above_surface
.ToString(),
3215 occlusion
.occlusion_from_inside_target().ToString());
3216 EXPECT_EQ(gfx::Rect().ToString(),
3217 occlusion
.occlusion_from_outside_target().ToString());
3222 ALL_OCCLUSIONTRACKER_TEST(
3223 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
3225 template <class Types
>
3226 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3227 : public OcclusionTrackerTest
<Types
> {
3230 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3232 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3234 gfx::Transform scale_by_half
;
3235 scale_by_half
.Scale(0.5, 0.5);
3237 // Make a surface and its replica, each 50x50, that are partially occluded
3238 // by opaque layers which are above them in the z-order. The surface is
3239 // scaled to test that the pixel moving is done in the target space, where
3240 // the background filter is applied, but the surface appears at 50, 50 and
3241 // the replica at 200, 50.
3242 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3243 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3244 typename
Types::LayerType
* filtered_surface
=
3245 this->CreateDrawingLayer(parent
,
3247 gfx::PointF(50.f
, 50.f
),
3248 gfx::Size(100, 100),
3250 this->CreateReplicaLayer(filtered_surface
,
3251 this->identity_matrix
,
3252 gfx::PointF(300.f
, 0.f
),
3254 typename
Types::LayerType
* above_surface_layer
=
3255 this->CreateDrawingLayer(parent
,
3256 this->identity_matrix
,
3257 gfx::PointF(70.f
, 50.f
),
3260 typename
Types::LayerType
* above_replica_layer
=
3261 this->CreateDrawingLayer(parent
,
3262 this->identity_matrix
,
3263 gfx::PointF(200.f
, 50.f
),
3266 typename
Types::LayerType
* beside_surface_layer
=
3267 this->CreateDrawingLayer(parent
,
3268 this->identity_matrix
,
3269 gfx::PointF(90.f
, 40.f
),
3272 typename
Types::LayerType
* beside_replica_layer
=
3273 this->CreateDrawingLayer(parent
,
3274 this->identity_matrix
,
3275 gfx::PointF(200.f
, 40.f
),
3279 // Filters make the layer own a surface.
3280 FilterOperations filters
;
3281 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3282 filtered_surface
->SetBackgroundFilters(filters
);
3284 // Save the distance of influence for the blur effect.
3285 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3287 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3289 this->CalcDrawEtc(parent
);
3291 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3292 gfx::Rect(0, 0, 1000, 1000));
3294 this->VisitLayer(beside_replica_layer
, &occlusion
);
3295 this->VisitLayer(beside_surface_layer
, &occlusion
);
3296 this->VisitLayer(above_replica_layer
, &occlusion
);
3297 this->VisitLayer(above_surface_layer
, &occlusion
);
3299 // The surface has a background blur, so it blurs non-opaque pixels below
3301 this->VisitLayer(filtered_surface
, &occlusion
);
3302 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3304 // The filter in the surface and replica are partially unoccluded. Only the
3305 // unoccluded parts should reduce occlusion. This means it will push back
3306 // the occlusion that touches the unoccluded part (occlusion_above___), but
3307 // it will not touch occlusion_beside____ since that is not beside the
3308 // unoccluded part of the surface, even though it is beside the occluded
3309 // part of the surface.
3310 gfx::Rect occlusion_above_surface
=
3311 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
3312 gfx::Rect occlusion_above_replica
=
3313 gfx::Rect(200, 50, 30 - outset_left
, 50);
3314 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
3315 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
3317 Region expected_occlusion
;
3318 expected_occlusion
.Union(occlusion_above_surface
);
3319 expected_occlusion
.Union(occlusion_above_replica
);
3320 expected_occlusion
.Union(occlusion_beside_surface
);
3321 expected_occlusion
.Union(occlusion_beside_replica
);
3323 ASSERT_EQ(expected_occlusion
.ToString(),
3324 occlusion
.occlusion_from_inside_target().ToString());
3325 EXPECT_EQ(gfx::Rect().ToString(),
3326 occlusion
.occlusion_from_outside_target().ToString());
3328 Region::Iterator
expected_rects(expected_occlusion
);
3329 Region::Iterator
target_surface_rects(
3330 occlusion
.occlusion_from_inside_target());
3331 for (; expected_rects
.has_rect();
3332 expected_rects
.next(), target_surface_rects
.next()) {
3333 ASSERT_TRUE(target_surface_rects
.has_rect());
3334 EXPECT_EQ(expected_rects
.rect(), target_surface_rects
.rect());
3339 ALL_OCCLUSIONTRACKER_TEST(
3340 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
3342 template <class Types
>
3343 class OcclusionTrackerTestMinimumTrackingSize
3344 : public OcclusionTrackerTest
<Types
> {
3346 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
3347 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3349 gfx::Size
tracking_size(100, 100);
3350 gfx::Size
below_tracking_size(99, 99);
3352 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3353 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3354 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
3355 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
3356 typename
Types::LayerType
* small
=
3357 this->CreateDrawingLayer(parent
,
3358 this->identity_matrix
,
3360 below_tracking_size
,
3362 this->CalcDrawEtc(parent
);
3364 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3365 gfx::Rect(0, 0, 1000, 1000));
3366 occlusion
.set_minimum_tracking_size(tracking_size
);
3368 // The small layer is not tracked because it is too small.
3369 this->VisitLayer(small
, &occlusion
);
3371 EXPECT_EQ(gfx::Rect().ToString(),
3372 occlusion
.occlusion_from_outside_target().ToString());
3373 EXPECT_EQ(gfx::Rect().ToString(),
3374 occlusion
.occlusion_from_inside_target().ToString());
3376 // The large layer is tracked as it is large enough.
3377 this->VisitLayer(large
, &occlusion
);
3379 EXPECT_EQ(gfx::Rect().ToString(),
3380 occlusion
.occlusion_from_outside_target().ToString());
3381 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
3382 occlusion
.occlusion_from_inside_target().ToString());
3386 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
3388 template <class Types
>
3389 class OcclusionTrackerTestScaledLayerIsClipped
3390 : public OcclusionTrackerTest
<Types
> {
3392 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
3393 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3395 gfx::Transform scale_transform
;
3396 scale_transform
.Scale(512.0, 512.0);
3398 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3399 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3400 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3401 this->identity_matrix
,
3402 gfx::PointF(10.f
, 10.f
),
3404 clip
->SetMasksToBounds(true);
3405 typename
Types::LayerType
* scale
= this->CreateLayer(
3406 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3407 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3408 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3409 this->CalcDrawEtc(parent
);
3411 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3412 gfx::Rect(0, 0, 1000, 1000));
3414 this->VisitLayer(scaled
, &occlusion
);
3416 EXPECT_EQ(gfx::Rect().ToString(),
3417 occlusion
.occlusion_from_outside_target().ToString());
3418 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3419 occlusion
.occlusion_from_inside_target().ToString());
3423 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
3425 template <class Types
>
3426 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3427 : public OcclusionTrackerTest
<Types
> {
3429 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
3430 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3432 gfx::Transform scale_transform
;
3433 scale_transform
.Scale(512.0, 512.0);
3435 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3436 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3437 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3438 this->identity_matrix
,
3439 gfx::PointF(10.f
, 10.f
),
3441 clip
->SetMasksToBounds(true);
3442 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
3443 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
3444 typename
Types::LayerType
* scale
= this->CreateLayer(
3445 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3446 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3447 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3448 this->CalcDrawEtc(parent
);
3450 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3451 gfx::Rect(0, 0, 1000, 1000));
3453 this->VisitLayer(scaled
, &occlusion
);
3454 this->VisitLayer(surface
, &occlusion
);
3455 this->VisitContributingSurface(surface
, &occlusion
);
3457 EXPECT_EQ(gfx::Rect().ToString(),
3458 occlusion
.occlusion_from_outside_target().ToString());
3459 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3460 occlusion
.occlusion_from_inside_target().ToString());
3464 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
3466 template <class Types
>
3467 class OcclusionTrackerTestCopyRequestDoesOcclude
3468 : public OcclusionTrackerTest
<Types
> {
3470 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
3471 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3473 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3474 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3475 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3476 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3477 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
3478 this->identity_matrix
,
3480 gfx::Size(200, 400));
3481 this->AddCopyRequest(copy
);
3482 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3484 this->identity_matrix
,
3486 gfx::Size(200, 400),
3488 this->CalcDrawEtc(root
);
3490 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3491 gfx::Rect(0, 0, 1000, 1000));
3493 this->VisitLayer(copy_child
, &occlusion
);
3494 EXPECT_EQ(gfx::Rect().ToString(),
3495 occlusion
.occlusion_from_outside_target().ToString());
3496 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3497 occlusion
.occlusion_from_inside_target().ToString());
3499 // CopyRequests cause the layer to own a surface.
3500 this->VisitContributingSurface(copy
, &occlusion
);
3502 // The occlusion from the copy should be kept.
3503 EXPECT_EQ(gfx::Rect().ToString(),
3504 occlusion
.occlusion_from_outside_target().ToString());
3505 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3506 occlusion
.occlusion_from_inside_target().ToString());
3510 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
3512 template <class Types
>
3513 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3514 : public OcclusionTrackerTest
<Types
> {
3516 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3518 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3520 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3521 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3522 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3523 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3524 typename
Types::LayerType
* hide
= this->CreateLayer(
3525 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
3526 typename
Types::LayerType
* copy
= this->CreateLayer(
3527 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
3528 this->AddCopyRequest(copy
);
3529 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3530 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
3532 // The |copy| layer is hidden but since it is being copied, it will be
3534 hide
->SetHideLayerAndSubtree(true);
3536 this->CalcDrawEtc(root
);
3538 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3539 gfx::Rect(0, 0, 1000, 1000));
3541 this->VisitLayer(copy_child
, &occlusion
);
3542 EXPECT_EQ(gfx::Rect().ToString(),
3543 occlusion
.occlusion_from_outside_target().ToString());
3544 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3545 occlusion
.occlusion_from_inside_target().ToString());
3547 // CopyRequests cause the layer to own a surface.
3548 this->VisitContributingSurface(copy
, &occlusion
);
3550 // The occlusion from the copy should be dropped since it is hidden.
3551 EXPECT_EQ(gfx::Rect().ToString(),
3552 occlusion
.occlusion_from_outside_target().ToString());
3553 EXPECT_EQ(gfx::Rect().ToString(),
3554 occlusion
.occlusion_from_inside_target().ToString());
3558 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)