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.
7 #include "cc/occlusion_tracker.h"
10 #include "cc/layer_animation_controller.h"
11 #include "cc/layer_impl.h"
12 #include "cc/layer_tree_host_common.h"
13 #include "cc/math_util.h"
14 #include "cc/overdraw_metrics.h"
15 #include "cc/single_thread_proxy.h"
16 #include "cc/test/animation_test_common.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 <public/WebFilterOperation.h>
22 #include <public/WebFilterOperations.h>
23 #include <public/WebTransformationMatrix.h>
26 using namespace WebKit
;
27 using namespace WebKitTests
;
31 class TestContentLayer
: public Layer
{
35 , m_overrideOpaqueContentsRect(false)
39 virtual bool drawsContent() const OVERRIDE
{ return true; }
40 virtual Region
visibleContentOpaqueRegion() const OVERRIDE
42 if (m_overrideOpaqueContentsRect
)
43 return gfx::IntersectRects(m_opaqueContentsRect
, visibleContentRect());
44 return Layer::visibleContentOpaqueRegion();
46 void setOpaqueContentsRect(const gfx::Rect
& opaqueContentsRect
)
48 m_overrideOpaqueContentsRect
= true;
49 m_opaqueContentsRect
= opaqueContentsRect
;
53 virtual ~TestContentLayer()
57 bool m_overrideOpaqueContentsRect
;
58 gfx::Rect m_opaqueContentsRect
;
61 class TestContentLayerImpl
: public LayerImpl
{
63 TestContentLayerImpl(int id
)
65 , m_overrideOpaqueContentsRect(false)
67 setDrawsContent(true);
70 virtual Region
visibleContentOpaqueRegion() const OVERRIDE
72 if (m_overrideOpaqueContentsRect
)
73 return gfx::IntersectRects(m_opaqueContentsRect
, visibleContentRect());
74 return LayerImpl::visibleContentOpaqueRegion();
76 void setOpaqueContentsRect(const gfx::Rect
& opaqueContentsRect
)
78 m_overrideOpaqueContentsRect
= true;
79 m_opaqueContentsRect
= opaqueContentsRect
;
83 bool m_overrideOpaqueContentsRect
;
84 gfx::Rect m_opaqueContentsRect
;
87 static inline bool layerImplDrawTransformIsUnknown(const Layer
* layer
) { return layer
->drawTransformIsAnimating(); }
88 static inline bool layerImplDrawTransformIsUnknown(const LayerImpl
*) { return false; }
90 template<typename LayerType
, typename RenderSurfaceType
>
91 class TestOcclusionTrackerWithClip
: public TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
> {
93 TestOcclusionTrackerWithClip(gfx::Rect viewportRect
, bool recordMetricsForFrame
= false)
94 : TestOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(viewportRect
, recordMetricsForFrame
)
95 , m_overrideLayerClipRect(false)
99 void setLayerClipRect(const gfx::Rect
& rect
) { m_overrideLayerClipRect
= true; m_layerClipRect
= rect
;}
100 void useDefaultLayerClipRect() { m_overrideLayerClipRect
= false; }
101 // 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.
102 bool occludedLayer(const LayerType
* layer
, const gfx::Rect
& contentRect
, bool* hasOcclusionFromOutsideTargetSurface
= 0) const
104 return this->occluded(layer
->renderTarget(), contentRect
, layer
->drawTransform(), layerImplDrawTransformIsUnknown(layer
), layerClipRectInTarget(layer
), hasOcclusionFromOutsideTargetSurface
);
106 // Gives an unoccluded sub-rect of |contentRect| in the content space of the layer. Simple wrapper around unoccludedContentRect.
107 gfx::Rect
unoccludedLayerContentRect(const LayerType
* layer
, const gfx::Rect
& contentRect
, bool* hasOcclusionFromOutsideTargetSurface
= 0) const
109 return this->unoccludedContentRect(layer
->renderTarget(), contentRect
, layer
->drawTransform(), layerImplDrawTransformIsUnknown(layer
), layerClipRectInTarget(layer
), hasOcclusionFromOutsideTargetSurface
);
114 virtual gfx::Rect
layerClipRectInTarget(const LayerType
* layer
) const { return m_overrideLayerClipRect
? m_layerClipRect
: OcclusionTrackerBase
<LayerType
, RenderSurfaceType
>::layerClipRectInTarget(layer
); }
117 bool m_overrideLayerClipRect
;
118 gfx::Rect m_layerClipRect
;
121 struct OcclusionTrackerTestMainThreadTypes
{
122 typedef Layer LayerType
;
123 typedef RenderSurface RenderSurfaceType
;
124 typedef TestContentLayer ContentLayerType
;
125 typedef scoped_refptr
<Layer
> LayerPtrType
;
126 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
127 typedef LayerIterator
<Layer
, std::vector
<scoped_refptr
<Layer
> >, RenderSurface
, LayerIteratorActions::FrontToBack
> TestLayerIterator
;
128 typedef OcclusionTracker OcclusionTrackerType
;
130 static LayerPtrType
createLayer()
132 return Layer::create();
134 static ContentLayerPtrType
createContentLayer() { return make_scoped_refptr(new ContentLayerType()); }
136 static LayerPtrType
passLayerPtr(ContentLayerPtrType
& layer
)
138 return layer
.release();
141 static LayerPtrType
passLayerPtr(LayerPtrType
& layer
)
143 return layer
.release();
146 static void destroyLayer(LayerPtrType
& layer
)
152 struct OcclusionTrackerTestImplThreadTypes
{
153 typedef LayerImpl LayerType
;
154 typedef RenderSurfaceImpl RenderSurfaceType
;
155 typedef TestContentLayerImpl ContentLayerType
;
156 typedef scoped_ptr
<LayerImpl
> LayerPtrType
;
157 typedef scoped_ptr
<ContentLayerType
> ContentLayerPtrType
;
158 typedef LayerIterator
<LayerImpl
, std::vector
<LayerImpl
*>, RenderSurfaceImpl
, LayerIteratorActions::FrontToBack
> TestLayerIterator
;
159 typedef OcclusionTrackerImpl OcclusionTrackerType
;
161 static LayerPtrType
createLayer() { return LayerImpl::create(nextLayerImplId
++); }
162 static ContentLayerPtrType
createContentLayer() { return make_scoped_ptr(new ContentLayerType(nextLayerImplId
++)); }
163 static int nextLayerImplId
;
165 static LayerPtrType
passLayerPtr(LayerPtrType
& layer
)
170 static LayerPtrType
passLayerPtr(ContentLayerPtrType
& layer
)
172 return layer
.PassAs
<LayerType
>();
175 static void destroyLayer(LayerPtrType
& layer
)
181 int OcclusionTrackerTestImplThreadTypes::nextLayerImplId
= 1;
183 template<typename Types
>
184 class OcclusionTrackerTest
: public testing::Test
{
186 OcclusionTrackerTest(bool opaqueLayers
)
187 : m_opaqueLayers(opaqueLayers
)
190 virtual void runMyTest() = 0;
192 virtual void TearDown()
194 Types::destroyLayer(m_root
);
195 m_renderSurfaceLayerList
.clear();
196 m_renderSurfaceLayerListImpl
.clear();
197 m_replicaLayers
.clear();
198 m_maskLayers
.clear();
199 LayerTreeHost::setNeedsFilterContext(false);
202 typename
Types::ContentLayerType
* createRoot(const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
204 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer());
205 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
206 setProperties(layerPtr
, transform
, position
, bounds
);
209 m_root
= Types::passLayerPtr(layer
);
213 typename
Types::LayerType
* createLayer(typename
Types::LayerType
* parent
, const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
215 typename
Types::LayerPtrType
layer(Types::createLayer());
216 typename
Types::LayerType
* layerPtr
= layer
.get();
217 setProperties(layerPtr
, transform
, position
, bounds
);
218 parent
->addChild(Types::passLayerPtr(layer
));
222 typename
Types::LayerType
* createSurface(typename
Types::LayerType
* parent
, const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
224 typename
Types::LayerType
* layer
= createLayer(parent
, transform
, position
, bounds
);
225 WebFilterOperations filters
;
226 filters
.append(WebFilterOperation::createGrayscaleFilter(0.5));
227 layer
->setFilters(filters
);
231 typename
Types::ContentLayerType
* createDrawingLayer(typename
Types::LayerType
* parent
, const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
, bool opaque
)
233 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer());
234 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
235 setProperties(layerPtr
, transform
, position
, bounds
);
238 layerPtr
->setContentsOpaque(opaque
);
240 layerPtr
->setContentsOpaque(false);
242 layerPtr
->setOpaqueContentsRect(gfx::Rect(gfx::Point(), bounds
));
244 layerPtr
->setOpaqueContentsRect(gfx::Rect());
247 parent
->addChild(Types::passLayerPtr(layer
));
251 typename
Types::LayerType
* createReplicaLayer(typename
Types::LayerType
* owningLayer
, const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
253 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer());
254 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
255 setProperties(layerPtr
, transform
, position
, bounds
);
256 setReplica(owningLayer
, Types::passLayerPtr(layer
));
260 typename
Types::LayerType
* createMaskLayer(typename
Types::LayerType
* owningLayer
, const gfx::Size
& bounds
)
262 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer());
263 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
264 setProperties(layerPtr
, identityMatrix
, gfx::PointF(), bounds
);
265 setMask(owningLayer
, Types::passLayerPtr(layer
));
269 typename
Types::ContentLayerType
* createDrawingSurface(typename
Types::LayerType
* parent
, const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
, bool opaque
)
271 typename
Types::ContentLayerType
* layer
= createDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
272 WebFilterOperations filters
;
273 filters
.append(WebFilterOperation::createGrayscaleFilter(0.5));
274 layer
->setFilters(filters
);
278 void calcDrawEtc(TestContentLayerImpl
* root
)
280 DCHECK(root
== m_root
.get());
281 int dummyMaxTextureSize
= 512;
282 LayerSorter layerSorter
;
284 DCHECK(!root
->renderSurface());
286 LayerTreeHostCommon::calculateDrawTransforms(root
, root
->bounds(), 1, 1, &layerSorter
, dummyMaxTextureSize
, m_renderSurfaceLayerListImpl
);
288 m_layerIterator
= m_layerIteratorBegin
= Types::TestLayerIterator::begin(&m_renderSurfaceLayerListImpl
);
291 void calcDrawEtc(TestContentLayer
* root
)
293 DCHECK(root
== m_root
.get());
294 int dummyMaxTextureSize
= 512;
296 DCHECK(!root
->renderSurface());
298 LayerTreeHostCommon::calculateDrawTransforms(root
, root
->bounds(), 1, 1, dummyMaxTextureSize
, m_renderSurfaceLayerList
);
300 m_layerIterator
= m_layerIteratorBegin
= Types::TestLayerIterator::begin(&m_renderSurfaceLayerList
);
303 void enterLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
305 ASSERT_EQ(layer
, *m_layerIterator
);
306 ASSERT_TRUE(m_layerIterator
.representsItself());
307 occlusion
.enterLayer(m_layerIterator
);
310 void leaveLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
312 ASSERT_EQ(layer
, *m_layerIterator
);
313 ASSERT_TRUE(m_layerIterator
.representsItself());
314 occlusion
.leaveLayer(m_layerIterator
);
318 void visitLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
320 enterLayer(layer
, occlusion
);
321 leaveLayer(layer
, occlusion
);
324 void enterContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
326 ASSERT_EQ(layer
, *m_layerIterator
);
327 ASSERT_TRUE(m_layerIterator
.representsTargetRenderSurface());
328 occlusion
.enterLayer(m_layerIterator
);
329 occlusion
.leaveLayer(m_layerIterator
);
331 ASSERT_TRUE(m_layerIterator
.representsContributingRenderSurface());
332 occlusion
.enterLayer(m_layerIterator
);
335 void leaveContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
337 ASSERT_EQ(layer
, *m_layerIterator
);
338 ASSERT_TRUE(m_layerIterator
.representsContributingRenderSurface());
339 occlusion
.leaveLayer(m_layerIterator
);
343 void visitContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
345 enterContributingSurface(layer
, occlusion
);
346 leaveContributingSurface(layer
, occlusion
);
349 void resetLayerIterator()
351 m_layerIterator
= m_layerIteratorBegin
;
354 const WebTransformationMatrix identityMatrix
;
357 void setBaseProperties(typename
Types::LayerType
* layer
, const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
359 layer
->setTransform(transform
);
360 layer
->setSublayerTransform(WebTransformationMatrix());
361 layer
->setAnchorPoint(gfx::PointF(0, 0));
362 layer
->setPosition(position
);
363 layer
->setBounds(bounds
);
366 void setProperties(Layer
* layer
, const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
368 setBaseProperties(layer
, transform
, position
, bounds
);
371 void setProperties(LayerImpl
* layer
, const WebTransformationMatrix
& transform
, const gfx::PointF
& position
, const gfx::Size
& bounds
)
373 setBaseProperties(layer
, transform
, position
, bounds
);
375 layer
->setContentBounds(layer
->bounds());
378 void setReplica(Layer
* owningLayer
, scoped_refptr
<Layer
> layer
)
380 owningLayer
->setReplicaLayer(layer
.get());
381 m_replicaLayers
.push_back(layer
);
384 void setReplica(LayerImpl
* owningLayer
, scoped_ptr
<LayerImpl
> layer
)
386 owningLayer
->setReplicaLayer(layer
.Pass());
389 void setMask(Layer
* owningLayer
, scoped_refptr
<Layer
> layer
)
391 owningLayer
->setMaskLayer(layer
.get());
392 m_maskLayers
.push_back(layer
);
395 void setMask(LayerImpl
* owningLayer
, scoped_ptr
<LayerImpl
> layer
)
397 owningLayer
->setMaskLayer(layer
.Pass());
401 // These hold ownership of the layers for the duration of the test.
402 typename
Types::LayerPtrType m_root
;
403 std::vector
<scoped_refptr
<Layer
> > m_renderSurfaceLayerList
;
404 std::vector
<LayerImpl
*> m_renderSurfaceLayerListImpl
;
405 typename
Types::TestLayerIterator m_layerIteratorBegin
;
406 typename
Types::TestLayerIterator m_layerIterator
;
407 typename
Types::LayerType
* m_lastLayerVisited
;
408 std::vector
<scoped_refptr
<Layer
> > m_replicaLayers
;
409 std::vector
<scoped_refptr
<Layer
> > m_maskLayers
;
412 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
413 class ClassName##MainThreadOpaqueLayers : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
415 ClassName##MainThreadOpaqueLayers() : ClassName<OcclusionTrackerTestMainThreadTypes>(true) { } \
417 TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
418 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
419 class ClassName##MainThreadOpaquePaints : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
421 ClassName##MainThreadOpaquePaints() : ClassName<OcclusionTrackerTestMainThreadTypes>(false) { } \
423 TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
425 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
426 class ClassName##ImplThreadOpaqueLayers : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
428 ClassName##ImplThreadOpaqueLayers() : ClassName<OcclusionTrackerTestImplThreadTypes>(true) { } \
430 TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
431 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
432 class ClassName##ImplThreadOpaquePaints : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
434 ClassName##ImplThreadOpaquePaints() : ClassName<OcclusionTrackerTestImplThreadTypes>(false) { } \
436 TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
438 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
439 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
440 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
441 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
442 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
444 #define MAIN_THREAD_TEST(ClassName) \
445 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
447 #define IMPL_THREAD_TEST(ClassName) \
448 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
450 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
451 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
452 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
454 template<class Types
>
455 class OcclusionTrackerTestIdentityTransforms
: public OcclusionTrackerTest
<Types
> {
457 OcclusionTrackerTestIdentityTransforms(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
461 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
462 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
463 this->calcDrawEtc(parent
);
465 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
466 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
468 this->visitLayer(layer
, occlusion
);
469 this->enterLayer(parent
, occlusion
);
471 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInScreenSpace().ToString());
472 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
474 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
475 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
476 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
477 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
478 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
480 occlusion
.useDefaultLayerClipRect();
481 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
482 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
483 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
484 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
485 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
486 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
488 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
489 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 30, 70, 70)));
490 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 29, 70, 70)));
491 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 29, 70, 70)));
492 EXPECT_RECT_EQ(gfx::Rect(31, 29, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 29, 70, 70)));
493 EXPECT_RECT_EQ(gfx::Rect(100, 30, 1, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 30, 70, 70)));
494 EXPECT_RECT_EQ(gfx::Rect(31, 31, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 31, 70, 70)));
495 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 31, 70, 70)));
496 EXPECT_RECT_EQ(gfx::Rect(29, 31, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 31, 70, 70)));
500 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms
);
502 template<class Types
>
503 class OcclusionTrackerTestQuadsMismatchLayer
: public OcclusionTrackerTest
<Types
> {
505 OcclusionTrackerTestQuadsMismatchLayer(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
508 WebTransformationMatrix layerTransform
;
509 layerTransform
.translate(10, 10);
511 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::Point(0, 0), gfx::Size(100, 100));
512 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(0, 0), gfx::Size(90, 90), true);
513 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(layer1
, layerTransform
, gfx::PointF(0, 0), gfx::Size(50, 50), true);
514 this->calcDrawEtc(parent
);
516 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
518 this->visitLayer(layer2
, occlusion
);
519 this->enterLayer(layer1
, occlusion
);
521 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
522 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
524 // This checks cases where the quads don't match their "containing"
525 // layers, e.g. in terms of transforms or clip rect. This is typical for
526 // DelegatedRendererLayer.
528 WebTransformationMatrix quadTransform
;
529 quadTransform
.translate(30, 30);
530 gfx::Rect
clipRectInTarget(0, 0, 100, 100);
532 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, gfx::Rect(0, 0, 10, 10), quadTransform
, false, clipRectInTarget
).IsEmpty());
533 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10), occlusion
.unoccludedContentRect(parent
, gfx::Rect(0, 0, 10, 10), quadTransform
, true, clipRectInTarget
));
534 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), occlusion
.unoccludedContentRect(parent
, gfx::Rect(40, 40, 10, 10), quadTransform
, false, clipRectInTarget
));
535 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), occlusion
.unoccludedContentRect(parent
, gfx::Rect(35, 30, 10, 10), quadTransform
, false, clipRectInTarget
));
536 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)));
540 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer
);
542 template<class Types
>
543 class OcclusionTrackerTestRotatedChild
: public OcclusionTrackerTest
<Types
> {
545 OcclusionTrackerTestRotatedChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
548 WebTransformationMatrix layerTransform
;
549 layerTransform
.translate(250, 250);
550 layerTransform
.rotate(90);
551 layerTransform
.translate(-250, -250);
553 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
554 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
555 this->calcDrawEtc(parent
);
557 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
558 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
560 this->visitLayer(layer
, occlusion
);
561 this->enterLayer(parent
, occlusion
);
563 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInScreenSpace().ToString());
564 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
566 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
567 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
568 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
569 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
570 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
572 occlusion
.useDefaultLayerClipRect();
573 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
574 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 70, 70)));
575 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 70, 70)));
576 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 70, 70)));
577 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 70, 70)));
578 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
580 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 30, 70, 70)).IsEmpty());
581 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 30, 70, 70)));
582 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 29, 70, 70)));
583 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 29, 70, 70)));
584 EXPECT_RECT_EQ(gfx::Rect(31, 29, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 29, 70, 70)));
585 EXPECT_RECT_EQ(gfx::Rect(100, 30, 1, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 30, 70, 70)));
586 EXPECT_RECT_EQ(gfx::Rect(31, 31, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 31, 70, 70)));
587 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 31, 70, 70)));
588 EXPECT_RECT_EQ(gfx::Rect(29, 31, 70, 70), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 31, 70, 70)));
592 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild
);
594 template<class Types
>
595 class OcclusionTrackerTestTranslatedChild
: public OcclusionTrackerTest
<Types
> {
597 OcclusionTrackerTestTranslatedChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
600 WebTransformationMatrix layerTransform
;
601 layerTransform
.translate(20, 20);
603 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
604 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
605 this->calcDrawEtc(parent
);
607 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
608 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
610 this->visitLayer(layer
, occlusion
);
611 this->enterLayer(parent
, occlusion
);
613 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
614 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
616 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
617 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
618 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
619 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(51, 50, 50, 50)));
620 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 51, 50, 50)));
622 occlusion
.useDefaultLayerClipRect();
623 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 50, 50, 50)));
624 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(49, 50, 50, 50)));
625 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 49, 50, 50)));
626 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(51, 50, 50, 50)));
627 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(50, 51, 50, 50)));
628 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
630 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
631 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 50, 50, 50)));
632 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 49, 50, 50)));
633 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 49, 50, 50)));
634 EXPECT_RECT_EQ(gfx::Rect(51, 49, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 49, 50, 50)));
635 EXPECT_RECT_EQ(gfx::Rect(100, 50, 1, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 50, 50, 50)));
636 EXPECT_RECT_EQ(gfx::Rect(51, 51, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 51, 50, 50)));
637 EXPECT_RECT_EQ(gfx::Rect(50, 100, 50, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 51, 50, 50)));
638 EXPECT_RECT_EQ(gfx::Rect(49, 51, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 51, 50, 50)));
640 occlusion
.useDefaultLayerClipRect();
641 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 50, 50, 50)).IsEmpty());
642 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 50, 50, 50)));
643 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 49, 50, 50)));
644 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 49, 50, 50)));
645 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 49, 50, 50)));
646 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 50, 50, 50)).IsEmpty());
647 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(51, 51, 50, 50)).IsEmpty());
648 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(50, 51, 50, 50)).IsEmpty());
649 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(49, 51, 50, 50)));
650 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
654 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild
);
656 template<class Types
>
657 class OcclusionTrackerTestChildInRotatedChild
: public OcclusionTrackerTest
<Types
> {
659 OcclusionTrackerTestChildInRotatedChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
662 WebTransformationMatrix childTransform
;
663 childTransform
.translate(250, 250);
664 childTransform
.rotate(90);
665 childTransform
.translate(-250, -250);
667 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
668 parent
->setMasksToBounds(true);
669 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(500, 500));
670 child
->setMasksToBounds(true);
671 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, this->identityMatrix
, gfx::PointF(10, 10), gfx::Size(500, 500), true);
672 this->calcDrawEtc(parent
);
674 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
675 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
677 this->visitLayer(layer
, occlusion
);
678 this->enterContributingSurface(child
, occlusion
);
680 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion
.occlusionInScreenSpace().ToString());
681 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
683 this->leaveContributingSurface(child
, occlusion
);
684 this->enterLayer(parent
, occlusion
);
686 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion
.occlusionInScreenSpace().ToString());
687 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion
.occlusionInTargetSurface().ToString());
689 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
690 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
691 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
692 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 40, 70, 60)));
693 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 41, 70, 60)));
695 occlusion
.useDefaultLayerClipRect();
696 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
697 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
698 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
699 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 40, 70, 60)));
700 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 41, 70, 60)));
701 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
704 /* Justification for the above occlusion from |layer|:
706 +---------------------+ +---------------------+
707 | | | |30 Visible region of |layer|: /////
708 | 30 | rotate(90) | |
709 | 30 + ---------------------------------+ | +---------------------------------+
710 100 | | 10 | | ==> | | |10 |
711 | |10+---------------------------------+ | +---------------------------------+ |
712 | | | | | | | | |///////////////| 420 | |
713 | | | | | | | | |///////////////|60 | |
714 | | | | | | | | |///////////////| | |
715 +----|--|-------------+ | | +--|--|---------------+ | |
716 | | | | 20|10| 70 | |
723 +--|-------------------------------+ | | +------------------------------|--+
725 +---------------------------------+ +---------------------------------+
731 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild
);
733 template<class Types
>
734 class OcclusionTrackerTestScaledRenderSurface
: public OcclusionTrackerTest
<Types
> {
736 OcclusionTrackerTestScaledRenderSurface(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
740 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200));
742 WebTransformationMatrix layer1Matrix
;
743 layer1Matrix
.scale(2);
744 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(parent
, layer1Matrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
745 layer1
->setForceRenderSurface(true);
747 WebTransformationMatrix layer2Matrix
;
748 layer2Matrix
.translate(25, 25);
749 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(layer1
, layer2Matrix
, gfx::PointF(0, 0), gfx::Size(50, 50), true);
750 typename
Types::ContentLayerType
* occluder
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 100), gfx::Size(500, 500), true);
751 this->calcDrawEtc(parent
);
753 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
755 this->visitLayer(occluder
, occlusion
);
756 this->enterLayer(layer2
, occlusion
);
758 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion
.occlusionInScreenSpace().ToString());
759 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInTargetSurface().ToString());
761 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), occlusion
.unoccludedLayerContentRect(layer2
, gfx::Rect(0, 0, 25, 25)));
762 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25), occlusion
.unoccludedLayerContentRect(layer2
, gfx::Rect(10, 25, 25, 25)));
763 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15), occlusion
.unoccludedLayerContentRect(layer2
, gfx::Rect(25, 10, 25, 25)));
764 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(layer2
, gfx::Rect(25, 25, 25, 25)).IsEmpty());
768 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface
);
770 template<class Types
>
771 class OcclusionTrackerTestVisitTargetTwoTimes
: public OcclusionTrackerTest
<Types
> {
773 OcclusionTrackerTestVisitTargetTwoTimes(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
776 WebTransformationMatrix childTransform
;
777 childTransform
.translate(250, 250);
778 childTransform
.rotate(90);
779 childTransform
.translate(-250, -250);
781 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
782 parent
->setMasksToBounds(true);
783 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(500, 500));
784 child
->setMasksToBounds(true);
785 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, this->identityMatrix
, gfx::PointF(10, 10), gfx::Size(500, 500), true);
786 // |child2| makes |parent|'s surface get considered by OcclusionTracker first, instead of |child|'s. This exercises different code in
787 // leaveToTargetRenderSurface, as the target surface has already been seen.
788 typename
Types::ContentLayerType
* child2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(30, 30), gfx::Size(60, 20), true);
789 this->calcDrawEtc(parent
);
791 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
792 occlusion
.setLayerClipRect(gfx::Rect(-10, -10, 1000, 1000));
794 this->visitLayer(child2
, occlusion
);
796 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion
.occlusionInScreenSpace().ToString());
797 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion
.occlusionInTargetSurface().ToString());
799 this->visitLayer(layer
, occlusion
);
801 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion
.occlusionInScreenSpace().ToString());
802 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
804 this->enterContributingSurface(child
, occlusion
);
806 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion
.occlusionInScreenSpace().ToString());
807 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
809 // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
810 this->leaveContributingSurface(child
, occlusion
);
811 this->enterLayer(parent
, occlusion
);
813 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion
.occlusionInScreenSpace().ToString());
814 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion
.occlusionInTargetSurface().ToString());
816 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 70, 70)));
817 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 30, 70, 70)));
819 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 30, 60, 10)));
820 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 30, 60, 10)));
821 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 29, 60, 10)));
822 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(31, 30, 60, 10)));
823 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 31, 60, 10)));
825 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
826 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
827 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
829 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 30, 60, 10)).IsEmpty());
830 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 30, 60, 10)));
831 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 29, 60, 10)));
832 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 30, 60, 10)));
833 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 31, 60, 10)).IsEmpty());
835 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
836 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 40, 70, 60)));
837 // This rect is mostly occluded by |child2|.
838 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 39, 70, 60)));
839 // This rect extends past top/right ends of |child2|.
840 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 29, 70, 70)));
841 // This rect extends past left/right ends of |child2|.
842 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(20, 39, 80, 60)));
843 EXPECT_RECT_EQ(gfx::Rect(100, 40, 1, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 40, 70, 60)));
844 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 41, 70, 60)));
846 /* Justification for the above occlusion from |layer|:
848 +---------------------+ +---------------------+
849 | | | |30 Visible region of |layer|: /////
850 | 30 | rotate(90) | 30 60 | |child2|: \\\\\
851 | 30 + ------------+--------------------+ | 30 +------------+--------------------+
852 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
853 | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
854 | + ------------+ | | | | | +------------+//| 420 | |
855 | | | | | | | | |///////////////|60 | |
856 | | | | | | | | |///////////////| | |
857 +----|--|-------------+ | | +--|--|---------------+ | |
858 | | | | 20|10| 70 | |
865 +--|-------------------------------+ | | +------------------------------|--+
867 +---------------------------------+ +---------------------------------+
873 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes
);
875 template<class Types
>
876 class OcclusionTrackerTestSurfaceRotatedOffAxis
: public OcclusionTrackerTest
<Types
> {
878 OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
881 WebTransformationMatrix childTransform
;
882 childTransform
.translate(250, 250);
883 childTransform
.rotate(95);
884 childTransform
.translate(-250, -250);
886 WebTransformationMatrix layerTransform
;
887 layerTransform
.translate(10, 10);
889 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
890 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(500, 500));
891 child
->setMasksToBounds(true);
892 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, layerTransform
, gfx::PointF(0, 0), gfx::Size(500, 500), true);
893 this->calcDrawEtc(parent
);
895 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
896 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
898 gfx::Rect clippedLayerInChild
= MathUtil::mapClippedRect(layerTransform
, layer
->visibleContentRect());
900 this->visitLayer(layer
, occlusion
);
901 this->enterContributingSurface(child
, occlusion
);
903 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInScreenSpace().ToString());
904 EXPECT_EQ(clippedLayerInChild
.ToString(), occlusion
.occlusionInTargetSurface().ToString());
906 EXPECT_TRUE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
907 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
908 clippedLayerInChild
.Offset(-1, 0);
909 EXPECT_FALSE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
910 EXPECT_FALSE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
911 clippedLayerInChild
.Offset(1, 0);
912 clippedLayerInChild
.Offset(1, 0);
913 EXPECT_FALSE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
914 EXPECT_FALSE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
915 clippedLayerInChild
.Offset(-1, 0);
916 clippedLayerInChild
.Offset(0, -1);
917 EXPECT_FALSE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
918 EXPECT_FALSE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
919 clippedLayerInChild
.Offset(0, 1);
920 clippedLayerInChild
.Offset(0, 1);
921 EXPECT_FALSE(occlusion
.occludedLayer(child
, clippedLayerInChild
));
922 EXPECT_FALSE(occlusion
.unoccludedLayerContentRect(child
, clippedLayerInChild
).IsEmpty());
923 clippedLayerInChild
.Offset(0, -1);
925 this->leaveContributingSurface(child
, occlusion
);
926 this->enterLayer(parent
, occlusion
);
928 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInScreenSpace().ToString());
929 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInTargetSurface().ToString());
931 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(75, 55, 1, 1)));
932 EXPECT_RECT_EQ(gfx::Rect(75, 55, 1, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(75, 55, 1, 1)));
936 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis
);
938 template<class Types
>
939 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
: public OcclusionTrackerTest
<Types
> {
941 OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
944 WebTransformationMatrix childTransform
;
945 childTransform
.translate(250, 250);
946 childTransform
.rotate(90);
947 childTransform
.translate(-250, -250);
949 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
950 parent
->setMasksToBounds(true);
951 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(500, 500));
952 child
->setMasksToBounds(true);
953 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child
, this->identityMatrix
, gfx::PointF(10, 10), gfx::Size(500, 500), true);
954 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child
, this->identityMatrix
, gfx::PointF(10, 450), gfx::Size(500, 60), true);
955 this->calcDrawEtc(parent
);
957 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
958 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
960 this->visitLayer(layer2
, occlusion
);
961 this->visitLayer(layer1
, occlusion
);
962 this->enterContributingSurface(child
, occlusion
);
964 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion
.occlusionInScreenSpace().ToString());
965 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
967 EXPECT_TRUE(occlusion
.occludedLayer(child
, gfx::Rect(10, 430, 60, 70)));
968 EXPECT_FALSE(occlusion
.occludedLayer(child
, gfx::Rect(9, 430, 60, 70)));
969 EXPECT_FALSE(occlusion
.occludedLayer(child
, gfx::Rect(10, 429, 60, 70)));
970 EXPECT_FALSE(occlusion
.occludedLayer(child
, gfx::Rect(11, 430, 60, 70)));
971 EXPECT_FALSE(occlusion
.occludedLayer(child
, gfx::Rect(10, 431, 60, 70)));
973 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(10, 430, 60, 70)).IsEmpty());
974 EXPECT_RECT_EQ(gfx::Rect(9, 430, 1, 70), occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(9, 430, 60, 70)));
975 EXPECT_RECT_EQ(gfx::Rect(10, 429, 60, 1), occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(10, 429, 60, 70)));
976 EXPECT_RECT_EQ(gfx::Rect(70, 430, 1, 70), occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(11, 430, 60, 70)));
977 EXPECT_RECT_EQ(gfx::Rect(10, 500, 60, 1), occlusion
.unoccludedLayerContentRect(child
, gfx::Rect(10, 431, 60, 70)));
979 this->leaveContributingSurface(child
, occlusion
);
980 this->enterLayer(parent
, occlusion
);
982 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion
.occlusionInScreenSpace().ToString());
983 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion
.occlusionInTargetSurface().ToString());
985 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 40, 70, 60)));
986 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 40, 70, 60)));
987 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 39, 70, 60)));
989 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 40, 70, 60)).IsEmpty());
990 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(29, 40, 70, 60)));
991 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 39, 70, 60)));
992 EXPECT_RECT_EQ(gfx::Rect(100, 40, 1, 60), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(31, 40, 70, 60)));
993 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(30, 41, 70, 60)));
995 /* Justification for the above occlusion from |layer1| and |layer2|:
997 +---------------------+
998 | |30 Visible region of |layer1|: /////
999 | | Visible region of |layer2|: \\\\\
1000 | +---------------------------------+
1002 | +---------------+-----------------+ |
1003 | | |\\\\\\\\\\\\|//| 420 | |
1004 | | |\\\\\\\\\\\\|//|60 | |
1005 | | |\\\\\\\\\\\\|//| | |
1006 +--|--|------------|--+ | |
1014 | +------------|-----------------|--+
1016 +---------------+-----------------+
1022 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
1024 template<class Types
>
1025 class OcclusionTrackerTestOverlappingSurfaceSiblings
: public OcclusionTrackerTest
<Types
> {
1027 OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1030 WebTransformationMatrix childTransform
;
1031 childTransform
.translate(250, 250);
1032 childTransform
.rotate(90);
1033 childTransform
.translate(-250, -250);
1035 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
1036 parent
->setMasksToBounds(true);
1037 typename
Types::LayerType
* child1
= this->createSurface(parent
, childTransform
, gfx::PointF(30, 30), gfx::Size(10, 10));
1038 typename
Types::LayerType
* child2
= this->createSurface(parent
, childTransform
, gfx::PointF(20, 40), gfx::Size(10, 10));
1039 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child1
, this->identityMatrix
, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1040 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child2
, this->identityMatrix
, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1041 this->calcDrawEtc(parent
);
1043 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1044 occlusion
.setLayerClipRect(gfx::Rect(-20, -20, 1000, 1000));
1046 this->visitLayer(layer2
, occlusion
);
1047 this->enterContributingSurface(child2
, occlusion
);
1049 EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1050 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1052 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1053 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1054 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1055 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1056 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1058 occlusion
.useDefaultLayerClipRect();
1059 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1060 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1061 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1062 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1063 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1064 occlusion
.setLayerClipRect(gfx::Rect(-20, -20, 1000, 1000));
1066 // There is nothing above child2's surface in the z-order.
1067 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion
.unoccludedContributingSurfaceContentRect(child2
, false, gfx::Rect(-10, 420, 70, 80)));
1069 this->leaveContributingSurface(child2
, occlusion
);
1070 this->visitLayer(layer1
, occlusion
);
1071 this->enterContributingSurface(child1
, occlusion
);
1073 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1074 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1076 EXPECT_TRUE(occlusion
.occludedLayer(child1
, gfx::Rect(-10, 430, 80, 70)));
1077 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(-11, 430, 80, 70)));
1078 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(-10, 429, 80, 70)));
1079 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(-10, 430, 81, 70)));
1080 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(-10, 430, 80, 71)));
1082 // child2's contents will occlude child1 below it.
1083 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, gfx::Rect(-10, 430, 80, 70)));
1085 this->leaveContributingSurface(child1
, occlusion
);
1086 this->enterLayer(parent
, occlusion
);
1088 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1089 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1091 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(20, 20, 80, 80)));
1093 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 20, 70, 80)));
1094 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(29, 20, 70, 80)));
1095 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(30, 19, 70, 80)));
1097 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(20, 30, 80, 70)));
1098 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(19, 30, 80, 70)));
1099 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(20, 29, 80, 70)));
1101 /* Justification for the above occlusion:
1103 +---------------------+
1105 | 30+ ---------------------------------+
1106 100 | 30| | layer2 |
1107 |20+----------------------------------+ |
1111 +--|-|----------------+ | |
1119 | +--------------------------------|-+
1121 +----------------------------------+
1127 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings
);
1129 template<class Types
>
1130 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
: public OcclusionTrackerTest
<Types
> {
1132 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1135 WebTransformationMatrix child1Transform
;
1136 child1Transform
.translate(250, 250);
1137 child1Transform
.rotate(-90);
1138 child1Transform
.translate(-250, -250);
1140 WebTransformationMatrix child2Transform
;
1141 child2Transform
.translate(250, 250);
1142 child2Transform
.rotate(90);
1143 child2Transform
.translate(-250, -250);
1145 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
1146 parent
->setMasksToBounds(true);
1147 typename
Types::LayerType
* child1
= this->createSurface(parent
, child1Transform
, gfx::PointF(30, 20), gfx::Size(10, 10));
1148 typename
Types::LayerType
* child2
= this->createDrawingSurface(parent
, child2Transform
, gfx::PointF(20, 40), gfx::Size(10, 10), false);
1149 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child1
, this->identityMatrix
, gfx::PointF(-10, -20), gfx::Size(510, 510), true);
1150 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child2
, this->identityMatrix
, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1151 this->calcDrawEtc(parent
);
1153 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1154 occlusion
.setLayerClipRect(gfx::Rect(-30, -30, 1000, 1000));
1156 this->visitLayer(layer2
, occlusion
);
1157 this->enterLayer(child2
, occlusion
);
1159 EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1160 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1162 EXPECT_TRUE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 80)));
1163 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-11, 420, 70, 80)));
1164 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 419, 70, 80)));
1165 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 71, 80)));
1166 EXPECT_FALSE(occlusion
.occludedLayer(child2
, gfx::Rect(-10, 420, 70, 81)));
1168 this->leaveLayer(child2
, occlusion
);
1169 this->enterContributingSurface(child2
, occlusion
);
1171 // There is nothing above child2's surface in the z-order.
1172 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion
.unoccludedContributingSurfaceContentRect(child2
, false, gfx::Rect(-10, 420, 70, 80)));
1174 this->leaveContributingSurface(child2
, occlusion
);
1175 this->visitLayer(layer1
, occlusion
);
1176 this->enterContributingSurface(child1
, occlusion
);
1178 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1179 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1181 EXPECT_TRUE(occlusion
.occludedLayer(child1
, gfx::Rect(420, -20, 80, 90)));
1182 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(419, -20, 80, 90)));
1183 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(420, -21, 80, 90)));
1184 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(420, -19, 80, 90)));
1185 EXPECT_FALSE(occlusion
.occludedLayer(child1
, gfx::Rect(421, -20, 80, 90)));
1187 // child2's contents will occlude child1 below it.
1188 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, gfx::Rect(420, -20, 80, 90)));
1189 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, gfx::Rect(420, -10, 80, 90)));
1190 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, gfx::Rect(420, -20, 70, 90)));
1192 this->leaveContributingSurface(child1
, occlusion
);
1193 this->enterLayer(parent
, occlusion
);
1195 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1196 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1198 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(10, 20, 90, 80)));
1199 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(9, 20, 90, 80)));
1200 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(10, 19, 90, 80)));
1201 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(11, 20, 90, 80)));
1202 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(10, 21, 90, 80)));
1204 /* Justification for the above occlusion:
1206 +---------------------+
1208 10+----------------------------------+
1209 100 || 30 | layer2 |
1210 |20+----------------------------------+
1214 +|-|------------------+ | |
1222 +----------------------------------+ |
1224 +----------------------------------+
1230 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1232 template<class Types
>
1233 class OcclusionTrackerTestFilters
: public OcclusionTrackerTest
<Types
> {
1235 OcclusionTrackerTestFilters(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1238 WebTransformationMatrix layerTransform
;
1239 layerTransform
.translate(250, 250);
1240 layerTransform
.rotate(90);
1241 layerTransform
.translate(-250, -250);
1243 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
1244 parent
->setMasksToBounds(true);
1245 typename
Types::ContentLayerType
* blurLayer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1246 typename
Types::ContentLayerType
* opaqueLayer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1247 typename
Types::ContentLayerType
* opacityLayer
= this->createDrawingLayer(parent
, layerTransform
, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1249 WebFilterOperations filters
;
1250 filters
.append(WebFilterOperation::createBlurFilter(10));
1251 blurLayer
->setFilters(filters
);
1254 filters
.append(WebFilterOperation::createGrayscaleFilter(0.5));
1255 opaqueLayer
->setFilters(filters
);
1258 filters
.append(WebFilterOperation::createOpacityFilter(0.5));
1259 opacityLayer
->setFilters(filters
);
1261 this->calcDrawEtc(parent
);
1263 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1264 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1266 // Opacity layer won't contribute to occlusion.
1267 this->visitLayer(opacityLayer
, occlusion
);
1268 this->enterContributingSurface(opacityLayer
, occlusion
);
1270 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().IsEmpty());
1271 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().IsEmpty());
1273 // And has nothing to contribute to its parent surface.
1274 this->leaveContributingSurface(opacityLayer
, occlusion
);
1275 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().IsEmpty());
1276 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().IsEmpty());
1278 // Opaque layer will contribute to occlusion.
1279 this->visitLayer(opaqueLayer
, occlusion
);
1280 this->enterContributingSurface(opaqueLayer
, occlusion
);
1282 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1283 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1285 // And it gets translated to the parent surface.
1286 this->leaveContributingSurface(opaqueLayer
, occlusion
);
1287 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1288 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1290 // The blur layer needs to throw away any occlusion from outside its subtree.
1291 this->enterLayer(blurLayer
, occlusion
);
1292 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().IsEmpty());
1293 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().IsEmpty());
1295 // And it won't contribute to occlusion.
1296 this->leaveLayer(blurLayer
, occlusion
);
1297 this->enterContributingSurface(blurLayer
, occlusion
);
1298 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().IsEmpty());
1299 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().IsEmpty());
1301 // But the opaque layer's occlusion is preserved on the parent.
1302 this->leaveContributingSurface(blurLayer
, occlusion
);
1303 this->enterLayer(parent
, occlusion
);
1304 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1305 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1309 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters
);
1311 template<class Types
>
1312 class OcclusionTrackerTestReplicaDoesOcclude
: public OcclusionTrackerTest
<Types
> {
1314 OcclusionTrackerTestReplicaDoesOcclude(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1317 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
1318 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1319 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size());
1320 this->calcDrawEtc(parent
);
1322 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1323 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1325 this->visitLayer(surface
, occlusion
);
1327 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1328 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1330 this->visitContributingSurface(surface
, occlusion
);
1331 this->enterLayer(parent
, occlusion
);
1333 // The surface and replica should both be occluding the parent.
1334 EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 50)).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1338 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude
);
1340 template<class Types
>
1341 class OcclusionTrackerTestReplicaWithClipping
: public OcclusionTrackerTest
<Types
> {
1343 OcclusionTrackerTestReplicaWithClipping(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1346 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 170));
1347 parent
->setMasksToBounds(true);
1348 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1349 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size());
1350 this->calcDrawEtc(parent
);
1352 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1353 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1355 this->visitLayer(surface
, occlusion
);
1357 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1358 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1360 this->visitContributingSurface(surface
, occlusion
);
1361 this->enterLayer(parent
, occlusion
);
1363 // The surface and replica should both be occluding the parent.
1364 EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 20)).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1368 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping
);
1370 template<class Types
>
1371 class OcclusionTrackerTestReplicaWithMask
: public OcclusionTrackerTest
<Types
> {
1373 OcclusionTrackerTestReplicaWithMask(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1376 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
1377 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1378 typename
Types::LayerType
* replica
= this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size());
1379 this->createMaskLayer(replica
, gfx::Size(10, 10));
1380 this->calcDrawEtc(parent
);
1382 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1383 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1385 this->visitLayer(surface
, occlusion
);
1387 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1388 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1390 this->visitContributingSurface(surface
, occlusion
);
1391 this->enterLayer(parent
, occlusion
);
1393 // The replica should not be occluding the parent, since it has a mask applied to it.
1394 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
1398 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask
);
1400 template<class Types
>
1401 class OcclusionTrackerTestLayerClipRectOutsideChild
: public OcclusionTrackerTest
<Types
> {
1403 OcclusionTrackerTestLayerClipRectOutsideChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1406 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1407 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1408 this->calcDrawEtc(parent
);
1410 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1411 occlusion
.setLayerClipRect(gfx::Rect(200, 100, 100, 100));
1413 this->enterLayer(layer
, occlusion
);
1415 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1416 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1417 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1418 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1419 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1421 occlusion
.useDefaultLayerClipRect();
1422 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1423 occlusion
.setLayerClipRect(gfx::Rect(200, 100, 100, 100));
1425 this->leaveLayer(layer
, occlusion
);
1426 this->visitContributingSurface(layer
, occlusion
);
1427 this->enterLayer(parent
, occlusion
);
1429 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1430 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1431 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1432 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1433 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1434 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1435 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1436 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1437 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1439 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
1443 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild
);
1445 template<class Types
>
1446 class OcclusionTrackerTestViewportRectOutsideChild
: public OcclusionTrackerTest
<Types
> {
1448 OcclusionTrackerTestViewportRectOutsideChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1451 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1452 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1453 this->calcDrawEtc(parent
);
1455 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(200, 100, 100, 100));
1456 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1458 this->enterLayer(layer
, occlusion
);
1460 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1461 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1462 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1463 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1464 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1466 occlusion
.useDefaultLayerClipRect();
1467 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1468 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1470 this->leaveLayer(layer
, occlusion
);
1471 this->visitContributingSurface(layer
, occlusion
);
1472 this->enterLayer(parent
, occlusion
);
1474 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1475 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1476 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1477 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1478 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1479 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1480 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1481 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1482 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1484 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
1488 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild
);
1490 template<class Types
>
1491 class OcclusionTrackerTestLayerClipRectOverChild
: public OcclusionTrackerTest
<Types
> {
1493 OcclusionTrackerTestLayerClipRectOverChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1496 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1497 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1498 this->calcDrawEtc(parent
);
1500 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1501 occlusion
.setLayerClipRect(gfx::Rect(100, 100, 100, 100));
1503 this->enterLayer(layer
, occlusion
);
1505 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1506 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1507 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1508 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1510 this->leaveLayer(layer
, occlusion
);
1511 this->visitContributingSurface(layer
, occlusion
);
1512 this->enterLayer(parent
, occlusion
);
1514 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1515 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1516 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1517 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1518 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1519 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1520 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1521 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1522 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1524 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1528 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild
);
1530 template<class Types
>
1531 class OcclusionTrackerTestViewportRectOverChild
: public OcclusionTrackerTest
<Types
> {
1533 OcclusionTrackerTestViewportRectOverChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1536 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1537 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1538 this->calcDrawEtc(parent
);
1540 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(100, 100, 100, 100));
1541 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1543 this->enterLayer(layer
, occlusion
);
1545 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1546 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1547 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1548 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1550 this->leaveLayer(layer
, occlusion
);
1551 this->visitContributingSurface(layer
, occlusion
);
1552 this->enterLayer(parent
, occlusion
);
1554 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1555 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1556 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1557 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1558 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1559 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1560 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1561 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1562 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1564 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1568 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild
);
1570 template<class Types
>
1571 class OcclusionTrackerTestLayerClipRectPartlyOverChild
: public OcclusionTrackerTest
<Types
> {
1573 OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1576 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1577 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1578 this->calcDrawEtc(parent
);
1580 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1581 occlusion
.setLayerClipRect(gfx::Rect(50, 50, 200, 200));
1583 this->enterLayer(layer
, occlusion
);
1585 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1586 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1587 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1588 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1590 this->leaveLayer(layer
, occlusion
);
1591 this->visitContributingSurface(layer
, occlusion
);
1592 this->enterLayer(parent
, occlusion
);
1594 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1595 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1596 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1597 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1598 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1599 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1600 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1601 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1602 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1604 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
1605 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 100)));
1606 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 100, 300, 100)));
1607 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(200, 100, 100, 100)));
1608 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(100, 200, 100, 100)));
1612 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild
);
1614 template<class Types
>
1615 class OcclusionTrackerTestViewportRectPartlyOverChild
: public OcclusionTrackerTest
<Types
> {
1617 OcclusionTrackerTestViewportRectPartlyOverChild(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1620 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1621 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1622 this->calcDrawEtc(parent
);
1624 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(50, 50, 200, 200));
1625 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1627 this->enterLayer(layer
, occlusion
);
1629 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1630 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1631 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1632 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1634 this->leaveLayer(layer
, occlusion
);
1635 this->visitContributingSurface(layer
, occlusion
);
1636 this->enterLayer(parent
, occlusion
);
1638 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1639 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1640 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1641 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1642 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1643 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1644 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1645 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1646 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1648 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
1649 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 100)));
1650 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 100, 300, 100)));
1651 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(200, 100, 100, 100)));
1652 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(100, 200, 100, 100)));
1656 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild
);
1658 template<class Types
>
1659 class OcclusionTrackerTestLayerClipRectOverNothing
: public OcclusionTrackerTest
<Types
> {
1661 OcclusionTrackerTestLayerClipRectOverNothing(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1664 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1665 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1666 this->calcDrawEtc(parent
);
1668 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1669 occlusion
.setLayerClipRect(gfx::Rect(500, 500, 100, 100));
1671 this->enterLayer(layer
, occlusion
);
1673 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1674 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1675 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1676 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1678 this->leaveLayer(layer
, occlusion
);
1679 this->visitContributingSurface(layer
, occlusion
);
1680 this->enterLayer(parent
, occlusion
);
1682 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1683 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1684 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1685 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1686 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1687 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1688 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1689 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1690 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1692 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1693 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 100)).IsEmpty());
1694 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 100, 300, 100)).IsEmpty());
1695 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(200, 100, 100, 100)).IsEmpty());
1696 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(100, 200, 100, 100)).IsEmpty());
1700 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverNothing
);
1702 template<class Types
>
1703 class OcclusionTrackerTestViewportRectOverNothing
: public OcclusionTrackerTest
<Types
> {
1705 OcclusionTrackerTestViewportRectOverNothing(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1708 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1709 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1710 this->calcDrawEtc(parent
);
1712 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(500, 500, 100, 100));
1713 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1715 this->enterLayer(layer
, occlusion
);
1717 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1718 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1719 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1720 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1722 this->leaveLayer(layer
, occlusion
);
1723 this->visitContributingSurface(layer
, occlusion
);
1724 this->enterLayer(parent
, occlusion
);
1726 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 0, 100, 100)));
1727 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1728 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 0, 100, 100)));
1729 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1730 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 100, 100, 100)));
1731 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 0, 100, 100)));
1732 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 200, 100, 100)));
1733 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 200, 100, 100)));
1734 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1736 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1737 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 100)).IsEmpty());
1738 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 100, 300, 100)).IsEmpty());
1739 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(200, 100, 100, 100)).IsEmpty());
1740 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(100, 200, 100, 100)).IsEmpty());
1744 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing
);
1746 template<class Types
>
1747 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
: public OcclusionTrackerTest
<Types
> {
1749 OcclusionTrackerTestLayerClipRectForLayerOffOrigin(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1752 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1753 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1754 this->calcDrawEtc(parent
);
1756 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1757 this->enterLayer(layer
, occlusion
);
1759 // This layer is translated when drawn into its target. So if the clip rect given from the target surface
1760 // is not in that target space, then after translating these query rects into the target, they will fall outside
1761 // the clip and be considered occluded.
1762 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1763 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1764 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1765 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1769 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin
);
1771 template<class Types
>
1772 class OcclusionTrackerTestOpaqueContentsRegionEmpty
: public OcclusionTrackerTest
<Types
> {
1774 OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1777 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1778 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 200), false);
1779 this->calcDrawEtc(parent
);
1781 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1782 this->enterLayer(layer
, occlusion
);
1784 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 0, 100, 100)));
1785 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 0, 100, 100)));
1786 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(0, 100, 100, 100)));
1787 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(100, 100, 100, 100)));
1789 // Occluded since its outside the surface bounds.
1790 EXPECT_TRUE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1792 // Test without any clip rect.
1793 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1794 EXPECT_FALSE(occlusion
.occludedLayer(layer
, gfx::Rect(200, 100, 100, 100)));
1795 occlusion
.useDefaultLayerClipRect();
1797 this->leaveLayer(layer
, occlusion
);
1798 this->visitContributingSurface(layer
, occlusion
);
1799 this->enterLayer(parent
, occlusion
);
1801 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().IsEmpty());
1805 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty
);
1807 template<class Types
>
1808 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
: public OcclusionTrackerTest
<Types
> {
1810 OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1813 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1814 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 100), gfx::Size(200, 200), false);
1815 this->calcDrawEtc(parent
);
1818 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1819 layer
->setOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1821 this->resetLayerIterator();
1822 this->visitLayer(layer
, occlusion
);
1823 this->enterLayer(parent
, occlusion
);
1825 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1827 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1828 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1829 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1833 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1834 layer
->setOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1836 this->resetLayerIterator();
1837 this->visitLayer(layer
, occlusion
);
1838 this->enterLayer(parent
, occlusion
);
1840 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1842 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1843 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1844 EXPECT_TRUE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1848 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1849 layer
->setOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1851 this->resetLayerIterator();
1852 this->visitLayer(layer
, occlusion
);
1853 this->enterLayer(parent
, occlusion
);
1855 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
1857 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(0, 100, 100, 100)));
1858 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(100, 100, 100, 100)));
1859 EXPECT_FALSE(occlusion
.occludedLayer(parent
, gfx::Rect(200, 200, 100, 100)));
1864 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1866 template<class Types
>
1867 class OcclusionTrackerTest3dTransform
: public OcclusionTrackerTest
<Types
> {
1869 OcclusionTrackerTest3dTransform(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1872 WebTransformationMatrix transform
;
1873 transform
.rotate3d(0, 30, 0);
1875 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1876 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1877 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, gfx::PointF(100, 100), gfx::Size(200, 200), true);
1878 this->calcDrawEtc(parent
);
1880 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1881 this->enterLayer(layer
, occlusion
);
1883 // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
1884 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion
.unoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1888 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform
);
1890 template<class Types
>
1891 class OcclusionTrackerTestUnsorted3dLayers
: public OcclusionTrackerTest
<Types
> {
1893 OcclusionTrackerTestUnsorted3dLayers(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1896 // Currently, the main thread layer iterator does not iterate over 3d items in
1897 // sorted order, because layer sorting is not performed on the main thread.
1898 // Because of this, the occlusion tracker cannot assume that a 3d layer occludes
1899 // other layers that have not yet been iterated over. For now, the expected
1900 // behavior is that a 3d layer simply does not add any occlusion to the occlusion
1903 WebTransformationMatrix translationToFront
;
1904 translationToFront
.translate3d(0, 0, -10);
1905 WebTransformationMatrix translationToBack
;
1906 translationToFront
.translate3d(0, 0, -100);
1908 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1909 typename
Types::ContentLayerType
* child1
= this->createDrawingLayer(parent
, translationToBack
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
1910 typename
Types::ContentLayerType
* child2
= this->createDrawingLayer(parent
, translationToFront
, gfx::PointF(50, 50), gfx::Size(100, 100), true);
1911 parent
->setPreserves3D(true);
1913 this->calcDrawEtc(parent
);
1915 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1916 this->visitLayer(child2
, occlusion
);
1917 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().IsEmpty());
1918 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().IsEmpty());
1920 this->visitLayer(child1
, occlusion
);
1921 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().IsEmpty());
1922 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().IsEmpty());
1926 // This test will have different layer ordering on the impl thread; the test will only work on the main thread.
1927 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers
);
1929 template<class Types
>
1930 class OcclusionTrackerTestPerspectiveTransform
: public OcclusionTrackerTest
<Types
> {
1932 OcclusionTrackerTestPerspectiveTransform(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1935 WebTransformationMatrix transform
;
1936 transform
.translate(150, 150);
1937 transform
.applyPerspective(400);
1938 transform
.rotate3d(1, 0, 0, -30);
1939 transform
.translate(-150, -150);
1941 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1942 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
1943 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, gfx::PointF(100, 100), gfx::Size(200, 200), true);
1944 container
->setPreserves3D(true);
1945 layer
->setPreserves3D(true);
1946 this->calcDrawEtc(parent
);
1948 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1949 this->enterLayer(layer
, occlusion
);
1951 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion
.unoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 200, 200)));
1955 // 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.
1956 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform
);
1958 template<class Types
>
1959 class OcclusionTrackerTestPerspectiveTransformBehindCamera
: public OcclusionTrackerTest
<Types
> {
1961 OcclusionTrackerTestPerspectiveTransformBehindCamera(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1964 // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
1965 WebTransformationMatrix transform
;
1966 transform
.translate(250, 50);
1967 transform
.applyPerspective(10);
1968 transform
.translate(-250, -50);
1969 transform
.translate(250, 50);
1970 transform
.rotate3d(1, 0, 0, -167);
1971 transform
.translate(-250, -50);
1973 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(500, 100));
1974 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(500, 500));
1975 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, gfx::PointF(0, 0), gfx::Size(500, 500), true);
1976 container
->setPreserves3D(true);
1977 layer
->setPreserves3D(true);
1978 this->calcDrawEtc(parent
);
1980 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
1981 this->enterLayer(layer
, occlusion
);
1983 // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
1984 // this will include many more pixels but must include at least the bottom 11 rows.
1985 EXPECT_TRUE(occlusion
.unoccludedLayerContentRect(layer
, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
1989 // 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.
1990 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera
);
1992 template<class Types
>
1993 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
: public OcclusionTrackerTest
<Types
> {
1995 OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
1998 WebTransformationMatrix transform
;
1999 transform
.translate(50, 50);
2000 transform
.applyPerspective(100);
2001 transform
.translate3d(0, 0, 110);
2002 transform
.translate(-50, -50);
2004 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
2005 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, transform
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2006 parent
->setPreserves3D(true);
2007 layer
->setPreserves3D(true);
2008 this->calcDrawEtc(parent
);
2010 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2012 // The |layer| is entirely behind the camera and should not occlude.
2013 this->visitLayer(layer
, occlusion
);
2014 this->enterLayer(parent
, occlusion
);
2015 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().IsEmpty());
2016 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().IsEmpty());
2020 // 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.
2021 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
2023 template<class Types
>
2024 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
: public OcclusionTrackerTest
<Types
> {
2026 OcclusionTrackerTestLargePixelsOccludeInsideClipRect(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2029 WebTransformationMatrix transform
;
2030 transform
.translate(50, 50);
2031 transform
.applyPerspective(100);
2032 transform
.translate3d(0, 0, 99);
2033 transform
.translate(-50, -50);
2035 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100));
2036 parent
->setMasksToBounds(true);
2037 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, transform
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2038 parent
->setPreserves3D(true);
2039 layer
->setPreserves3D(true);
2040 this->calcDrawEtc(parent
);
2042 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2044 // This is very close to the camera, so pixels in its visibleContentRect will actually go outside of the layer's clipRect.
2045 // Ensure that those pixels don't occlude things outside the clipRect.
2046 this->visitLayer(layer
, occlusion
);
2047 this->enterLayer(parent
, occlusion
);
2048 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2049 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2053 // 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.
2054 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
2056 template<class Types
>
2057 class OcclusionTrackerTestAnimationOpacity1OnMainThread
: public OcclusionTrackerTest
<Types
> {
2059 OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2062 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
2063 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2064 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2065 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2066 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2067 typename
Types::ContentLayerType
* parent2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2068 typename
Types::ContentLayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(250, 0), gfx::Size(50, 300), true);
2070 addOpacityTransitionToController(*layer
->layerAnimationController(), 10, 0, 1, false);
2071 addOpacityTransitionToController(*surface
->layerAnimationController(), 10, 0, 1, false);
2072 this->calcDrawEtc(parent
);
2074 EXPECT_TRUE(layer
->drawOpacityIsAnimating());
2075 EXPECT_FALSE(surface
->drawOpacityIsAnimating());
2076 EXPECT_TRUE(surface
->renderSurface()->drawOpacityIsAnimating());
2078 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2080 this->visitLayer(topmost
, occlusion
);
2081 this->enterLayer(parent2
, occlusion
);
2082 // This occlusion will affect all surfaces.
2083 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent2
, gfx::Rect(0, 0, 300, 300)));
2084 this->leaveLayer(parent2
, occlusion
);
2086 this->visitLayer(surfaceChild2
, occlusion
);
2087 this->enterLayer(surfaceChild
, occlusion
);
2088 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), occlusion
.unoccludedLayerContentRect(surfaceChild
, gfx::Rect(0, 0, 300, 300)));
2089 this->leaveLayer(surfaceChild
, occlusion
);
2090 this->enterLayer(surface
, occlusion
);
2091 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2092 this->leaveLayer(surface
, occlusion
);
2094 this->enterContributingSurface(surface
, occlusion
);
2095 // Occlusion within the surface is lost when leaving the animating surface.
2096 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 300, 300)));
2097 this->leaveContributingSurface(surface
, occlusion
);
2099 this->visitLayer(layer
, occlusion
);
2100 this->enterLayer(parent
, occlusion
);
2102 // Occlusion is not added for the animating |layer|.
2103 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2107 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread
);
2109 template<class Types
>
2110 class OcclusionTrackerTestAnimationOpacity0OnMainThread
: public OcclusionTrackerTest
<Types
> {
2112 OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2115 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
2116 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2117 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2118 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2119 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2120 typename
Types::ContentLayerType
* parent2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2121 typename
Types::ContentLayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(250, 0), gfx::Size(50, 300), true);
2123 addOpacityTransitionToController(*layer
->layerAnimationController(), 10, 1, 0, false);
2124 addOpacityTransitionToController(*surface
->layerAnimationController(), 10, 1, 0, false);
2125 this->calcDrawEtc(parent
);
2127 EXPECT_TRUE(layer
->drawOpacityIsAnimating());
2128 EXPECT_FALSE(surface
->drawOpacityIsAnimating());
2129 EXPECT_TRUE(surface
->renderSurface()->drawOpacityIsAnimating());
2131 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2133 this->visitLayer(topmost
, occlusion
);
2134 this->enterLayer(parent2
, occlusion
);
2135 // This occlusion will affect all surfaces.
2136 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2137 this->leaveLayer(parent2
, occlusion
);
2139 this->visitLayer(surfaceChild2
, occlusion
);
2140 this->enterLayer(surfaceChild
, occlusion
);
2141 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), occlusion
.unoccludedLayerContentRect(surfaceChild
, gfx::Rect(0, 0, 300, 300)));
2142 this->leaveLayer(surfaceChild
, occlusion
);
2143 this->enterLayer(surface
, occlusion
);
2144 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2145 this->leaveLayer(surface
, occlusion
);
2147 this->enterContributingSurface(surface
, occlusion
);
2148 // Occlusion within the surface is lost when leaving the animating surface.
2149 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 300, 300)));
2150 this->leaveContributingSurface(surface
, occlusion
);
2152 this->visitLayer(layer
, occlusion
);
2153 this->enterLayer(parent
, occlusion
);
2155 // Occlusion is not added for the animating |layer|.
2156 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2160 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread
);
2162 template<class Types
>
2163 class OcclusionTrackerTestAnimationTranslateOnMainThread
: public OcclusionTrackerTest
<Types
> {
2165 OcclusionTrackerTestAnimationTranslateOnMainThread(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2168 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
2169 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2170 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2171 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2172 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2173 typename
Types::ContentLayerType
* surface2
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(50, 300), true);
2175 addAnimatedTransformToController(*layer
->layerAnimationController(), 10, 30, 0);
2176 addAnimatedTransformToController(*surface
->layerAnimationController(), 10, 30, 0);
2177 addAnimatedTransformToController(*surfaceChild
->layerAnimationController(), 10, 30, 0);
2178 this->calcDrawEtc(parent
);
2180 EXPECT_TRUE(layer
->drawTransformIsAnimating());
2181 EXPECT_TRUE(layer
->screenSpaceTransformIsAnimating());
2182 EXPECT_TRUE(surface
->renderSurface()->targetSurfaceTransformsAreAnimating());
2183 EXPECT_TRUE(surface
->renderSurface()->screenSpaceTransformsAreAnimating());
2184 // The surface owning layer doesn't animate against its own surface.
2185 EXPECT_FALSE(surface
->drawTransformIsAnimating());
2186 EXPECT_TRUE(surface
->screenSpaceTransformIsAnimating());
2187 EXPECT_TRUE(surfaceChild
->drawTransformIsAnimating());
2188 EXPECT_TRUE(surfaceChild
->screenSpaceTransformIsAnimating());
2190 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2192 this->visitLayer(surface2
, occlusion
);
2193 this->enterContributingSurface(surface2
, occlusion
);
2195 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2197 this->leaveContributingSurface(surface2
, occlusion
);
2198 this->enterLayer(surfaceChild2
, occlusion
);
2200 // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2201 // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer.
2202 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300), occlusion
.unoccludedLayerContentRect(surfaceChild2
, gfx::Rect(0, 0, 100, 300)));
2203 EXPECT_FALSE(occlusion
.occludedLayer(surfaceChild
, gfx::Rect(0, 0, 50, 300)));
2205 this->leaveLayer(surfaceChild2
, occlusion
);
2206 this->enterLayer(surfaceChild
, occlusion
);
2207 EXPECT_FALSE(occlusion
.occludedLayer(surfaceChild
, gfx::Rect(0, 0, 100, 300)));
2208 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2209 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2210 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2212 // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target and the screen, so it
2213 // can't be occluded.
2214 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300), occlusion
.unoccludedLayerContentRect(surfaceChild
, gfx::Rect(0, 0, 200, 300)));
2215 EXPECT_FALSE(occlusion
.occludedLayer(surfaceChild
, gfx::Rect(0, 0, 50, 300)));
2217 this->leaveLayer(surfaceChild
, occlusion
);
2218 this->enterLayer(surface
, occlusion
);
2219 // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2220 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2221 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2222 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2224 this->leaveLayer(surface
, occlusion
);
2225 // The surface's owning layer is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2226 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2227 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2228 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion
.unoccludedLayerContentRect(surface
, gfx::Rect(0, 0, 300, 300)));
2230 this->enterContributingSurface(surface
, occlusion
);
2231 // The contributing |surface| is animating so it can't be occluded.
2232 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 300, 300)));
2233 this->leaveContributingSurface(surface
, occlusion
);
2235 this->enterLayer(layer
, occlusion
);
2236 // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
2237 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2238 this->leaveLayer(layer
, occlusion
);
2240 this->enterLayer(parent
, occlusion
);
2241 // The |layer| is animating in the screen and in its target, so no occlusion is added.
2242 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), occlusion
.unoccludedLayerContentRect(parent
, gfx::Rect(0, 0, 300, 300)));
2246 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread
);
2248 template<class Types
>
2249 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
: public OcclusionTrackerTest
<Types
> {
2251 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2254 WebTransformationMatrix surfaceTransform
;
2255 surfaceTransform
.translate(300, 300);
2256 surfaceTransform
.scale(2);
2257 surfaceTransform
.translate(-150, -150);
2259 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(500, 500));
2260 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, surfaceTransform
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2261 typename
Types::ContentLayerType
* surface2
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size(300, 300), false);
2262 surface
->setOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2263 surface2
->setOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2264 this->calcDrawEtc(parent
);
2266 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2268 this->visitLayer(surface2
, occlusion
);
2269 this->visitContributingSurface(surface2
, occlusion
);
2271 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2272 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2274 // Clear any stored occlusion.
2275 occlusion
.setOcclusionInScreenSpace(Region());
2276 occlusion
.setOcclusionInTargetSurface(Region());
2278 this->visitLayer(surface
, occlusion
);
2279 this->visitContributingSurface(surface
, occlusion
);
2281 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2282 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2286 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
2288 template<class Types
>
2289 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
: public OcclusionTrackerTest
<Types
> {
2291 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2294 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 300));
2295 parent
->setMasksToBounds(true);
2296 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(500, 300), false);
2297 surface
->setOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2298 this->calcDrawEtc(parent
);
2300 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2302 this->visitLayer(surface
, occlusion
);
2303 this->visitContributingSurface(surface
, occlusion
);
2305 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2306 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2310 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2312 template<class Types
>
2313 class OcclusionTrackerTestReplicaOccluded
: public OcclusionTrackerTest
<Types
> {
2315 OcclusionTrackerTestReplicaOccluded(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2318 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2319 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2320 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(100, 100));
2321 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(100, 100), true);
2322 this->calcDrawEtc(parent
);
2324 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2325 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2327 // |topmost| occludes the replica, but not the surface itself.
2328 this->visitLayer(topmost
, occlusion
);
2330 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2331 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2333 this->visitLayer(surface
, occlusion
);
2335 EXPECT_EQ(gfx::Rect(0, 0, 100, 200).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2336 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2338 this->enterContributingSurface(surface
, occlusion
);
2340 // Surface is not occluded so it shouldn't think it is.
2341 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2345 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded
);
2347 template<class Types
>
2348 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
: public OcclusionTrackerTest
<Types
> {
2350 OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2353 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2354 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2355 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(100, 100));
2356 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 110), true);
2357 this->calcDrawEtc(parent
);
2359 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2360 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2362 // |topmost| occludes the surface, but not the entire surface's replica.
2363 this->visitLayer(topmost
, occlusion
);
2365 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2366 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2368 this->visitLayer(surface
, occlusion
);
2370 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2371 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2373 this->enterContributingSurface(surface
, occlusion
);
2375 // Surface is occluded, but only the top 10px of the replica.
2376 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2377 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90), occlusion
.unoccludedContributingSurfaceContentRect(surface
, true, gfx::Rect(0, 0, 100, 100)));
2381 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2383 template<class Types
>
2384 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
: public OcclusionTrackerTest
<Types
> {
2386 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2389 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2390 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2391 this->createReplicaLayer(surface
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(100, 100));
2392 typename
Types::LayerType
* overSurface
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(40, 100), true);
2393 typename
Types::LayerType
* overReplica
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(50, 100), true);
2394 this->calcDrawEtc(parent
);
2396 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2397 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2399 // These occlude the surface and replica differently, so we can test each one.
2400 this->visitLayer(overReplica
, occlusion
);
2401 this->visitLayer(overSurface
, occlusion
);
2403 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2404 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2406 this->visitLayer(surface
, occlusion
);
2408 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2409 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2411 this->enterContributingSurface(surface
, occlusion
);
2413 // Surface and replica are occluded different amounts.
2414 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2415 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, true, gfx::Rect(0, 0, 100, 100)));
2419 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
2421 template<class Types
>
2422 class OcclusionTrackerTestSurfaceChildOfSurface
: public OcclusionTrackerTest
<Types
> {
2424 OcclusionTrackerTestSurfaceChildOfSurface(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2427 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2429 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2430 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2431 typename
Types::LayerType
* surfaceChild
= this->createDrawingSurface(surface
, this->identityMatrix
, gfx::PointF(0, 10), gfx::Size(100, 50), true);
2432 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 50), true);
2433 this->calcDrawEtc(parent
);
2435 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(-100, -100, 1000, 1000));
2437 // |topmost| occludes everything partially so we know occlusion is happening at all.
2438 this->visitLayer(topmost
, occlusion
);
2440 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2441 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2443 this->visitLayer(surfaceChild
, occlusion
);
2445 // surfaceChild increases the occlusion in the screen by a narrow sliver.
2446 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2447 // In its own surface, surfaceChild is at 0,0 as is its occlusion.
2448 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2450 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2451 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2452 // as its parent does not have a clipRect.
2454 this->enterContributingSurface(surfaceChild
, occlusion
);
2455 // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
2456 // does not get clipped away inappropriately.
2457 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10), occlusion
.unoccludedContributingSurfaceContentRect(surfaceChild
, false, gfx::Rect(0, 0, 100, 50)));
2458 this->leaveContributingSurface(surfaceChild
, occlusion
);
2460 // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
2461 this->enterLayer(surface
, occlusion
);
2462 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2463 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2464 this->leaveLayer(surface
, occlusion
);
2466 this->enterContributingSurface(surface
, occlusion
);
2467 // The surface's parent does have a clipRect as it is the root layer.
2468 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2472 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface
);
2474 template<class Types
>
2475 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
: public OcclusionTrackerTest
<Types
> {
2477 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2480 // This test verifies that the top-most surface is considered occluded outside of its target's clipRect and outside the viewport rect.
2482 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 200));
2483 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2484 this->calcDrawEtc(parent
);
2487 // Make a viewport rect that is larger than the root layer.
2488 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2490 this->visitLayer(surface
, occlusion
);
2492 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2493 this->enterContributingSurface(surface
, occlusion
);
2494 // Make sure the parent's clipRect clips the unoccluded region of the child surface.
2495 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 300)));
2497 this->resetLayerIterator();
2499 // Make a viewport rect that is smaller than the root layer.
2500 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 100, 100));
2502 this->visitLayer(surface
, occlusion
);
2504 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2505 this->enterContributingSurface(surface
, occlusion
);
2506 // Make sure the viewport rect clips the unoccluded region of the child surface.
2507 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 300)));
2512 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
);
2514 template<class Types
>
2515 class OcclusionTrackerTestSurfaceChildOfClippingSurface
: public OcclusionTrackerTest
<Types
> {
2517 OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2520 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2522 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(80, 200));
2523 parent
->setMasksToBounds(true);
2524 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2525 typename
Types::LayerType
* surfaceChild
= this->createDrawingSurface(surface
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 100), false);
2526 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(100, 50), true);
2527 this->calcDrawEtc(parent
);
2529 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2530 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2532 // |topmost| occludes everything partially so we know occlusion is happening at all.
2533 this->visitLayer(topmost
, occlusion
);
2535 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2536 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2538 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2539 this->visitLayer(surfaceChild
, occlusion
);
2541 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2542 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2544 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2545 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2546 // as its parent does not have a clipRect.
2548 this->enterContributingSurface(surfaceChild
, occlusion
);
2549 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
2550 EXPECT_RECT_EQ(gfx::Rect(0, 50, 80, 50), occlusion
.unoccludedContributingSurfaceContentRect(surfaceChild
, false, gfx::Rect(0, 0, 100, 100)));
2551 this->leaveContributingSurface(surfaceChild
, occlusion
);
2553 this->visitLayer(surface
, occlusion
);
2554 this->enterContributingSurface(surface
, occlusion
);
2555 // The surface's parent does have a clipRect as it is the root layer.
2556 EXPECT_RECT_EQ(gfx::Rect(0, 50, 80, 50), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, gfx::Rect(0, 0, 100, 100)));
2560 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface
);
2562 template<class Types
>
2563 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
: public OcclusionTrackerTest
<Types
> {
2565 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2568 WebTransformationMatrix scaleByHalf
;
2569 scaleByHalf
.scale(0.5);
2571 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2572 // 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
2573 // appears at 50, 50 and the replica at 200, 50.
2574 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2575 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2576 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(300, 0), gfx::Size());
2577 typename
Types::LayerType
* occludingLayer1
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 50), true);
2578 typename
Types::LayerType
* occludingLayer2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(300, 50), true);
2579 typename
Types::LayerType
* occludingLayer3
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 50), gfx::Size(50, 50), true);
2580 typename
Types::LayerType
* occludingLayer4
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 50), gfx::Size(100, 50), true);
2581 typename
Types::LayerType
* occludingLayer5
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(250, 50), gfx::Size(50, 50), true);
2583 // Filters make the layer own a surface.
2584 WebFilterOperations filters
;
2585 filters
.append(WebFilterOperation::createBlurFilter(10));
2586 filteredSurface
->setBackgroundFilters(filters
);
2588 // Save the distance of influence for the blur effect.
2589 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2590 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2592 this->calcDrawEtc(parent
);
2594 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2595 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2597 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2598 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2599 this->visitLayer(occludingLayer5
, occlusion
);
2600 this->visitLayer(occludingLayer4
, occlusion
);
2601 this->visitLayer(occludingLayer3
, occlusion
);
2602 this->visitLayer(occludingLayer2
, occlusion
);
2603 this->visitLayer(occludingLayer1
, occlusion
);
2605 Region expectedOcclusion
;
2606 expectedOcclusion
.Union(gfx::Rect(0, 0, 300, 50));
2607 expectedOcclusion
.Union(gfx::Rect(0, 50, 50, 50));
2608 expectedOcclusion
.Union(gfx::Rect(100, 50, 100, 50));
2609 expectedOcclusion
.Union(gfx::Rect(250, 50, 50, 50));
2610 expectedOcclusion
.Union(gfx::Rect(0, 100, 300, 50));
2612 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionInScreenSpace().ToString());
2613 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionInTargetSurface().ToString());
2615 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2616 this->enterLayer(filteredSurface
, occlusion
);
2617 EXPECT_RECT_EQ(gfx::Rect(1, 0, 99, 100), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(1, 0, 100, 100)));
2618 EXPECT_RECT_EQ(gfx::Rect(0, 1, 100, 99), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(0, 1, 100, 100)));
2619 EXPECT_RECT_EQ(gfx::Rect(0, 0, 99, 100), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(-1, 0, 100, 100)));
2620 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 99), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(0, -1, 100, 100)));
2622 EXPECT_RECT_EQ(gfx::Rect(300 + 1, 0, 99, 100), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(300 + 1, 0, 100, 100)));
2623 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 1, 100, 99), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(300 + 0, 1, 100, 100)));
2624 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 0, 99, 100), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(300 - 1, 0, 100, 100)));
2625 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 0, 100, 99), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(300 + 0, -1, 100, 100)));
2626 this->leaveLayer(filteredSurface
, occlusion
);
2628 // The filtered layer/replica does not occlude.
2629 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionInScreenSpace().ToString());
2630 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInTargetSurface().ToString());
2632 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2633 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2634 this->visitContributingSurface(filteredSurface
, occlusion
);
2636 this->enterLayer(parent
, occlusion
);
2638 Region expectedBlurredOcclusion
;
2639 expectedBlurredOcclusion
.Union(gfx::Rect(0, 0, 300, 50 - outsetTop
));
2640 expectedBlurredOcclusion
.Union(gfx::Rect(0, 50 - outsetTop
, 50 - outsetLeft
, 50 + outsetTop
+ outsetBottom
));
2641 expectedBlurredOcclusion
.Union(gfx::Rect(100 + outsetRight
, 50 - outsetTop
, 100 - outsetRight
- outsetLeft
, 50 + outsetTop
+ outsetBottom
));
2642 expectedBlurredOcclusion
.Union(gfx::Rect(250 + outsetRight
, 50 - outsetTop
, 50 - outsetRight
, 50 + outsetTop
+ outsetBottom
));
2643 expectedBlurredOcclusion
.Union(gfx::Rect(0, 100 + outsetBottom
, 300, 50 - outsetBottom
));
2645 EXPECT_EQ(expectedBlurredOcclusion
.ToString(), occlusion
.occlusionInScreenSpace().ToString());
2646 EXPECT_EQ(expectedBlurredOcclusion
.ToString(), occlusion
.occlusionInTargetSurface().ToString());
2648 gfx::Rect outsetRect
;
2651 // Nothing in the blur outsets for the filteredSurface is occluded.
2652 outsetRect
= gfx::Rect(50 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2653 testRect
= outsetRect
;
2654 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2656 // Stuff outside the blur outsets is still occluded though.
2657 testRect
= outsetRect
;
2658 testRect
.Inset(0, 0, -1, 0);
2659 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2660 testRect
= outsetRect
;
2661 testRect
.Inset(0, 0, 0, -1);
2662 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2663 testRect
= outsetRect
;
2664 testRect
.Inset(-1, 0, 0, 0);
2665 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2666 testRect
= outsetRect
;
2667 testRect
.Inset(0, -1, 0, 0);
2668 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2670 // Nothing in the blur outsets for the filteredSurface's replica is occluded.
2671 outsetRect
= gfx::Rect(200 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2672 testRect
= outsetRect
;
2673 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2675 // Stuff outside the blur outsets is still occluded though.
2676 testRect
= outsetRect
;
2677 testRect
.Inset(0, 0, -1, 0);
2678 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2679 testRect
= outsetRect
;
2680 testRect
.Inset(0, 0, 0, -1);
2681 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2682 testRect
= outsetRect
;
2683 testRect
.Inset(-1, 0, 0, 0);
2684 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2685 testRect
= outsetRect
;
2686 testRect
.Inset(0, -1, 0, 0);
2687 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedLayerContentRect(parent
, testRect
));
2691 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
2693 template<class Types
>
2694 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
: public OcclusionTrackerTest
<Types
> {
2696 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2699 WebTransformationMatrix scaleByHalf
;
2700 scaleByHalf
.scale(0.5);
2702 // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
2703 typename
Types::ContentLayerType
* root
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(75, 75));
2704 typename
Types::LayerType
* parent
= this->createSurface(root
, scaleByHalf
, gfx::PointF(0, 0), gfx::Size(150, 150));
2705 parent
->setMasksToBounds(true);
2706 typename
Types::LayerType
* filteredSurface1
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2707 typename
Types::LayerType
* filteredSurface2
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2708 typename
Types::LayerType
* occludingLayerAbove
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 100), gfx::Size(50, 50), true);
2710 // Filters make the layers own surfaces.
2711 WebFilterOperations filters
;
2712 filters
.append(WebFilterOperation::createBlurFilter(1));
2713 filteredSurface1
->setBackgroundFilters(filters
);
2714 filteredSurface2
->setBackgroundFilters(filters
);
2716 // Save the distance of influence for the blur effect.
2717 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2718 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2720 this->calcDrawEtc(root
);
2722 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2723 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2725 this->visitLayer(occludingLayerAbove
, occlusion
);
2726 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion
.occlusionInScreenSpace().ToString());
2727 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion
.occlusionInTargetSurface().ToString());
2729 this->visitLayer(filteredSurface2
, occlusion
);
2730 this->visitContributingSurface(filteredSurface2
, occlusion
);
2731 this->visitLayer(filteredSurface1
, occlusion
);
2732 this->visitContributingSurface(filteredSurface1
, occlusion
);
2734 // Test expectations in the target.
2735 gfx::Rect expectedOcclusion
= gfx::Rect(100 / 2 + outsetRight
* 2, 100 / 2 + outsetBottom
* 2, 50 / 2 - (outsetLeft
+ outsetRight
) * 2, 50 / 2 - (outsetTop
+ outsetBottom
) * 2);
2736 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionInTargetSurface().ToString());
2738 // Test expectations in the screen are the same as in the target, as the render surface is 1:1 with the screen.
2739 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionInScreenSpace().ToString());
2743 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
2745 template<class Types
>
2746 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
: public OcclusionTrackerTest
<Types
> {
2748 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2751 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2752 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2753 // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
2754 // the background filter.
2755 typename
Types::LayerType
* clippingSurface
= this->createSurface(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 70));
2756 clippingSurface
->setMasksToBounds(true);
2757 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(clippingSurface
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size(50, 50), false);
2758 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(150, 0), gfx::Size());
2759 typename
Types::LayerType
* occludingLayer1
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 50), true);
2760 typename
Types::LayerType
* occludingLayer2
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 100), gfx::Size(300, 50), true);
2761 typename
Types::LayerType
* occludingLayer3
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 50), gfx::Size(50, 50), true);
2762 typename
Types::LayerType
* occludingLayer4
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(100, 50), gfx::Size(100, 50), true);
2763 typename
Types::LayerType
* occludingLayer5
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(250, 50), gfx::Size(50, 50), true);
2765 // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
2766 WebFilterOperations filters
;
2767 filters
.append(WebFilterOperation::createBlurFilter(12));
2768 filteredSurface
->setBackgroundFilters(filters
);
2770 // Save the distance of influence for the blur effect.
2771 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2772 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2774 this->calcDrawEtc(parent
);
2776 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2777 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2779 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2780 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2781 this->visitLayer(occludingLayer5
, occlusion
);
2782 this->visitLayer(occludingLayer4
, occlusion
);
2783 this->visitLayer(occludingLayer3
, occlusion
);
2784 this->visitLayer(occludingLayer2
, occlusion
);
2785 this->visitLayer(occludingLayer1
, occlusion
);
2787 Region expectedOcclusion
;
2788 expectedOcclusion
.Union(gfx::Rect(0, 0, 300, 50));
2789 expectedOcclusion
.Union(gfx::Rect(0, 50, 50, 50));
2790 expectedOcclusion
.Union(gfx::Rect(100, 50, 100, 50));
2791 expectedOcclusion
.Union(gfx::Rect(250, 50, 50, 50));
2792 expectedOcclusion
.Union(gfx::Rect(0, 100, 300, 50));
2794 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionInScreenSpace().ToString());
2795 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionInTargetSurface().ToString());
2797 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2798 this->enterLayer(filteredSurface
, occlusion
);
2799 EXPECT_RECT_EQ(gfx::Rect(1, 0, 49, 50), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(1, 0, 50, 50)));
2800 EXPECT_RECT_EQ(gfx::Rect(0, 1, 50, 49), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(0, 1, 50, 50)));
2801 EXPECT_RECT_EQ(gfx::Rect(0, 0, 49, 50), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(-1, 0, 50, 50)));
2802 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 49), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(0, -1, 50, 50)));
2804 EXPECT_RECT_EQ(gfx::Rect(150 + 1, 0, 49, 50), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(150 + 1, 0, 50, 50)));
2805 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 1, 50, 49), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(150 + 0, 1, 50, 50)));
2806 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 0, 49, 50), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(150 - 1, 0, 50, 50)));
2807 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 0, 50, 49), occlusion
.unoccludedLayerContentRect(filteredSurface
, gfx::Rect(150 + 0, -1, 50, 50)));
2808 this->leaveLayer(filteredSurface
, occlusion
);
2810 // The filtered layer/replica does not occlude.
2811 EXPECT_EQ(expectedOcclusion
.ToString(), occlusion
.occlusionInScreenSpace().ToString());
2812 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInTargetSurface().ToString());
2814 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2815 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2816 this->visitContributingSurface(filteredSurface
, occlusion
);
2818 this->enterContributingSurface(clippingSurface
, occlusion
);
2820 Region expectedBlurredOcclusion
;
2821 expectedBlurredOcclusion
.Union(gfx::Rect(0, 0, 300, 50 - outsetTop
));
2822 expectedBlurredOcclusion
.Union(gfx::Rect(0, 50 - outsetTop
, 50 - outsetLeft
, 20 + outsetTop
+ outsetBottom
));
2823 expectedBlurredOcclusion
.Union(gfx::Rect(100 + outsetRight
, 50 - outsetTop
, 100 - outsetRight
- outsetLeft
, 20 + outsetTop
+ outsetBottom
));
2824 expectedBlurredOcclusion
.Union(gfx::Rect(250 + outsetRight
, 50 - outsetTop
, 50 - outsetRight
, 20 + outsetTop
+ outsetBottom
));
2825 expectedBlurredOcclusion
.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
2827 EXPECT_EQ(expectedBlurredOcclusion
.ToString(), occlusion
.occlusionInScreenSpace().ToString());
2828 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInTargetSurface().ToString());
2830 gfx::Rect outsetRect
;
2831 gfx::Rect clippedOutsetRect
;
2834 // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
2835 outsetRect
= gfx::Rect(50 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2836 clippedOutsetRect
= gfx::IntersectRects(outsetRect
, gfx::Rect(0 - outsetLeft
, 0 - outsetTop
, 300 + outsetLeft
+ outsetRight
, 70 + outsetTop
+ outsetBottom
));
2837 testRect
= outsetRect
;
2838 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2840 // Stuff outside the (clipped) blur outsets is still occluded though.
2841 testRect
= outsetRect
;
2842 testRect
.Inset(0, 0, -1, 0);
2843 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2844 testRect
= outsetRect
;
2845 testRect
.Inset(0, 0, 0, -1);
2846 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2847 testRect
= outsetRect
;
2848 testRect
.Inset(-1, 0, 0, 0);
2849 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2850 testRect
= outsetRect
;
2851 testRect
.Inset(0, -1, 0, 0);
2852 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2854 // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
2855 outsetRect
= gfx::Rect(200 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2856 clippedOutsetRect
= gfx::IntersectRects(outsetRect
, gfx::Rect(0 - outsetLeft
, 0 - outsetTop
, 300 + outsetLeft
+ outsetRight
, 70 + outsetTop
+ outsetBottom
));
2857 testRect
= outsetRect
;
2858 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2860 // Stuff outside the (clipped) blur outsets is still occluded though.
2861 testRect
= outsetRect
;
2862 testRect
.Inset(0, 0, -1, 0);
2863 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2864 testRect
= outsetRect
;
2865 testRect
.Inset(0, 0, 0, -1);
2866 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2867 testRect
= outsetRect
;
2868 testRect
.Inset(-1, 0, 0, 0);
2869 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2870 testRect
= outsetRect
;
2871 testRect
.Inset(0, -1, 0, 0);
2872 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedLayerContentRect(clippingSurface
, testRect
));
2876 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
);
2878 template<class Types
>
2879 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
: public OcclusionTrackerTest
<Types
> {
2881 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2884 WebTransformationMatrix scaleByHalf
;
2885 scaleByHalf
.scale(0.5);
2887 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
2888 // 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
2889 // appears at 50, 50 and the replica at 200, 50.
2890 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2891 typename
Types::LayerType
* behindSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(60, 60), gfx::Size(30, 30), true);
2892 typename
Types::LayerType
* behindReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(210, 60), gfx::Size(30, 30), true);
2893 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2894 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(300, 0), gfx::Size());
2896 // Filters make the layer own a surface.
2897 WebFilterOperations filters
;
2898 filters
.append(WebFilterOperation::createBlurFilter(3));
2899 filteredSurface
->setBackgroundFilters(filters
);
2901 this->calcDrawEtc(parent
);
2903 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2904 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2906 // The surface has a background blur, so it blurs non-opaque pixels below it.
2907 this->visitLayer(filteredSurface
, occlusion
);
2908 this->visitContributingSurface(filteredSurface
, occlusion
);
2910 this->visitLayer(behindReplicaLayer
, occlusion
);
2911 this->visitLayer(behindSurfaceLayer
, occlusion
);
2913 // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
2914 // So it should not be modified by the filter here.
2915 gfx::Rect occlusionBehindSurface
= gfx::Rect(60, 60, 30, 30);
2916 gfx::Rect occlusionBehindReplica
= gfx::Rect(210, 60, 30, 30);
2918 Region expectedOpaqueBounds
= UnionRegions(occlusionBehindSurface
, occlusionBehindReplica
);
2919 EXPECT_EQ(expectedOpaqueBounds
.ToString(), occlusion
.occlusionInScreenSpace().ToString());
2920 EXPECT_EQ(expectedOpaqueBounds
.ToString(), occlusion
.occlusionInTargetSurface().ToString());
2924 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
2926 template<class Types
>
2927 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
: public OcclusionTrackerTest
<Types
> {
2929 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2932 WebTransformationMatrix scaleByHalf
;
2933 scaleByHalf
.scale(0.5);
2935 // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
2936 // 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
2937 // appears at 50, 50 and the replica at 200, 50.
2938 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2939 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2940 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(300, 0), gfx::Size());
2941 typename
Types::LayerType
* aboveSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(50, 50), gfx::Size(50, 50), true);
2942 typename
Types::LayerType
* aboveReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(200, 50), gfx::Size(50, 50), true);
2944 // Filters make the layer own a surface.
2945 WebFilterOperations filters
;
2946 filters
.append(WebFilterOperation::createBlurFilter(3));
2947 filteredSurface
->setBackgroundFilters(filters
);
2949 this->calcDrawEtc(parent
);
2951 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
2952 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2954 this->visitLayer(aboveReplicaLayer
, occlusion
);
2955 this->visitLayer(aboveSurfaceLayer
, occlusion
);
2957 // The surface has a background blur, so it blurs non-opaque pixels below it.
2958 this->visitLayer(filteredSurface
, occlusion
);
2959 this->visitContributingSurface(filteredSurface
, occlusion
);
2961 // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
2962 gfx::Rect occlusionAboveSurface
= gfx::Rect(50, 50, 50, 50);
2963 gfx::Rect occlusionAboveReplica
= gfx::Rect(200, 50, 50, 50);
2965 Region expectedOpaqueRegion
= UnionRegions(occlusionAboveSurface
, occlusionAboveReplica
);
2966 EXPECT_EQ(expectedOpaqueRegion
, occlusion
.occlusionInScreenSpace());
2967 EXPECT_EQ(expectedOpaqueRegion
, occlusion
.occlusionInTargetSurface());
2971 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
2973 template<class Types
>
2974 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
: public OcclusionTrackerTest
<Types
> {
2976 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
2979 WebTransformationMatrix scaleByHalf
;
2980 scaleByHalf
.scale(0.5);
2982 // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
2983 // 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
2984 // appears at 50, 50 and the replica at 200, 50.
2985 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(300, 150));
2986 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2987 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, gfx::PointF(300, 0), gfx::Size());
2988 typename
Types::LayerType
* aboveSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(70, 50), gfx::Size(30, 50), true);
2989 typename
Types::LayerType
* aboveReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(200, 50), gfx::Size(30, 50), true);
2990 typename
Types::LayerType
* besideSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(90, 40), gfx::Size(10, 10), true);
2991 typename
Types::LayerType
* besideReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(200, 40), gfx::Size(10, 10), true);
2993 // Filters make the layer own a surface.
2994 WebFilterOperations filters
;
2995 filters
.append(WebFilterOperation::createBlurFilter(3));
2996 filteredSurface
->setBackgroundFilters(filters
);
2998 // Save the distance of influence for the blur effect.
2999 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
3000 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
3002 this->calcDrawEtc(parent
);
3004 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
3005 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
3007 this->visitLayer(besideReplicaLayer
, occlusion
);
3008 this->visitLayer(besideSurfaceLayer
, occlusion
);
3009 this->visitLayer(aboveReplicaLayer
, occlusion
);
3010 this->visitLayer(aboveSurfaceLayer
, occlusion
);
3012 // The surface has a background blur, so it blurs non-opaque pixels below it.
3013 this->visitLayer(filteredSurface
, occlusion
);
3014 this->visitContributingSurface(filteredSurface
, occlusion
);
3016 // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
3017 // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
3018 // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
3019 // the occluded part of the surface.
3020 gfx::Rect occlusionAboveSurface
= gfx::Rect(70 + outsetRight
, 50, 30 - outsetRight
, 50);
3021 gfx::Rect occlusionAboveReplica
= gfx::Rect(200, 50, 30 - outsetLeft
, 50);
3022 gfx::Rect occlusionBesideSurface
= gfx::Rect(90, 40, 10, 10);
3023 gfx::Rect occlusionBesideReplica
= gfx::Rect(200, 40, 10, 10);
3025 Region expectedOcclusion
;
3026 expectedOcclusion
.Union(occlusionAboveSurface
);
3027 expectedOcclusion
.Union(occlusionAboveReplica
);
3028 expectedOcclusion
.Union(occlusionBesideSurface
);
3029 expectedOcclusion
.Union(occlusionBesideReplica
);
3031 ASSERT_EQ(expectedOcclusion
, occlusion
.occlusionInTargetSurface());
3032 ASSERT_EQ(expectedOcclusion
, occlusion
.occlusionInScreenSpace());
3034 Region::Iterator
expectedRects(expectedOcclusion
);
3035 Region::Iterator
screenSpaceRects(occlusion
.occlusionInScreenSpace());
3036 Region::Iterator
targetSurfaceRects(occlusion
.occlusionInTargetSurface());
3037 for (; expectedRects
.has_rect(); expectedRects
.next(), screenSpaceRects
.next(), targetSurfaceRects
.next()) {
3038 ASSERT_TRUE(screenSpaceRects
.has_rect());
3039 ASSERT_TRUE(targetSurfaceRects
.has_rect());
3040 EXPECT_EQ(expectedRects
.rect(), screenSpaceRects
.rect());
3041 EXPECT_EQ(expectedRects
.rect(), targetSurfaceRects
.rect());
3046 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
3048 template<class Types
>
3049 class OcclusionTrackerTestMinimumTrackingSize
: public OcclusionTrackerTest
<Types
> {
3051 OcclusionTrackerTestMinimumTrackingSize(bool opaqueLayers
) : OcclusionTrackerTest
<Types
>(opaqueLayers
) {}
3054 gfx::Size
trackingSize(100, 100);
3055 gfx::Size
belowTrackingSize(99, 99);
3057 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, gfx::PointF(0, 0), gfx::Size(400, 400));
3058 typename
Types::LayerType
* large
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), trackingSize
, true);
3059 typename
Types::LayerType
* small
= this->createDrawingLayer(parent
, this->identityMatrix
, gfx::PointF(0, 0), belowTrackingSize
, true);
3060 this->calcDrawEtc(parent
);
3062 TestOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(gfx::Rect(0, 0, 1000, 1000));
3063 occlusion
.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
3064 occlusion
.setMinimumTrackingSize(trackingSize
);
3066 // The small layer is not tracked because it is too small.
3067 this->visitLayer(small
, occlusion
);
3069 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInScreenSpace().ToString());
3070 EXPECT_EQ(gfx::Rect().ToString(), occlusion
.occlusionInTargetSurface().ToString());
3072 // The large layer is tracked as it is large enough.
3073 this->visitLayer(large
, occlusion
);
3075 EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize
).ToString(), occlusion
.occlusionInScreenSpace().ToString());
3076 EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize
).ToString(), occlusion
.occlusionInTargetSurface().ToString());
3080 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize
);
3082 } // anonymous namespace