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());
98 struct OcclusionTrackerTestMainThreadTypes
{
99 typedef Layer LayerType
;
100 typedef FakeLayerTreeHost HostType
;
101 typedef RenderSurface RenderSurfaceType
;
102 typedef TestContentLayer ContentLayerType
;
103 typedef scoped_refptr
<Layer
> LayerPtrType
;
104 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
105 typedef LayerIterator
<Layer
> TestLayerIterator
;
106 typedef OcclusionTracker
<Layer
> OcclusionTrackerType
;
108 static LayerPtrType
CreateLayer(HostType
* host
) { return Layer::Create(); }
109 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
110 return make_scoped_refptr(new ContentLayerType());
113 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
114 LayerPtrType
ref(*layer
);
119 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
120 LayerPtrType
ref(*layer
);
125 static void DestroyLayer(LayerPtrType
* layer
) { *layer
= NULL
; }
128 struct OcclusionTrackerTestImplThreadTypes
{
129 typedef LayerImpl LayerType
;
130 typedef LayerTreeImpl HostType
;
131 typedef RenderSurfaceImpl RenderSurfaceType
;
132 typedef TestContentLayerImpl ContentLayerType
;
133 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
134 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
135 typedef LayerIterator
<LayerImpl
> TestLayerIterator
;
136 typedef OcclusionTracker
<LayerImpl
> OcclusionTrackerType
;
138 static LayerPtrType
CreateLayer(HostType
* host
) {
139 return LayerImpl::Create(host
, next_layer_impl_id
++);
141 static ContentLayerPtrType
CreateContentLayer(HostType
* host
) {
142 return make_scoped_ptr(new ContentLayerType(host
, next_layer_impl_id
++));
144 static int next_layer_impl_id
;
146 static LayerPtrType
PassLayerPtr(LayerPtrType
* layer
) {
147 return layer
->Pass();
150 static LayerPtrType
PassLayerPtr(ContentLayerPtrType
* layer
) {
151 return layer
->PassAs
<LayerType
>();
154 static void DestroyLayer(LayerPtrType
* layer
) { layer
->reset(); }
157 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id
= 1;
159 template <typename Types
> class OcclusionTrackerTest
: public testing::Test
{
161 explicit OcclusionTrackerTest(bool opaque_layers
)
162 : opaque_layers_(opaque_layers
), host_(FakeLayerTreeHost::Create()) {}
164 virtual void RunMyTest() = 0;
166 virtual void TearDown() {
167 Types::DestroyLayer(&root_
);
168 render_surface_layer_list_
.reset();
169 render_surface_layer_list_impl_
.clear();
170 replica_layers_
.clear();
171 mask_layers_
.clear();
174 typename
Types::HostType
* GetHost();
176 typename
Types::ContentLayerType
* CreateRoot(const gfx::Transform
& transform
,
177 const gfx::PointF
& position
,
178 const gfx::Size
& bounds
) {
179 typename
Types::ContentLayerPtrType
layer(
180 Types::CreateContentLayer(GetHost()));
181 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
182 SetProperties(layer_ptr
, transform
, position
, bounds
);
184 DCHECK(!root_
.get());
185 root_
= Types::PassLayerPtr(&layer
);
187 SetRootLayerOnMainThread(layer_ptr
);
192 typename
Types::LayerType
* CreateLayer(typename
Types::LayerType
* parent
,
193 const gfx::Transform
& transform
,
194 const gfx::PointF
& position
,
195 const gfx::Size
& bounds
) {
196 typename
Types::LayerPtrType
layer(Types::CreateLayer(GetHost()));
197 typename
Types::LayerType
* layer_ptr
= layer
.get();
198 SetProperties(layer_ptr
, transform
, position
, bounds
);
199 parent
->AddChild(Types::PassLayerPtr(&layer
));
203 typename
Types::LayerType
* CreateSurface(typename
Types::LayerType
* parent
,
204 const gfx::Transform
& transform
,
205 const gfx::PointF
& position
,
206 const gfx::Size
& bounds
) {
207 typename
Types::LayerType
* layer
=
208 CreateLayer(parent
, transform
, position
, bounds
);
209 layer
->SetForceRenderSurface(true);
213 typename
Types::ContentLayerType
* CreateDrawingLayer(
214 typename
Types::LayerType
* parent
,
215 const gfx::Transform
& transform
,
216 const gfx::PointF
& position
,
217 const gfx::Size
& bounds
,
219 typename
Types::ContentLayerPtrType
layer(
220 Types::CreateContentLayer(GetHost()));
221 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
222 SetProperties(layer_ptr
, transform
, position
, bounds
);
224 if (opaque_layers_
) {
225 layer_ptr
->SetContentsOpaque(opaque
);
227 layer_ptr
->SetContentsOpaque(false);
229 layer_ptr
->SetOpaqueContentsRect(gfx::Rect(bounds
));
231 layer_ptr
->SetOpaqueContentsRect(gfx::Rect());
234 parent
->AddChild(Types::PassLayerPtr(&layer
));
238 typename
Types::LayerType
* CreateReplicaLayer(
239 typename
Types::LayerType
* owning_layer
,
240 const gfx::Transform
& transform
,
241 const gfx::PointF
& position
,
242 const gfx::Size
& bounds
) {
243 typename
Types::ContentLayerPtrType
layer(
244 Types::CreateContentLayer(GetHost()));
245 typename
Types::ContentLayerType
* layer_ptr
= layer
.get();
246 SetProperties(layer_ptr
, transform
, position
, bounds
);
247 SetReplica(owning_layer
, Types::PassLayerPtr(&layer
));
251 typename
Types::LayerType
* CreateMaskLayer(
252 typename
Types::LayerType
* owning_layer
,
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
, identity_matrix
, gfx::PointF(), bounds
);
258 SetMask(owning_layer
, Types::PassLayerPtr(&layer
));
262 typename
Types::ContentLayerType
* CreateDrawingSurface(
263 typename
Types::LayerType
* parent
,
264 const gfx::Transform
& transform
,
265 const gfx::PointF
& position
,
266 const gfx::Size
& bounds
,
268 typename
Types::ContentLayerType
* layer
=
269 CreateDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
270 layer
->SetForceRenderSurface(true);
275 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {}
277 void AddCopyRequest(Layer
* layer
) {
278 layer
->RequestCopyOfOutput(
279 CopyOutputRequest::CreateBitmapRequest(base::Bind(
280 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
281 base::Unretained(this))));
284 void AddCopyRequest(LayerImpl
* layer
) {
285 ScopedPtrVector
<CopyOutputRequest
> requests
;
287 CopyOutputRequest::CreateBitmapRequest(base::Bind(
288 &OcclusionTrackerTest
<Types
>::CopyOutputCallback
,
289 base::Unretained(this))));
290 layer
->PassCopyRequests(&requests
);
293 void CalcDrawEtc(TestContentLayerImpl
* root
) {
294 DCHECK(root
== root_
.get());
295 DCHECK(!root
->render_surface());
297 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
298 root
, root
->bounds(), &render_surface_layer_list_impl_
);
299 inputs
.can_adjust_raster_scales
= true;
300 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
302 layer_iterator_
= layer_iterator_begin_
=
303 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_
);
306 void CalcDrawEtc(TestContentLayer
* root
) {
307 DCHECK(root
== root_
.get());
308 DCHECK(!root
->render_surface());
310 render_surface_layer_list_
.reset(new RenderSurfaceLayerList
);
311 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
312 root
, root
->bounds(), render_surface_layer_list_
.get());
313 inputs
.can_adjust_raster_scales
= true;
314 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
316 layer_iterator_
= layer_iterator_begin_
=
317 Types::TestLayerIterator::Begin(render_surface_layer_list_
.get());
320 void SetDrawsContent(LayerImpl
* layer_impl
, bool draws_content
) {
321 layer_impl
->SetDrawsContent(draws_content
);
324 void SetDrawsContent(Layer
* layer
, bool draws_content
) {
325 layer
->SetIsDrawable(draws_content
);
328 void EnterLayer(typename
Types::LayerType
* layer
,
329 typename
Types::OcclusionTrackerType
* occlusion
) {
330 ASSERT_EQ(layer
, *layer_iterator_
);
331 ASSERT_TRUE(layer_iterator_
.represents_itself());
332 occlusion
->EnterLayer(layer_iterator_
);
335 void LeaveLayer(typename
Types::LayerType
* layer
,
336 typename
Types::OcclusionTrackerType
* occlusion
) {
337 ASSERT_EQ(layer
, *layer_iterator_
);
338 ASSERT_TRUE(layer_iterator_
.represents_itself());
339 occlusion
->LeaveLayer(layer_iterator_
);
343 void VisitLayer(typename
Types::LayerType
* layer
,
344 typename
Types::OcclusionTrackerType
* occlusion
) {
345 EnterLayer(layer
, occlusion
);
346 LeaveLayer(layer
, occlusion
);
349 void EnterContributingSurface(
350 typename
Types::LayerType
* layer
,
351 typename
Types::OcclusionTrackerType
* occlusion
) {
352 ASSERT_EQ(layer
, *layer_iterator_
);
353 ASSERT_TRUE(layer_iterator_
.represents_target_render_surface());
354 occlusion
->EnterLayer(layer_iterator_
);
355 occlusion
->LeaveLayer(layer_iterator_
);
357 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
358 occlusion
->EnterLayer(layer_iterator_
);
361 void LeaveContributingSurface(
362 typename
Types::LayerType
* layer
,
363 typename
Types::OcclusionTrackerType
* occlusion
) {
364 ASSERT_EQ(layer
, *layer_iterator_
);
365 ASSERT_TRUE(layer_iterator_
.represents_contributing_render_surface());
366 occlusion
->LeaveLayer(layer_iterator_
);
370 void VisitContributingSurface(
371 typename
Types::LayerType
* layer
,
372 typename
Types::OcclusionTrackerType
* occlusion
) {
373 EnterContributingSurface(layer
, occlusion
);
374 LeaveContributingSurface(layer
, occlusion
);
377 void ResetLayerIterator() { layer_iterator_
= layer_iterator_begin_
; }
379 const gfx::Transform identity_matrix
;
382 void SetRootLayerOnMainThread(Layer
* root
) {
383 host_
->SetRootLayer(scoped_refptr
<Layer
>(root
));
386 void SetRootLayerOnMainThread(LayerImpl
* root
) {}
388 void SetBaseProperties(typename
Types::LayerType
* layer
,
389 const gfx::Transform
& transform
,
390 const gfx::PointF
& position
,
391 const gfx::Size
& bounds
) {
392 layer
->SetTransform(transform
);
393 layer
->SetAnchorPoint(gfx::PointF());
394 layer
->SetPosition(position
);
395 layer
->SetBounds(bounds
);
398 void SetProperties(Layer
* layer
,
399 const gfx::Transform
& transform
,
400 const gfx::PointF
& position
,
401 const gfx::Size
& bounds
) {
402 SetBaseProperties(layer
, transform
, position
, bounds
);
405 void SetProperties(LayerImpl
* layer
,
406 const gfx::Transform
& transform
,
407 const gfx::PointF
& position
,
408 const gfx::Size
& bounds
) {
409 SetBaseProperties(layer
, transform
, position
, bounds
);
411 layer
->SetContentBounds(layer
->bounds());
414 void SetReplica(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
415 owning_layer
->SetReplicaLayer(layer
.get());
416 replica_layers_
.push_back(layer
);
419 void SetReplica(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
420 owning_layer
->SetReplicaLayer(layer
.Pass());
423 void SetMask(Layer
* owning_layer
, scoped_refptr
<Layer
> layer
) {
424 owning_layer
->SetMaskLayer(layer
.get());
425 mask_layers_
.push_back(layer
);
428 void SetMask(LayerImpl
* owning_layer
, scoped_ptr
<LayerImpl
> layer
) {
429 owning_layer
->SetMaskLayer(layer
.Pass());
433 scoped_ptr
<FakeLayerTreeHost
> host_
;
434 // These hold ownership of the layers for the duration of the test.
435 typename
Types::LayerPtrType root_
;
436 scoped_ptr
<RenderSurfaceLayerList
> render_surface_layer_list_
;
437 LayerImplList render_surface_layer_list_impl_
;
438 typename
Types::TestLayerIterator layer_iterator_begin_
;
439 typename
Types::TestLayerIterator layer_iterator_
;
440 typename
Types::LayerType
* last_layer_visited_
;
441 LayerList replica_layers_
;
442 LayerList mask_layers_
;
447 OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::GetHost() {
453 OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::GetHost() {
454 return host_
->host_impl()->active_tree();
457 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
458 class ClassName##MainThreadOpaqueLayers \
459 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
460 public: /* NOLINT(whitespace/indent) */ \
461 ClassName##MainThreadOpaqueLayers() \
462 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
464 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
465 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
466 class ClassName##MainThreadOpaquePaints \
467 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
468 public: /* NOLINT(whitespace/indent) */ \
469 ClassName##MainThreadOpaquePaints() \
470 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
472 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
474 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
475 class ClassName##ImplThreadOpaqueLayers \
476 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
477 public: /* NOLINT(whitespace/indent) */ \
478 ClassName##ImplThreadOpaqueLayers() \
479 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
481 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
482 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
483 class ClassName##ImplThreadOpaquePaints \
484 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
485 public: /* NOLINT(whitespace/indent) */ \
486 ClassName##ImplThreadOpaquePaints() \
487 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
489 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
491 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
492 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
493 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
494 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
495 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
497 #define MAIN_THREAD_TEST(ClassName) \
498 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
500 #define IMPL_THREAD_TEST(ClassName) \
501 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
503 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
504 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
505 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
507 template <class Types
>
508 class OcclusionTrackerTestIdentityTransforms
509 : public OcclusionTrackerTest
<Types
> {
511 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers
)
512 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
515 typename
Types::ContentLayerType
* root
= this->CreateRoot(
516 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
517 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
518 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
519 typename
Types::ContentLayerType
* layer
=
520 this->CreateDrawingLayer(parent
,
521 this->identity_matrix
,
522 gfx::PointF(30.f
, 30.f
),
525 parent
->SetMasksToBounds(true);
526 this->CalcDrawEtc(root
);
528 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
529 gfx::Rect(0, 0, 1000, 1000));
531 this->VisitLayer(layer
, &occlusion
);
532 this->EnterLayer(parent
, &occlusion
);
534 EXPECT_EQ(gfx::Rect().ToString(),
535 occlusion
.occlusion_from_outside_target().ToString());
536 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
537 occlusion
.occlusion_from_inside_target().ToString());
539 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
540 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
541 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
542 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
543 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
545 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
546 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
547 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
548 occlusion
.UnoccludedLayerContentRect(
549 parent
, gfx::Rect(29, 30, 70, 70)));
550 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
551 occlusion
.UnoccludedLayerContentRect(
552 parent
, gfx::Rect(29, 29, 70, 70)));
553 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
554 occlusion
.UnoccludedLayerContentRect(
555 parent
, gfx::Rect(30, 29, 70, 70)));
556 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
557 occlusion
.UnoccludedLayerContentRect(
558 parent
, gfx::Rect(31, 29, 69, 70)));
559 EXPECT_RECT_EQ(gfx::Rect(),
560 occlusion
.UnoccludedLayerContentRect(
561 parent
, gfx::Rect(31, 30, 69, 70)));
562 EXPECT_RECT_EQ(gfx::Rect(),
563 occlusion
.UnoccludedLayerContentRect(
564 parent
, gfx::Rect(31, 31, 69, 69)));
565 EXPECT_RECT_EQ(gfx::Rect(),
566 occlusion
.UnoccludedLayerContentRect(
567 parent
, gfx::Rect(30, 31, 70, 69)));
568 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
569 occlusion
.UnoccludedLayerContentRect(
570 parent
, gfx::Rect(29, 31, 70, 69)));
574 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
576 template <class Types
>
577 class OcclusionTrackerTestQuadsMismatchLayer
578 : public OcclusionTrackerTest
<Types
> {
580 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers
)
581 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
583 gfx::Transform layer_transform
;
584 layer_transform
.Translate(10.0, 10.0);
586 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
587 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(100, 100));
588 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
589 parent
, layer_transform
, gfx::PointF(), gfx::Size(90, 90), true);
590 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
591 layer1
, layer_transform
, gfx::PointF(), gfx::Size(50, 50), true);
592 this->CalcDrawEtc(parent
);
594 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
595 gfx::Rect(0, 0, 1000, 1000));
597 this->VisitLayer(layer2
, &occlusion
);
598 this->EnterLayer(layer1
, &occlusion
);
600 EXPECT_EQ(gfx::Rect().ToString(),
601 occlusion
.occlusion_from_outside_target().ToString());
602 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
603 occlusion
.occlusion_from_inside_target().ToString());
605 // This checks cases where the quads don't match their "containing"
606 // layers, e.g. in terms of transforms or clip rect. This is typical for
607 // DelegatedRendererLayer.
609 gfx::Transform quad_transform
;
610 quad_transform
.Translate(30.0, 30.0);
612 EXPECT_TRUE(occlusion
.UnoccludedContentRect(parent
,
613 gfx::Rect(0, 0, 10, 10),
614 quad_transform
).IsEmpty());
615 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
616 occlusion
.UnoccludedContentRect(
617 parent
, gfx::Rect(40, 40, 10, 10), quad_transform
));
618 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
619 occlusion
.UnoccludedContentRect(
620 parent
, gfx::Rect(35, 30, 10, 10), quad_transform
));
624 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
626 template <class Types
>
627 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
629 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers
)
630 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
632 gfx::Transform layer_transform
;
633 layer_transform
.Translate(250.0, 250.0);
634 layer_transform
.Rotate(90.0);
635 layer_transform
.Translate(-250.0, -250.0);
637 typename
Types::ContentLayerType
* root
= this->CreateRoot(
638 this->identity_matrix
, gfx::Point(0, 0), gfx::Size(200, 200));
639 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
640 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
641 typename
Types::ContentLayerType
* layer
=
642 this->CreateDrawingLayer(parent
,
644 gfx::PointF(30.f
, 30.f
),
647 parent
->SetMasksToBounds(true);
648 this->CalcDrawEtc(root
);
650 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
651 gfx::Rect(0, 0, 1000, 1000));
653 this->VisitLayer(layer
, &occlusion
);
654 this->EnterLayer(parent
, &occlusion
);
656 EXPECT_EQ(gfx::Rect().ToString(),
657 occlusion
.occlusion_from_outside_target().ToString());
658 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
659 occlusion
.occlusion_from_inside_target().ToString());
661 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
662 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
663 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
664 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 69, 70)));
665 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 70, 69)));
667 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
668 parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
669 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
670 occlusion
.UnoccludedLayerContentRect(
671 parent
, gfx::Rect(29, 30, 69, 70)));
672 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
673 occlusion
.UnoccludedLayerContentRect(
674 parent
, gfx::Rect(29, 29, 70, 70)));
675 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
676 occlusion
.UnoccludedLayerContentRect(
677 parent
, gfx::Rect(30, 29, 70, 70)));
678 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
679 occlusion
.UnoccludedLayerContentRect(
680 parent
, gfx::Rect(31, 29, 69, 70)));
681 EXPECT_RECT_EQ(gfx::Rect(),
682 occlusion
.UnoccludedLayerContentRect(
683 parent
, gfx::Rect(31, 30, 69, 70)));
684 EXPECT_RECT_EQ(gfx::Rect(),
685 occlusion
.UnoccludedLayerContentRect(
686 parent
, gfx::Rect(31, 31, 69, 69)));
687 EXPECT_RECT_EQ(gfx::Rect(),
688 occlusion
.UnoccludedLayerContentRect(
689 parent
, gfx::Rect(30, 31, 70, 69)));
690 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
691 occlusion
.UnoccludedLayerContentRect(
692 parent
, gfx::Rect(29, 31, 70, 69)));
696 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
698 template <class Types
>
699 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
701 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers
)
702 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
704 gfx::Transform layer_transform
;
705 layer_transform
.Translate(20.0, 20.0);
707 typename
Types::ContentLayerType
* root
= this->CreateRoot(
708 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
709 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
710 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
711 typename
Types::ContentLayerType
* layer
=
712 this->CreateDrawingLayer(parent
,
714 gfx::PointF(30.f
, 30.f
),
717 parent
->SetMasksToBounds(true);
718 this->CalcDrawEtc(root
);
720 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
721 gfx::Rect(0, 0, 1000, 1000));
723 this->VisitLayer(layer
, &occlusion
);
724 this->EnterLayer(parent
, &occlusion
);
726 EXPECT_EQ(gfx::Rect().ToString(),
727 occlusion
.occlusion_from_outside_target().ToString());
728 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
729 occlusion
.occlusion_from_inside_target().ToString());
731 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
732 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
733 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
734 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(51, 50, 49, 50)));
735 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(50, 51, 50, 49)));
737 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
738 parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
739 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
740 occlusion
.UnoccludedLayerContentRect(
741 parent
, gfx::Rect(49, 50, 50, 50)));
742 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
743 occlusion
.UnoccludedLayerContentRect(
744 parent
, gfx::Rect(49, 49, 50, 50)));
745 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
746 occlusion
.UnoccludedLayerContentRect(
747 parent
, gfx::Rect(50, 49, 50, 50)));
748 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
749 occlusion
.UnoccludedLayerContentRect(
750 parent
, gfx::Rect(51, 49, 49, 50)));
751 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
752 parent
, gfx::Rect(51, 50, 49, 50)).IsEmpty());
753 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
754 parent
, gfx::Rect(51, 51, 49, 49)).IsEmpty());
755 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
756 parent
, gfx::Rect(50, 51, 50, 49)).IsEmpty());
757 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
758 occlusion
.UnoccludedLayerContentRect(
759 parent
, gfx::Rect(49, 51, 50, 49)));
763 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
765 template <class Types
>
766 class OcclusionTrackerTestChildInRotatedChild
767 : public OcclusionTrackerTest
<Types
> {
769 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers
)
770 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
772 gfx::Transform child_transform
;
773 child_transform
.Translate(250.0, 250.0);
774 child_transform
.Rotate(90.0);
775 child_transform
.Translate(-250.0, -250.0);
777 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
778 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
779 parent
->SetMasksToBounds(true);
780 typename
Types::LayerType
* child
= this->CreateSurface(
781 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
782 child
->SetMasksToBounds(true);
783 typename
Types::ContentLayerType
* layer
=
784 this->CreateDrawingLayer(child
,
785 this->identity_matrix
,
786 gfx::PointF(10.f
, 10.f
),
789 this->CalcDrawEtc(parent
);
791 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
792 gfx::Rect(0, 0, 1000, 1000));
794 this->VisitLayer(layer
, &occlusion
);
795 this->EnterContributingSurface(child
, &occlusion
);
797 EXPECT_EQ(gfx::Rect().ToString(),
798 occlusion
.occlusion_from_outside_target().ToString());
799 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
800 occlusion
.occlusion_from_inside_target().ToString());
802 this->LeaveContributingSurface(child
, &occlusion
);
803 this->EnterLayer(parent
, &occlusion
);
805 EXPECT_EQ(gfx::Rect().ToString(),
806 occlusion
.occlusion_from_outside_target().ToString());
807 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
808 occlusion
.occlusion_from_inside_target().ToString());
810 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
811 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
812 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
813 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 40, 69, 60)));
814 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 41, 70, 59)));
816 /* Justification for the above occlusion from |layer|:
818 +---------------------+
821 | 30 + ---------------------------------+
823 | |10+---------------------------------+
827 +----|--|-------------+ | |
835 +--|-------------------------------+ |
837 +---------------------------------+
840 +---------------------+
841 | |30 Visible region of |layer|: /////
843 | +---------------------------------+
845 | +---------------------------------+ |
846 | | |///////////////| 420 | |
847 | | |///////////////|60 | |
848 | | |///////////////| | |
849 +--|--|---------------+ | |
857 | +------------------------------|--+
859 +---------------------------------+
866 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
868 template <class Types
>
869 class OcclusionTrackerTestScaledRenderSurface
870 : public OcclusionTrackerTest
<Types
> {
872 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers
)
873 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
876 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
877 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
879 gfx::Transform layer1_matrix
;
880 layer1_matrix
.Scale(2.0, 2.0);
881 typename
Types::ContentLayerType
* layer1
= this->CreateDrawingLayer(
882 parent
, layer1_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
883 layer1
->SetForceRenderSurface(true);
885 gfx::Transform layer2_matrix
;
886 layer2_matrix
.Translate(25.0, 25.0);
887 typename
Types::ContentLayerType
* layer2
= this->CreateDrawingLayer(
888 layer1
, layer2_matrix
, gfx::PointF(), gfx::Size(50, 50), true);
889 typename
Types::ContentLayerType
* occluder
=
890 this->CreateDrawingLayer(parent
,
891 this->identity_matrix
,
892 gfx::PointF(100.f
, 100.f
),
895 this->CalcDrawEtc(parent
);
897 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
898 gfx::Rect(0, 0, 1000, 1000));
900 this->VisitLayer(occluder
, &occlusion
);
901 this->EnterLayer(layer2
, &occlusion
);
903 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
904 occlusion
.occlusion_from_outside_target().ToString());
905 EXPECT_EQ(gfx::Rect().ToString(),
906 occlusion
.occlusion_from_inside_target().ToString());
909 gfx::Rect(0, 0, 25, 25),
910 occlusion
.UnoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
911 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
912 occlusion
.UnoccludedLayerContentRect(
913 layer2
, gfx::Rect(10, 25, 25, 25)));
914 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
915 occlusion
.UnoccludedLayerContentRect(
916 layer2
, gfx::Rect(25, 10, 25, 25)));
917 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
918 layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
922 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
924 template <class Types
>
925 class OcclusionTrackerTestVisitTargetTwoTimes
926 : public OcclusionTrackerTest
<Types
> {
928 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers
)
929 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
931 gfx::Transform child_transform
;
932 child_transform
.Translate(250.0, 250.0);
933 child_transform
.Rotate(90.0);
934 child_transform
.Translate(-250.0, -250.0);
936 typename
Types::ContentLayerType
* root
= this->CreateRoot(
937 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 200));
938 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
939 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
940 parent
->SetMasksToBounds(true);
941 typename
Types::LayerType
* child
= this->CreateSurface(
942 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
943 child
->SetMasksToBounds(true);
944 typename
Types::ContentLayerType
* layer
=
945 this->CreateDrawingLayer(child
,
946 this->identity_matrix
,
947 gfx::PointF(10.f
, 10.f
),
950 // |child2| makes |parent|'s surface get considered by OcclusionTracker
951 // first, instead of |child|'s. This exercises different code in
952 // LeaveToRenderTarget, as the target surface has already been seen.
953 typename
Types::ContentLayerType
* child2
=
954 this->CreateDrawingLayer(parent
,
955 this->identity_matrix
,
956 gfx::PointF(30.f
, 30.f
),
959 this->CalcDrawEtc(root
);
961 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
962 gfx::Rect(0, 0, 1000, 1000));
964 this->VisitLayer(child2
, &occlusion
);
966 EXPECT_EQ(gfx::Rect().ToString(),
967 occlusion
.occlusion_from_outside_target().ToString());
968 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
969 occlusion
.occlusion_from_inside_target().ToString());
971 this->VisitLayer(layer
, &occlusion
);
973 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
974 occlusion
.occlusion_from_outside_target().ToString());
975 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
976 occlusion
.occlusion_from_inside_target().ToString());
978 this->EnterContributingSurface(child
, &occlusion
);
980 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
981 occlusion
.occlusion_from_outside_target().ToString());
982 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
983 occlusion
.occlusion_from_inside_target().ToString());
985 // Occlusion in |child2| should get merged with the |child| surface we are
987 this->LeaveContributingSurface(child
, &occlusion
);
988 this->EnterLayer(parent
, &occlusion
);
990 EXPECT_EQ(gfx::Rect().ToString(),
991 occlusion
.occlusion_from_outside_target().ToString());
992 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
994 occlusion
.occlusion_from_inside_target().ToString());
996 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
997 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
998 occlusion
.UnoccludedLayerContentRect(
999 parent
, gfx::Rect(30, 30, 70, 70)));
1001 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
1002 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
1003 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
1004 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
1005 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
1007 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1008 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1009 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1011 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1012 parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1013 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1014 occlusion
.UnoccludedLayerContentRect(
1015 parent
, gfx::Rect(29, 30, 60, 10)));
1016 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1017 occlusion
.UnoccludedLayerContentRect(
1018 parent
, gfx::Rect(30, 29, 60, 10)));
1019 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1020 occlusion
.UnoccludedLayerContentRect(
1021 parent
, gfx::Rect(31, 30, 60, 10)));
1022 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1023 parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1025 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1026 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1027 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1028 occlusion
.UnoccludedLayerContentRect(
1029 parent
, gfx::Rect(29, 40, 70, 60)));
1030 // This rect is mostly occluded by |child2|.
1031 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1032 occlusion
.UnoccludedLayerContentRect(
1033 parent
, gfx::Rect(30, 39, 70, 60)));
1034 // This rect extends past top/right ends of |child2|.
1035 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1036 occlusion
.UnoccludedLayerContentRect(
1037 parent
, gfx::Rect(30, 29, 70, 70)));
1038 // This rect extends past left/right ends of |child2|.
1039 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1040 occlusion
.UnoccludedLayerContentRect(
1041 parent
, gfx::Rect(20, 39, 80, 60)));
1042 EXPECT_RECT_EQ(gfx::Rect(),
1043 occlusion
.UnoccludedLayerContentRect(
1044 parent
, gfx::Rect(31, 40, 69, 60)));
1045 EXPECT_RECT_EQ(gfx::Rect(),
1046 occlusion
.UnoccludedLayerContentRect(
1047 parent
, gfx::Rect(30, 41, 70, 59)));
1049 /* Justification for the above occlusion from |layer|:
1051 +---------------------+
1054 | 30 + ------------+--------------------+
1055 100 | | 10 | | | ==>
1056 | |10+----------|----------------------+
1057 | + ------------+ | | |
1060 +----|--|-------------+ | |
1068 +--|-------------------------------+ |
1070 +---------------------------------+
1074 +---------------------+
1075 | |30 Visible region of |layer|: /////
1076 | 30 60 | |child2|: \\\\\
1077 | 30 +------------+--------------------+
1078 | |\\\\\\\\\\\\| |10 |
1079 | +--|\\\\\\\\\\\\|-----------------+ |
1080 | | +------------+//| 420 | |
1081 | | |///////////////|60 | |
1082 | | |///////////////| | |
1083 +--|--|---------------+ | |
1091 | +------------------------------|--+
1093 +---------------------------------+
1099 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
1101 template <class Types
>
1102 class OcclusionTrackerTestSurfaceRotatedOffAxis
1103 : public OcclusionTrackerTest
<Types
> {
1105 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers
)
1106 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1108 gfx::Transform child_transform
;
1109 child_transform
.Translate(250.0, 250.0);
1110 child_transform
.Rotate(95.0);
1111 child_transform
.Translate(-250.0, -250.0);
1113 gfx::Transform layer_transform
;
1114 layer_transform
.Translate(10.0, 10.0);
1116 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1117 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1118 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1119 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1120 typename
Types::LayerType
* child
= this->CreateLayer(
1121 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(500, 500));
1122 child
->SetMasksToBounds(true);
1123 typename
Types::ContentLayerType
* layer
= this->CreateDrawingLayer(
1124 child
, layer_transform
, gfx::PointF(), gfx::Size(500, 500), true);
1125 this->CalcDrawEtc(root
);
1127 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1128 gfx::Rect(0, 0, 1000, 1000));
1130 gfx::Rect clipped_layer_in_child
= MathUtil::MapEnclosingClippedRect(
1131 layer_transform
, layer
->visible_content_rect());
1133 this->VisitLayer(layer
, &occlusion
);
1134 this->EnterContributingSurface(child
, &occlusion
);
1136 EXPECT_EQ(gfx::Rect().ToString(),
1137 occlusion
.occlusion_from_outside_target().ToString());
1138 EXPECT_EQ(clipped_layer_in_child
.ToString(),
1139 occlusion
.occlusion_from_inside_target().ToString());
1141 this->LeaveContributingSurface(child
, &occlusion
);
1142 this->EnterLayer(parent
, &occlusion
);
1144 EXPECT_EQ(gfx::Rect().ToString(),
1145 occlusion
.occlusion_from_outside_target().ToString());
1146 EXPECT_EQ(gfx::Rect().ToString(),
1147 occlusion
.occlusion_from_inside_target().ToString());
1149 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
1151 gfx::Rect(75, 55, 1, 1),
1152 occlusion
.UnoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
1156 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
1158 template <class Types
>
1159 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1160 : public OcclusionTrackerTest
<Types
> {
1162 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers
)
1163 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1165 gfx::Transform child_transform
;
1166 child_transform
.Translate(250.0, 250.0);
1167 child_transform
.Rotate(90.0);
1168 child_transform
.Translate(-250.0, -250.0);
1170 typename
Types::ContentLayerType
* root
= this->CreateRoot(
1171 this->identity_matrix
, gfx::PointF(), gfx::Size(1000, 1000));
1172 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
1173 root
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100), true);
1174 parent
->SetMasksToBounds(true);
1175 typename
Types::ContentLayerType
* child
=
1176 this->CreateDrawingSurface(parent
,
1178 gfx::PointF(30.f
, 30.f
),
1179 gfx::Size(500, 500),
1181 child
->SetMasksToBounds(true);
1182 typename
Types::ContentLayerType
* layer1
=
1183 this->CreateDrawingLayer(child
,
1184 this->identity_matrix
,
1185 gfx::PointF(10.f
, 10.f
),
1186 gfx::Size(500, 500),
1188 typename
Types::ContentLayerType
* layer2
=
1189 this->CreateDrawingLayer(child
,
1190 this->identity_matrix
,
1191 gfx::PointF(10.f
, 450.f
),
1194 this->CalcDrawEtc(root
);
1196 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1197 gfx::Rect(0, 0, 1000, 1000));
1199 this->VisitLayer(layer2
, &occlusion
);
1200 this->VisitLayer(layer1
, &occlusion
);
1201 this->VisitLayer(child
, &occlusion
);
1202 this->EnterContributingSurface(child
, &occlusion
);
1204 EXPECT_EQ(gfx::Rect().ToString(),
1205 occlusion
.occlusion_from_outside_target().ToString());
1206 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1207 occlusion
.occlusion_from_inside_target().ToString());
1209 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
1210 EXPECT_FALSE(occlusion
.OccludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
1211 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(11, 430, 59, 70)));
1212 EXPECT_TRUE(occlusion
.OccludedLayer(child
, gfx::Rect(10, 431, 60, 69)));
1214 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1215 child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1217 gfx::Rect(9, 430, 1, 70),
1218 occlusion
.UnoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
1219 EXPECT_RECT_EQ(gfx::Rect(),
1220 occlusion
.UnoccludedLayerContentRect(
1221 child
, gfx::Rect(11, 430, 59, 70)));
1222 EXPECT_RECT_EQ(gfx::Rect(),
1223 occlusion
.UnoccludedLayerContentRect(
1224 child
, gfx::Rect(10, 431, 60, 69)));
1226 this->LeaveContributingSurface(child
, &occlusion
);
1227 this->EnterLayer(parent
, &occlusion
);
1229 EXPECT_EQ(gfx::Rect().ToString(),
1230 occlusion
.occlusion_from_outside_target().ToString());
1231 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1232 occlusion
.occlusion_from_inside_target().ToString());
1234 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1235 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1236 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1238 EXPECT_TRUE(occlusion
.UnoccludedLayerContentRect(
1239 parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1240 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1241 occlusion
.UnoccludedLayerContentRect(
1242 parent
, gfx::Rect(29, 40, 70, 60)));
1243 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1244 occlusion
.UnoccludedLayerContentRect(
1245 parent
, gfx::Rect(30, 39, 70, 60)));
1246 EXPECT_RECT_EQ(gfx::Rect(),
1247 occlusion
.UnoccludedLayerContentRect(
1248 parent
, gfx::Rect(31, 40, 69, 60)));
1249 EXPECT_RECT_EQ(gfx::Rect(),
1250 occlusion
.UnoccludedLayerContentRect(
1251 parent
, gfx::Rect(30, 41, 70, 59)));
1253 /* Justification for the above occlusion from |layer1| and |layer2|:
1255 +---------------------+
1256 | |30 Visible region of |layer1|: /////
1257 | | Visible region of |layer2|: \\\\\
1258 | +---------------------------------+
1260 | +---------------+-----------------+ |
1261 | | |\\\\\\\\\\\\|//| 420 | |
1262 | | |\\\\\\\\\\\\|//|60 | |
1263 | | |\\\\\\\\\\\\|//| | |
1264 +--|--|------------|--+ | |
1272 | +------------|-----------------|--+
1274 +---------------+-----------------+
1280 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1282 template <class Types
>
1283 class OcclusionTrackerTestOverlappingSurfaceSiblings
1284 : public OcclusionTrackerTest
<Types
> {
1286 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers
)
1287 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1289 gfx::Transform child_transform
;
1290 child_transform
.Translate(250.0, 250.0);
1291 child_transform
.Rotate(90.0);
1292 child_transform
.Translate(-250.0, -250.0);
1294 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1295 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1296 parent
->SetMasksToBounds(true);
1297 typename
Types::LayerType
* child1
= this->CreateSurface(
1298 parent
, child_transform
, gfx::PointF(30.f
, 30.f
), gfx::Size(10, 10));
1299 typename
Types::LayerType
* child2
= this->CreateSurface(
1300 parent
, child_transform
, gfx::PointF(20.f
, 40.f
), gfx::Size(10, 10));
1301 typename
Types::ContentLayerType
* layer1
=
1302 this->CreateDrawingLayer(child1
,
1303 this->identity_matrix
,
1304 gfx::PointF(-10.f
, -10.f
),
1305 gfx::Size(510, 510),
1307 typename
Types::ContentLayerType
* layer2
=
1308 this->CreateDrawingLayer(child2
,
1309 this->identity_matrix
,
1310 gfx::PointF(-10.f
, -10.f
),
1311 gfx::Size(510, 510),
1313 this->CalcDrawEtc(parent
);
1315 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1316 gfx::Rect(0, 0, 1000, 1000));
1318 this->VisitLayer(layer2
, &occlusion
);
1319 this->EnterContributingSurface(child2
, &occlusion
);
1321 EXPECT_EQ(gfx::Rect().ToString(),
1322 occlusion
.occlusion_from_outside_target().ToString());
1323 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1324 occlusion
.occlusion_from_inside_target().ToString());
1326 // There is nothing above child2's surface in the z-order.
1327 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1328 occlusion
.UnoccludedContributingSurfaceContentRect(
1329 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1331 this->LeaveContributingSurface(child2
, &occlusion
);
1332 this->VisitLayer(layer1
, &occlusion
);
1333 this->EnterContributingSurface(child1
, &occlusion
);
1335 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1336 occlusion
.occlusion_from_outside_target().ToString());
1337 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1338 occlusion
.occlusion_from_inside_target().ToString());
1340 // child2's contents will occlude child1 below it.
1341 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1342 occlusion
.UnoccludedContributingSurfaceContentRect(
1343 child1
, false, gfx::Rect(-10, 430, 80, 70)));
1345 this->LeaveContributingSurface(child1
, &occlusion
);
1346 this->EnterLayer(parent
, &occlusion
);
1348 EXPECT_EQ(gfx::Rect().ToString(),
1349 occlusion
.occlusion_from_outside_target().ToString());
1350 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1352 occlusion
.occlusion_from_inside_target().ToString());
1354 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1356 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1357 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1358 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1360 EXPECT_TRUE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1361 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1362 EXPECT_FALSE(occlusion
.OccludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1364 /* Justification for the above occlusion:
1366 +---------------------+
1368 | 30+ ---------------------------------+
1369 100 | 30| | layer2 |
1370 |20+----------------------------------+ |
1374 +--|-|----------------+ | |
1382 | +--------------------------------|-+
1384 +----------------------------------+
1390 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1392 template <class Types
>
1393 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1394 : public OcclusionTrackerTest
<Types
> {
1396 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1398 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
1400 gfx::Transform child1_transform
;
1401 child1_transform
.Translate(250.0, 250.0);
1402 child1_transform
.Rotate(-90.0);
1403 child1_transform
.Translate(-250.0, -250.0);
1405 gfx::Transform child2_transform
;
1406 child2_transform
.Translate(250.0, 250.0);
1407 child2_transform
.Rotate(90.0);
1408 child2_transform
.Translate(-250.0, -250.0);
1410 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
1411 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 100));
1412 parent
->SetMasksToBounds(true);
1413 typename
Types::LayerType
* child1
= this->CreateSurface(
1414 parent
, child1_transform
, gfx::PointF(30.f
, 20.f
), gfx::Size(10, 10));
1415 typename
Types::LayerType
* child2
=
1416 this->CreateDrawingSurface(parent
,
1418 gfx::PointF(20.f
, 40.f
),
1421 typename
Types::ContentLayerType
* layer1
=
1422 this->CreateDrawingLayer(child1
,
1423 this->identity_matrix
,
1424 gfx::PointF(-10.f
, -20.f
),
1425 gfx::Size(510, 510),
1427 typename
Types::ContentLayerType
* layer2
=
1428 this->CreateDrawingLayer(child2
,
1429 this->identity_matrix
,
1430 gfx::PointF(-10.f
, -10.f
),
1431 gfx::Size(510, 510),
1433 this->CalcDrawEtc(parent
);
1435 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
1436 gfx::Rect(0, 0, 1000, 1000));
1438 this->VisitLayer(layer2
, &occlusion
);
1439 this->EnterLayer(child2
, &occlusion
);
1441 EXPECT_EQ(gfx::Rect().ToString(),
1442 occlusion
.occlusion_from_outside_target().ToString());
1443 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1444 occlusion
.occlusion_from_inside_target().ToString());
1446 this->LeaveLayer(child2
, &occlusion
);
1447 this->EnterContributingSurface(child2
, &occlusion
);
1449 // There is nothing above child2's surface in the z-order.
1450 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1451 occlusion
.UnoccludedContributingSurfaceContentRect(
1452 child2
, false, gfx::Rect(-10, 420, 70, 80)));
1454 this->LeaveContributingSurface(child2
, &occlusion
);
1455 this->VisitLayer(layer1
, &occlusion
);
1456 this->EnterContributingSurface(child1
, &occlusion
);
1458 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1459 occlusion
.occlusion_from_outside_target().ToString());
1460 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1461 occlusion
.occlusion_from_inside_target().ToString());
1463 // child2's contents will occlude child1 below it.
1464 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1465 occlusion
.UnoccludedContributingSurfaceContentRect(
1466 child1
, false, gfx::Rect(420, -20, 80, 90)));
1467 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1468 occlusion
.UnoccludedContributingSurfaceContentRect(
1469 child1
, false, gfx::Rect(420, -10, 80, 90)));
1470 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1471 occlusion
.UnoccludedContributingSurfaceContentRect(
1472 child1
, false, gfx::Rect(420, -20, 70, 90)));
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
.UnoccludedContributingSurfaceContentRect(
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
.UnoccludedContributingSurfaceContentRect(
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
.UnoccludedContributingSurfaceContentRect(
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
.UnoccludedContributingSurfaceContentRect(
2685 surface
, false, gfx::Rect(0, 0, 100, 100)));
2686 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2687 occlusion
.UnoccludedContributingSurfaceContentRect(
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
.UnoccludedContributingSurfaceContentRect(
2751 surface
, false, gfx::Rect(0, 0, 100, 100)));
2752 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2753 occlusion
.UnoccludedContributingSurfaceContentRect(
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
.UnoccludedContributingSurfaceContentRect(
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
.UnoccludedContributingSurfaceContentRect(
2838 surface
, false, gfx::Rect(0, 0, 100, 100)));
2842 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2844 template <class Types
>
2845 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
2846 : public OcclusionTrackerTest
<Types
> {
2848 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
2850 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2852 // This test verifies that the top-most surface is considered occluded
2853 // outside of its target's clip rect and outside the viewport rect.
2855 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2856 this->identity_matrix
, gfx::PointF(), gfx::Size(100, 200));
2857 typename
Types::LayerType
* surface
=
2858 this->CreateDrawingSurface(parent
,
2859 this->identity_matrix
,
2861 gfx::Size(100, 300),
2863 this->CalcDrawEtc(parent
);
2865 // Make a viewport rect that is larger than the root layer.
2866 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2867 gfx::Rect(0, 0, 1000, 1000));
2869 this->VisitLayer(surface
, &occlusion
);
2871 // The root layer always has a clip rect. So the parent of |surface| has a
2872 // clip rect giving the surface itself a clip rect.
2873 this->EnterContributingSurface(surface
, &occlusion
);
2874 // Make sure the parent's clip rect clips the unoccluded region of the
2876 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
2877 occlusion
.UnoccludedContributingSurfaceContentRect(
2878 surface
, false, gfx::Rect(0, 0, 100, 300)));
2880 this->ResetLayerIterator();
2882 // Make a viewport rect that is smaller than the root layer.
2883 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2884 gfx::Rect(0, 0, 100, 100));
2886 this->VisitLayer(surface
, &occlusion
);
2888 // The root layer always has a clip rect. So the parent of |surface| has a
2889 // clip rect giving the surface itself a clip rect.
2890 this->EnterContributingSurface(surface
, &occlusion
);
2891 // Make sure the viewport rect clips the unoccluded region of the child
2893 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2894 occlusion
.UnoccludedContributingSurfaceContentRect(
2895 surface
, false, gfx::Rect(0, 0, 100, 300)));
2900 ALL_OCCLUSIONTRACKER_TEST(
2901 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
);
2903 template <class Types
>
2904 class OcclusionTrackerTestSurfaceChildOfClippingSurface
2905 : public OcclusionTrackerTest
<Types
> {
2907 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers
)
2908 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2910 // This test verifies that the surface cliprect does not end up empty and
2911 // clip away the entire unoccluded rect.
2913 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2914 this->identity_matrix
, gfx::PointF(), gfx::Size(80, 200));
2915 parent
->SetMasksToBounds(true);
2916 typename
Types::LayerType
* surface
=
2917 this->CreateDrawingSurface(parent
,
2918 this->identity_matrix
,
2920 gfx::Size(100, 100),
2922 typename
Types::LayerType
* surface_child
=
2923 this->CreateDrawingSurface(surface
,
2924 this->identity_matrix
,
2926 gfx::Size(100, 100),
2928 typename
Types::LayerType
* topmost
= this->CreateDrawingLayer(
2929 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(100, 50), true);
2930 this->CalcDrawEtc(parent
);
2932 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
2933 gfx::Rect(0, 0, 1000, 1000));
2935 // |topmost| occludes everything partially so we know occlusion is happening
2937 this->VisitLayer(topmost
, &occlusion
);
2939 EXPECT_EQ(gfx::Rect().ToString(),
2940 occlusion
.occlusion_from_outside_target().ToString());
2941 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
2942 occlusion
.occlusion_from_inside_target().ToString());
2944 // surface_child is not opaque and does not occlude, so we have a non-empty
2945 // unoccluded area on surface.
2946 this->VisitLayer(surface_child
, &occlusion
);
2948 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
2949 occlusion
.occlusion_from_outside_target().ToString());
2950 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
2951 occlusion
.occlusion_from_inside_target().ToString());
2953 // The root layer always has a clip rect. So the parent of |surface| has a
2954 // clip rect. However, the owning layer for |surface| does not mask to
2955 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2956 // |surface_child| exercises different code paths as its parent does not
2957 // have a clip rect.
2959 this->EnterContributingSurface(surface_child
, &occlusion
);
2960 // The surface_child's parent does not have a clip rect as it owns a render
2963 gfx::Rect(0, 50, 80, 50).ToString(),
2964 occlusion
.UnoccludedContributingSurfaceContentRect(
2965 surface_child
, false, gfx::Rect(0, 0, 100, 100)).ToString());
2966 this->LeaveContributingSurface(surface_child
, &occlusion
);
2968 this->VisitLayer(surface
, &occlusion
);
2969 this->EnterContributingSurface(surface
, &occlusion
);
2970 // The surface's parent does have a clip rect as it is the root layer.
2971 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
2972 occlusion
.UnoccludedContributingSurfaceContentRect(
2973 surface
, false, gfx::Rect(0, 0, 100, 100)).ToString());
2977 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface
);
2979 template <class Types
>
2980 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2981 : public OcclusionTrackerTest
<Types
> {
2983 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2985 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
2987 gfx::Transform scale_by_half
;
2988 scale_by_half
.Scale(0.5, 0.5);
2990 // Make a 50x50 filtered surface that is completely surrounded by opaque
2991 // layers which are above it in the z-order. The surface is scaled to test
2992 // that the pixel moving is done in the target space, where the background
2993 // filter is applied.
2994 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
2995 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
2996 typename
Types::LayerType
* filtered_surface
=
2997 this->CreateDrawingLayer(parent
,
2999 gfx::PointF(50.f
, 50.f
),
3000 gfx::Size(100, 100),
3002 typename
Types::LayerType
* occluding_layer1
= this->CreateDrawingLayer(
3003 parent
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 50), true);
3004 typename
Types::LayerType
* occluding_layer2
=
3005 this->CreateDrawingLayer(parent
,
3006 this->identity_matrix
,
3007 gfx::PointF(0.f
, 100.f
),
3010 typename
Types::LayerType
* occluding_layer3
=
3011 this->CreateDrawingLayer(parent
,
3012 this->identity_matrix
,
3013 gfx::PointF(0.f
, 50.f
),
3016 typename
Types::LayerType
* occluding_layer4
=
3017 this->CreateDrawingLayer(parent
,
3018 this->identity_matrix
,
3019 gfx::PointF(100.f
, 50.f
),
3023 // Filters make the layer own a surface.
3024 FilterOperations filters
;
3025 filters
.Append(FilterOperation::CreateBlurFilter(10.f
));
3026 filtered_surface
->SetBackgroundFilters(filters
);
3028 // Save the distance of influence for the blur effect.
3029 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3031 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3033 this->CalcDrawEtc(parent
);
3035 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3036 gfx::Rect(0, 0, 1000, 1000));
3038 // These layers occlude pixels directly beside the filtered_surface. Because
3039 // filtered surface blends pixels in a radius, it will need to see some of
3040 // the pixels (up to radius far) underneath the occluding layers.
3041 this->VisitLayer(occluding_layer4
, &occlusion
);
3042 this->VisitLayer(occluding_layer3
, &occlusion
);
3043 this->VisitLayer(occluding_layer2
, &occlusion
);
3044 this->VisitLayer(occluding_layer1
, &occlusion
);
3046 Region expected_occlusion
;
3047 expected_occlusion
.Union(gfx::Rect(0, 0, 200, 50));
3048 expected_occlusion
.Union(gfx::Rect(0, 50, 50, 50));
3049 expected_occlusion
.Union(gfx::Rect(100, 50, 100, 50));
3050 expected_occlusion
.Union(gfx::Rect(0, 100, 200, 50));
3052 EXPECT_EQ(expected_occlusion
.ToString(),
3053 occlusion
.occlusion_from_inside_target().ToString());
3054 EXPECT_EQ(gfx::Rect().ToString(),
3055 occlusion
.occlusion_from_outside_target().ToString());
3057 this->VisitLayer(filtered_surface
, &occlusion
);
3059 // The filtered layer does not occlude.
3060 Region expected_occlusion_outside_surface
;
3061 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, -50, 200, 50));
3062 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 0, 50, 50));
3063 expected_occlusion_outside_surface
.Union(gfx::Rect(50, 0, 100, 50));
3064 expected_occlusion_outside_surface
.Union(gfx::Rect(-50, 50, 200, 50));
3066 EXPECT_EQ(expected_occlusion_outside_surface
.ToString(),
3067 occlusion
.occlusion_from_outside_target().ToString());
3068 EXPECT_EQ(gfx::Rect().ToString(),
3069 occlusion
.occlusion_from_inside_target().ToString());
3071 // The surface has a background blur, so it needs pixels that are currently
3072 // considered occluded in order to be drawn. So the pixels it needs should
3073 // be removed some the occluded area so that when we get to the parent they
3075 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3077 this->EnterLayer(parent
, &occlusion
);
3079 Region expected_blurred_occlusion
;
3080 expected_blurred_occlusion
.Union(gfx::Rect(0, 0, 200, 50 - outset_top
));
3081 expected_blurred_occlusion
.Union(gfx::Rect(
3082 0, 50 - outset_top
, 50 - outset_left
, 50 + outset_top
+ outset_bottom
));
3083 expected_blurred_occlusion
.Union(
3084 gfx::Rect(100 + outset_right
,
3087 50 + outset_top
+ outset_bottom
));
3088 expected_blurred_occlusion
.Union(
3089 gfx::Rect(0, 100 + outset_bottom
, 200, 50 - outset_bottom
));
3091 EXPECT_EQ(expected_blurred_occlusion
.ToString(),
3092 occlusion
.occlusion_from_inside_target().ToString());
3093 EXPECT_EQ(gfx::Rect().ToString(),
3094 occlusion
.occlusion_from_outside_target().ToString());
3096 gfx::Rect outset_rect
;
3097 gfx::Rect test_rect
;
3099 // Nothing in the blur outsets for the filtered_surface is occluded.
3100 outset_rect
= gfx::Rect(50 - outset_left
,
3102 50 + outset_left
+ outset_right
,
3103 50 + outset_top
+ outset_bottom
);
3104 test_rect
= outset_rect
;
3106 outset_rect
.ToString(),
3107 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3109 // Stuff outside the blur outsets is still occluded though.
3110 test_rect
= outset_rect
;
3111 test_rect
.Inset(0, 0, -1, 0);
3113 outset_rect
.ToString(),
3114 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3115 test_rect
= outset_rect
;
3116 test_rect
.Inset(0, 0, 0, -1);
3118 outset_rect
.ToString(),
3119 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3120 test_rect
= outset_rect
;
3121 test_rect
.Inset(-1, 0, 0, 0);
3123 outset_rect
.ToString(),
3124 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3125 test_rect
= outset_rect
;
3126 test_rect
.Inset(0, -1, 0, 0);
3128 outset_rect
.ToString(),
3129 occlusion
.UnoccludedLayerContentRect(parent
, test_rect
).ToString());
3133 ALL_OCCLUSIONTRACKER_TEST(
3134 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
3136 template <class Types
>
3137 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3138 : public OcclusionTrackerTest
<Types
> {
3140 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3142 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3144 gfx::Transform scale_by_half
;
3145 scale_by_half
.Scale(0.5, 0.5);
3147 // Makes two surfaces that completely cover |parent|. The occlusion both
3148 // above and below the filters will be reduced by each of them.
3149 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3150 this->identity_matrix
, gfx::PointF(), gfx::Size(75, 75));
3151 typename
Types::LayerType
* parent
= this->CreateSurface(
3152 root
, scale_by_half
, gfx::PointF(), gfx::Size(150, 150));
3153 parent
->SetMasksToBounds(true);
3154 typename
Types::LayerType
* filtered_surface1
= this->CreateDrawingLayer(
3155 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3156 typename
Types::LayerType
* filtered_surface2
= this->CreateDrawingLayer(
3157 parent
, scale_by_half
, gfx::PointF(), gfx::Size(300, 300), false);
3158 typename
Types::LayerType
* occluding_layer_above
=
3159 this->CreateDrawingLayer(parent
,
3160 this->identity_matrix
,
3161 gfx::PointF(100.f
, 100.f
),
3165 // Filters make the layers own surfaces.
3166 FilterOperations filters
;
3167 filters
.Append(FilterOperation::CreateBlurFilter(1.f
));
3168 filtered_surface1
->SetBackgroundFilters(filters
);
3169 filtered_surface2
->SetBackgroundFilters(filters
);
3171 // Save the distance of influence for the blur effect.
3172 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3174 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3176 this->CalcDrawEtc(root
);
3178 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3179 gfx::Rect(0, 0, 1000, 1000));
3181 this->VisitLayer(occluding_layer_above
, &occlusion
);
3182 EXPECT_EQ(gfx::Rect().ToString(),
3183 occlusion
.occlusion_from_outside_target().ToString());
3184 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3185 occlusion
.occlusion_from_inside_target().ToString());
3187 this->VisitLayer(filtered_surface2
, &occlusion
);
3188 this->VisitContributingSurface(filtered_surface2
, &occlusion
);
3189 this->VisitLayer(filtered_surface1
, &occlusion
);
3190 this->VisitContributingSurface(filtered_surface1
, &occlusion
);
3192 // Test expectations in the target.
3193 gfx::Rect expected_occlusion
=
3194 gfx::Rect(100 / 2 + outset_right
* 2,
3195 100 / 2 + outset_bottom
* 2,
3196 50 / 2 - (outset_left
+ outset_right
) * 2,
3197 50 / 2 - (outset_top
+ outset_bottom
) * 2);
3198 EXPECT_EQ(expected_occlusion
.ToString(),
3199 occlusion
.occlusion_from_inside_target().ToString());
3201 // Test expectations in the screen are the same as in the target, as the
3202 // render surface is 1:1 with the screen.
3203 EXPECT_EQ(expected_occlusion
.ToString(),
3204 occlusion
.occlusion_from_outside_target().ToString());
3208 ALL_OCCLUSIONTRACKER_TEST(
3209 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
3211 template <class Types
>
3212 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3213 : public OcclusionTrackerTest
<Types
> {
3215 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3217 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3219 gfx::Transform scale_by_half
;
3220 scale_by_half
.Scale(0.5, 0.5);
3222 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3223 // centered below each. The surface is scaled to test that the pixel moving
3224 // is done in the target space, where the background filter is applied, but
3225 // the surface appears at 50, 50 and the replica at 200, 50.
3226 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3227 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3228 typename
Types::LayerType
* behind_surface_layer
=
3229 this->CreateDrawingLayer(parent
,
3230 this->identity_matrix
,
3231 gfx::PointF(60.f
, 60.f
),
3234 typename
Types::LayerType
* behind_replica_layer
=
3235 this->CreateDrawingLayer(parent
,
3236 this->identity_matrix
,
3237 gfx::PointF(210.f
, 60.f
),
3240 typename
Types::LayerType
* filtered_surface
=
3241 this->CreateDrawingLayer(parent
,
3243 gfx::PointF(50.f
, 50.f
),
3244 gfx::Size(100, 100),
3246 this->CreateReplicaLayer(filtered_surface
,
3247 this->identity_matrix
,
3248 gfx::PointF(300.f
, 0.f
),
3251 // Filters make the layer own a surface.
3252 FilterOperations filters
;
3253 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3254 filtered_surface
->SetBackgroundFilters(filters
);
3256 this->CalcDrawEtc(parent
);
3258 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3259 gfx::Rect(0, 0, 1000, 1000));
3261 // The surface has a background blur, so it blurs non-opaque pixels below
3263 this->VisitLayer(filtered_surface
, &occlusion
);
3264 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3266 this->VisitLayer(behind_replica_layer
, &occlusion
);
3267 this->VisitLayer(behind_surface_layer
, &occlusion
);
3269 // The layers behind the surface are not blurred, and their occlusion does
3270 // not change, until we leave the surface. So it should not be modified by
3272 gfx::Rect occlusion_behind_surface
= gfx::Rect(60, 60, 30, 30);
3273 gfx::Rect occlusion_behind_replica
= gfx::Rect(210, 60, 30, 30);
3275 Region expected_opaque_bounds
=
3276 UnionRegions(occlusion_behind_surface
, occlusion_behind_replica
);
3277 EXPECT_EQ(expected_opaque_bounds
.ToString(),
3278 occlusion
.occlusion_from_inside_target().ToString());
3280 EXPECT_EQ(gfx::Rect().ToString(),
3281 occlusion
.occlusion_from_outside_target().ToString());
3285 ALL_OCCLUSIONTRACKER_TEST(
3286 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
3288 template <class Types
>
3289 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3290 : public OcclusionTrackerTest
<Types
> {
3292 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3294 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3296 gfx::Transform scale_by_half
;
3297 scale_by_half
.Scale(0.5, 0.5);
3299 // Make a 50x50 filtered surface that is completely occluded by an opaque
3300 // layer which is above it in the z-order. The surface is
3301 // scaled to test that the pixel moving is done in the target space, where
3302 // the background filter is applied, but the surface appears at 50, 50.
3303 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3304 this->identity_matrix
, gfx::PointF(), gfx::Size(200, 150));
3305 typename
Types::LayerType
* filtered_surface
=
3306 this->CreateDrawingLayer(parent
,
3308 gfx::PointF(50.f
, 50.f
),
3309 gfx::Size(100, 100),
3311 typename
Types::LayerType
* occluding_layer
=
3312 this->CreateDrawingLayer(parent
,
3313 this->identity_matrix
,
3314 gfx::PointF(50.f
, 50.f
),
3318 // Filters make the layer own a surface.
3319 FilterOperations filters
;
3320 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3321 filtered_surface
->SetBackgroundFilters(filters
);
3323 this->CalcDrawEtc(parent
);
3325 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3326 gfx::Rect(0, 0, 1000, 1000));
3328 this->VisitLayer(occluding_layer
, &occlusion
);
3330 this->VisitLayer(filtered_surface
, &occlusion
);
3332 // The layers above the filtered surface occlude from outside.
3333 gfx::Rect occlusion_above_surface
= gfx::Rect(0, 0, 50, 50);
3335 EXPECT_EQ(gfx::Rect().ToString(),
3336 occlusion
.occlusion_from_inside_target().ToString());
3337 EXPECT_EQ(occlusion_above_surface
.ToString(),
3338 occlusion
.occlusion_from_outside_target().ToString());
3341 // The surface has a background blur, so it blurs non-opaque pixels below
3343 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3345 // The filter is completely occluded, so it should not blur anything and
3346 // reduce any occlusion.
3347 gfx::Rect occlusion_above_surface
= gfx::Rect(50, 50, 50, 50);
3349 EXPECT_EQ(occlusion_above_surface
.ToString(),
3350 occlusion
.occlusion_from_inside_target().ToString());
3351 EXPECT_EQ(gfx::Rect().ToString(),
3352 occlusion
.occlusion_from_outside_target().ToString());
3357 ALL_OCCLUSIONTRACKER_TEST(
3358 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
3360 template <class Types
>
3361 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3362 : public OcclusionTrackerTest
<Types
> {
3365 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3367 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3369 gfx::Transform scale_by_half
;
3370 scale_by_half
.Scale(0.5, 0.5);
3372 // Make a surface and its replica, each 50x50, that are partially occluded
3373 // by opaque layers which are above them in the z-order. The surface is
3374 // scaled to test that the pixel moving is done in the target space, where
3375 // the background filter is applied, but the surface appears at 50, 50 and
3376 // the replica at 200, 50.
3377 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3378 this->identity_matrix
, gfx::PointF(), gfx::Size(300, 150));
3379 typename
Types::LayerType
* filtered_surface
=
3380 this->CreateDrawingLayer(parent
,
3382 gfx::PointF(50.f
, 50.f
),
3383 gfx::Size(100, 100),
3385 this->CreateReplicaLayer(filtered_surface
,
3386 this->identity_matrix
,
3387 gfx::PointF(300.f
, 0.f
),
3389 typename
Types::LayerType
* above_surface_layer
=
3390 this->CreateDrawingLayer(parent
,
3391 this->identity_matrix
,
3392 gfx::PointF(70.f
, 50.f
),
3395 typename
Types::LayerType
* above_replica_layer
=
3396 this->CreateDrawingLayer(parent
,
3397 this->identity_matrix
,
3398 gfx::PointF(200.f
, 50.f
),
3401 typename
Types::LayerType
* beside_surface_layer
=
3402 this->CreateDrawingLayer(parent
,
3403 this->identity_matrix
,
3404 gfx::PointF(90.f
, 40.f
),
3407 typename
Types::LayerType
* beside_replica_layer
=
3408 this->CreateDrawingLayer(parent
,
3409 this->identity_matrix
,
3410 gfx::PointF(200.f
, 40.f
),
3414 // Filters make the layer own a surface.
3415 FilterOperations filters
;
3416 filters
.Append(FilterOperation::CreateBlurFilter(3.f
));
3417 filtered_surface
->SetBackgroundFilters(filters
);
3419 // Save the distance of influence for the blur effect.
3420 int outset_top
, outset_right
, outset_bottom
, outset_left
;
3422 &outset_top
, &outset_right
, &outset_bottom
, &outset_left
);
3424 this->CalcDrawEtc(parent
);
3426 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3427 gfx::Rect(0, 0, 1000, 1000));
3429 this->VisitLayer(beside_replica_layer
, &occlusion
);
3430 this->VisitLayer(beside_surface_layer
, &occlusion
);
3431 this->VisitLayer(above_replica_layer
, &occlusion
);
3432 this->VisitLayer(above_surface_layer
, &occlusion
);
3434 // The surface has a background blur, so it blurs non-opaque pixels below
3436 this->VisitLayer(filtered_surface
, &occlusion
);
3437 this->VisitContributingSurface(filtered_surface
, &occlusion
);
3439 // The filter in the surface and replica are partially unoccluded. Only the
3440 // unoccluded parts should reduce occlusion. This means it will push back
3441 // the occlusion that touches the unoccluded part (occlusion_above___), but
3442 // it will not touch occlusion_beside____ since that is not beside the
3443 // unoccluded part of the surface, even though it is beside the occluded
3444 // part of the surface.
3445 gfx::Rect occlusion_above_surface
=
3446 gfx::Rect(70 + outset_right
, 50, 30 - outset_right
, 50);
3447 gfx::Rect occlusion_above_replica
=
3448 gfx::Rect(200, 50, 30 - outset_left
, 50);
3449 gfx::Rect occlusion_beside_surface
= gfx::Rect(90, 40, 10, 10);
3450 gfx::Rect occlusion_beside_replica
= gfx::Rect(200, 40, 10, 10);
3452 Region expected_occlusion
;
3453 expected_occlusion
.Union(occlusion_above_surface
);
3454 expected_occlusion
.Union(occlusion_above_replica
);
3455 expected_occlusion
.Union(occlusion_beside_surface
);
3456 expected_occlusion
.Union(occlusion_beside_replica
);
3458 ASSERT_EQ(expected_occlusion
.ToString(),
3459 occlusion
.occlusion_from_inside_target().ToString());
3460 EXPECT_EQ(gfx::Rect().ToString(),
3461 occlusion
.occlusion_from_outside_target().ToString());
3463 Region::Iterator
expected_rects(expected_occlusion
);
3464 Region::Iterator
target_surface_rects(
3465 occlusion
.occlusion_from_inside_target());
3466 for (; expected_rects
.has_rect();
3467 expected_rects
.next(), target_surface_rects
.next()) {
3468 ASSERT_TRUE(target_surface_rects
.has_rect());
3469 EXPECT_EQ(expected_rects
.rect(), target_surface_rects
.rect());
3474 ALL_OCCLUSIONTRACKER_TEST(
3475 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
3477 template <class Types
>
3478 class OcclusionTrackerTestMinimumTrackingSize
3479 : public OcclusionTrackerTest
<Types
> {
3481 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers
)
3482 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3484 gfx::Size
tracking_size(100, 100);
3485 gfx::Size
below_tracking_size(99, 99);
3487 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3488 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3489 typename
Types::LayerType
* large
= this->CreateDrawingLayer(
3490 parent
, this->identity_matrix
, gfx::PointF(), tracking_size
, true);
3491 typename
Types::LayerType
* small
=
3492 this->CreateDrawingLayer(parent
,
3493 this->identity_matrix
,
3495 below_tracking_size
,
3497 this->CalcDrawEtc(parent
);
3499 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3500 gfx::Rect(0, 0, 1000, 1000));
3501 occlusion
.set_minimum_tracking_size(tracking_size
);
3503 // The small layer is not tracked because it is too small.
3504 this->VisitLayer(small
, &occlusion
);
3506 EXPECT_EQ(gfx::Rect().ToString(),
3507 occlusion
.occlusion_from_outside_target().ToString());
3508 EXPECT_EQ(gfx::Rect().ToString(),
3509 occlusion
.occlusion_from_inside_target().ToString());
3511 // The large layer is tracked as it is large enough.
3512 this->VisitLayer(large
, &occlusion
);
3514 EXPECT_EQ(gfx::Rect().ToString(),
3515 occlusion
.occlusion_from_outside_target().ToString());
3516 EXPECT_EQ(gfx::Rect(tracking_size
).ToString(),
3517 occlusion
.occlusion_from_inside_target().ToString());
3521 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
3523 template <class Types
>
3524 class OcclusionTrackerTestScaledLayerIsClipped
3525 : public OcclusionTrackerTest
<Types
> {
3527 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers
)
3528 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3530 gfx::Transform scale_transform
;
3531 scale_transform
.Scale(512.0, 512.0);
3533 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3534 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3535 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3536 this->identity_matrix
,
3537 gfx::PointF(10.f
, 10.f
),
3539 clip
->SetMasksToBounds(true);
3540 typename
Types::LayerType
* scale
= this->CreateLayer(
3541 clip
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3542 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3543 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3544 this->CalcDrawEtc(parent
);
3546 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3547 gfx::Rect(0, 0, 1000, 1000));
3549 this->VisitLayer(scaled
, &occlusion
);
3551 EXPECT_EQ(gfx::Rect().ToString(),
3552 occlusion
.occlusion_from_outside_target().ToString());
3553 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3554 occlusion
.occlusion_from_inside_target().ToString());
3558 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped
)
3560 template <class Types
>
3561 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3562 : public OcclusionTrackerTest
<Types
> {
3564 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers
)
3565 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3567 gfx::Transform scale_transform
;
3568 scale_transform
.Scale(512.0, 512.0);
3570 typename
Types::ContentLayerType
* parent
= this->CreateRoot(
3571 this->identity_matrix
, gfx::PointF(), gfx::Size(400, 400));
3572 typename
Types::LayerType
* clip
= this->CreateLayer(parent
,
3573 this->identity_matrix
,
3574 gfx::PointF(10.f
, 10.f
),
3576 clip
->SetMasksToBounds(true);
3577 typename
Types::LayerType
* surface
= this->CreateDrawingSurface(
3578 clip
, this->identity_matrix
, gfx::PointF(), gfx::Size(400, 30), false);
3579 typename
Types::LayerType
* scale
= this->CreateLayer(
3580 surface
, scale_transform
, gfx::PointF(), gfx::Size(1, 1));
3581 typename
Types::LayerType
* scaled
= this->CreateDrawingLayer(
3582 scale
, this->identity_matrix
, gfx::PointF(), gfx::Size(500, 500), true);
3583 this->CalcDrawEtc(parent
);
3585 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3586 gfx::Rect(0, 0, 1000, 1000));
3588 this->VisitLayer(scaled
, &occlusion
);
3589 this->VisitLayer(surface
, &occlusion
);
3590 this->VisitContributingSurface(surface
, &occlusion
);
3592 EXPECT_EQ(gfx::Rect().ToString(),
3593 occlusion
.occlusion_from_outside_target().ToString());
3594 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3595 occlusion
.occlusion_from_inside_target().ToString());
3599 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped
)
3601 template <class Types
>
3602 class OcclusionTrackerTestCopyRequestDoesOcclude
3603 : public OcclusionTrackerTest
<Types
> {
3605 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers
)
3606 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3608 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3609 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3610 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3611 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3612 typename
Types::LayerType
* copy
= this->CreateLayer(parent
,
3613 this->identity_matrix
,
3615 gfx::Size(200, 400));
3616 this->AddCopyRequest(copy
);
3617 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3619 this->identity_matrix
,
3621 gfx::Size(200, 400),
3623 this->CalcDrawEtc(root
);
3625 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3626 gfx::Rect(0, 0, 1000, 1000));
3628 this->VisitLayer(copy_child
, &occlusion
);
3629 EXPECT_EQ(gfx::Rect().ToString(),
3630 occlusion
.occlusion_from_outside_target().ToString());
3631 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3632 occlusion
.occlusion_from_inside_target().ToString());
3634 // CopyRequests cause the layer to own a surface.
3635 this->VisitContributingSurface(copy
, &occlusion
);
3637 // The occlusion from the copy should be kept.
3638 EXPECT_EQ(gfx::Rect().ToString(),
3639 occlusion
.occlusion_from_outside_target().ToString());
3640 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3641 occlusion
.occlusion_from_inside_target().ToString());
3645 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude
)
3647 template <class Types
>
3648 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3649 : public OcclusionTrackerTest
<Types
> {
3651 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3653 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3655 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3656 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3657 typename
Types::ContentLayerType
* parent
= this->CreateDrawingLayer(
3658 root
, this->identity_matrix
, gfx::Point(), gfx::Size(400, 400), true);
3659 typename
Types::LayerType
* hide
= this->CreateLayer(
3660 parent
, this->identity_matrix
, gfx::Point(), gfx::Size());
3661 typename
Types::LayerType
* copy
= this->CreateLayer(
3662 hide
, this->identity_matrix
, gfx::Point(100, 0), gfx::Size(200, 400));
3663 this->AddCopyRequest(copy
);
3664 typename
Types::LayerType
* copy_child
= this->CreateDrawingLayer(
3665 copy
, this->identity_matrix
, gfx::PointF(), gfx::Size(200, 400), true);
3667 // The |copy| layer is hidden but since it is being copied, it will be
3669 hide
->SetHideLayerAndSubtree(true);
3671 this->CalcDrawEtc(root
);
3673 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3674 gfx::Rect(0, 0, 1000, 1000));
3676 this->VisitLayer(copy_child
, &occlusion
);
3677 EXPECT_EQ(gfx::Rect().ToString(),
3678 occlusion
.occlusion_from_outside_target().ToString());
3679 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3680 occlusion
.occlusion_from_inside_target().ToString());
3682 // CopyRequests cause the layer to own a surface.
3683 this->VisitContributingSurface(copy
, &occlusion
);
3685 // The occlusion from the copy should be dropped since it is hidden.
3686 EXPECT_EQ(gfx::Rect().ToString(),
3687 occlusion
.occlusion_from_outside_target().ToString());
3688 EXPECT_EQ(gfx::Rect().ToString(),
3689 occlusion
.occlusion_from_inside_target().ToString());
3693 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
)
3695 template <class Types
>
3696 class OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
3697 : public OcclusionTrackerTest
<Types
> {
3699 explicit OcclusionTrackerTestEmptyEventLayerDoesNotOcclude(
3701 : OcclusionTrackerTest
<Types
>(opaque_layers
) {}
3703 typename
Types::ContentLayerType
* root
= this->CreateRoot(
3704 this->identity_matrix
, gfx::Point(), gfx::Size(400, 400));
3705 typename
Types::ContentLayerType
* empty_layer
= this->CreateDrawingLayer(
3706 root
, this->identity_matrix
, gfx::Point(), gfx::Size(200, 200), true);
3707 this->SetDrawsContent(empty_layer
, false);
3708 empty_layer
->SetTouchEventHandlerRegion(gfx::Rect(10, 10, 10, 10));
3710 this->CalcDrawEtc(root
);
3712 TestOcclusionTrackerWithClip
<typename
Types::LayerType
> occlusion(
3713 gfx::Rect(0, 0, 1000, 1000));
3715 this->VisitLayer(empty_layer
, &occlusion
);
3717 EXPECT_EQ(gfx::Rect().ToString(),
3718 occlusion
.occlusion_from_outside_target().ToString());
3719 EXPECT_EQ(gfx::Rect().ToString(),
3720 occlusion
.occlusion_from_inside_target().ToString());
3724 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
)