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/occlusion_tracker.h"
8 #include "cc/layer_animation_controller.h"
9 #include "cc/layer_impl.h"
10 #include "cc/layer_tree_host_common.h"
11 #include "cc/math_util.h"
12 #include "cc/overdraw_metrics.h"
13 #include "cc/single_thread_proxy.h"
14 #include "cc/test/animation_test_common.h"
15 #include "cc/test/fake_impl_proxy.h"
16 #include "cc/test/fake_layer_tree_host_impl.h"
17 #include "cc/test/geometry_test_utils.h"
18 #include "cc/test/occlusion_tracker_test_common.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.h"
22 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h"
23 #include "ui/gfx/transform.h"
28 class TestContentLayer
: public Layer
{
32 , m_overrideOpaqueContentsRect(false)
36 virtual bool drawsContent() const OVERRIDE
{ return true; }
37 virtual Region
visibleContentOpaqueRegion() const OVERRIDE
39 if (m_overrideOpaqueContentsRect
)
40 return gfx::IntersectRects(m_opaqueContentsRect
, visibleContentRect());
41 return Layer::visibleContentOpaqueRegion();
43 void setOpaqueContentsRect(const gfx::Rect
& opaqueContentsRect
)
45 m_overrideOpaqueContentsRect
= true;
46 m_opaqueContentsRect
= opaqueContentsRect
;
50 virtual ~TestContentLayer()
54 bool m_overrideOpaqueContentsRect
;
55 gfx::Rect m_opaqueContentsRect
;
58 class TestContentLayerImpl
: public LayerImpl
{
60 TestContentLayerImpl(LayerTreeImpl
* treeImpl
, int id
)
61 : LayerImpl(treeImpl
, id
)
62 , m_overrideOpaqueContentsRect(false)
64 setDrawsContent(true);
67 virtual Region
visibleContentOpaqueRegion() const OVERRIDE
69 if (m_overrideOpaqueContentsRect
)
70 return gfx::IntersectRects(m_opaqueContentsRect
, visibleContentRect());
71 return LayerImpl::visibleContentOpaqueRegion();
73 void setOpaqueContentsRect(const gfx::Rect
& opaqueContentsRect
)
75 m_overrideOpaqueContentsRect
= true;
76 m_opaqueContentsRect
= opaqueContentsRect
;
80 bool m_overrideOpaqueContentsRect
;
81 gfx::Rect m_opaqueContentsRect
;
84 static inline bool layerImplDrawTransformIsUnknown(const Layer
* layer
) { return layer
->drawTransformIsAnimating(); }
85 static inline bool layerImplDrawTransformIsUnknown(const LayerImpl
*) { return false; }
87 template<typename LayerType
, typename RenderSurfaceType
>
88 class TestOcclusionTrackerWithClip
: public TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
> {
90 TestOcclusionTrackerWithClip(gfx::Rect viewportRect
, bool recordMetricsForFrame
= false)
91 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(viewportRect
, recordMetricsForFrame
)
92 , m_overrideLayerClipRect(false)
96 void setLayerClipRect(const gfx::Rect
& rect
) { m_overrideLayerClipRect
= true; m_layerClipRect
= rect
;}
97 void useDefaultLayerClipRect() { m_overrideLayerClipRect
= false; }
98 // Returns true if the given rect in content space for the layer is fully occluded in either screen space or the layer's target surface.
99 bool occludedLayer(const LayerType
* layer
, const gfx::Rect
& contentRect
, bool* hasOcclusionFromOutsideTargetSurface
= 0) const
101 return this->occluded(layer
->renderTarget(), contentRect
, layer
->drawTransform(), layerImplDrawTransformIsUnknown(layer
), layerClipRectInTarget(layer
), hasOcclusionFromOutsideTargetSurface
);
103 // Gives an unoccluded sub-rect of |contentRect| in the content space of the layer. Simple wrapper around unoccludedContentRect.
104 gfx::Rect
unoccludedLayerContentRect(const LayerType
* layer
, const gfx::Rect
& contentRect
, bool* hasOcclusionFromOutsideTargetSurface
= 0) const
106 return this->unoccludedContentRect(layer
->renderTarget(), contentRect
, layer
->drawTransform(), layerImplDrawTransformIsUnknown(layer
), layerClipRectInTarget(layer
), hasOcclusionFromOutsideTargetSurface
);
111 virtual gfx::Rect
layerClipRectInTarget(const LayerType
* layer
) const { return m_overrideLayerClipRect
? m_layerClipRect
: OcclusionTrackerBase
<LayerType
, RenderSurfaceType
>::layerClipRectInTarget(layer
); }
114 bool m_overrideLayerClipRect
;
115 gfx::Rect m_layerClipRect
;
118 struct OcclusionTrackerTestMainThreadTypes
{
119 typedef Layer LayerType
;
120 typedef LayerTreeHost HostType
;
121 typedef RenderSurface RenderSurfaceType
;
122 typedef TestContentLayer ContentLayerType
;
123 typedef scoped_refptr
<Layer
> LayerPtrType
;
124 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
125 typedef LayerIterator
<Layer
, std::vector
<scoped_refptr
<Layer
> >, RenderSurface
, LayerIteratorActions::FrontToBack
> TestLayerIterator
;
126 typedef OcclusionTracker OcclusionTrackerType
;
128 static LayerPtrType
createLayer(HostType
*)
130 return Layer::create();
132 static ContentLayerPtrType
createContentLayer(HostType
*) { return make_scoped_refptr(new ContentLayerType()); }
134 static LayerPtrType
passLayerPtr(ContentLayerPtrType
& layer
)
136 LayerPtrType
ref(layer
);
141 static LayerPtrType
passLayerPtr(LayerPtrType
& layer
)
143 LayerPtrType
ref(layer
);
148 static void destroyLayer(LayerPtrType
& layer
)
154 struct OcclusionTrackerTestImplThreadTypes
{
155 typedef LayerImpl LayerType
;
156 typedef LayerTreeImpl HostType
;
157 typedef RenderSurfaceImpl RenderSurfaceType
;
158 typedef TestContentLayerImpl ContentLayerType
;
159 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
160 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
161 typedef LayerIterator
<LayerImpl
, std::vector
<LayerImpl
*>, RenderSurfaceImpl
, LayerIteratorActions::FrontToBack
> TestLayerIterator
;
162 typedef OcclusionTrackerImpl OcclusionTrackerType
;
164 static LayerPtrType
createLayer(HostType
* host
) { return LayerImpl::create(host
, nextLayerImplId
++); }
165 static ContentLayerPtrType
createContentLayer(HostType
* host
) { return make_scoped_ptr(new ContentLayerType(host
, nextLayerImplId
++)); }
166 static int nextLayerImplId
;
168 static LayerPtrType
passLayerPtr(LayerPtrType
& layer
)
173 static LayerPtrType
passLayerPtr(ContentLayerPtrType
& layer
)
175 return layer
.PassAs
<LayerType
>();
178 static void destroyLayer(LayerPtrType
& layer
)
184 int OcclusionTrackerTestImplThreadTypes::nextLayerImplId
= 1;
186 template<typename Types
>
187 class OcclusionTrackerTest
: public testing::Test
{
189 OcclusionTrackerTest(bool opaqueLayers
)
190 : m_hostImpl(&m_proxy
)
191 , m_opaqueLayers(opaqueLayers
)
195 virtual void runMyTest() = 0;
197 virtual void TearDown()
199 Types::destroyLayer(m_root
);
200 m_renderSurfaceLayerList
.clear();
201 m_renderSurfaceLayerListImpl
.clear();
202 m_replicaLayers
.clear();
203 m_maskLayers
.clear();
204 LayerTreeHost::setNeedsFilterContext(false);
207 typename
Types::HostType
* getHost();
209 typename
Types::ContentLayerType
* createRoot(const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
211 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer(getHost()));
212 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
213 setProperties(layerPtr
, transform
, position
, bounds
);
216 m_root
= Types::passLayerPtr(layer
);
220 typename
Types::LayerType
* createLayer(typename
Types::LayerType
* parent
, const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
222 typename
Types::LayerPtrType
layer(Types::createLayer(getHost()));
223 typename
Types::LayerType
* layerPtr
= layer
.get();
224 setProperties(layerPtr
, transform
, position
, bounds
);
225 parent
->addChild(Types::passLayerPtr(layer
));
229 typename
Types::LayerType
* createSurface(typename
Types::LayerType
* parent
, const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
231 typename
Types::LayerType
* layer
= createLayer(parent
, transform
, position
, bounds
);
232 WebKit::WebFilterOperations filters
;
233 filters
.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5));
234 layer
->setFilters(filters
);
238 typename
Types::ContentLayerType
* createDrawingLayer(typename
Types::LayerType
* parent
, const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
, bool opaque
)
240 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer(getHost()));
241 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
242 setProperties(layerPtr
, transform
, position
, bounds
);
245 layerPtr
->setContentsOpaque(opaque
);
247 layerPtr
->setContentsOpaque(false);
249 layerPtr
->setOpaqueContentsRect(gfx::Rect(gfx::Point(), bounds
));
251 layerPtr
->setOpaqueContentsRect(gfx::Rect());
254 parent
->addChild(Types::passLayerPtr(layer
));
258 typename
Types::LayerType
* createReplicaLayer(typename
Types::LayerType
* owningLayer
, const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
260 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer(getHost()));
261 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
262 setProperties(layerPtr
, transform
, position
, bounds
);
263 setReplica(owningLayer
, Types::passLayerPtr(layer
));
267 typename
Types::LayerType
* createMaskLayer(typename
Types::LayerType
* owningLayer
, const gfx::Size
& bounds
)
269 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer(getHost()));
270 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
271 setProperties(layerPtr
, identityMatrix
, gfx::PointF(), bounds
);
272 setMask(owningLayer
, Types::passLayerPtr(layer
));
276 typename
Types::ContentLayerType
* createDrawingSurface(typename
Types::LayerType
* parent
, const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
, bool opaque
)
278 typename
Types::ContentLayerType
* layer
= createDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
279 WebKit::WebFilterOperations filters
;
280 filters
.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5));
281 layer
->setFilters(filters
);
285 void calcDrawEtc(TestContentLayerImpl
* root
)
287 DCHECK(root
== m_root
.get());
288 int dummyMaxTextureSize
= 512;
290 DCHECK(!root
->renderSurface());
292 LayerTreeHostCommon::calculateDrawProperties(root
, root
->bounds(), 1, 1, dummyMaxTextureSize
, false, m_renderSurfaceLayerListImpl
);
294 m_layerIterator
= m_layerIteratorBegin
= Types::TestLayerIterator::begin(&m_renderSurfaceLayerListImpl
);
297 void calcDrawEtc(TestContentLayer
* root
)
299 DCHECK(root
== m_root
.get());
300 int dummyMaxTextureSize
= 512;
302 DCHECK(!root
->renderSurface());
304 LayerTreeHostCommon::calculateDrawProperties(root
, root
->bounds(), 1, 1, dummyMaxTextureSize
, false, m_renderSurfaceLayerList
);
306 m_layerIterator
= m_layerIteratorBegin
= Types::TestLayerIterator::begin(&m_renderSurfaceLayerList
);
309 void enterLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
311 ASSERT_EQ(layer
, *m_layerIterator
);
312 ASSERT_TRUE(m_layerIterator
.representsItself());
313 occlusion
.enterLayer(m_layerIterator
);
316 void leaveLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
318 ASSERT_EQ(layer
, *m_layerIterator
);
319 ASSERT_TRUE(m_layerIterator
.representsItself());
320 occlusion
.leaveLayer(m_layerIterator
);
324 void visitLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
326 enterLayer(layer
, occlusion
);
327 leaveLayer(layer
, occlusion
);
330 void enterContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
332 ASSERT_EQ(layer
, *m_layerIterator
);
333 ASSERT_TRUE(m_layerIterator
.representsTargetRenderSurface());
334 occlusion
.enterLayer(m_layerIterator
);
335 occlusion
.leaveLayer(m_layerIterator
);
337 ASSERT_TRUE(m_layerIterator
.representsContributingRenderSurface());
338 occlusion
.enterLayer(m_layerIterator
);
341 void leaveContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
343 ASSERT_EQ(layer
, *m_layerIterator
);
344 ASSERT_TRUE(m_layerIterator
.representsContributingRenderSurface());
345 occlusion
.leaveLayer(m_layerIterator
);
349 void visitContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
351 enterContributingSurface(layer
, occlusion
);
352 leaveContributingSurface(layer
, occlusion
);
355 void resetLayerIterator()
357 m_layerIterator
= m_layerIteratorBegin
;
360 const gfx::Transform identityMatrix
;
363 void setBaseProperties(typename
Types::LayerType
* layer
, const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
365 layer
->setTransform(transform
);
366 layer
->setSublayerTransform(gfx::Transform());
367 layer
->setAnchorPoint(gfx::PointF(0, 0));
368 layer
->setPosition(position
);
369 layer
->setBounds(bounds
);
372 void setProperties(Layer
* layer
, const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
374 setBaseProperties(layer
, transform
, position
, bounds
);
377 void setProperties(LayerImpl
* layer
, const gfx::Transform
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
379 setBaseProperties(layer
, transform
, position
, bounds
);
381 layer
->setContentBounds(layer
->bounds());
384 void setReplica(Layer
* owningLayer
, scoped_refptr
<Layer
> layer
)
386 owningLayer
->setReplicaLayer(layer
.get());
387 m_replicaLayers
.push_back(layer
);
390 void setReplica(LayerImpl
* owningLayer
, scoped_ptr
<LayerImpl
> layer
)
392 owningLayer
->setReplicaLayer(layer
.Pass());
395 void setMask(Layer
* owningLayer
, scoped_refptr
<Layer
> layer
)
397 owningLayer
->setMaskLayer(layer
.get());
398 m_maskLayers
.push_back(layer
);
401 void setMask(LayerImpl
* owningLayer
, scoped_ptr
<LayerImpl
> layer
)
403 owningLayer
->setMaskLayer(layer
.Pass());
406 FakeImplProxy m_proxy
;
407 FakeLayerTreeHostImpl m_hostImpl
;
409 // These hold ownership of the layers for the duration of the test.
410 typename
Types::LayerPtrType m_root
;
411 std::vector
<scoped_refptr
<Layer
> > m_renderSurfaceLayerList
;
412 std::vector
<LayerImpl
*> m_renderSurfaceLayerListImpl
;
413 typename
Types::TestLayerIterator m_layerIteratorBegin
;
414 typename
Types::TestLayerIterator m_layerIterator
;
415 typename
Types::LayerType
* m_lastLayerVisited
;
416 std::vector
<scoped_refptr
<Layer
> > m_replicaLayers
;
417 std::vector
<scoped_refptr
<Layer
> > m_maskLayers
;
421 LayerTreeHost
* OcclusionTrackerTest
<OcclusionTrackerTestMainThreadTypes
>::getHost()
427 LayerTreeImpl
* OcclusionTrackerTest
<OcclusionTrackerTestImplThreadTypes
>::getHost()
429 return m_hostImpl
.activeTree();
432 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
433 class ClassName##MainThreadOpaqueLayers : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
435 ClassName##MainThreadOpaqueLayers() : ClassName<OcclusionTrackerTestMainThreadTypes>(true) { } \
437 TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
438 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
439 class ClassName##MainThreadOpaquePaints : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
441 ClassName##MainThreadOpaquePaints() : ClassName<OcclusionTrackerTestMainThreadTypes>(false) { } \
443 TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
445 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
446 class ClassName##ImplThreadOpaqueLayers : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
448 ClassName##ImplThreadOpaqueLayers() : ClassName<OcclusionTrackerTestImplThreadTypes>(true) { } \
450 TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
451 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
452 class ClassName##ImplThreadOpaquePaints : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
454 ClassName##ImplThreadOpaquePaints() : ClassName<OcclusionTrackerTestImplThreadTypes>(false) { } \
456 TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
458 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
459 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
460 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
461 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
462 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
464 #define MAIN_THREAD_TEST(ClassName) \
465 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
467 #define IMPL_THREAD_TEST(ClassName) \
468 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
470 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
471 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
472 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
474 template<class Types
>
475 class OcclusionTrackerTestIdentityTransforms
: public OcclusionTrackerTest
<Types
> {
477 OcclusionTrackerTestIdentityTransforms(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
481 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
482 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
483 this->calcDrawEtc(parent
);
485 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
486 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
488 this->visitLayer(layer
, occlusion
);
489 this->enterLayer(parent
, occlusion
);
491 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
492 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
494 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
495 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
496 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
497 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
498 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
500 occlusion
.useDefaultLayerClipRect();
501 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
502 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
503 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
504 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
505 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
506 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
508 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
509 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 30, 70, 70)));
510 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 29, 70, 70)));
511 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 29, 70, 70)));
512 EXPECT_RECT_EQ(gfx::Rect(31, 29, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 29, 70, 70)));
513 EXPECT_RECT_EQ(gfx::Rect(100, 30, 1, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 30, 70, 70)));
514 EXPECT_RECT_EQ(gfx::Rect(31, 31, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 31, 70, 70)));
515 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 31, 70, 70)));
516 EXPECT_RECT_EQ(gfx::Rect(29, 31, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 31, 70, 70)));
520 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
522 template<class Types
>
523 class OcclusionTrackerTestQuadsMismatchLayer
: public OcclusionTrackerTest
<Types
> {
525 OcclusionTrackerTestQuadsMismatchLayer(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
528 gfx::Transform layerTransform
;
529 layerTransform
.Translate(10, 10);
531 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::Point(0, 0), gfx::Size(100, 100));
532 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(0, 0), gfx::Size(90, 90), true);
533 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(layer1
, layerTransform
, gfx::PointF(0, 0), gfx::Size(50, 50), true);
534 this->calcDrawEtc(parent
);
536 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
538 this->visitLayer(layer2
, occlusion
);
539 this->enterLayer(layer1
, occlusion
);
541 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
542 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
544 // This checks cases where the quads don't match their "containing"
545 // layers, e.g. in terms of transforms or clip rect. This is typical for
546 // DelegatedRendererLayer.
548 gfx::Transform quadTransform
;
549 quadTransform
.Translate(30, 30);
550 gfx::Rect
clipRectInTarget(0, 0, 100, 100);
552 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, gfx::Rect(0, 0, 10, 10), quadTransform
, false, clipRectInTarget
).IsEmpty());
553 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10), occlusion
.unoccludedContentRect(parent
, gfx::Rect(0, 0, 10, 10), quadTransform
, true, clipRectInTarget
));
554 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), occlusion
.unoccludedContentRect(parent
, gfx::Rect(40, 40, 10, 10), quadTransform
, false, clipRectInTarget
));
555 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), occlusion
.unoccludedContentRect(parent
, gfx::Rect(35, 30, 10, 10), quadTransform
, false, clipRectInTarget
));
556 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5), occlusion
.unoccludedContentRect(parent
, gfx::Rect(40, 40, 10, 10), quadTransform
, false, gfx::Rect(0, 0, 75, 75)));
560 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
562 template<class Types
>
563 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
565 OcclusionTrackerTestRotatedChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
568 gfx::Transform layerTransform
;
569 layerTransform
.Translate(250, 250);
570 layerTransform
.Rotate(90);
571 layerTransform
.Translate(-250, -250);
573 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
574 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
575 this->calcDrawEtc(parent
);
577 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
578 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
580 this->visitLayer(layer
, occlusion
);
581 this->enterLayer(parent
, occlusion
);
583 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
584 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
586 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
587 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
588 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
589 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
590 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
592 occlusion
.useDefaultLayerClipRect();
593 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
594 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
595 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
596 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
597 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
598 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
600 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
601 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 30, 70, 70)));
602 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 29, 70, 70)));
603 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 29, 70, 70)));
604 EXPECT_RECT_EQ(gfx::Rect(31, 29, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 29, 70, 70)));
605 EXPECT_RECT_EQ(gfx::Rect(100, 30, 1, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 30, 70, 70)));
606 EXPECT_RECT_EQ(gfx::Rect(31, 31, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 31, 70, 70)));
607 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 31, 70, 70)));
608 EXPECT_RECT_EQ(gfx::Rect(29, 31, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 31, 70, 70)));
612 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
614 template<class Types
>
615 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
617 OcclusionTrackerTestTranslatedChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
620 gfx::Transform layerTransform
;
621 layerTransform
.Translate(20, 20);
623 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
624 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
625 this->calcDrawEtc(parent
);
627 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
628 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
630 this->visitLayer(layer
, occlusion
);
631 this->enterLayer(parent
, occlusion
);
633 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
634 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
636 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
637 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
638 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
639 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(51, 50, 50, 50)));
640 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 51, 50, 50)));
642 occlusion
.useDefaultLayerClipRect();
643 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
644 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
645 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
646 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(51, 50, 50, 50)));
647 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 51, 50, 50)));
648 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
650 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
651 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 50, 50, 50)));
652 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 49, 50, 50)));
653 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 49, 50, 50)));
654 EXPECT_RECT_EQ(gfx::Rect(51, 49, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 49, 50, 50)));
655 EXPECT_RECT_EQ(gfx::Rect(100, 50, 1, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 50, 50, 50)));
656 EXPECT_RECT_EQ(gfx::Rect(51, 51, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 51, 50, 50)));
657 EXPECT_RECT_EQ(gfx::Rect(50, 100, 50, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 51, 50, 50)));
658 EXPECT_RECT_EQ(gfx::Rect(49, 51, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 51, 50, 50)));
660 occlusion
.useDefaultLayerClipRect();
661 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
662 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 50, 50, 50)));
663 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 49, 50, 50)));
664 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 49, 50, 50)));
665 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 49, 50, 50)));
666 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 50, 50, 50)).IsEmpty());
667 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 51, 50, 50)).IsEmpty());
668 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 51, 50, 50)).IsEmpty());
669 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 51, 50, 50)));
670 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
674 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
676 template<class Types
>
677 class OcclusionTrackerTestChildInRotatedChild
: public OcclusionTrackerTest
<Types
> {
679 OcclusionTrackerTestChildInRotatedChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
682 gfx::Transform childTransform
;
683 childTransform
.Translate(250, 250);
684 childTransform
.Rotate(90);
685 childTransform
.Translate(-250, -250);
687 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
688 parent
->setMasksToBounds(true);
689 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(500, 500));
690 child
->setMasksToBounds(true);
691 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, this->identityMatrix
, gfx::PointF(10, 10), gfx::Size(500, 500), true);
692 this->calcDrawEtc(parent
);
694 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
695 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
697 this->visitLayer(layer
, occlusion
);
698 this->enterContributingSurface(child
, occlusion
);
700 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
701 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
703 this->leaveContributingSurface(child
, occlusion
);
704 this->enterLayer(parent
, occlusion
);
706 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
707 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
709 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
710 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
711 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
712 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 40, 70, 60)));
713 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 41, 70, 60)));
715 occlusion
.useDefaultLayerClipRect();
716 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
717 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
718 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
719 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 40, 70, 60)));
720 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 41, 70, 60)));
721 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
724 /* Justification for the above occlusion from |layer|:
726 +---------------------+ +---------------------+
727 | | | |30 Visible region of |layer|: /////
728 | 30 | rotate(90) | |
729 | 30 + ---------------------------------+ | +---------------------------------+
730 100 | | 10 | | ==> | | |10 |
731 | |10+---------------------------------+ | +---------------------------------+ |
732 | | | | | | | | |///////////////| 420 | |
733 | | | | | | | | |///////////////|60 | |
734 | | | | | | | | |///////////////| | |
735 +----|--|-------------+ | | +--|--|---------------+ | |
736 | | | | 20|10| 70 | |
743 +--|-------------------------------+ | | +------------------------------|--+
745 +---------------------------------+ +---------------------------------+
751 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
753 template<class Types
>
754 class OcclusionTrackerTestScaledRenderSurface
: public OcclusionTrackerTest
<Types
> {
756 OcclusionTrackerTestScaledRenderSurface(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
760 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200));
762 gfx::Transform layer1Matrix
;
763 layer1Matrix
.Scale(2, 2);
764 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(parent
, layer1Matrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
765 layer1
->setForceRenderSurface(true);
767 gfx::Transform layer2Matrix
;
768 layer2Matrix
.Translate(25, 25);
769 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(layer1
, layer2Matrix
, gfx::PointF(0, 0), gfx::Size(50, 50), true);
770 typename
Types::ContentLayerType
* occluder
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 100), gfx::Size(500, 500), true);
771 this->calcDrawEtc(parent
);
773 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
775 this->visitLayer(occluder
, occlusion
);
776 this->enterLayer(layer2
, occlusion
);
778 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
779 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromInsideTarget().ToString());
781 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), occlusion
.unoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
782 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25), occlusion
.unoccludedLayerContentRect(layer2
, gfx::Rect(10, 25, 25, 25)));
783 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15), occlusion
.unoccludedLayerContentRect(layer2
, gfx::Rect(25, 10, 25, 25)));
784 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
788 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
790 template<class Types
>
791 class OcclusionTrackerTestVisitTargetTwoTimes
: public OcclusionTrackerTest
<Types
> {
793 OcclusionTrackerTestVisitTargetTwoTimes(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
796 gfx::Transform childTransform
;
797 childTransform
.Translate(250, 250);
798 childTransform
.Rotate(90);
799 childTransform
.Translate(-250, -250);
801 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
802 parent
->setMasksToBounds(true);
803 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(500, 500));
804 child
->setMasksToBounds(true);
805 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, this->identityMatrix
, gfx::PointF(10, 10), gfx::Size(500, 500), true);
806 // |child2| makes |parent|'s surface get considered by OcclusionTracker first, instead of |child|'s. This exercises different code in
807 // leaveToTargetRenderSurface, as the target surface has already been seen.
808 typename
Types::ContentLayerType
* child2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(30, 30), gfx::Size(60, 20), true);
809 this->calcDrawEtc(parent
);
811 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
812 occlusion
.setLayerClipRect(gfx::Rect(-10, -10, 1000, 1000));
814 this->visitLayer(child2
, occlusion
);
816 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
817 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
819 this->visitLayer(layer
, occlusion
);
821 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
822 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
824 this->enterContributingSurface(child
, occlusion
);
826 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
827 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
829 // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
830 this->leaveContributingSurface(child
, occlusion
);
831 this->enterLayer(parent
, occlusion
);
833 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
834 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
836 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
837 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 30, 70, 70)));
839 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
840 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
841 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
842 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
843 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
845 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
846 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
847 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
849 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
850 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 30, 60, 10)));
851 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 29, 60, 10)));
852 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 30, 60, 10)));
853 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
855 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
856 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 40, 70, 60)));
857 // This rect is mostly occluded by |child2|.
858 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 39, 70, 60)));
859 // This rect extends past top/right ends of |child2|.
860 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 29, 70, 70)));
861 // This rect extends past left/right ends of |child2|.
862 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(20, 39, 80, 60)));
863 EXPECT_RECT_EQ(gfx::Rect(100, 40, 1, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 40, 70, 60)));
864 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 41, 70, 60)));
866 /* Justification for the above occlusion from |layer|:
868 +---------------------+ +---------------------+
869 | | | |30 Visible region of |layer|: /////
870 | 30 | rotate(90) | 30 60 | |child2|: \\\\\
871 | 30 + ------------+--------------------+ | 30 +------------+--------------------+
872 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
873 | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
874 | + ------------+ | | | | | +------------+//| 420 | |
875 | | | | | | | | |///////////////|60 | |
876 | | | | | | | | |///////////////| | |
877 +----|--|-------------+ | | +--|--|---------------+ | |
878 | | | | 20|10| 70 | |
885 +--|-------------------------------+ | | +------------------------------|--+
887 +---------------------------------+ +---------------------------------+
893 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
895 template<class Types
>
896 class OcclusionTrackerTestSurfaceRotatedOffAxis
: public OcclusionTrackerTest
<Types
> {
898 OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
901 gfx::Transform childTransform
;
902 childTransform
.Translate(250, 250);
903 childTransform
.Rotate(95);
904 childTransform
.Translate(-250, -250);
906 gfx::Transform layerTransform
;
907 layerTransform
.Translate(10, 10);
909 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
910 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(500, 500));
911 child
->setMasksToBounds(true);
912 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, layerTransform
, gfx::PointF(0, 0), gfx::Size(500, 500), true);
913 this->calcDrawEtc(parent
);
915 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
916 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
918 gfx::Rect clippedLayerInChild
= MathUtil::mapClippedRect(layerTransform
, layer
->visibleContentRect());
920 this->visitLayer(layer
, occlusion
);
921 this->enterContributingSurface(child
, occlusion
);
923 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
924 EXPECT_EQ(clippedLayerInChild
.ToString(), occlusion
.occlusionFromInsideTarget().ToString());
926 EXPECT_TRUE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
927 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
928 clippedLayerInChild
+= gfx::Vector2d(-1, 0);
929 EXPECT_FALSE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
930 EXPECT_FALSE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
931 clippedLayerInChild
+= gfx::Vector2d(1, 0);
932 clippedLayerInChild
+= gfx::Vector2d(1, 0);
933 EXPECT_FALSE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
934 EXPECT_FALSE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
935 clippedLayerInChild
+= gfx::Vector2d(-1, 0);
936 clippedLayerInChild
+= gfx::Vector2d(0, -1);
937 EXPECT_FALSE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
938 EXPECT_FALSE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
939 clippedLayerInChild
+= gfx::Vector2d(0, 1);
940 clippedLayerInChild
+= gfx::Vector2d(0, 1);
941 EXPECT_FALSE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
942 EXPECT_FALSE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
943 clippedLayerInChild
+= gfx::Vector2d(0, -1);
945 this->leaveContributingSurface(child
, occlusion
);
946 this->enterLayer(parent
, occlusion
);
948 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
949 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromInsideTarget().ToString());
951 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
952 EXPECT_RECT_EQ(gfx::Rect(75, 55, 1, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
956 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
958 template<class Types
>
959 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
: public OcclusionTrackerTest
<Types
> {
961 OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
964 gfx::Transform childTransform
;
965 childTransform
.Translate(250, 250);
966 childTransform
.Rotate(90);
967 childTransform
.Translate(-250, -250);
969 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
970 parent
->setMasksToBounds(true);
971 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(500, 500));
972 child
->setMasksToBounds(true);
973 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child
, this->identityMatrix
, gfx::PointF(10, 10), gfx::Size(500, 500), true);
974 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child
, this->identityMatrix
, gfx::PointF(10, 450), gfx::Size(500, 60), true);
975 this->calcDrawEtc(parent
);
977 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
978 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
980 this->visitLayer(layer2
, occlusion
);
981 this->visitLayer(layer1
, occlusion
);
982 this->enterContributingSurface(child
, occlusion
);
984 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
985 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
987 EXPECT_TRUE(occlusion
.occludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
988 EXPECT_FALSE(occlusion
.occludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
989 EXPECT_FALSE(occlusion
.occludedLayer(child
, gfx::Rect(10, 429, 60, 70)));
990 EXPECT_FALSE(occlusion
.occludedLayer(child
, gfx::Rect(11, 430, 60, 70)));
991 EXPECT_FALSE(occlusion
.occludedLayer(child
, gfx::Rect(10, 431, 60, 70)));
993 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
994 EXPECT_RECT_EQ(gfx::Rect(9, 430, 1, 70), occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
995 EXPECT_RECT_EQ(gfx::Rect(10, 429, 60, 1), occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(10, 429, 60, 70)));
996 EXPECT_RECT_EQ(gfx::Rect(70, 430, 1, 70), occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(11, 430, 60, 70)));
997 EXPECT_RECT_EQ(gfx::Rect(10, 500, 60, 1), occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(10, 431, 60, 70)));
999 this->leaveContributingSurface(child
, occlusion
);
1000 this->enterLayer(parent
, occlusion
);
1002 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
1003 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1005 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
1006 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
1007 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
1009 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1010 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 40, 70, 60)));
1011 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 39, 70, 60)));
1012 EXPECT_RECT_EQ(gfx::Rect(100, 40, 1, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 40, 70, 60)));
1013 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 41, 70, 60)));
1015 /* Justification for the above occlusion from |layer1| and |layer2|:
1017 +---------------------+
1018 | |30 Visible region of |layer1|: /////
1019 | | Visible region of |layer2|: \\\\\
1020 | +---------------------------------+
1022 | +---------------+-----------------+ |
1023 | | |\\\\\\\\\\\\|//| 420 | |
1024 | | |\\\\\\\\\\\\|//|60 | |
1025 | | |\\\\\\\\\\\\|//| | |
1026 +--|--|------------|--+ | |
1034 | +------------|-----------------|--+
1036 +---------------+-----------------+
1042 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1044 template<class Types
>
1045 class OcclusionTrackerTestOverlappingSurfaceSiblings
: public OcclusionTrackerTest
<Types
> {
1047 OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1050 gfx::Transform childTransform
;
1051 childTransform
.Translate(250, 250);
1052 childTransform
.Rotate(90);
1053 childTransform
.Translate(-250, -250);
1055 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
1056 parent
->setMasksToBounds(true);
1057 typename
Types::LayerType
* child1
= this->createSurface(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(10, 10));
1058 typename
Types::LayerType
* child2
= this->createSurface(parent
, childTransform
, gfx::PointF(20, 40), gfx::Size(10, 10));
1059 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child1
, this->identityMatrix
, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1060 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child2
, this->identityMatrix
, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1061 this->calcDrawEtc(parent
);
1063 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1064 occlusion
.setLayerClipRect(gfx::Rect(-20, -20, 1000, 1000));
1066 this->visitLayer(layer2
, occlusion
);
1067 this->enterContributingSurface(child2
, occlusion
);
1069 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
1070 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1072 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1073 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1074 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1075 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1076 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1078 occlusion
.useDefaultLayerClipRect();
1079 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1080 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1081 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1082 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1083 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1084 occlusion
.setLayerClipRect(gfx::Rect(-20, -20, 1000, 1000));
1086 // There is nothing above child2's surface in the z-order.
1087 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion
.unoccludedContributingSurfaceContentRect(child2
, false, gfx::Rect(-10, 420, 70, 80)));
1089 this->leaveContributingSurface(child2
, occlusion
);
1090 this->visitLayer(layer1
, occlusion
);
1091 this->enterContributingSurface(child1
, occlusion
);
1093 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
1094 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1096 EXPECT_TRUE(occlusion
.occludedLayer(child1
, gfx::Rect(-10, 430, 80, 70)));
1097 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(-11, 430, 80, 70)));
1098 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(-10, 429, 80, 70)));
1099 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(-10, 430, 81, 70)));
1100 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(-10, 430, 80, 71)));
1102 // child2's contents will occlude child1 below it.
1103 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, gfx::Rect(-10, 430, 80, 70)));
1105 this->leaveContributingSurface(child1
, occlusion
);
1106 this->enterLayer(parent
, occlusion
);
1108 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
1109 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1111 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1113 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1114 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1115 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1117 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1118 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1119 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1121 /* Justification for the above occlusion:
1123 +---------------------+
1125 | 30+ ---------------------------------+
1126 100 | 30| | layer2 |
1127 |20+----------------------------------+ |
1131 +--|-|----------------+ | |
1139 | +--------------------------------|-+
1141 +----------------------------------+
1147 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1149 template<class Types
>
1150 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
: public OcclusionTrackerTest
<Types
> {
1152 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1155 gfx::Transform child1Transform
;
1156 child1Transform
.Translate(250, 250);
1157 child1Transform
.Rotate(-90);
1158 child1Transform
.Translate(-250, -250);
1160 gfx::Transform child2Transform
;
1161 child2Transform
.Translate(250, 250);
1162 child2Transform
.Rotate(90);
1163 child2Transform
.Translate(-250, -250);
1165 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
1166 parent
->setMasksToBounds(true);
1167 typename
Types::LayerType
* child1
= this->createSurface(parent
, child1Transform
, gfx::PointF(30, 20), gfx::Size(10, 10));
1168 typename
Types::LayerType
* child2
= this->createDrawingSurface(parent
, child2Transform
, gfx::PointF(20, 40), gfx::Size(10, 10), false);
1169 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child1
, this->identityMatrix
, gfx::PointF(-10, -20), gfx::Size(510, 510), true);
1170 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child2
, this->identityMatrix
, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1171 this->calcDrawEtc(parent
);
1173 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1174 occlusion
.setLayerClipRect(gfx::Rect(-30, -30, 1000, 1000));
1176 this->visitLayer(layer2
, occlusion
);
1177 this->enterLayer(child2
, occlusion
);
1179 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
1180 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1182 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1183 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1184 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1185 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1186 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1188 this->leaveLayer(child2
, occlusion
);
1189 this->enterContributingSurface(child2
, occlusion
);
1191 // There is nothing above child2's surface in the z-order.
1192 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion
.unoccludedContributingSurfaceContentRect(child2
, false, gfx::Rect(-10, 420, 70, 80)));
1194 this->leaveContributingSurface(child2
, occlusion
);
1195 this->visitLayer(layer1
, occlusion
);
1196 this->enterContributingSurface(child1
, occlusion
);
1198 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
1199 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1201 EXPECT_TRUE(occlusion
.occludedLayer(child1
, gfx::Rect(420, -20, 80, 90)));
1202 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(419, -20, 80, 90)));
1203 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(420, -21, 80, 90)));
1204 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(420, -19, 80, 90)));
1205 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(421, -20, 80, 90)));
1207 // child2's contents will occlude child1 below it.
1208 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, gfx::Rect(420, -20, 80, 90)));
1209 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, gfx::Rect(420, -10, 80, 90)));
1210 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, gfx::Rect(420, -20, 70, 90)));
1212 this->leaveContributingSurface(child1
, occlusion
);
1213 this->enterLayer(parent
, occlusion
);
1215 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
1216 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1218 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(10, 20, 90, 80)));
1219 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(9, 20, 90, 80)));
1220 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(10, 19, 90, 80)));
1221 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(11, 20, 90, 80)));
1222 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(10, 21, 90, 80)));
1224 /* Justification for the above occlusion:
1226 +---------------------+
1228 10+----------------------------------+
1229 100 || 30 | layer2 |
1230 |20+----------------------------------+
1234 +|-|------------------+ | |
1242 +----------------------------------+ |
1244 +----------------------------------+
1250 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1252 template<class Types
>
1253 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1255 OcclusionTrackerTestFilters(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1258 gfx::Transform layerTransform
;
1259 layerTransform
.Translate(250, 250);
1260 layerTransform
.Rotate(90);
1261 layerTransform
.Translate(-250, -250);
1263 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
1264 parent
->setMasksToBounds(true);
1265 typename
Types::ContentLayerType
* blurLayer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1266 typename
Types::ContentLayerType
* opaqueLayer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1267 typename
Types::ContentLayerType
* opacityLayer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1269 WebKit::WebFilterOperations filters
;
1270 filters
.append(WebKit::WebFilterOperation::createBlurFilter(10));
1271 blurLayer
->setFilters(filters
);
1274 filters
.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5));
1275 opaqueLayer
->setFilters(filters
);
1278 filters
.append(WebKit::WebFilterOperation::createOpacityFilter(0.5));
1279 opacityLayer
->setFilters(filters
);
1281 this->calcDrawEtc(parent
);
1283 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1284 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1286 // Opacity layer won't contribute to occlusion.
1287 this->visitLayer(opacityLayer
, occlusion
);
1288 this->enterContributingSurface(opacityLayer
, occlusion
);
1290 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1291 EXPECT_TRUE(occlusion
.occlusionFromInsideTarget().IsEmpty());
1293 // And has nothing to contribute to its parent surface.
1294 this->leaveContributingSurface(opacityLayer
, occlusion
);
1295 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1296 EXPECT_TRUE(occlusion
.occlusionFromInsideTarget().IsEmpty());
1298 // Opaque layer will contribute to occlusion.
1299 this->visitLayer(opaqueLayer
, occlusion
);
1300 this->enterContributingSurface(opaqueLayer
, occlusion
);
1302 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1303 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1305 // And it gets translated to the parent surface.
1306 this->leaveContributingSurface(opaqueLayer
, occlusion
);
1307 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1308 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1310 // The blur layer needs to throw away any occlusion from outside its subtree.
1311 this->enterLayer(blurLayer
, occlusion
);
1312 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1313 EXPECT_TRUE(occlusion
.occlusionFromInsideTarget().IsEmpty());
1315 // And it won't contribute to occlusion.
1316 this->leaveLayer(blurLayer
, occlusion
);
1317 this->enterContributingSurface(blurLayer
, occlusion
);
1318 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1319 EXPECT_TRUE(occlusion
.occlusionFromInsideTarget().IsEmpty());
1321 // But the opaque layer's occlusion is preserved on the parent.
1322 this->leaveContributingSurface(blurLayer
, occlusion
);
1323 this->enterLayer(parent
, occlusion
);
1324 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1325 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1329 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1331 template<class Types
>
1332 class OcclusionTrackerTestReplicaDoesOcclude
: public OcclusionTrackerTest
<Types
> {
1334 OcclusionTrackerTestReplicaDoesOcclude(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1337 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
1338 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1339 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size());
1340 this->calcDrawEtc(parent
);
1342 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1343 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1345 this->visitLayer(surface
, occlusion
);
1347 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1349 this->visitContributingSurface(surface
, occlusion
);
1350 this->enterLayer(parent
, occlusion
);
1352 // The surface and replica should both be occluding the parent.
1353 EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 50)).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1357 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1359 template<class Types
>
1360 class OcclusionTrackerTestReplicaWithClipping
: public OcclusionTrackerTest
<Types
> {
1362 OcclusionTrackerTestReplicaWithClipping(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1365 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 170));
1366 parent
->setMasksToBounds(true);
1367 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1368 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size());
1369 this->calcDrawEtc(parent
);
1371 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1372 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1374 this->visitLayer(surface
, occlusion
);
1376 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1378 this->visitContributingSurface(surface
, occlusion
);
1379 this->enterLayer(parent
, occlusion
);
1381 // The surface and replica should both be occluding the parent.
1382 EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 20)).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1386 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1388 template<class Types
>
1389 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1391 OcclusionTrackerTestReplicaWithMask(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1394 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
1395 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1396 typename
Types::LayerType
* replica
= this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size());
1397 this->createMaskLayer(replica
, gfx::Size(10, 10));
1398 this->calcDrawEtc(parent
);
1400 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1401 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1403 this->visitLayer(surface
, occlusion
);
1405 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1407 this->visitContributingSurface(surface
, occlusion
);
1408 this->enterLayer(parent
, occlusion
);
1410 // The replica should not be occluding the parent, since it has a mask applied to it.
1411 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1415 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1417 template<class Types
>
1418 class OcclusionTrackerTestLayerClipRectOutsideChild
: public OcclusionTrackerTest
<Types
> {
1420 OcclusionTrackerTestLayerClipRectOutsideChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1423 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1424 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1425 this->calcDrawEtc(parent
);
1427 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1428 occlusion
.setLayerClipRect(gfx::Rect(200, 100, 100, 100));
1430 this->enterLayer(layer
, occlusion
);
1432 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1433 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1434 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1435 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1436 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1438 occlusion
.useDefaultLayerClipRect();
1439 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1440 occlusion
.setLayerClipRect(gfx::Rect(200, 100, 100, 100));
1442 this->leaveLayer(layer
, occlusion
);
1443 this->visitContributingSurface(layer
, occlusion
);
1444 this->enterLayer(parent
, occlusion
);
1446 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1447 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1448 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1449 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1450 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1451 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1452 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1453 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1454 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1456 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
1460 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild
);
1462 template<class Types
>
1463 class OcclusionTrackerTestViewportRectOutsideChild
: public OcclusionTrackerTest
<Types
> {
1465 OcclusionTrackerTestViewportRectOutsideChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1468 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1469 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1470 this->calcDrawEtc(parent
);
1472 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(200, 100, 100, 100));
1473 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1475 this->enterLayer(layer
, occlusion
);
1477 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1478 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1479 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1480 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1481 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1483 occlusion
.useDefaultLayerClipRect();
1484 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1485 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1487 this->leaveLayer(layer
, occlusion
);
1488 this->visitContributingSurface(layer
, occlusion
);
1489 this->enterLayer(parent
, occlusion
);
1491 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1492 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1493 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1494 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1495 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1496 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1497 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1498 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1499 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1501 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
1505 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild
);
1507 template<class Types
>
1508 class OcclusionTrackerTestLayerClipRectOverChild
: public OcclusionTrackerTest
<Types
> {
1510 OcclusionTrackerTestLayerClipRectOverChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1513 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1514 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1515 this->calcDrawEtc(parent
);
1517 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1518 occlusion
.setLayerClipRect(gfx::Rect(100, 100, 100, 100));
1520 this->enterLayer(layer
, occlusion
);
1522 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1523 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1524 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1525 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1527 this->leaveLayer(layer
, occlusion
);
1528 this->visitContributingSurface(layer
, occlusion
);
1529 this->enterLayer(parent
, occlusion
);
1531 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1532 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1533 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1534 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1535 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1536 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1537 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1538 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1539 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1541 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1545 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild
);
1547 template<class Types
>
1548 class OcclusionTrackerTestViewportRectOverChild
: public OcclusionTrackerTest
<Types
> {
1550 OcclusionTrackerTestViewportRectOverChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1553 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1554 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1555 this->calcDrawEtc(parent
);
1557 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(100, 100, 100, 100));
1558 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1560 this->enterLayer(layer
, occlusion
);
1562 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1563 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1564 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1565 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1567 this->leaveLayer(layer
, occlusion
);
1568 this->visitContributingSurface(layer
, occlusion
);
1569 this->enterLayer(parent
, occlusion
);
1571 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1572 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1573 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1574 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1575 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1576 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1577 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1578 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1579 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1581 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1585 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild
);
1587 template<class Types
>
1588 class OcclusionTrackerTestLayerClipRectPartlyOverChild
: public OcclusionTrackerTest
<Types
> {
1590 OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1593 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1594 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1595 this->calcDrawEtc(parent
);
1597 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1598 occlusion
.setLayerClipRect(gfx::Rect(50, 50, 200, 200));
1600 this->enterLayer(layer
, occlusion
);
1602 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1603 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1604 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1605 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1607 this->leaveLayer(layer
, occlusion
);
1608 this->visitContributingSurface(layer
, occlusion
);
1609 this->enterLayer(parent
, occlusion
);
1611 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1612 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1613 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1614 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1615 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1616 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1617 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1618 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1619 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1621 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
1622 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 100)));
1623 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 100, 300, 100)));
1624 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(200, 100, 100, 100)));
1625 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(100, 200, 100, 100)));
1629 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild
);
1631 template<class Types
>
1632 class OcclusionTrackerTestViewportRectPartlyOverChild
: public OcclusionTrackerTest
<Types
> {
1634 OcclusionTrackerTestViewportRectPartlyOverChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1637 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1638 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1639 this->calcDrawEtc(parent
);
1641 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(50, 50, 200, 200));
1642 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1644 this->enterLayer(layer
, occlusion
);
1646 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1647 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1648 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1649 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1651 this->leaveLayer(layer
, occlusion
);
1652 this->visitContributingSurface(layer
, occlusion
);
1653 this->enterLayer(parent
, occlusion
);
1655 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1656 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1657 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1658 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1659 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1660 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1661 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1662 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1663 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1665 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
1666 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 100)));
1667 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 100, 300, 100)));
1668 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(200, 100, 100, 100)));
1669 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(100, 200, 100, 100)));
1673 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild
);
1675 template<class Types
>
1676 class OcclusionTrackerTestLayerClipRectOverNothing
: public OcclusionTrackerTest
<Types
> {
1678 OcclusionTrackerTestLayerClipRectOverNothing(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1681 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1682 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1683 this->calcDrawEtc(parent
);
1685 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1686 occlusion
.setLayerClipRect(gfx::Rect(500, 500, 100, 100));
1688 this->enterLayer(layer
, occlusion
);
1690 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1691 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1692 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1693 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1695 this->leaveLayer(layer
, occlusion
);
1696 this->visitContributingSurface(layer
, occlusion
);
1697 this->enterLayer(parent
, occlusion
);
1699 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1700 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1701 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1702 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1703 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1704 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1705 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1706 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1707 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1709 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1710 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 100)).IsEmpty());
1711 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 100, 300, 100)).IsEmpty());
1712 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(200, 100, 100, 100)).IsEmpty());
1713 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(100, 200, 100, 100)).IsEmpty());
1717 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverNothing
);
1719 template<class Types
>
1720 class OcclusionTrackerTestViewportRectOverNothing
: public OcclusionTrackerTest
<Types
> {
1722 OcclusionTrackerTestViewportRectOverNothing(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1725 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1726 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1727 this->calcDrawEtc(parent
);
1729 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(500, 500, 100, 100));
1730 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1732 this->enterLayer(layer
, occlusion
);
1734 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1735 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1736 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1737 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1739 this->leaveLayer(layer
, occlusion
);
1740 this->visitContributingSurface(layer
, occlusion
);
1741 this->enterLayer(parent
, occlusion
);
1743 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1744 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1745 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1746 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1747 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1748 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1749 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1750 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1751 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1753 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1754 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 100)).IsEmpty());
1755 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 100, 300, 100)).IsEmpty());
1756 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(200, 100, 100, 100)).IsEmpty());
1757 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(100, 200, 100, 100)).IsEmpty());
1761 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing
);
1763 template<class Types
>
1764 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
: public OcclusionTrackerTest
<Types
> {
1766 OcclusionTrackerTestLayerClipRectForLayerOffOrigin(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1769 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1770 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1771 this->calcDrawEtc(parent
);
1773 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1774 this->enterLayer(layer
, occlusion
);
1776 // This layer is translated when drawn into its target. So if the clip rect given from the target surface
1777 // is not in that target space, then after translating these query rects into the target, they will fall outside
1778 // the clip and be considered occluded.
1779 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1780 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1781 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1782 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1786 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin
);
1788 template<class Types
>
1789 class OcclusionTrackerTestOpaqueContentsRegionEmpty
: public OcclusionTrackerTest
<Types
> {
1791 OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1794 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1795 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), false);
1796 this->calcDrawEtc(parent
);
1798 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1799 this->enterLayer(layer
, occlusion
);
1801 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1802 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1803 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1804 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1806 // Occluded since its outside the surface bounds.
1807 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1809 // Test without any clip rect.
1810 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1811 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1812 occlusion
.useDefaultLayerClipRect();
1814 this->leaveLayer(layer
, occlusion
);
1815 this->visitContributingSurface(layer
, occlusion
);
1816 this->enterLayer(parent
, occlusion
);
1818 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1822 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1824 template<class Types
>
1825 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
: public OcclusionTrackerTest
<Types
> {
1827 OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1830 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1831 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 100), gfx::Size(200, 200), false);
1832 this->calcDrawEtc(parent
);
1835 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1836 layer
->setOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1838 this->resetLayerIterator();
1839 this->visitLayer(layer
, occlusion
);
1840 this->enterLayer(parent
, occlusion
);
1842 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1844 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1845 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1846 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1850 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1851 layer
->setOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1853 this->resetLayerIterator();
1854 this->visitLayer(layer
, occlusion
);
1855 this->enterLayer(parent
, occlusion
);
1857 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1859 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1860 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1861 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1865 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1866 layer
->setOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1868 this->resetLayerIterator();
1869 this->visitLayer(layer
, occlusion
);
1870 this->enterLayer(parent
, occlusion
);
1872 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
1874 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1875 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1876 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1881 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1883 template<class Types
>
1884 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
1886 OcclusionTrackerTest3dTransform(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1889 gfx::Transform transform
;
1890 MathUtil::rotateEulerAngles(&transform
, 0, 30, 0);
1892 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1893 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1894 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, gfx::PointF(100, 100), gfx::Size(200, 200), true);
1895 this->calcDrawEtc(parent
);
1897 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1898 this->enterLayer(layer
, occlusion
);
1900 // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
1901 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion
.unoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1905 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
1907 template<class Types
>
1908 class OcclusionTrackerTestUnsorted3dLayers
: public OcclusionTrackerTest
<Types
> {
1910 OcclusionTrackerTestUnsorted3dLayers(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1913 // Currently, the main thread layer iterator does not iterate over 3d items in
1914 // sorted order, because layer sorting is not performed on the main thread.
1915 // Because of this, the occlusion tracker cannot assume that a 3d layer occludes
1916 // other layers that have not yet been iterated over. For now, the expected
1917 // behavior is that a 3d layer simply does not add any occlusion to the occlusion
1920 gfx::Transform translationToFront
;
1921 translationToFront
.Translate3d(0, 0, -10);
1922 gfx::Transform translationToBack
;
1923 translationToFront
.Translate3d(0, 0, -100);
1925 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1926 typename
Types::ContentLayerType
* child1
= this->createDrawingLayer(parent
, translationToBack
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
1927 typename
Types::ContentLayerType
* child2
= this->createDrawingLayer(parent
, translationToFront
, gfx::PointF(50, 50), gfx::Size(100, 100), true);
1928 parent
->setPreserves3D(true);
1930 this->calcDrawEtc(parent
);
1932 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1933 this->visitLayer(child2
, occlusion
);
1934 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1935 EXPECT_TRUE(occlusion
.occlusionFromInsideTarget().IsEmpty());
1937 this->visitLayer(child1
, occlusion
);
1938 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
1939 EXPECT_TRUE(occlusion
.occlusionFromInsideTarget().IsEmpty());
1943 // This test will have different layer ordering on the impl thread; the test will only work on the main thread.
1944 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1946 template<class Types
>
1947 class OcclusionTrackerTestPerspectiveTransform
: public OcclusionTrackerTest
<Types
> {
1949 OcclusionTrackerTestPerspectiveTransform(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1952 gfx::Transform transform
;
1953 transform
.Translate(150, 150);
1954 transform
.ApplyPerspectiveDepth(400);
1955 transform
.RotateAboutXAxis(-30);
1956 transform
.Translate(-150, -150);
1958 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1959 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1960 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, gfx::PointF(100, 100), gfx::Size(200, 200), true);
1961 container
->setPreserves3D(true);
1962 layer
->setPreserves3D(true);
1963 this->calcDrawEtc(parent
);
1965 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1966 this->enterLayer(layer
, occlusion
);
1968 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion
.unoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1972 // This test requires accumulating occlusion of 3d layers, which are skipped by the occlusion tracker on the main thread. So this test should run on the impl thread.
1973 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
1975 template<class Types
>
1976 class OcclusionTrackerTestPerspectiveTransformBehindCamera
: public OcclusionTrackerTest
<Types
> {
1978 OcclusionTrackerTestPerspectiveTransformBehindCamera(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1981 // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
1982 gfx::Transform transform
;
1983 transform
.Translate(250, 50);
1984 transform
.ApplyPerspectiveDepth(10);
1985 transform
.Translate(-250, -50);
1986 transform
.Translate(250, 50);
1987 transform
.RotateAboutXAxis(-167);
1988 transform
.Translate(-250, -50);
1990 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(500, 100));
1991 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(500, 500));
1992 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, gfx::PointF(0, 0), gfx::Size(500, 500), true);
1993 container
->setPreserves3D(true);
1994 layer
->setPreserves3D(true);
1995 this->calcDrawEtc(parent
);
1997 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1998 this->enterLayer(layer
, occlusion
);
2000 // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
2001 // this will include many more pixels but must include at least the bottom 11 rows.
2002 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
2006 // This test requires accumulating occlusion of 3d layers, which are skipped by the occlusion tracker on the main thread. So this test should run on the impl thread.
2007 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
2009 template<class Types
>
2010 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
: public OcclusionTrackerTest
<Types
> {
2012 OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2015 gfx::Transform transform
;
2016 transform
.Translate(50, 50);
2017 transform
.ApplyPerspectiveDepth(100);
2018 transform
.Translate3d(0, 0, 110);
2019 transform
.Translate(-50, -50);
2021 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
2022 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, transform
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2023 parent
->setPreserves3D(true);
2024 layer
->setPreserves3D(true);
2025 this->calcDrawEtc(parent
);
2027 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2029 // The |layer| is entirely behind the camera and should not occlude.
2030 this->visitLayer(layer
, occlusion
);
2031 this->enterLayer(parent
, occlusion
);
2032 EXPECT_TRUE(occlusion
.occlusionFromInsideTarget().IsEmpty());
2033 EXPECT_TRUE(occlusion
.occlusionFromOutsideTarget().IsEmpty());
2037 // This test requires accumulating occlusion of 3d layers, which are skipped by the occlusion tracker on the main thread. So this test should run on the impl thread.
2038 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2040 template<class Types
>
2041 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
: public OcclusionTrackerTest
<Types
> {
2043 OcclusionTrackerTestLargePixelsOccludeInsideClipRect(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2046 gfx::Transform transform
;
2047 transform
.Translate(50, 50);
2048 transform
.ApplyPerspectiveDepth(100);
2049 transform
.Translate3d(0, 0, 99);
2050 transform
.Translate(-50, -50);
2052 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
2053 parent
->setMasksToBounds(true);
2054 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, transform
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2055 parent
->setPreserves3D(true);
2056 layer
->setPreserves3D(true);
2057 this->calcDrawEtc(parent
);
2059 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2061 // This is very close to the camera, so pixels in its visibleContentRect will actually go outside of the layer's clipRect.
2062 // Ensure that those pixels don't occlude things outside the clipRect.
2063 this->visitLayer(layer
, occlusion
);
2064 this->enterLayer(parent
, occlusion
);
2065 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2066 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2070 // This test requires accumulating occlusion of 3d layers, which are skipped by the occlusion tracker on the main thread. So this test should run on the impl thread.
2071 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2073 template<class Types
>
2074 class OcclusionTrackerTestAnimationOpacity1OnMainThread
: public OcclusionTrackerTest
<Types
> {
2076 OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2079 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
2080 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2081 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2082 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2083 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2084 typename
Types::ContentLayerType
* parent2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2085 typename
Types::ContentLayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(250, 0), gfx::Size(50, 300), true);
2087 addOpacityTransitionToController(*layer
->layerAnimationController(), 10, 0, 1, false);
2088 addOpacityTransitionToController(*surface
->layerAnimationController(), 10, 0, 1, false);
2089 this->calcDrawEtc(parent
);
2091 EXPECT_TRUE(layer
->drawOpacityIsAnimating());
2092 EXPECT_FALSE(surface
->drawOpacityIsAnimating());
2093 EXPECT_TRUE(surface
->renderSurface()->drawOpacityIsAnimating());
2095 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2097 this->visitLayer(topmost
, occlusion
);
2098 this->enterLayer(parent2
, occlusion
);
2099 // This occlusion will affect all surfaces.
2100 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent2
, gfx::Rect(0, 0, 300, 300)));
2101 this->leaveLayer(parent2
, occlusion
);
2103 this->visitLayer(surfaceChild2
, occlusion
);
2104 this->enterLayer(surfaceChild
, occlusion
);
2105 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), occlusion
.unoccludedLayerContentRect(surfaceChild
, gfx::Rect(0, 0, 300, 300)));
2106 this->leaveLayer(surfaceChild
, occlusion
);
2107 this->enterLayer(surface
, occlusion
);
2108 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2109 this->leaveLayer(surface
, occlusion
);
2111 this->enterContributingSurface(surface
, occlusion
);
2112 // Occlusion within the surface is lost when leaving the animating surface.
2113 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 300, 300)));
2114 this->leaveContributingSurface(surface
, occlusion
);
2116 this->visitLayer(layer
, occlusion
);
2117 this->enterLayer(parent
, occlusion
);
2119 // Occlusion is not added for the animating |layer|.
2120 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2124 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2126 template<class Types
>
2127 class OcclusionTrackerTestAnimationOpacity0OnMainThread
: public OcclusionTrackerTest
<Types
> {
2129 OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2132 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
2133 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2134 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2135 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2136 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2137 typename
Types::ContentLayerType
* parent2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2138 typename
Types::ContentLayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(250, 0), gfx::Size(50, 300), true);
2140 addOpacityTransitionToController(*layer
->layerAnimationController(), 10, 1, 0, false);
2141 addOpacityTransitionToController(*surface
->layerAnimationController(), 10, 1, 0, false);
2142 this->calcDrawEtc(parent
);
2144 EXPECT_TRUE(layer
->drawOpacityIsAnimating());
2145 EXPECT_FALSE(surface
->drawOpacityIsAnimating());
2146 EXPECT_TRUE(surface
->renderSurface()->drawOpacityIsAnimating());
2148 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2150 this->visitLayer(topmost
, occlusion
);
2151 this->enterLayer(parent2
, occlusion
);
2152 // This occlusion will affect all surfaces.
2153 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2154 this->leaveLayer(parent2
, occlusion
);
2156 this->visitLayer(surfaceChild2
, occlusion
);
2157 this->enterLayer(surfaceChild
, occlusion
);
2158 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), occlusion
.unoccludedLayerContentRect(surfaceChild
, gfx::Rect(0, 0, 300, 300)));
2159 this->leaveLayer(surfaceChild
, occlusion
);
2160 this->enterLayer(surface
, occlusion
);
2161 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2162 this->leaveLayer(surface
, occlusion
);
2164 this->enterContributingSurface(surface
, occlusion
);
2165 // Occlusion within the surface is lost when leaving the animating surface.
2166 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 300, 300)));
2167 this->leaveContributingSurface(surface
, occlusion
);
2169 this->visitLayer(layer
, occlusion
);
2170 this->enterLayer(parent
, occlusion
);
2172 // Occlusion is not added for the animating |layer|.
2173 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2177 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2179 template<class Types
>
2180 class OcclusionTrackerTestAnimationTranslateOnMainThread
: public OcclusionTrackerTest
<Types
> {
2182 OcclusionTrackerTestAnimationTranslateOnMainThread(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2185 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
2186 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2187 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2188 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2189 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2190 typename
Types::ContentLayerType
* surface2
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(50, 300), true);
2192 addAnimatedTransformToController(*layer
->layerAnimationController(), 10, 30, 0);
2193 addAnimatedTransformToController(*surface
->layerAnimationController(), 10, 30, 0);
2194 addAnimatedTransformToController(*surfaceChild
->layerAnimationController(), 10, 30, 0);
2195 this->calcDrawEtc(parent
);
2197 EXPECT_TRUE(layer
->drawTransformIsAnimating());
2198 EXPECT_TRUE(layer
->screenSpaceTransformIsAnimating());
2199 EXPECT_TRUE(surface
->renderSurface()->targetSurfaceTransformsAreAnimating());
2200 EXPECT_TRUE(surface
->renderSurface()->screenSpaceTransformsAreAnimating());
2201 // The surface owning layer doesn't animate against its own surface.
2202 EXPECT_FALSE(surface
->drawTransformIsAnimating());
2203 EXPECT_TRUE(surface
->screenSpaceTransformIsAnimating());
2204 EXPECT_TRUE(surfaceChild
->drawTransformIsAnimating());
2205 EXPECT_TRUE(surfaceChild
->screenSpaceTransformIsAnimating());
2207 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2209 this->visitLayer(surface2
, occlusion
);
2210 this->enterContributingSurface(surface2
, occlusion
);
2212 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2214 this->leaveContributingSurface(surface2
, occlusion
);
2215 this->enterLayer(surfaceChild2
, occlusion
);
2217 // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2218 // It also means that things occluding from outside the target (e.g. surface2) cannot occlude this layer.
2219 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2221 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300), occlusion
.unoccludedLayerContentRect(surfaceChild2
, gfx::Rect(0, 0, 100, 300)));
2222 EXPECT_FALSE(occlusion
.occludedLayer(surfaceChild
, gfx::Rect(0, 0, 50, 300)));
2224 this->leaveLayer(surfaceChild2
, occlusion
);
2225 this->enterLayer(surfaceChild
, occlusion
);
2226 EXPECT_FALSE(occlusion
.occludedLayer(surfaceChild
, gfx::Rect(0, 0, 100, 300)));
2227 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2228 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2229 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2231 // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target, so it can't be occluded.
2232 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300), occlusion
.unoccludedLayerContentRect(surfaceChild
, gfx::Rect(0, 0, 200, 300)));
2233 EXPECT_FALSE(occlusion
.occludedLayer(surfaceChild
, gfx::Rect(0, 0, 50, 300)));
2235 this->leaveLayer(surfaceChild
, occlusion
);
2236 this->enterLayer(surface
, occlusion
);
2237 // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen from within the target only.
2238 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2239 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2240 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2242 this->leaveLayer(surface
, occlusion
);
2243 // The surface's owning layer is moving in screen space but not relative to its target, so occlusion should happen within the target only.
2244 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2245 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2246 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2248 this->enterContributingSurface(surface
, occlusion
);
2249 // The contributing |surface| is animating so it can't be occluded.
2250 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 300, 300)));
2251 this->leaveContributingSurface(surface
, occlusion
);
2253 this->enterLayer(layer
, occlusion
);
2254 // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
2255 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2256 this->leaveLayer(layer
, occlusion
);
2258 this->enterLayer(parent
, occlusion
);
2259 // The |layer| is animating in the screen and in its target, so no occlusion is added.
2260 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2264 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
2266 template<class Types
>
2267 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
: public OcclusionTrackerTest
<Types
> {
2269 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2272 gfx::Transform surfaceTransform
;
2273 surfaceTransform
.Translate(300, 300);
2274 surfaceTransform
.Scale(2, 2);
2275 surfaceTransform
.Translate(-150, -150);
2277 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(500, 500));
2278 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, surfaceTransform
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2279 typename
Types::ContentLayerType
* surface2
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size(300, 300), false);
2280 surface
->setOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2281 surface2
->setOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2282 this->calcDrawEtc(parent
);
2284 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2286 this->visitLayer(surface2
, occlusion
);
2287 this->visitContributingSurface(surface2
, occlusion
);
2289 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2290 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2292 // Clear any stored occlusion.
2293 occlusion
.setOcclusionFromOutsideTarget(Region());
2294 occlusion
.setOcclusionFromInsideTarget(Region());
2296 this->visitLayer(surface
, occlusion
);
2297 this->visitContributingSurface(surface
, occlusion
);
2299 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2300 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2304 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
2306 template<class Types
>
2307 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
: public OcclusionTrackerTest
<Types
> {
2309 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2312 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
2313 parent
->setMasksToBounds(true);
2314 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(500, 300), false);
2315 surface
->setOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2316 this->calcDrawEtc(parent
);
2318 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2320 this->visitLayer(surface
, occlusion
);
2321 this->visitContributingSurface(surface
, occlusion
);
2323 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2324 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2328 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2330 template<class Types
>
2331 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
2333 OcclusionTrackerTestReplicaOccluded(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2336 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2337 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2338 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(100, 100));
2339 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(100, 100), true);
2340 this->calcDrawEtc(parent
);
2342 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2343 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2345 // |topmost| occludes the replica, but not the surface itself.
2346 this->visitLayer(topmost
, occlusion
);
2348 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2349 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2351 this->visitLayer(surface
, occlusion
);
2353 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2354 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2356 this->enterContributingSurface(surface
, occlusion
);
2358 // Surface is not occluded so it shouldn't think it is.
2359 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2363 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
2365 template<class Types
>
2366 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
: public OcclusionTrackerTest
<Types
> {
2368 OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2371 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2372 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2373 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(100, 100));
2374 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 110), true);
2375 this->calcDrawEtc(parent
);
2377 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2378 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2380 // |topmost| occludes the surface, but not the entire surface's replica.
2381 this->visitLayer(topmost
, occlusion
);
2383 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2384 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2386 this->visitLayer(surface
, occlusion
);
2388 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2389 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2391 this->enterContributingSurface(surface
, occlusion
);
2393 // Surface is occluded, but only the top 10px of the replica.
2394 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2395 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90), occlusion
.unoccludedContributingSurfaceContentRect(surface
, true, gfx::Rect(0, 0, 100, 100)));
2399 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2401 template<class Types
>
2402 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
: public OcclusionTrackerTest
<Types
> {
2404 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2407 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2408 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2409 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(100, 100));
2410 typename
Types::LayerType
* overSurface
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(40, 100), true);
2411 typename
Types::LayerType
* overReplica
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(50, 100), true);
2412 this->calcDrawEtc(parent
);
2414 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2415 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2417 // These occlude the surface and replica differently, so we can test each one.
2418 this->visitLayer(overReplica
, occlusion
);
2419 this->visitLayer(overSurface
, occlusion
);
2421 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2422 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2424 this->visitLayer(surface
, occlusion
);
2426 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2427 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2429 this->enterContributingSurface(surface
, occlusion
);
2431 // Surface and replica are occluded different amounts.
2432 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2433 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, true, gfx::Rect(0, 0, 100, 100)));
2437 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
2439 template<class Types
>
2440 class OcclusionTrackerTestSurfaceChildOfSurface
: public OcclusionTrackerTest
<Types
> {
2442 OcclusionTrackerTestSurfaceChildOfSurface(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2445 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2447 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2448 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2449 typename
Types::LayerType
* surfaceChild
= this->createDrawingSurface(surface
, this->identityMatrix
, gfx::PointF(0, 10), gfx::Size(100, 50), true);
2450 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 50), true);
2451 this->calcDrawEtc(parent
);
2453 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(-100, -100, 1000, 1000));
2455 // |topmost| occludes everything partially so we know occlusion is happening at all.
2456 this->visitLayer(topmost
, occlusion
);
2458 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2459 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2461 this->visitLayer(surfaceChild
, occlusion
);
2463 // surfaceChild increases the occlusion in the screen by a narrow sliver.
2464 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2465 // In its own surface, surfaceChild is at 0,0 as is its occlusion.
2466 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2468 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2469 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2470 // as its parent does not have a clipRect.
2472 this->enterContributingSurface(surfaceChild
, occlusion
);
2473 // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
2474 // does not get clipped away inappropriately.
2475 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10), occlusion
.unoccludedContributingSurfaceContentRect(surfaceChild
, false, gfx::Rect(0, 0, 100, 50)));
2476 this->leaveContributingSurface(surfaceChild
, occlusion
);
2478 // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
2479 this->enterLayer(surface
, occlusion
);
2480 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2481 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2482 this->leaveLayer(surface
, occlusion
);
2484 this->enterContributingSurface(surface
, occlusion
);
2485 // The surface's parent does have a clipRect as it is the root layer.
2486 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2490 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2492 template<class Types
>
2493 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
: public OcclusionTrackerTest
<Types
> {
2495 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2498 // This test verifies that the top-most surface is considered occluded outside of its target's clipRect and outside the viewport rect.
2500 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2501 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2502 this->calcDrawEtc(parent
);
2505 // Make a viewport rect that is larger than the root layer.
2506 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2508 this->visitLayer(surface
, occlusion
);
2510 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2511 this->enterContributingSurface(surface
, occlusion
);
2512 // Make sure the parent's clipRect clips the unoccluded region of the child surface.
2513 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 300)));
2515 this->resetLayerIterator();
2517 // Make a viewport rect that is smaller than the root layer.
2518 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 100, 100));
2520 this->visitLayer(surface
, occlusion
);
2522 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2523 this->enterContributingSurface(surface
, occlusion
);
2524 // Make sure the viewport rect clips the unoccluded region of the child surface.
2525 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 300)));
2530 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
);
2532 template<class Types
>
2533 class OcclusionTrackerTestSurfaceChildOfClippingSurface
: public OcclusionTrackerTest
<Types
> {
2535 OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2538 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2540 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(80, 200));
2541 parent
->setMasksToBounds(true);
2542 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2543 typename
Types::LayerType
* surfaceChild
= this->createDrawingSurface(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), false);
2544 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 50), true);
2545 this->calcDrawEtc(parent
);
2547 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2548 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2550 // |topmost| occludes everything partially so we know occlusion is happening at all.
2551 this->visitLayer(topmost
, occlusion
);
2553 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2554 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2556 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2557 this->visitLayer(surfaceChild
, occlusion
);
2559 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2560 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2562 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2563 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2564 // as its parent does not have a clipRect.
2566 this->enterContributingSurface(surfaceChild
, occlusion
);
2567 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
2568 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(), occlusion
.unoccludedContributingSurfaceContentRect(surfaceChild
, false, gfx::Rect(0, 0, 100, 100)).ToString());
2569 this->leaveContributingSurface(surfaceChild
, occlusion
);
2571 this->visitLayer(surface
, occlusion
);
2572 this->enterContributingSurface(surface
, occlusion
);
2573 // The surface's parent does have a clipRect as it is the root layer.
2574 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)).ToString());
2578 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface
);
2580 template<class Types
>
2581 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
: public OcclusionTrackerTest
<Types
> {
2583 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2586 gfx::Transform scaleByHalf
;
2587 scaleByHalf
.Scale(0.5, 0.5);
2589 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2590 // The surface is scaled to test that the pixel moving is done in the target space, where the background filter is applied, but the surface
2591 // appears at 50, 50 and the replica at 200, 50.
2592 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2593 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2594 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(300, 0), gfx::Size());
2595 typename
Types::LayerType
* occludingLayer1
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 50), true);
2596 typename
Types::LayerType
* occludingLayer2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(300, 50), true);
2597 typename
Types::LayerType
* occludingLayer3
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 50), gfx::Size(50, 50), true);
2598 typename
Types::LayerType
* occludingLayer4
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 50), gfx::Size(100, 50), true);
2599 typename
Types::LayerType
* occludingLayer5
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(250, 50), gfx::Size(50, 50), true);
2601 // Filters make the layer own a surface.
2602 WebKit::WebFilterOperations filters
;
2603 filters
.append(WebKit::WebFilterOperation::createBlurFilter(10));
2604 filteredSurface
->setBackgroundFilters(filters
);
2606 // Save the distance of influence for the blur effect.
2607 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2608 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2610 this->calcDrawEtc(parent
);
2612 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2613 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2615 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2616 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2617 this->visitLayer(occludingLayer5
, occlusion
);
2618 this->visitLayer(occludingLayer4
, occlusion
);
2619 this->visitLayer(occludingLayer3
, occlusion
);
2620 this->visitLayer(occludingLayer2
, occlusion
);
2621 this->visitLayer(occludingLayer1
, occlusion
);
2623 Region expectedOcclusion
;
2624 expectedOcclusion
.Union(gfx::Rect(0, 0, 300, 50));
2625 expectedOcclusion
.Union(gfx::Rect(0, 50, 50, 50));
2626 expectedOcclusion
.Union(gfx::Rect(100, 50, 100, 50));
2627 expectedOcclusion
.Union(gfx::Rect(250, 50, 50, 50));
2628 expectedOcclusion
.Union(gfx::Rect(0, 100, 300, 50));
2630 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2631 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2633 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2634 this->enterLayer(filteredSurface
, occlusion
);
2635 EXPECT_RECT_EQ(gfx::Rect(1, 0, 99, 100), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(1, 0, 100, 100)));
2636 EXPECT_RECT_EQ(gfx::Rect(0, 1, 100, 99), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(0, 1, 100, 100)));
2637 EXPECT_RECT_EQ(gfx::Rect(0, 0, 99, 100), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(-1, 0, 100, 100)));
2638 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 99), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(0, -1, 100, 100)));
2640 EXPECT_RECT_EQ(gfx::Rect(300 + 1, 0, 99, 100), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(300 + 1, 0, 100, 100)));
2641 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 1, 100, 99), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(300 + 0, 1, 100, 100)));
2642 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 0, 99, 100), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(300 - 1, 0, 100, 100)));
2643 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 0, 100, 99), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(300 + 0, -1, 100, 100)));
2644 this->leaveLayer(filteredSurface
, occlusion
);
2646 // The filtered layer/replica does not occlude.
2647 Region expectedOcclusionOutsideSurface
;
2648 expectedOcclusionOutsideSurface
.Union(gfx::Rect(-50, -50, 300, 50));
2649 expectedOcclusionOutsideSurface
.Union(gfx::Rect(-50, 0, 50, 50));
2650 expectedOcclusionOutsideSurface
.Union(gfx::Rect(50, 0, 100, 50));
2651 expectedOcclusionOutsideSurface
.Union(gfx::Rect(200, 0, 50, 50));
2652 expectedOcclusionOutsideSurface
.Union(gfx::Rect(-50, 50, 300, 50));
2654 EXPECT_EQ(expectedOcclusionOutsideSurface
.ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2655 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2657 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2658 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2659 this->visitContributingSurface(filteredSurface
, occlusion
);
2661 this->enterLayer(parent
, occlusion
);
2663 Region expectedBlurredOcclusion
;
2664 expectedBlurredOcclusion
.Union(gfx::Rect(0, 0, 300, 50 - outsetTop
));
2665 expectedBlurredOcclusion
.Union(gfx::Rect(0, 50 - outsetTop
, 50 - outsetLeft
, 50 + outsetTop
+ outsetBottom
));
2666 expectedBlurredOcclusion
.Union(gfx::Rect(100 + outsetRight
, 50 - outsetTop
, 100 - outsetRight
- outsetLeft
, 50 + outsetTop
+ outsetBottom
));
2667 expectedBlurredOcclusion
.Union(gfx::Rect(250 + outsetRight
, 50 - outsetTop
, 50 - outsetRight
, 50 + outsetTop
+ outsetBottom
));
2668 expectedBlurredOcclusion
.Union(gfx::Rect(0, 100 + outsetBottom
, 300, 50 - outsetBottom
));
2670 EXPECT_EQ(expectedBlurredOcclusion
.ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2671 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2673 gfx::Rect outsetRect
;
2676 // Nothing in the blur outsets for the filteredSurface is occluded.
2677 outsetRect
= gfx::Rect(50 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2678 testRect
= outsetRect
;
2679 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2681 // Stuff outside the blur outsets is still occluded though.
2682 testRect
= outsetRect
;
2683 testRect
.Inset(0, 0, -1, 0);
2684 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2685 testRect
= outsetRect
;
2686 testRect
.Inset(0, 0, 0, -1);
2687 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2688 testRect
= outsetRect
;
2689 testRect
.Inset(-1, 0, 0, 0);
2690 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2691 testRect
= outsetRect
;
2692 testRect
.Inset(0, -1, 0, 0);
2693 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2695 // Nothing in the blur outsets for the filteredSurface's replica is occluded.
2696 outsetRect
= gfx::Rect(200 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2697 testRect
= outsetRect
;
2698 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2700 // Stuff outside the blur outsets is still occluded though.
2701 testRect
= outsetRect
;
2702 testRect
.Inset(0, 0, -1, 0);
2703 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2704 testRect
= outsetRect
;
2705 testRect
.Inset(0, 0, 0, -1);
2706 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2707 testRect
= outsetRect
;
2708 testRect
.Inset(-1, 0, 0, 0);
2709 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2710 testRect
= outsetRect
;
2711 testRect
.Inset(0, -1, 0, 0);
2712 EXPECT_EQ(outsetRect
.ToString(), occlusion
.unoccludedLayerContentRect(parent
, testRect
).ToString());
2716 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
2718 template<class Types
>
2719 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
: public OcclusionTrackerTest
<Types
> {
2721 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2724 gfx::Transform scaleByHalf
;
2725 scaleByHalf
.Scale(0.5, 0.5);
2727 // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
2728 typename
Types::ContentLayerType
* root
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(75, 75));
2729 typename
Types::LayerType
* parent
= this->createSurface(root
, scaleByHalf
, gfx::PointF(0, 0), gfx::Size(150, 150));
2730 parent
->setMasksToBounds(true);
2731 typename
Types::LayerType
* filteredSurface1
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2732 typename
Types::LayerType
* filteredSurface2
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2733 typename
Types::LayerType
* occludingLayerAbove
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 100), gfx::Size(50, 50), true);
2735 // Filters make the layers own surfaces.
2736 WebKit::WebFilterOperations filters
;
2737 filters
.append(WebKit::WebFilterOperation::createBlurFilter(1));
2738 filteredSurface1
->setBackgroundFilters(filters
);
2739 filteredSurface2
->setBackgroundFilters(filters
);
2741 // Save the distance of influence for the blur effect.
2742 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2743 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2745 this->calcDrawEtc(root
);
2747 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2748 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2750 this->visitLayer(occludingLayerAbove
, occlusion
);
2751 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2752 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2754 this->visitLayer(filteredSurface2
, occlusion
);
2755 this->visitContributingSurface(filteredSurface2
, occlusion
);
2756 this->visitLayer(filteredSurface1
, occlusion
);
2757 this->visitContributingSurface(filteredSurface1
, occlusion
);
2759 // Test expectations in the target.
2760 gfx::Rect expectedOcclusion
= gfx::Rect(100 / 2 + outsetRight
* 2, 100 / 2 + outsetBottom
* 2, 50 / 2 - (outsetLeft
+ outsetRight
) * 2, 50 / 2 - (outsetTop
+ outsetBottom
) * 2);
2761 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2763 // Test expectations in the screen are the same as in the target, as the render surface is 1:1 with the screen.
2764 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2768 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
2770 template<class Types
>
2771 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
: public OcclusionTrackerTest
<Types
> {
2773 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2776 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2777 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2778 // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
2779 // the background filter.
2780 typename
Types::LayerType
* clippingSurface
= this->createSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 70));
2781 clippingSurface
->setMasksToBounds(true);
2782 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(clippingSurface
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size(50, 50), false);
2783 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(150, 0), gfx::Size());
2784 typename
Types::LayerType
* occludingLayer1
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 50), true);
2785 typename
Types::LayerType
* occludingLayer2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(300, 50), true);
2786 typename
Types::LayerType
* occludingLayer3
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 50), gfx::Size(50, 50), true);
2787 typename
Types::LayerType
* occludingLayer4
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 50), gfx::Size(100, 50), true);
2788 typename
Types::LayerType
* occludingLayer5
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(250, 50), gfx::Size(50, 50), true);
2790 // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
2791 WebKit::WebFilterOperations filters
;
2792 filters
.append(WebKit::WebFilterOperation::createBlurFilter(12));
2793 filteredSurface
->setBackgroundFilters(filters
);
2795 // Save the distance of influence for the blur effect.
2796 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2797 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2799 this->calcDrawEtc(parent
);
2801 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2802 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2804 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2805 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2806 this->visitLayer(occludingLayer5
, occlusion
);
2807 this->visitLayer(occludingLayer4
, occlusion
);
2808 this->visitLayer(occludingLayer3
, occlusion
);
2809 this->visitLayer(occludingLayer2
, occlusion
);
2810 this->visitLayer(occludingLayer1
, occlusion
);
2812 Region expectedOcclusion
;
2813 expectedOcclusion
.Union(gfx::Rect(0, 0, 300, 50));
2814 expectedOcclusion
.Union(gfx::Rect(0, 50, 50, 50));
2815 expectedOcclusion
.Union(gfx::Rect(100, 50, 100, 50));
2816 expectedOcclusion
.Union(gfx::Rect(250, 50, 50, 50));
2817 expectedOcclusion
.Union(gfx::Rect(0, 100, 300, 50));
2819 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2820 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2822 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2823 this->enterLayer(filteredSurface
, occlusion
);
2824 EXPECT_RECT_EQ(gfx::Rect(1, 0, 49, 50), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(1, 0, 50, 50)));
2825 EXPECT_RECT_EQ(gfx::Rect(0, 1, 50, 49), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(0, 1, 50, 50)));
2826 EXPECT_RECT_EQ(gfx::Rect(0, 0, 49, 50), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(-1, 0, 50, 50)));
2827 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 49), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(0, -1, 50, 50)));
2829 EXPECT_RECT_EQ(gfx::Rect(150 + 1, 0, 49, 50), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(150 + 1, 0, 50, 50)));
2830 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 1, 50, 49), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(150 + 0, 1, 50, 50)));
2831 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 0, 49, 50), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(150 - 1, 0, 50, 50)));
2832 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 0, 50, 49), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(150 + 0, -1, 50, 50)));
2833 this->leaveLayer(filteredSurface
, occlusion
);
2835 // The filtered layer/replica does not occlude.
2836 Region expectedOcclusionOutsideSurface
;
2837 expectedOcclusionOutsideSurface
.Union(gfx::Rect(-50, -50, 300, 50));
2838 expectedOcclusionOutsideSurface
.Union(gfx::Rect(-50, 0, 50, 50));
2839 expectedOcclusionOutsideSurface
.Union(gfx::Rect(50, 0, 100, 50));
2840 expectedOcclusionOutsideSurface
.Union(gfx::Rect(200, 0, 50, 50));
2841 expectedOcclusionOutsideSurface
.Union(gfx::Rect(-50, 50, 300, 50));
2843 EXPECT_EQ(expectedOcclusionOutsideSurface
.ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2844 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2846 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2847 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2848 this->visitContributingSurface(filteredSurface
, occlusion
);
2850 this->enterContributingSurface(clippingSurface
, occlusion
);
2852 Region expectedBlurredOcclusion
;
2853 expectedBlurredOcclusion
.Union(gfx::Rect(0, 0, 300, 50 - outsetTop
));
2854 expectedBlurredOcclusion
.Union(gfx::Rect(0, 50 - outsetTop
, 50 - outsetLeft
, 20 + outsetTop
+ outsetBottom
));
2855 expectedBlurredOcclusion
.Union(gfx::Rect(100 + outsetRight
, 50 - outsetTop
, 100 - outsetRight
- outsetLeft
, 20 + outsetTop
+ outsetBottom
));
2856 expectedBlurredOcclusion
.Union(gfx::Rect(250 + outsetRight
, 50 - outsetTop
, 50 - outsetRight
, 20 + outsetTop
+ outsetBottom
));
2857 expectedBlurredOcclusion
.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
2859 EXPECT_EQ(expectedBlurredOcclusion
.ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2860 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2862 gfx::Rect outsetRect
;
2863 gfx::Rect clippedOutsetRect
;
2866 // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
2867 outsetRect
= gfx::Rect(50 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2868 clippedOutsetRect
= gfx::IntersectRects(outsetRect
, gfx::Rect(0 - outsetLeft
, 0 - outsetTop
, 300 + outsetLeft
+ outsetRight
, 70 + outsetTop
+ outsetBottom
));
2869 testRect
= outsetRect
;
2870 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2872 // Stuff outside the (clipped) blur outsets is still occluded though.
2873 testRect
= outsetRect
;
2874 testRect
.Inset(0, 0, -1, 0);
2875 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2876 testRect
= outsetRect
;
2877 testRect
.Inset(0, 0, 0, -1);
2878 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2879 testRect
= outsetRect
;
2880 testRect
.Inset(-1, 0, 0, 0);
2881 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2882 testRect
= outsetRect
;
2883 testRect
.Inset(0, -1, 0, 0);
2884 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2886 // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
2887 outsetRect
= gfx::Rect(200 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2888 clippedOutsetRect
= gfx::IntersectRects(outsetRect
, gfx::Rect(0 - outsetLeft
, 0 - outsetTop
, 300 + outsetLeft
+ outsetRight
, 70 + outsetTop
+ outsetBottom
));
2889 testRect
= outsetRect
;
2890 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2892 // Stuff outside the (clipped) blur outsets is still occluded though.
2893 testRect
= outsetRect
;
2894 testRect
.Inset(0, 0, -1, 0);
2895 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2896 testRect
= outsetRect
;
2897 testRect
.Inset(0, 0, 0, -1);
2898 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2899 testRect
= outsetRect
;
2900 testRect
.Inset(-1, 0, 0, 0);
2901 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2902 testRect
= outsetRect
;
2903 testRect
.Inset(0, -1, 0, 0);
2904 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2908 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
);
2910 template<class Types
>
2911 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
: public OcclusionTrackerTest
<Types
> {
2913 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2916 gfx::Transform scaleByHalf
;
2917 scaleByHalf
.Scale(0.5, 0.5);
2919 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
2920 // The surface is scaled to test that the pixel moving is done in the target space, where the background filter is applied, but the surface
2921 // appears at 50, 50 and the replica at 200, 50.
2922 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2923 typename
Types::LayerType
* behindSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(60, 60), gfx::Size(30, 30), true);
2924 typename
Types::LayerType
* behindReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(210, 60), gfx::Size(30, 30), true);
2925 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2926 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(300, 0), gfx::Size());
2928 // Filters make the layer own a surface.
2929 WebKit::WebFilterOperations filters
;
2930 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3));
2931 filteredSurface
->setBackgroundFilters(filters
);
2933 this->calcDrawEtc(parent
);
2935 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2936 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2938 // The surface has a background blur, so it blurs non-opaque pixels below it.
2939 this->visitLayer(filteredSurface
, occlusion
);
2940 this->visitContributingSurface(filteredSurface
, occlusion
);
2942 this->visitLayer(behindReplicaLayer
, occlusion
);
2943 this->visitLayer(behindSurfaceLayer
, occlusion
);
2945 // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
2946 // So it should not be modified by the filter here.
2947 gfx::Rect occlusionBehindSurface
= gfx::Rect(60, 60, 30, 30);
2948 gfx::Rect occlusionBehindReplica
= gfx::Rect(210, 60, 30, 30);
2950 Region expectedOpaqueBounds
= UnionRegions(occlusionBehindSurface
, occlusionBehindReplica
);
2951 EXPECT_EQ(expectedOpaqueBounds
.ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2953 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
2957 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
2959 template<class Types
>
2960 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
: public OcclusionTrackerTest
<Types
> {
2962 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2965 gfx::Transform scaleByHalf
;
2966 scaleByHalf
.Scale(0.5, 0.5);
2968 // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
2969 // The surface is scaled to test that the pixel moving is done in the target space, where the background filter is applied, but the surface
2970 // appears at 50, 50 and the replica at 200, 50.
2971 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2972 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2973 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(300, 0), gfx::Size());
2974 typename
Types::LayerType
* aboveSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size(50, 50), true);
2975 typename
Types::LayerType
* aboveReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(200, 50), gfx::Size(50, 50), true);
2977 // Filters make the layer own a surface.
2978 WebKit::WebFilterOperations filters
;
2979 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3));
2980 filteredSurface
->setBackgroundFilters(filters
);
2982 this->calcDrawEtc(parent
);
2984 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2985 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2987 this->visitLayer(aboveReplicaLayer
, occlusion
);
2988 this->visitLayer(aboveSurfaceLayer
, occlusion
);
2990 this->visitLayer(filteredSurface
, occlusion
);
2993 // The layers above the filtered surface occlude from outside.
2994 gfx::Rect occlusionAboveSurface
= gfx::Rect(0, 0, 50, 50);
2995 gfx::Rect occlusionAboveReplica
= gfx::Rect(150, 0, 50, 50);
2996 Region expectedOpaqueRegion
= UnionRegions(occlusionAboveSurface
, occlusionAboveReplica
);
2998 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromInsideTarget().ToString());
2999 EXPECT_EQ(expectedOpaqueRegion
.ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
3002 // The surface has a background blur, so it blurs non-opaque pixels below it.
3003 this->visitContributingSurface(filteredSurface
, occlusion
);
3006 // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
3007 gfx::Rect occlusionAboveSurface
= gfx::Rect(50, 50, 50, 50);
3008 gfx::Rect occlusionAboveReplica
= gfx::Rect(200, 50, 50, 50);
3009 Region expectedOpaqueRegion
= UnionRegions(occlusionAboveSurface
, occlusionAboveReplica
);
3011 EXPECT_EQ(expectedOpaqueRegion
.ToString(), occlusion
.occlusionFromInsideTarget().ToString());
3012 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
3017 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
3019 template<class Types
>
3020 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
: public OcclusionTrackerTest
<Types
> {
3022 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
3025 gfx::Transform scaleByHalf
;
3026 scaleByHalf
.Scale(0.5, 0.5);
3028 // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
3029 // The surface is scaled to test that the pixel moving is done in the target space, where the background filter is applied, but the surface
3030 // appears at 50, 50 and the replica at 200, 50.
3031 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
3032 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(50, 50), gfx::Size(100, 100), false);
3033 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(300, 0), gfx::Size());
3034 typename
Types::LayerType
* aboveSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(70, 50), gfx::Size(30, 50), true);
3035 typename
Types::LayerType
* aboveReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(200, 50), gfx::Size(30, 50), true);
3036 typename
Types::LayerType
* besideSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(90, 40), gfx::Size(10, 10), true);
3037 typename
Types::LayerType
* besideReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(200, 40), gfx::Size(10, 10), true);
3039 // Filters make the layer own a surface.
3040 WebKit::WebFilterOperations filters
;
3041 filters
.append(WebKit::WebFilterOperation::createBlurFilter(3));
3042 filteredSurface
->setBackgroundFilters(filters
);
3044 // Save the distance of influence for the blur effect.
3045 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
3046 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
3048 this->calcDrawEtc(parent
);
3050 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
3051 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
3053 this->visitLayer(besideReplicaLayer
, occlusion
);
3054 this->visitLayer(besideSurfaceLayer
, occlusion
);
3055 this->visitLayer(aboveReplicaLayer
, occlusion
);
3056 this->visitLayer(aboveSurfaceLayer
, occlusion
);
3058 // The surface has a background blur, so it blurs non-opaque pixels below it.
3059 this->visitLayer(filteredSurface
, occlusion
);
3060 this->visitContributingSurface(filteredSurface
, occlusion
);
3062 // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
3063 // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
3064 // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
3065 // the occluded part of the surface.
3066 gfx::Rect occlusionAboveSurface
= gfx::Rect(70 + outsetRight
, 50, 30 - outsetRight
, 50);
3067 gfx::Rect occlusionAboveReplica
= gfx::Rect(200, 50, 30 - outsetLeft
, 50);
3068 gfx::Rect occlusionBesideSurface
= gfx::Rect(90, 40, 10, 10);
3069 gfx::Rect occlusionBesideReplica
= gfx::Rect(200, 40, 10, 10);
3071 Region expectedOcclusion
;
3072 expectedOcclusion
.Union(occlusionAboveSurface
);
3073 expectedOcclusion
.Union(occlusionAboveReplica
);
3074 expectedOcclusion
.Union(occlusionBesideSurface
);
3075 expectedOcclusion
.Union(occlusionBesideReplica
);
3077 ASSERT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionFromInsideTarget().ToString());
3078 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
3080 Region::Iterator
expectedRects(expectedOcclusion
);
3081 Region::Iterator
targetSurfaceRects(occlusion
.occlusionFromInsideTarget());
3082 for (; expectedRects
.has_rect(); expectedRects
.next(), targetSurfaceRects
.next()) {
3083 ASSERT_TRUE(targetSurfaceRects
.has_rect());
3084 EXPECT_EQ(expectedRects
.rect(), targetSurfaceRects
.rect());
3089 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
3091 template<class Types
>
3092 class OcclusionTrackerTestMinimumTrackingSize
: public OcclusionTrackerTest
<Types
> {
3094 OcclusionTrackerTestMinimumTrackingSize(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
3097 gfx::Size
trackingSize(100, 100);
3098 gfx::Size
belowTrackingSize(99, 99);
3100 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(400, 400));
3101 typename
Types::LayerType
* large
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), trackingSize
, true);
3102 typename
Types::LayerType
* small
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), belowTrackingSize
, true);
3103 this->calcDrawEtc(parent
);
3105 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
3106 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
3107 occlusion
.setMinimumTrackingSize(trackingSize
);
3109 // The small layer is not tracked because it is too small.
3110 this->visitLayer(small
, occlusion
);
3112 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
3113 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromInsideTarget().ToString());
3115 // The large layer is tracked as it is large enough.
3116 this->visitLayer(large
, occlusion
);
3118 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionFromOutsideTarget().ToString());
3119 EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize
).ToString(), occlusion
.occlusionFromInsideTarget().ToString());
3123 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);