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 "CCOcclusionTracker.h"
9 #include "CCAnimationTestCommon.h"
10 #include "CCGeometryTestUtils.h"
11 #include "CCLayerAnimationController.h"
12 #include "CCLayerTreeHostCommon.h"
13 #include "CCMathUtil.h"
14 #include "CCOcclusionTrackerTestCommon.h"
15 #include "CCOverdrawMetrics.h"
16 #include "CCSingleThreadProxy.h"
17 #include "CCTiledLayerImpl.h"
19 #include "TiledLayerChromium.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include <public/WebFilterOperation.h>
23 #include <public/WebFilterOperations.h>
24 #include <public/WebTransformationMatrix.h>
27 using namespace WebKit
;
28 using namespace WebKitTests
;
32 class TestContentLayerChromium
: public TiledLayerChromium
{
34 TestContentLayerChromium()
35 : TiledLayerChromium()
36 , m_overrideOpaqueContentsRect(false)
40 virtual bool drawsContent() const OVERRIDE
{ return true; }
41 virtual Region
visibleContentOpaqueRegion() const OVERRIDE
43 if (m_overrideOpaqueContentsRect
)
44 return intersection(m_opaqueContentsRect
, visibleContentRect());
45 return LayerChromium::visibleContentOpaqueRegion();
47 void setOpaqueContentsRect(const IntRect
& opaqueContentsRect
)
49 m_overrideOpaqueContentsRect
= true;
50 m_opaqueContentsRect
= opaqueContentsRect
;
53 virtual LayerTextureUpdater
* textureUpdater() const OVERRIDE
{ return 0; }
54 virtual void createTextureUpdaterIfNeeded() OVERRIDE
{ }
57 virtual ~TestContentLayerChromium()
61 bool m_overrideOpaqueContentsRect
;
62 IntRect m_opaqueContentsRect
;
65 class TestContentLayerImpl
: public CCTiledLayerImpl
{
67 TestContentLayerImpl(int id
)
68 : CCTiledLayerImpl(id
)
69 , m_overrideOpaqueContentsRect(false)
71 setDrawsContent(true);
74 virtual Region
visibleContentOpaqueRegion() const OVERRIDE
76 if (m_overrideOpaqueContentsRect
)
77 return intersection(m_opaqueContentsRect
, visibleContentRect());
78 return CCLayerImpl::visibleContentOpaqueRegion();
80 void setOpaqueContentsRect(const IntRect
& opaqueContentsRect
)
82 m_overrideOpaqueContentsRect
= true;
83 m_opaqueContentsRect
= opaqueContentsRect
;
87 bool m_overrideOpaqueContentsRect
;
88 IntRect m_opaqueContentsRect
;
91 template<typename LayerType
, typename RenderSurfaceType
>
92 class TestCCOcclusionTrackerWithClip
: public TestCCOcclusionTrackerBase
<LayerType
, RenderSurfaceType
> {
94 TestCCOcclusionTrackerWithClip(IntRect viewportRect
, bool recordMetricsForFrame
= false)
95 : TestCCOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>(viewportRect
, recordMetricsForFrame
)
96 , m_overrideLayerClipRect(false)
100 void setLayerClipRect(const IntRect
& rect
) { m_overrideLayerClipRect
= true; m_layerClipRect
= rect
;}
101 void useDefaultLayerClipRect() { m_overrideLayerClipRect
= false; }
104 virtual IntRect
layerClipRectInTarget(const LayerType
* layer
) const { return m_overrideLayerClipRect
? m_layerClipRect
: CCOcclusionTrackerBase
<LayerType
, RenderSurfaceType
>::layerClipRectInTarget(layer
); }
107 bool m_overrideLayerClipRect
;
108 IntRect m_layerClipRect
;
111 struct CCOcclusionTrackerTestMainThreadTypes
{
112 typedef LayerChromium LayerType
;
113 typedef RenderSurfaceChromium RenderSurfaceType
;
114 typedef TestContentLayerChromium ContentLayerType
;
115 typedef scoped_refptr
<LayerChromium
> LayerPtrType
;
116 typedef scoped_refptr
<LayerChromium
> PassLayerPtrType
;
117 typedef scoped_refptr
<ContentLayerType
> ContentLayerPtrType
;
118 typedef scoped_refptr
<ContentLayerType
> PassContentLayerPtrType
;
119 typedef CCLayerIterator
<LayerChromium
, std::vector
<scoped_refptr
<LayerChromium
> >, RenderSurfaceChromium
, CCLayerIteratorActions::FrontToBack
> LayerIterator
;
120 typedef CCOcclusionTracker OcclusionTrackerType
;
122 static PassLayerPtrType
createLayer()
124 return LayerChromium::create();
126 static PassContentLayerPtrType
createContentLayer() { return make_scoped_refptr(new ContentLayerType()); }
128 static void destroyLayer(LayerPtrType
& layer
)
134 struct CCOcclusionTrackerTestImplThreadTypes
{
135 typedef CCLayerImpl LayerType
;
136 typedef CCRenderSurface RenderSurfaceType
;
137 typedef TestContentLayerImpl ContentLayerType
;
138 typedef OwnPtr
<CCLayerImpl
> LayerPtrType
;
139 typedef PassOwnPtr
<CCLayerImpl
> PassLayerPtrType
;
140 typedef OwnPtr
<ContentLayerType
> ContentLayerPtrType
;
141 typedef PassOwnPtr
<ContentLayerType
> PassContentLayerPtrType
;
142 typedef CCLayerIterator
<CCLayerImpl
, std::vector
<CCLayerImpl
*>, CCRenderSurface
, CCLayerIteratorActions::FrontToBack
> LayerIterator
;
143 typedef CCOcclusionTrackerImpl OcclusionTrackerType
;
145 static PassLayerPtrType
createLayer() { return CCLayerImpl::create(nextCCLayerImplId
++); }
146 static PassContentLayerPtrType
createContentLayer() { return adoptPtr(new ContentLayerType(nextCCLayerImplId
++)); }
147 static int nextCCLayerImplId
;
149 static void destroyLayer(LayerPtrType
& layer
)
155 int CCOcclusionTrackerTestImplThreadTypes::nextCCLayerImplId
= 1;
157 template<typename Types
, bool opaqueLayers
>
158 class CCOcclusionTrackerTest
: public testing::Test
{
160 CCOcclusionTrackerTest()
164 virtual void runMyTest() = 0;
166 virtual void TearDown()
168 Types::destroyLayer(m_root
);
169 m_renderSurfaceLayerListChromium
.clear();
170 m_renderSurfaceLayerListImpl
.clear();
171 m_replicaLayers
.clear();
172 m_maskLayers
.clear();
173 CCLayerTreeHost::setNeedsFilterContext(false);
176 typename
Types::ContentLayerType
* createRoot(const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
)
178 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer());
179 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
180 setProperties(layerPtr
, transform
, position
, bounds
);
183 m_root
= layer
.release();
187 typename
Types::LayerType
* createLayer(typename
Types::LayerType
* parent
, const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
)
189 typename
Types::LayerPtrType
layer(Types::createLayer());
190 typename
Types::LayerType
* layerPtr
= layer
.get();
191 setProperties(layerPtr
, transform
, position
, bounds
);
192 parent
->addChild(layer
.release());
196 typename
Types::LayerType
* createSurface(typename
Types::LayerType
* parent
, const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
)
198 typename
Types::LayerType
* layer
= createLayer(parent
, transform
, position
, bounds
);
199 WebFilterOperations filters
;
200 filters
.append(WebFilterOperation::createGrayscaleFilter(0.5));
201 layer
->setFilters(filters
);
205 typename
Types::ContentLayerType
* createDrawingLayer(typename
Types::LayerType
* parent
, const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
, bool opaque
)
207 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer());
208 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
209 setProperties(layerPtr
, transform
, position
, bounds
);
212 layerPtr
->setContentsOpaque(opaque
);
214 layerPtr
->setContentsOpaque(false);
216 layerPtr
->setOpaqueContentsRect(IntRect(IntPoint(), bounds
));
218 layerPtr
->setOpaqueContentsRect(IntRect());
221 parent
->addChild(layer
.release());
225 typename
Types::LayerType
* createReplicaLayer(typename
Types::LayerType
* owningLayer
, const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
)
227 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer());
228 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
229 setProperties(layerPtr
, transform
, position
, bounds
);
230 setReplica(owningLayer
, layer
.release());
234 typename
Types::LayerType
* createMaskLayer(typename
Types::LayerType
* owningLayer
, const IntSize
& bounds
)
236 typename
Types::ContentLayerPtrType
layer(Types::createContentLayer());
237 typename
Types::ContentLayerType
* layerPtr
= layer
.get();
238 setProperties(layerPtr
, identityMatrix
, FloatPoint(), bounds
);
239 setMask(owningLayer
, layer
.release());
243 typename
Types::ContentLayerType
* createDrawingSurface(typename
Types::LayerType
* parent
, const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
, bool opaque
)
245 typename
Types::ContentLayerType
* layer
= createDrawingLayer(parent
, transform
, position
, bounds
, opaque
);
246 WebFilterOperations filters
;
247 filters
.append(WebFilterOperation::createGrayscaleFilter(0.5));
248 layer
->setFilters(filters
);
252 void calcDrawEtc(TestContentLayerImpl
* root
)
254 ASSERT(root
== m_root
.get());
255 int dummyMaxTextureSize
= 512;
256 CCLayerSorter layerSorter
;
258 ASSERT(!root
->renderSurface());
260 CCLayerTreeHostCommon::calculateDrawTransforms(root
, root
->bounds(), 1, 1, &layerSorter
, dummyMaxTextureSize
, m_renderSurfaceLayerListImpl
);
262 m_layerIterator
= m_layerIteratorBegin
= Types::LayerIterator::begin(&m_renderSurfaceLayerListImpl
);
265 void calcDrawEtc(TestContentLayerChromium
* root
)
267 ASSERT(root
== m_root
.get());
268 int dummyMaxTextureSize
= 512;
270 ASSERT(!root
->renderSurface());
272 CCLayerTreeHostCommon::calculateDrawTransforms(root
, root
->bounds(), 1, 1, dummyMaxTextureSize
, m_renderSurfaceLayerListChromium
);
274 m_layerIterator
= m_layerIteratorBegin
= Types::LayerIterator::begin(&m_renderSurfaceLayerListChromium
);
277 void enterLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
279 ASSERT_EQ(layer
, *m_layerIterator
);
280 ASSERT_TRUE(m_layerIterator
.representsItself());
281 occlusion
.enterLayer(m_layerIterator
);
284 void leaveLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
286 ASSERT_EQ(layer
, *m_layerIterator
);
287 ASSERT_TRUE(m_layerIterator
.representsItself());
288 occlusion
.leaveLayer(m_layerIterator
);
292 void visitLayer(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
294 enterLayer(layer
, occlusion
);
295 leaveLayer(layer
, occlusion
);
298 void enterContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
300 ASSERT_EQ(layer
, *m_layerIterator
);
301 ASSERT_TRUE(m_layerIterator
.representsTargetRenderSurface());
302 occlusion
.enterLayer(m_layerIterator
);
303 occlusion
.leaveLayer(m_layerIterator
);
305 ASSERT_TRUE(m_layerIterator
.representsContributingRenderSurface());
306 occlusion
.enterLayer(m_layerIterator
);
309 void leaveContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
311 ASSERT_EQ(layer
, *m_layerIterator
);
312 ASSERT_TRUE(m_layerIterator
.representsContributingRenderSurface());
313 occlusion
.leaveLayer(m_layerIterator
);
317 void visitContributingSurface(typename
Types::LayerType
* layer
, typename
Types::OcclusionTrackerType
& occlusion
)
319 enterContributingSurface(layer
, occlusion
);
320 leaveContributingSurface(layer
, occlusion
);
323 void resetLayerIterator()
325 m_layerIterator
= m_layerIteratorBegin
;
328 const WebTransformationMatrix identityMatrix
;
331 void setBaseProperties(typename
Types::LayerType
* layer
, const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
)
333 layer
->setTransform(transform
);
334 layer
->setSublayerTransform(WebTransformationMatrix());
335 layer
->setAnchorPoint(FloatPoint(0, 0));
336 layer
->setPosition(position
);
337 layer
->setBounds(bounds
);
340 void setProperties(LayerChromium
* layer
, const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
)
342 setBaseProperties(layer
, transform
, position
, bounds
);
345 void setProperties(CCLayerImpl
* layer
, const WebTransformationMatrix
& transform
, const FloatPoint
& position
, const IntSize
& bounds
)
347 setBaseProperties(layer
, transform
, position
, bounds
);
349 layer
->setContentBounds(layer
->bounds());
352 void setReplica(LayerChromium
* owningLayer
, scoped_refptr
<LayerChromium
> layer
)
354 owningLayer
->setReplicaLayer(layer
.get());
355 m_replicaLayers
.push_back(layer
);
358 void setReplica(CCLayerImpl
* owningLayer
, PassOwnPtr
<CCLayerImpl
> layer
)
360 owningLayer
->setReplicaLayer(layer
);
363 void setMask(LayerChromium
* owningLayer
, scoped_refptr
<LayerChromium
> layer
)
365 owningLayer
->setMaskLayer(layer
.get());
366 m_maskLayers
.push_back(layer
);
369 void setMask(CCLayerImpl
* owningLayer
, PassOwnPtr
<CCLayerImpl
> layer
)
371 owningLayer
->setMaskLayer(layer
);
374 // These hold ownership of the layers for the duration of the test.
375 typename
Types::LayerPtrType m_root
;
376 std::vector
<scoped_refptr
<LayerChromium
> > m_renderSurfaceLayerListChromium
;
377 std::vector
<CCLayerImpl
*> m_renderSurfaceLayerListImpl
;
378 typename
Types::LayerIterator m_layerIteratorBegin
;
379 typename
Types::LayerIterator m_layerIterator
;
380 typename
Types::LayerType
* m_lastLayerVisited
;
381 std::vector
<scoped_refptr
<LayerChromium
> > m_replicaLayers
;
382 std::vector
<scoped_refptr
<LayerChromium
> > m_maskLayers
;
385 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
386 class ClassName##MainThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestMainThreadTypes, true> { \
388 ClassName##MainThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestMainThreadTypes, true>() { } \
390 TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
391 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
392 class ClassName##MainThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestMainThreadTypes, false> { \
394 ClassName##MainThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestMainThreadTypes, false>() { } \
396 TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
398 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
399 class ClassName##ImplThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestImplThreadTypes, true> { \
400 DebugScopedSetImplThread impl; \
402 ClassName##ImplThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestImplThreadTypes, true>() { } \
404 TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
405 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
406 class ClassName##ImplThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestImplThreadTypes, false> { \
407 DebugScopedSetImplThread impl; \
409 ClassName##ImplThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestImplThreadTypes, false>() { } \
411 TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
413 #define ALL_CCOCCLUSIONTRACKER_TEST(ClassName) \
414 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
415 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
416 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
417 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
419 #define MAIN_THREAD_TEST(ClassName) \
420 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
421 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName)
423 #define IMPL_THREAD_TEST(ClassName) \
424 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
425 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
427 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
428 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
429 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
430 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
431 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
433 template<class Types
, bool opaqueLayers
>
434 class CCOcclusionTrackerTestIdentityTransforms
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
438 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
439 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(30, 30), IntSize(500, 500), true);
440 this->calcDrawEtc(parent
);
442 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
443 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
445 this->visitLayer(layer
, occlusion
);
446 this->enterLayer(parent
, occlusion
);
448 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInScreenSpace().bounds());
449 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
450 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInTargetSurface().bounds());
451 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
453 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 30, 70, 70)));
454 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 30, 70, 70)));
455 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 29, 70, 70)));
456 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(31, 30, 70, 70)));
457 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 31, 70, 70)));
459 occlusion
.useDefaultLayerClipRect();
460 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 30, 70, 70)));
461 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 30, 70, 70)));
462 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 29, 70, 70)));
463 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(31, 30, 70, 70)));
464 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 31, 70, 70)));
465 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
467 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(30, 30, 70, 70)).isEmpty());
468 EXPECT_RECT_EQ(IntRect(29, 30, 1, 70), occlusion
.unoccludedContentRect(parent
, IntRect(29, 30, 70, 70)));
469 EXPECT_RECT_EQ(IntRect(29, 29, 70, 70), occlusion
.unoccludedContentRect(parent
, IntRect(29, 29, 70, 70)));
470 EXPECT_RECT_EQ(IntRect(30, 29, 70, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 29, 70, 70)));
471 EXPECT_RECT_EQ(IntRect(31, 29, 70, 70), occlusion
.unoccludedContentRect(parent
, IntRect(31, 29, 70, 70)));
472 EXPECT_RECT_EQ(IntRect(100, 30, 1, 70), occlusion
.unoccludedContentRect(parent
, IntRect(31, 30, 70, 70)));
473 EXPECT_RECT_EQ(IntRect(31, 31, 70, 70), occlusion
.unoccludedContentRect(parent
, IntRect(31, 31, 70, 70)));
474 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 31, 70, 70)));
475 EXPECT_RECT_EQ(IntRect(29, 31, 70, 70), occlusion
.unoccludedContentRect(parent
, IntRect(29, 31, 70, 70)));
479 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestIdentityTransforms
);
481 template<class Types
, bool opaqueLayers
>
482 class CCOcclusionTrackerTestRotatedChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
486 WebTransformationMatrix layerTransform
;
487 layerTransform
.translate(250, 250);
488 layerTransform
.rotate(90);
489 layerTransform
.translate(-250, -250);
491 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
492 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, layerTransform
, FloatPoint(30, 30), IntSize(500, 500), true);
493 this->calcDrawEtc(parent
);
495 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
496 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
498 this->visitLayer(layer
, occlusion
);
499 this->enterLayer(parent
, occlusion
);
501 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInScreenSpace().bounds());
502 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
503 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInTargetSurface().bounds());
504 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
506 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 30, 70, 70)));
507 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 30, 70, 70)));
508 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 29, 70, 70)));
509 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(31, 30, 70, 70)));
510 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 31, 70, 70)));
512 occlusion
.useDefaultLayerClipRect();
513 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 30, 70, 70)));
514 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 30, 70, 70)));
515 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 29, 70, 70)));
516 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(31, 30, 70, 70)));
517 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 31, 70, 70)));
518 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
520 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(30, 30, 70, 70)).isEmpty());
521 EXPECT_RECT_EQ(IntRect(29, 30, 1, 70), occlusion
.unoccludedContentRect(parent
, IntRect(29, 30, 70, 70)));
522 EXPECT_RECT_EQ(IntRect(29, 29, 70, 70), occlusion
.unoccludedContentRect(parent
, IntRect(29, 29, 70, 70)));
523 EXPECT_RECT_EQ(IntRect(30, 29, 70, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 29, 70, 70)));
524 EXPECT_RECT_EQ(IntRect(31, 29, 70, 70), occlusion
.unoccludedContentRect(parent
, IntRect(31, 29, 70, 70)));
525 EXPECT_RECT_EQ(IntRect(100, 30, 1, 70), occlusion
.unoccludedContentRect(parent
, IntRect(31, 30, 70, 70)));
526 EXPECT_RECT_EQ(IntRect(31, 31, 70, 70), occlusion
.unoccludedContentRect(parent
, IntRect(31, 31, 70, 70)));
527 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 31, 70, 70)));
528 EXPECT_RECT_EQ(IntRect(29, 31, 70, 70), occlusion
.unoccludedContentRect(parent
, IntRect(29, 31, 70, 70)));
532 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestRotatedChild
);
534 template<class Types
, bool opaqueLayers
>
535 class CCOcclusionTrackerTestTranslatedChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
539 WebTransformationMatrix layerTransform
;
540 layerTransform
.translate(20, 20);
542 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
543 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, layerTransform
, FloatPoint(30, 30), IntSize(500, 500), true);
544 this->calcDrawEtc(parent
);
546 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
547 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
549 this->visitLayer(layer
, occlusion
);
550 this->enterLayer(parent
, occlusion
);
552 EXPECT_RECT_EQ(IntRect(50, 50, 50, 50), occlusion
.occlusionInScreenSpace().bounds());
553 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
554 EXPECT_RECT_EQ(IntRect(50, 50, 50, 50), occlusion
.occlusionInTargetSurface().bounds());
555 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
557 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(50, 50, 50, 50)));
558 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(49, 50, 50, 50)));
559 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(50, 49, 50, 50)));
560 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(51, 50, 50, 50)));
561 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(50, 51, 50, 50)));
563 occlusion
.useDefaultLayerClipRect();
564 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(50, 50, 50, 50)));
565 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(49, 50, 50, 50)));
566 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(50, 49, 50, 50)));
567 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(51, 50, 50, 50)));
568 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(50, 51, 50, 50)));
569 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
571 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(50, 50, 50, 50)).isEmpty());
572 EXPECT_RECT_EQ(IntRect(49, 50, 1, 50), occlusion
.unoccludedContentRect(parent
, IntRect(49, 50, 50, 50)));
573 EXPECT_RECT_EQ(IntRect(49, 49, 50, 50), occlusion
.unoccludedContentRect(parent
, IntRect(49, 49, 50, 50)));
574 EXPECT_RECT_EQ(IntRect(50, 49, 50, 1), occlusion
.unoccludedContentRect(parent
, IntRect(50, 49, 50, 50)));
575 EXPECT_RECT_EQ(IntRect(51, 49, 50, 50), occlusion
.unoccludedContentRect(parent
, IntRect(51, 49, 50, 50)));
576 EXPECT_RECT_EQ(IntRect(100, 50, 1, 50), occlusion
.unoccludedContentRect(parent
, IntRect(51, 50, 50, 50)));
577 EXPECT_RECT_EQ(IntRect(51, 51, 50, 50), occlusion
.unoccludedContentRect(parent
, IntRect(51, 51, 50, 50)));
578 EXPECT_RECT_EQ(IntRect(50, 100, 50, 1), occlusion
.unoccludedContentRect(parent
, IntRect(50, 51, 50, 50)));
579 EXPECT_RECT_EQ(IntRect(49, 51, 50, 50), occlusion
.unoccludedContentRect(parent
, IntRect(49, 51, 50, 50)));
581 occlusion
.useDefaultLayerClipRect();
582 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(50, 50, 50, 50)).isEmpty());
583 EXPECT_RECT_EQ(IntRect(49, 50, 1, 50), occlusion
.unoccludedContentRect(parent
, IntRect(49, 50, 50, 50)));
584 EXPECT_RECT_EQ(IntRect(49, 49, 50, 50), occlusion
.unoccludedContentRect(parent
, IntRect(49, 49, 50, 50)));
585 EXPECT_RECT_EQ(IntRect(50, 49, 50, 1), occlusion
.unoccludedContentRect(parent
, IntRect(50, 49, 50, 50)));
586 EXPECT_RECT_EQ(IntRect(51, 49, 49, 1), occlusion
.unoccludedContentRect(parent
, IntRect(51, 49, 50, 50)));
587 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(51, 50, 50, 50)).isEmpty());
588 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(51, 51, 50, 50)).isEmpty());
589 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(50, 51, 50, 50)).isEmpty());
590 EXPECT_RECT_EQ(IntRect(49, 51, 1, 49), occlusion
.unoccludedContentRect(parent
, IntRect(49, 51, 50, 50)));
591 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
595 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTranslatedChild
);
597 template<class Types
, bool opaqueLayers
>
598 class CCOcclusionTrackerTestChildInRotatedChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
602 WebTransformationMatrix childTransform
;
603 childTransform
.translate(250, 250);
604 childTransform
.rotate(90);
605 childTransform
.translate(-250, -250);
607 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
608 parent
->setMasksToBounds(true);
609 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, FloatPoint(30, 30), IntSize(500, 500));
610 child
->setMasksToBounds(true);
611 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, this->identityMatrix
, FloatPoint(10, 10), IntSize(500, 500), true);
612 this->calcDrawEtc(parent
);
614 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
615 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
617 this->visitLayer(layer
, occlusion
);
618 this->enterContributingSurface(child
, occlusion
);
620 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion
.occlusionInScreenSpace().bounds());
621 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
622 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion
.occlusionInTargetSurface().bounds());
623 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
625 this->leaveContributingSurface(child
, occlusion
);
626 this->enterLayer(parent
, occlusion
);
628 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion
.occlusionInScreenSpace().bounds());
629 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
630 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion
.occlusionInTargetSurface().bounds());
631 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
633 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 40, 70, 60)));
634 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 40, 70, 60)));
635 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 39, 70, 60)));
636 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(31, 40, 70, 60)));
637 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 41, 70, 60)));
639 occlusion
.useDefaultLayerClipRect();
640 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 40, 70, 60)));
641 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 40, 70, 60)));
642 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 39, 70, 60)));
643 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(31, 40, 70, 60)));
644 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 41, 70, 60)));
645 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
648 /* Justification for the above occlusion from |layer|:
650 +---------------------+ +---------------------+
651 | | | |30 Visible region of |layer|: /////
652 | 30 | rotate(90) | |
653 | 30 + ---------------------------------+ | +---------------------------------+
654 100 | | 10 | | ==> | | |10 |
655 | |10+---------------------------------+ | +---------------------------------+ |
656 | | | | | | | | |///////////////| 420 | |
657 | | | | | | | | |///////////////|60 | |
658 | | | | | | | | |///////////////| | |
659 +----|--|-------------+ | | +--|--|---------------+ | |
660 | | | | 20|10| 70 | |
667 +--|-------------------------------+ | | +------------------------------|--+
669 +---------------------------------+ +---------------------------------+
675 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestChildInRotatedChild
);
677 template<class Types
, bool opaqueLayers
>
678 class CCOcclusionTrackerTestVisitTargetTwoTimes
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
682 WebTransformationMatrix childTransform
;
683 childTransform
.translate(250, 250);
684 childTransform
.rotate(90);
685 childTransform
.translate(-250, -250);
687 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
688 parent
->setMasksToBounds(true);
689 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, FloatPoint(30, 30), IntSize(500, 500));
690 child
->setMasksToBounds(true);
691 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, this->identityMatrix
, FloatPoint(10, 10), IntSize(500, 500), true);
692 // |child2| makes |parent|'s surface get considered by CCOcclusionTracker first, instead of |child|'s. This exercises different code in
693 // leaveToTargetRenderSurface, as the target surface has already been seen.
694 typename
Types::ContentLayerType
* child2
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(30, 30), IntSize(60, 20), true);
695 this->calcDrawEtc(parent
);
697 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
698 occlusion
.setLayerClipRect(IntRect(-10, -10, 1000, 1000));
700 this->visitLayer(child2
, occlusion
);
702 EXPECT_RECT_EQ(IntRect(30, 30, 60, 20), occlusion
.occlusionInScreenSpace().bounds());
703 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
704 EXPECT_RECT_EQ(IntRect(30, 30, 60, 20), occlusion
.occlusionInTargetSurface().bounds());
705 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
707 this->visitLayer(layer
, occlusion
);
709 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInScreenSpace().bounds());
710 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
711 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion
.occlusionInTargetSurface().bounds());
712 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
714 this->enterContributingSurface(child
, occlusion
);
716 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInScreenSpace().bounds());
717 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
718 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion
.occlusionInTargetSurface().bounds());
719 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
721 // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
722 this->leaveContributingSurface(child
, occlusion
);
723 this->enterLayer(parent
, occlusion
);
725 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInScreenSpace().bounds());
726 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
727 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInTargetSurface().bounds());
728 EXPECT_EQ(2u, occlusion
.occlusionInTargetSurface().rects().size());
730 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 30, 70, 70)));
731 EXPECT_RECT_EQ(IntRect(90, 30, 10, 10), occlusion
.unoccludedContentRect(parent
, IntRect(30, 30, 70, 70)));
733 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 30, 60, 10)));
734 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 30, 60, 10)));
735 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 29, 60, 10)));
736 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(31, 30, 60, 10)));
737 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 31, 60, 10)));
739 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 40, 70, 60)));
740 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 40, 70, 60)));
741 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 39, 70, 60)));
743 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(30, 30, 60, 10)).isEmpty());
744 EXPECT_RECT_EQ(IntRect(29, 30, 1, 10), occlusion
.unoccludedContentRect(parent
, IntRect(29, 30, 60, 10)));
745 EXPECT_RECT_EQ(IntRect(30, 29, 60, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 29, 60, 10)));
746 EXPECT_RECT_EQ(IntRect(90, 30, 1, 10), occlusion
.unoccludedContentRect(parent
, IntRect(31, 30, 60, 10)));
747 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(30, 31, 60, 10)).isEmpty());
749 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(30, 40, 70, 60)).isEmpty());
750 EXPECT_RECT_EQ(IntRect(29, 40, 1, 60), occlusion
.unoccludedContentRect(parent
, IntRect(29, 40, 70, 60)));
751 // This rect is mostly occluded by |child2|.
752 EXPECT_RECT_EQ(IntRect(90, 39, 10, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 39, 70, 60)));
753 // This rect extends past top/right ends of |child2|.
754 EXPECT_RECT_EQ(IntRect(30, 29, 70, 11), occlusion
.unoccludedContentRect(parent
, IntRect(30, 29, 70, 70)));
755 // This rect extends past left/right ends of |child2|.
756 EXPECT_RECT_EQ(IntRect(20, 39, 80, 60), occlusion
.unoccludedContentRect(parent
, IntRect(20, 39, 80, 60)));
757 EXPECT_RECT_EQ(IntRect(100, 40, 1, 60), occlusion
.unoccludedContentRect(parent
, IntRect(31, 40, 70, 60)));
758 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 41, 70, 60)));
760 /* Justification for the above occlusion from |layer|:
762 +---------------------+ +---------------------+
763 | | | |30 Visible region of |layer|: /////
764 | 30 | rotate(90) | 30 60 | |child2|: \\\\\
765 | 30 + ------------+--------------------+ | 30 +------------+--------------------+
766 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
767 | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
768 | + ------------+ | | | | | +------------+//| 420 | |
769 | | | | | | | | |///////////////|60 | |
770 | | | | | | | | |///////////////| | |
771 +----|--|-------------+ | | +--|--|---------------+ | |
772 | | | | 20|10| 70 | |
779 +--|-------------------------------+ | | +------------------------------|--+
781 +---------------------------------+ +---------------------------------+
787 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestVisitTargetTwoTimes
);
789 template<class Types
, bool opaqueLayers
>
790 class CCOcclusionTrackerTestSurfaceRotatedOffAxis
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
794 WebTransformationMatrix childTransform
;
795 childTransform
.translate(250, 250);
796 childTransform
.rotate(95);
797 childTransform
.translate(-250, -250);
799 WebTransformationMatrix layerTransform
;
800 layerTransform
.translate(10, 10);
802 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
803 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, FloatPoint(30, 30), IntSize(500, 500));
804 child
->setMasksToBounds(true);
805 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(child
, layerTransform
, FloatPoint(0, 0), IntSize(500, 500), true);
806 this->calcDrawEtc(parent
);
808 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
809 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
811 IntRect clippedLayerInChild
= CCMathUtil::mapClippedRect(layerTransform
, layer
->visibleContentRect());
813 this->visitLayer(layer
, occlusion
);
814 this->enterContributingSurface(child
, occlusion
);
816 EXPECT_RECT_EQ(IntRect(), occlusion
.occlusionInScreenSpace().bounds());
817 EXPECT_EQ(0u, occlusion
.occlusionInScreenSpace().rects().size());
818 EXPECT_RECT_EQ(clippedLayerInChild
, occlusion
.occlusionInTargetSurface().bounds());
819 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
821 EXPECT_TRUE(occlusion
.occluded(child
, clippedLayerInChild
));
822 EXPECT_TRUE(occlusion
.unoccludedContentRect(child
, clippedLayerInChild
).isEmpty());
823 clippedLayerInChild
.move(-1, 0);
824 EXPECT_FALSE(occlusion
.occluded(child
, clippedLayerInChild
));
825 EXPECT_FALSE(occlusion
.unoccludedContentRect(child
, clippedLayerInChild
).isEmpty());
826 clippedLayerInChild
.move(1, 0);
827 clippedLayerInChild
.move(1, 0);
828 EXPECT_FALSE(occlusion
.occluded(child
, clippedLayerInChild
));
829 EXPECT_FALSE(occlusion
.unoccludedContentRect(child
, clippedLayerInChild
).isEmpty());
830 clippedLayerInChild
.move(-1, 0);
831 clippedLayerInChild
.move(0, -1);
832 EXPECT_FALSE(occlusion
.occluded(child
, clippedLayerInChild
));
833 EXPECT_FALSE(occlusion
.unoccludedContentRect(child
, clippedLayerInChild
).isEmpty());
834 clippedLayerInChild
.move(0, 1);
835 clippedLayerInChild
.move(0, 1);
836 EXPECT_FALSE(occlusion
.occluded(child
, clippedLayerInChild
));
837 EXPECT_FALSE(occlusion
.unoccludedContentRect(child
, clippedLayerInChild
).isEmpty());
838 clippedLayerInChild
.move(0, -1);
840 this->leaveContributingSurface(child
, occlusion
);
841 this->enterLayer(parent
, occlusion
);
843 EXPECT_RECT_EQ(IntRect(), occlusion
.occlusionInScreenSpace().bounds());
844 EXPECT_EQ(0u, occlusion
.occlusionInScreenSpace().rects().size());
845 EXPECT_RECT_EQ(IntRect(), occlusion
.occlusionInTargetSurface().bounds());
846 EXPECT_EQ(0u, occlusion
.occlusionInTargetSurface().rects().size());
848 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(75, 55, 1, 1)));
849 EXPECT_RECT_EQ(IntRect(75, 55, 1, 1), occlusion
.unoccludedContentRect(parent
, IntRect(75, 55, 1, 1)));
853 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceRotatedOffAxis
);
855 template<class Types
, bool opaqueLayers
>
856 class CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
860 WebTransformationMatrix childTransform
;
861 childTransform
.translate(250, 250);
862 childTransform
.rotate(90);
863 childTransform
.translate(-250, -250);
865 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
866 parent
->setMasksToBounds(true);
867 typename
Types::LayerType
* child
= this->createLayer(parent
, childTransform
, FloatPoint(30, 30), IntSize(500, 500));
868 child
->setMasksToBounds(true);
869 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child
, this->identityMatrix
, FloatPoint(10, 10), IntSize(500, 500), true);
870 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child
, this->identityMatrix
, FloatPoint(10, 450), IntSize(500, 60), true);
871 this->calcDrawEtc(parent
);
873 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
874 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
876 this->visitLayer(layer2
, occlusion
);
877 this->visitLayer(layer1
, occlusion
);
878 this->enterContributingSurface(child
, occlusion
);
880 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion
.occlusionInScreenSpace().bounds());
881 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
882 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion
.occlusionInTargetSurface().bounds());
883 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
885 EXPECT_TRUE(occlusion
.occluded(child
, IntRect(10, 430, 60, 70)));
886 EXPECT_FALSE(occlusion
.occluded(child
, IntRect(9, 430, 60, 70)));
887 EXPECT_FALSE(occlusion
.occluded(child
, IntRect(10, 429, 60, 70)));
888 EXPECT_FALSE(occlusion
.occluded(child
, IntRect(11, 430, 60, 70)));
889 EXPECT_FALSE(occlusion
.occluded(child
, IntRect(10, 431, 60, 70)));
891 EXPECT_TRUE(occlusion
.unoccludedContentRect(child
, IntRect(10, 430, 60, 70)).isEmpty());
892 EXPECT_RECT_EQ(IntRect(9, 430, 1, 70), occlusion
.unoccludedContentRect(child
, IntRect(9, 430, 60, 70)));
893 EXPECT_RECT_EQ(IntRect(10, 429, 60, 1), occlusion
.unoccludedContentRect(child
, IntRect(10, 429, 60, 70)));
894 EXPECT_RECT_EQ(IntRect(70, 430, 1, 70), occlusion
.unoccludedContentRect(child
, IntRect(11, 430, 60, 70)));
895 EXPECT_RECT_EQ(IntRect(10, 500, 60, 1), occlusion
.unoccludedContentRect(child
, IntRect(10, 431, 60, 70)));
897 this->leaveContributingSurface(child
, occlusion
);
898 this->enterLayer(parent
, occlusion
);
900 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion
.occlusionInScreenSpace().bounds());
901 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
902 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion
.occlusionInTargetSurface().bounds());
903 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
905 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 40, 70, 60)));
906 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 40, 70, 60)));
907 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 39, 70, 60)));
909 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(30, 40, 70, 60)).isEmpty());
910 EXPECT_RECT_EQ(IntRect(29, 40, 1, 60), occlusion
.unoccludedContentRect(parent
, IntRect(29, 40, 70, 60)));
911 EXPECT_RECT_EQ(IntRect(30, 39, 70, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 39, 70, 60)));
912 EXPECT_RECT_EQ(IntRect(100, 40, 1, 60), occlusion
.unoccludedContentRect(parent
, IntRect(31, 40, 70, 60)));
913 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion
.unoccludedContentRect(parent
, IntRect(30, 41, 70, 60)));
915 /* Justification for the above occlusion from |layer1| and |layer2|:
917 +---------------------+
918 | |30 Visible region of |layer1|: /////
919 | | Visible region of |layer2|: \\\\\
920 | +---------------------------------+
922 | +---------------+-----------------+ |
923 | | |\\\\\\\\\\\\|//| 420 | |
924 | | |\\\\\\\\\\\\|//|60 | |
925 | | |\\\\\\\\\\\\|//| | |
926 +--|--|------------|--+ | |
934 | +------------|-----------------|--+
936 +---------------+-----------------+
942 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren
);
944 template<class Types
, bool opaqueLayers
>
945 class CCOcclusionTrackerTestOverlappingSurfaceSiblings
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
949 WebTransformationMatrix childTransform
;
950 childTransform
.translate(250, 250);
951 childTransform
.rotate(90);
952 childTransform
.translate(-250, -250);
954 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
955 parent
->setMasksToBounds(true);
956 typename
Types::LayerType
* child1
= this->createSurface(parent
, childTransform
, FloatPoint(30, 30), IntSize(10, 10));
957 typename
Types::LayerType
* child2
= this->createSurface(parent
, childTransform
, FloatPoint(20, 40), IntSize(10, 10));
958 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child1
, this->identityMatrix
, FloatPoint(-10, -10), IntSize(510, 510), true);
959 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child2
, this->identityMatrix
, FloatPoint(-10, -10), IntSize(510, 510), true);
960 this->calcDrawEtc(parent
);
962 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
963 occlusion
.setLayerClipRect(IntRect(-20, -20, 1000, 1000));
965 this->visitLayer(layer2
, occlusion
);
966 this->enterContributingSurface(child2
, occlusion
);
968 EXPECT_RECT_EQ(IntRect(20, 30, 80, 70), occlusion
.occlusionInScreenSpace().bounds());
969 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
970 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion
.occlusionInTargetSurface().bounds());
971 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
973 EXPECT_TRUE(occlusion
.occluded(child2
, IntRect(-10, 420, 70, 80)));
974 EXPECT_FALSE(occlusion
.occluded(child2
, IntRect(-11, 420, 70, 80)));
975 EXPECT_FALSE(occlusion
.occluded(child2
, IntRect(-10, 419, 70, 80)));
976 EXPECT_FALSE(occlusion
.occluded(child2
, IntRect(-10, 420, 71, 80)));
977 EXPECT_FALSE(occlusion
.occluded(child2
, IntRect(-10, 420, 70, 81)));
979 occlusion
.useDefaultLayerClipRect();
980 EXPECT_TRUE(occlusion
.occluded(child2
, IntRect(-10, 420, 70, 80)));
981 EXPECT_TRUE(occlusion
.occluded(child2
, IntRect(-11, 420, 70, 80)));
982 EXPECT_TRUE(occlusion
.occluded(child2
, IntRect(-10, 419, 70, 80)));
983 EXPECT_TRUE(occlusion
.occluded(child2
, IntRect(-10, 420, 71, 80)));
984 EXPECT_TRUE(occlusion
.occluded(child2
, IntRect(-10, 420, 70, 81)));
985 occlusion
.setLayerClipRect(IntRect(-20, -20, 1000, 1000));
987 // There is nothing above child2's surface in the z-order.
988 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion
.unoccludedContributingSurfaceContentRect(child2
, false, IntRect(-10, 420, 70, 80)));
990 this->leaveContributingSurface(child2
, occlusion
);
991 this->visitLayer(layer1
, occlusion
);
992 this->enterContributingSurface(child1
, occlusion
);
994 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion
.occlusionInScreenSpace().bounds());
995 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
996 EXPECT_RECT_EQ(IntRect(-10, 430, 80, 70), occlusion
.occlusionInTargetSurface().bounds());
997 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
999 EXPECT_TRUE(occlusion
.occluded(child1
, IntRect(-10, 430, 80, 70)));
1000 EXPECT_FALSE(occlusion
.occluded(child1
, IntRect(-11, 430, 80, 70)));
1001 EXPECT_FALSE(occlusion
.occluded(child1
, IntRect(-10, 429, 80, 70)));
1002 EXPECT_FALSE(occlusion
.occluded(child1
, IntRect(-10, 430, 81, 70)));
1003 EXPECT_FALSE(occlusion
.occluded(child1
, IntRect(-10, 430, 80, 71)));
1005 // child2's contents will occlude child1 below it.
1006 EXPECT_RECT_EQ(IntRect(-10, 430, 10, 70), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, IntRect(-10, 430, 80, 70)));
1008 this->leaveContributingSurface(child1
, occlusion
);
1009 this->enterLayer(parent
, occlusion
);
1011 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion
.occlusionInScreenSpace().bounds());
1012 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
1013 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion
.occlusionInTargetSurface().bounds());
1014 EXPECT_EQ(2u, occlusion
.occlusionInTargetSurface().rects().size());
1016 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(20, 20, 80, 80)));
1018 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(30, 20, 70, 80)));
1019 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(29, 20, 70, 80)));
1020 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(30, 19, 70, 80)));
1022 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(20, 30, 80, 70)));
1023 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(19, 30, 80, 70)));
1024 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(20, 29, 80, 70)));
1026 /* Justification for the above occlusion:
1028 +---------------------+
1030 | 30+ ---------------------------------+
1031 100 | 30| | layer2 |
1032 |20+----------------------------------+ |
1036 +--|-|----------------+ | |
1044 | +--------------------------------|-+
1046 +----------------------------------+
1052 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblings
);
1054 template<class Types
, bool opaqueLayers
>
1055 class CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1059 WebTransformationMatrix child1Transform
;
1060 child1Transform
.translate(250, 250);
1061 child1Transform
.rotate(-90);
1062 child1Transform
.translate(-250, -250);
1064 WebTransformationMatrix child2Transform
;
1065 child2Transform
.translate(250, 250);
1066 child2Transform
.rotate(90);
1067 child2Transform
.translate(-250, -250);
1069 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
1070 parent
->setMasksToBounds(true);
1071 typename
Types::LayerType
* child1
= this->createSurface(parent
, child1Transform
, FloatPoint(30, 20), IntSize(10, 10));
1072 typename
Types::LayerType
* child2
= this->createDrawingSurface(parent
, child2Transform
, FloatPoint(20, 40), IntSize(10, 10), false);
1073 typename
Types::ContentLayerType
* layer1
= this->createDrawingLayer(child1
, this->identityMatrix
, FloatPoint(-10, -20), IntSize(510, 510), true);
1074 typename
Types::ContentLayerType
* layer2
= this->createDrawingLayer(child2
, this->identityMatrix
, FloatPoint(-10, -10), IntSize(510, 510), true);
1075 this->calcDrawEtc(parent
);
1077 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1078 occlusion
.setLayerClipRect(IntRect(-30, -30, 1000, 1000));
1080 this->visitLayer(layer2
, occlusion
);
1081 this->enterLayer(child2
, occlusion
);
1083 EXPECT_RECT_EQ(IntRect(20, 30, 80, 70), occlusion
.occlusionInScreenSpace().bounds());
1084 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1085 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion
.occlusionInTargetSurface().bounds());
1086 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1088 EXPECT_TRUE(occlusion
.occluded(child2
, IntRect(-10, 420, 70, 80)));
1089 EXPECT_FALSE(occlusion
.occluded(child2
, IntRect(-11, 420, 70, 80)));
1090 EXPECT_FALSE(occlusion
.occluded(child2
, IntRect(-10, 419, 70, 80)));
1091 EXPECT_FALSE(occlusion
.occluded(child2
, IntRect(-10, 420, 71, 80)));
1092 EXPECT_FALSE(occlusion
.occluded(child2
, IntRect(-10, 420, 70, 81)));
1094 this->leaveLayer(child2
, occlusion
);
1095 this->enterContributingSurface(child2
, occlusion
);
1097 // There is nothing above child2's surface in the z-order.
1098 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion
.unoccludedContributingSurfaceContentRect(child2
, false, IntRect(-10, 420, 70, 80)));
1100 this->leaveContributingSurface(child2
, occlusion
);
1101 this->visitLayer(layer1
, occlusion
);
1102 this->enterContributingSurface(child1
, occlusion
);
1104 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion
.occlusionInScreenSpace().bounds());
1105 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1106 EXPECT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion
.occlusionInTargetSurface().bounds());
1107 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1109 EXPECT_TRUE(occlusion
.occluded(child1
, IntRect(420, -20, 80, 90)));
1110 EXPECT_FALSE(occlusion
.occluded(child1
, IntRect(419, -20, 80, 90)));
1111 EXPECT_FALSE(occlusion
.occluded(child1
, IntRect(420, -21, 80, 90)));
1112 EXPECT_FALSE(occlusion
.occluded(child1
, IntRect(420, -19, 80, 90)));
1113 EXPECT_FALSE(occlusion
.occluded(child1
, IntRect(421, -20, 80, 90)));
1115 // child2's contents will occlude child1 below it.
1116 EXPECT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, IntRect(420, -20, 80, 90)));
1117 EXPECT_RECT_EQ(IntRect(490, -10, 10, 80), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, IntRect(420, -10, 80, 90)));
1118 EXPECT_RECT_EQ(IntRect(420, -20, 70, 10), occlusion
.unoccludedContributingSurfaceContentRect(child1
, false, IntRect(420, -20, 70, 90)));
1120 this->leaveContributingSurface(child1
, occlusion
);
1121 this->enterLayer(parent
, occlusion
);
1123 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion
.occlusionInScreenSpace().bounds());
1124 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1125 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion
.occlusionInTargetSurface().bounds());
1126 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1128 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(10, 20, 90, 80)));
1129 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(9, 20, 90, 80)));
1130 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(10, 19, 90, 80)));
1131 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(11, 20, 90, 80)));
1132 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(10, 21, 90, 80)));
1134 /* Justification for the above occlusion:
1136 +---------------------+
1138 10+----------------------------------+
1139 100 || 30 | layer2 |
1140 |20+----------------------------------+
1144 +|-|------------------+ | |
1152 +----------------------------------+ |
1154 +----------------------------------+
1160 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
);
1162 template<class Types
, bool opaqueLayers
>
1163 class CCOcclusionTrackerTestFilters
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1167 WebTransformationMatrix layerTransform
;
1168 layerTransform
.translate(250, 250);
1169 layerTransform
.rotate(90);
1170 layerTransform
.translate(-250, -250);
1172 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
1173 parent
->setMasksToBounds(true);
1174 typename
Types::ContentLayerType
* blurLayer
= this->createDrawingLayer(parent
, layerTransform
, FloatPoint(30, 30), IntSize(500, 500), true);
1175 typename
Types::ContentLayerType
* opaqueLayer
= this->createDrawingLayer(parent
, layerTransform
, FloatPoint(30, 30), IntSize(500, 500), true);
1176 typename
Types::ContentLayerType
* opacityLayer
= this->createDrawingLayer(parent
, layerTransform
, FloatPoint(30, 30), IntSize(500, 500), true);
1178 WebFilterOperations filters
;
1179 filters
.append(WebFilterOperation::createBlurFilter(10));
1180 blurLayer
->setFilters(filters
);
1183 filters
.append(WebFilterOperation::createGrayscaleFilter(0.5));
1184 opaqueLayer
->setFilters(filters
);
1187 filters
.append(WebFilterOperation::createOpacityFilter(0.5));
1188 opacityLayer
->setFilters(filters
);
1190 this->calcDrawEtc(parent
);
1192 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1193 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1195 // Opacity layer won't contribute to occlusion.
1196 this->visitLayer(opacityLayer
, occlusion
);
1197 this->enterContributingSurface(opacityLayer
, occlusion
);
1199 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().isEmpty());
1200 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().isEmpty());
1202 // And has nothing to contribute to its parent surface.
1203 this->leaveContributingSurface(opacityLayer
, occlusion
);
1204 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().isEmpty());
1205 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().isEmpty());
1207 // Opaque layer will contribute to occlusion.
1208 this->visitLayer(opaqueLayer
, occlusion
);
1209 this->enterContributingSurface(opaqueLayer
, occlusion
);
1211 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInScreenSpace().bounds());
1212 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1213 EXPECT_RECT_EQ(IntRect(0, 430, 70, 70), occlusion
.occlusionInTargetSurface().bounds());
1214 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1216 // And it gets translated to the parent surface.
1217 this->leaveContributingSurface(opaqueLayer
, occlusion
);
1218 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInScreenSpace().bounds());
1219 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1220 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInTargetSurface().bounds());
1221 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1223 // The blur layer needs to throw away any occlusion from outside its subtree.
1224 this->enterLayer(blurLayer
, occlusion
);
1225 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().isEmpty());
1226 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().isEmpty());
1228 // And it won't contribute to occlusion.
1229 this->leaveLayer(blurLayer
, occlusion
);
1230 this->enterContributingSurface(blurLayer
, occlusion
);
1231 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().isEmpty());
1232 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().isEmpty());
1234 // But the opaque layer's occlusion is preserved on the parent.
1235 this->leaveContributingSurface(blurLayer
, occlusion
);
1236 this->enterLayer(parent
, occlusion
);
1237 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInScreenSpace().bounds());
1238 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1239 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion
.occlusionInTargetSurface().bounds());
1240 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1244 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestFilters
);
1246 template<class Types
, bool opaqueLayers
>
1247 class CCOcclusionTrackerTestReplicaDoesOcclude
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1251 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 200));
1252 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 100), IntSize(50, 50), true);
1253 this->createReplicaLayer(surface
, this->identityMatrix
, FloatPoint(50, 50), IntSize());
1254 this->calcDrawEtc(parent
);
1256 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1257 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1259 this->visitLayer(surface
, occlusion
);
1261 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion
.occlusionInScreenSpace().bounds());
1262 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1263 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion
.occlusionInTargetSurface().bounds());
1264 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1266 this->visitContributingSurface(surface
, occlusion
);
1267 this->enterLayer(parent
, occlusion
);
1269 // The surface and replica should both be occluding the parent.
1270 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion
.occlusionInTargetSurface().bounds());
1271 EXPECT_EQ(2u, occlusion
.occlusionInTargetSurface().rects().size());
1275 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaDoesOcclude
);
1277 template<class Types
, bool opaqueLayers
>
1278 class CCOcclusionTrackerTestReplicaWithClipping
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1282 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 170));
1283 parent
->setMasksToBounds(true);
1284 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 100), IntSize(50, 50), true);
1285 this->createReplicaLayer(surface
, this->identityMatrix
, FloatPoint(50, 50), IntSize());
1286 this->calcDrawEtc(parent
);
1288 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1289 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1291 this->visitLayer(surface
, occlusion
);
1293 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion
.occlusionInScreenSpace().bounds());
1294 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1295 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion
.occlusionInTargetSurface().bounds());
1296 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1298 this->visitContributingSurface(surface
, occlusion
);
1299 this->enterLayer(parent
, occlusion
);
1301 // The surface and replica should both be occluding the parent.
1302 EXPECT_RECT_EQ(IntRect(0, 100, 100, 70), occlusion
.occlusionInTargetSurface().bounds());
1303 EXPECT_EQ(2u, occlusion
.occlusionInTargetSurface().rects().size());
1307 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithClipping
);
1309 template<class Types
, bool opaqueLayers
>
1310 class CCOcclusionTrackerTestReplicaWithMask
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1314 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 200));
1315 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 100), IntSize(50, 50), true);
1316 typename
Types::LayerType
* replica
= this->createReplicaLayer(surface
, this->identityMatrix
, FloatPoint(50, 50), IntSize());
1317 this->createMaskLayer(replica
, IntSize(10, 10));
1318 this->calcDrawEtc(parent
);
1320 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1321 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1323 this->visitLayer(surface
, occlusion
);
1325 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion
.occlusionInScreenSpace().bounds());
1326 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1327 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion
.occlusionInTargetSurface().bounds());
1328 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1330 this->visitContributingSurface(surface
, occlusion
);
1331 this->enterLayer(parent
, occlusion
);
1333 // The replica should not be occluding the parent, since it has a mask applied to it.
1334 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion
.occlusionInTargetSurface().bounds());
1335 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1339 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithMask
);
1341 template<class Types
, bool opaqueLayers
>
1342 class CCOcclusionTrackerTestLayerClipRectOutsideChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1346 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1347 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1348 this->calcDrawEtc(parent
);
1350 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1351 occlusion
.setLayerClipRect(IntRect(200, 100, 100, 100));
1353 this->enterLayer(layer
, occlusion
);
1355 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1356 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1357 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1358 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1359 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(200, 100, 100, 100)));
1361 occlusion
.useDefaultLayerClipRect();
1362 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(200, 100, 100, 100)));
1363 occlusion
.setLayerClipRect(IntRect(200, 100, 100, 100));
1365 this->leaveLayer(layer
, occlusion
);
1366 this->visitContributingSurface(layer
, occlusion
);
1367 this->enterLayer(parent
, occlusion
);
1369 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 0, 100, 100)));
1370 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1371 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 0, 100, 100)));
1372 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1373 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 100, 100, 100)));
1374 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 0, 100, 100)));
1375 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 200, 100, 100)));
1376 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 200, 100, 100)));
1377 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1379 EXPECT_RECT_EQ(IntRect(200, 100, 100, 100), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
1383 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOutsideChild
);
1385 template<class Types
, bool opaqueLayers
>
1386 class CCOcclusionTrackerTestViewportRectOutsideChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1390 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1391 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1392 this->calcDrawEtc(parent
);
1394 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(200, 100, 100, 100));
1395 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1397 this->enterLayer(layer
, occlusion
);
1399 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1400 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1401 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1402 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1403 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(200, 100, 100, 100)));
1405 occlusion
.useDefaultLayerClipRect();
1406 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(200, 100, 100, 100)));
1407 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1409 this->leaveLayer(layer
, occlusion
);
1410 this->visitContributingSurface(layer
, occlusion
);
1411 this->enterLayer(parent
, occlusion
);
1413 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 0, 100, 100)));
1414 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1415 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 0, 100, 100)));
1416 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1417 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 100, 100, 100)));
1418 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 0, 100, 100)));
1419 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 200, 100, 100)));
1420 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 200, 100, 100)));
1421 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1423 EXPECT_RECT_EQ(IntRect(200, 100, 100, 100), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
1427 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOutsideChild
);
1429 template<class Types
, bool opaqueLayers
>
1430 class CCOcclusionTrackerTestLayerClipRectOverChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1434 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1435 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1436 this->calcDrawEtc(parent
);
1438 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1439 occlusion
.setLayerClipRect(IntRect(100, 100, 100, 100));
1441 this->enterLayer(layer
, occlusion
);
1443 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1444 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1445 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1446 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1448 this->leaveLayer(layer
, occlusion
);
1449 this->visitContributingSurface(layer
, occlusion
);
1450 this->enterLayer(parent
, occlusion
);
1452 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 0, 100, 100)));
1453 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1454 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 0, 100, 100)));
1455 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1456 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 100, 100, 100)));
1457 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 0, 100, 100)));
1458 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 200, 100, 100)));
1459 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 200, 100, 100)));
1460 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1462 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)).isEmpty());
1466 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOverChild
);
1468 template<class Types
, bool opaqueLayers
>
1469 class CCOcclusionTrackerTestViewportRectOverChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1473 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1474 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1475 this->calcDrawEtc(parent
);
1477 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(100, 100, 100, 100));
1478 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1480 this->enterLayer(layer
, occlusion
);
1482 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1483 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1484 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1485 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1487 this->leaveLayer(layer
, occlusion
);
1488 this->visitContributingSurface(layer
, occlusion
);
1489 this->enterLayer(parent
, occlusion
);
1491 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 0, 100, 100)));
1492 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1493 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 0, 100, 100)));
1494 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1495 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 100, 100, 100)));
1496 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 0, 100, 100)));
1497 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 200, 100, 100)));
1498 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 200, 100, 100)));
1499 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1501 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)).isEmpty());
1505 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOverChild
);
1507 template<class Types
, bool opaqueLayers
>
1508 class CCOcclusionTrackerTestLayerClipRectPartlyOverChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1512 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1513 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1514 this->calcDrawEtc(parent
);
1516 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1517 occlusion
.setLayerClipRect(IntRect(50, 50, 200, 200));
1519 this->enterLayer(layer
, occlusion
);
1521 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1522 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1523 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1524 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1526 this->leaveLayer(layer
, occlusion
);
1527 this->visitContributingSurface(layer
, occlusion
);
1528 this->enterLayer(parent
, occlusion
);
1530 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 0, 100, 100)));
1531 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1532 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 0, 100, 100)));
1533 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1534 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 100, 100, 100)));
1535 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 0, 100, 100)));
1536 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(0, 200, 100, 100)));
1537 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(100, 200, 100, 100)));
1538 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1540 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
1541 EXPECT_RECT_EQ(IntRect(200, 50, 50, 50), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 100)));
1542 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion
.unoccludedContentRect(parent
, IntRect(0, 100, 300, 100)));
1543 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion
.unoccludedContentRect(parent
, IntRect(200, 100, 100, 100)));
1544 EXPECT_RECT_EQ(IntRect(100, 200, 100, 50), occlusion
.unoccludedContentRect(parent
, IntRect(100, 200, 100, 100)));
1548 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectPartlyOverChild
);
1550 template<class Types
, bool opaqueLayers
>
1551 class CCOcclusionTrackerTestViewportRectPartlyOverChild
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1555 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1556 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1557 this->calcDrawEtc(parent
);
1559 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(50, 50, 200, 200));
1560 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1562 this->enterLayer(layer
, occlusion
);
1564 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1565 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1566 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1567 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1569 this->leaveLayer(layer
, occlusion
);
1570 this->visitContributingSurface(layer
, occlusion
);
1571 this->enterLayer(parent
, occlusion
);
1573 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 0, 100, 100)));
1574 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1575 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 0, 100, 100)));
1576 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1577 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 100, 100, 100)));
1578 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 0, 100, 100)));
1579 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(0, 200, 100, 100)));
1580 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(100, 200, 100, 100)));
1581 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1583 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
1584 EXPECT_RECT_EQ(IntRect(200, 50, 50, 50), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 100)));
1585 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion
.unoccludedContentRect(parent
, IntRect(0, 100, 300, 100)));
1586 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion
.unoccludedContentRect(parent
, IntRect(200, 100, 100, 100)));
1587 EXPECT_RECT_EQ(IntRect(100, 200, 100, 50), occlusion
.unoccludedContentRect(parent
, IntRect(100, 200, 100, 100)));
1591 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectPartlyOverChild
);
1593 template<class Types
, bool opaqueLayers
>
1594 class CCOcclusionTrackerTestLayerClipRectOverNothing
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1598 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1599 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1600 this->calcDrawEtc(parent
);
1602 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1603 occlusion
.setLayerClipRect(IntRect(500, 500, 100, 100));
1605 this->enterLayer(layer
, occlusion
);
1607 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1608 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1609 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1610 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1612 this->leaveLayer(layer
, occlusion
);
1613 this->visitContributingSurface(layer
, occlusion
);
1614 this->enterLayer(parent
, occlusion
);
1616 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 0, 100, 100)));
1617 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1618 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 0, 100, 100)));
1619 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1620 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 100, 100, 100)));
1621 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 0, 100, 100)));
1622 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 200, 100, 100)));
1623 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 200, 100, 100)));
1624 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1626 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)).isEmpty());
1627 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 100)).isEmpty());
1628 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(0, 100, 300, 100)).isEmpty());
1629 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(200, 100, 100, 100)).isEmpty());
1630 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(100, 200, 100, 100)).isEmpty());
1634 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOverNothing
);
1636 template<class Types
, bool opaqueLayers
>
1637 class CCOcclusionTrackerTestViewportRectOverNothing
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1641 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1642 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1643 this->calcDrawEtc(parent
);
1645 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(500, 500, 100, 100));
1646 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1648 this->enterLayer(layer
, occlusion
);
1650 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1651 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1652 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1653 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1655 this->leaveLayer(layer
, occlusion
);
1656 this->visitContributingSurface(layer
, occlusion
);
1657 this->enterLayer(parent
, occlusion
);
1659 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 0, 100, 100)));
1660 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1661 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 0, 100, 100)));
1662 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1663 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 100, 100, 100)));
1664 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 0, 100, 100)));
1665 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(0, 200, 100, 100)));
1666 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 200, 100, 100)));
1667 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1669 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)).isEmpty());
1670 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 100)).isEmpty());
1671 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(0, 100, 300, 100)).isEmpty());
1672 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(200, 100, 100, 100)).isEmpty());
1673 EXPECT_TRUE(occlusion
.unoccludedContentRect(parent
, IntRect(100, 200, 100, 100)).isEmpty());
1677 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOverNothing
);
1679 template<class Types
, bool opaqueLayers
>
1680 class CCOcclusionTrackerTestLayerClipRectForLayerOffOrigin
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1684 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1685 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), true);
1686 this->calcDrawEtc(parent
);
1688 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1689 this->enterLayer(layer
, occlusion
);
1691 // This layer is translated when drawn into its target. So if the clip rect given from the target surface
1692 // is not in that target space, then after translating these query rects into the target, they will fall outside
1693 // the clip and be considered occluded.
1694 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1695 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1696 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1697 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1701 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectForLayerOffOrigin
);
1703 template<class Types
, bool opaqueLayers
>
1704 class CCOcclusionTrackerTestOpaqueContentsRegionEmpty
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1708 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1709 typename
Types::ContentLayerType
* layer
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 200), false);
1710 this->calcDrawEtc(parent
);
1712 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1713 this->enterLayer(layer
, occlusion
);
1715 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(0, 0, 100, 100)));
1716 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 0, 100, 100)));
1717 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(0, 100, 100, 100)));
1718 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(100, 100, 100, 100)));
1720 // Occluded since its outside the surface bounds.
1721 EXPECT_TRUE(occlusion
.occluded(layer
, IntRect(200, 100, 100, 100)));
1723 // Test without any clip rect.
1724 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1725 EXPECT_FALSE(occlusion
.occluded(layer
, IntRect(200, 100, 100, 100)));
1726 occlusion
.useDefaultLayerClipRect();
1728 this->leaveLayer(layer
, occlusion
);
1729 this->visitContributingSurface(layer
, occlusion
);
1730 this->enterLayer(parent
, occlusion
);
1732 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().bounds().isEmpty());
1733 EXPECT_EQ(0u, occlusion
.occlusionInScreenSpace().rects().size());
1737 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionEmpty
);
1739 template<class Types
, bool opaqueLayers
>
1740 class CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1744 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1745 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(100, 100), IntSize(200, 200), false);
1746 this->calcDrawEtc(parent
);
1749 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1750 layer
->setOpaqueContentsRect(IntRect(0, 0, 100, 100));
1752 this->resetLayerIterator();
1753 this->visitLayer(layer
, occlusion
);
1754 this->enterLayer(parent
, occlusion
);
1756 EXPECT_RECT_EQ(IntRect(100, 100, 100, 100), occlusion
.occlusionInScreenSpace().bounds());
1757 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1759 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1760 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1761 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1765 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1766 layer
->setOpaqueContentsRect(IntRect(20, 20, 180, 180));
1768 this->resetLayerIterator();
1769 this->visitLayer(layer
, occlusion
);
1770 this->enterLayer(parent
, occlusion
);
1772 EXPECT_RECT_EQ(IntRect(120, 120, 180, 180), occlusion
.occlusionInScreenSpace().bounds());
1773 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1775 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1776 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1777 EXPECT_TRUE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1781 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1782 layer
->setOpaqueContentsRect(IntRect(150, 150, 100, 100));
1784 this->resetLayerIterator();
1785 this->visitLayer(layer
, occlusion
);
1786 this->enterLayer(parent
, occlusion
);
1788 EXPECT_RECT_EQ(IntRect(250, 250, 50, 50), occlusion
.occlusionInScreenSpace().bounds());
1789 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1791 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(0, 100, 100, 100)));
1792 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(100, 100, 100, 100)));
1793 EXPECT_FALSE(occlusion
.occluded(parent
, IntRect(200, 200, 100, 100)));
1798 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty
);
1800 template<class Types
, bool opaqueLayers
>
1801 class CCOcclusionTrackerTest3dTransform
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1805 WebTransformationMatrix transform
;
1806 transform
.rotate3d(0, 30, 0);
1808 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1809 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1810 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, FloatPoint(100, 100), IntSize(200, 200), true);
1811 this->calcDrawEtc(parent
);
1813 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1814 this->enterLayer(layer
, occlusion
);
1816 // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
1817 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), occlusion
.unoccludedContentRect(layer
, IntRect(0, 0, 200, 200)));
1821 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTest3dTransform
);
1823 template<class Types
, bool opaqueLayers
>
1824 class CCOcclusionTrackerTestUnsorted3dLayers
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1828 // Currently, the main thread layer iterator does not iterate over 3d items in
1829 // sorted order, because layer sorting is not performed on the main thread.
1830 // Because of this, the occlusion tracker cannot assume that a 3d layer occludes
1831 // other layers that have not yet been iterated over. For now, the expected
1832 // behavior is that a 3d layer simply does not add any occlusion to the occlusion
1835 WebTransformationMatrix translationToFront
;
1836 translationToFront
.translate3d(0, 0, -10);
1837 WebTransformationMatrix translationToBack
;
1838 translationToFront
.translate3d(0, 0, -100);
1840 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1841 typename
Types::ContentLayerType
* child1
= this->createDrawingLayer(parent
, translationToBack
, FloatPoint(0, 0), IntSize(100, 100), true);
1842 typename
Types::ContentLayerType
* child2
= this->createDrawingLayer(parent
, translationToFront
, FloatPoint(50, 50), IntSize(100, 100), true);
1843 parent
->setPreserves3D(true);
1845 this->calcDrawEtc(parent
);
1847 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1848 this->visitLayer(child2
, occlusion
);
1849 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().isEmpty());
1850 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().isEmpty());
1852 this->visitLayer(child1
, occlusion
);
1853 EXPECT_TRUE(occlusion
.occlusionInScreenSpace().isEmpty());
1854 EXPECT_TRUE(occlusion
.occlusionInTargetSurface().isEmpty());
1858 // This test will have different layer ordering on the impl thread; the test will only work on the main thread.
1859 MAIN_THREAD_TEST(CCOcclusionTrackerTestUnsorted3dLayers
);
1861 template<class Types
, bool opaqueLayers
>
1862 class CCOcclusionTrackerTestPerspectiveTransform
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1866 WebTransformationMatrix transform
;
1867 transform
.translate(150, 150);
1868 transform
.applyPerspective(400);
1869 transform
.rotate3d(1, 0, 0, -30);
1870 transform
.translate(-150, -150);
1872 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1873 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1874 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, FloatPoint(100, 100), IntSize(200, 200), true);
1875 container
->setPreserves3D(true);
1876 layer
->setPreserves3D(true);
1877 this->calcDrawEtc(parent
);
1879 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1880 this->enterLayer(layer
, occlusion
);
1882 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), occlusion
.unoccludedContentRect(layer
, IntRect(0, 0, 200, 200)));
1886 // 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.
1887 IMPL_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransform
);
1889 template<class Types
, bool opaqueLayers
>
1890 class CCOcclusionTrackerTestPerspectiveTransformBehindCamera
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1894 // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
1895 WebTransformationMatrix transform
;
1896 transform
.translate(250, 50);
1897 transform
.applyPerspective(10);
1898 transform
.translate(-250, -50);
1899 transform
.translate(250, 50);
1900 transform
.rotate3d(1, 0, 0, -167);
1901 transform
.translate(-250, -50);
1903 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(500, 100));
1904 typename
Types::LayerType
* container
= this->createLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(500, 500));
1905 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(container
, transform
, FloatPoint(0, 0), IntSize(500, 500), true);
1906 container
->setPreserves3D(true);
1907 layer
->setPreserves3D(true);
1908 this->calcDrawEtc(parent
);
1910 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1911 this->enterLayer(layer
, occlusion
);
1913 // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
1914 // this will include many more pixels but must include at least the bottom 11 rows.
1915 EXPECT_TRUE(occlusion
.unoccludedContentRect(layer
, IntRect(0, 0, 500, 500)).contains(IntRect(0, 489, 500, 11)));
1919 // 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.
1920 IMPL_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransformBehindCamera
);
1922 template<class Types
, bool opaqueLayers
>
1923 class CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1927 WebTransformationMatrix transform
;
1928 transform
.translate(50, 50);
1929 transform
.applyPerspective(100);
1930 transform
.translate3d(0, 0, 110);
1931 transform
.translate(-50, -50);
1933 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
1934 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, transform
, FloatPoint(0, 0), IntSize(100, 100), true);
1935 parent
->setPreserves3D(true);
1936 layer
->setPreserves3D(true);
1937 this->calcDrawEtc(parent
);
1939 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1941 // The |layer| is entirely behind the camera and should not occlude.
1942 this->visitLayer(layer
, occlusion
);
1943 this->enterLayer(parent
, occlusion
);
1944 EXPECT_EQ(0u, occlusion
.occlusionInTargetSurface().rects().size());
1945 EXPECT_EQ(0u, occlusion
.occlusionInScreenSpace().rects().size());
1949 // 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.
1950 IMPL_THREAD_TEST(CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude
);
1952 template<class Types
, bool opaqueLayers
>
1953 class CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1957 WebTransformationMatrix transform
;
1958 transform
.translate(50, 50);
1959 transform
.applyPerspective(100);
1960 transform
.translate3d(0, 0, 99);
1961 transform
.translate(-50, -50);
1963 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100));
1964 parent
->setMasksToBounds(true);
1965 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, transform
, FloatPoint(0, 0), IntSize(100, 100), true);
1966 parent
->setPreserves3D(true);
1967 layer
->setPreserves3D(true);
1968 this->calcDrawEtc(parent
);
1970 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
1972 // This is very close to the camera, so pixels in its visibleContentRect will actually go outside of the layer's clipRect.
1973 // Ensure that those pixels don't occlude things outside the clipRect.
1974 this->visitLayer(layer
, occlusion
);
1975 this->enterLayer(parent
, occlusion
);
1976 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion
.occlusionInTargetSurface().bounds());
1977 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
1978 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion
.occlusionInScreenSpace().bounds());
1979 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
1983 // 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.
1984 IMPL_THREAD_TEST(CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect
);
1986 template<class Types
, bool opaqueLayers
>
1987 class CCOcclusionTrackerTestAnimationOpacity1OnMainThread
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
1991 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
1992 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300), true);
1993 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300), true);
1994 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 300), true);
1995 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 300), true);
1996 typename
Types::ContentLayerType
* parent2
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300), false);
1997 typename
Types::ContentLayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(250, 0), IntSize(50, 300), true);
1999 addOpacityTransitionToController(*layer
->layerAnimationController(), 10, 0, 1, false);
2000 addOpacityTransitionToController(*surface
->layerAnimationController(), 10, 0, 1, false);
2001 this->calcDrawEtc(parent
);
2003 EXPECT_TRUE(layer
->drawOpacityIsAnimating());
2004 EXPECT_FALSE(surface
->drawOpacityIsAnimating());
2005 EXPECT_TRUE(surface
->renderSurface()->drawOpacityIsAnimating());
2007 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2009 this->visitLayer(topmost
, occlusion
);
2010 this->enterLayer(parent2
, occlusion
);
2011 // This occlusion will affect all surfaces.
2012 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion
.unoccludedContentRect(parent2
, IntRect(0, 0, 300, 300)));
2013 this->leaveLayer(parent2
, occlusion
);
2015 this->visitLayer(surfaceChild2
, occlusion
);
2016 this->enterLayer(surfaceChild
, occlusion
);
2017 EXPECT_RECT_EQ(IntRect(100, 0, 100, 300), occlusion
.unoccludedContentRect(surfaceChild
, IntRect(0, 0, 300, 300)));
2018 this->leaveLayer(surfaceChild
, occlusion
);
2019 this->enterLayer(surface
, occlusion
);
2020 EXPECT_RECT_EQ(IntRect(200, 0, 50, 300), occlusion
.unoccludedContentRect(surface
, IntRect(0, 0, 300, 300)));
2021 this->leaveLayer(surface
, occlusion
);
2023 this->enterContributingSurface(surface
, occlusion
);
2024 // Occlusion within the surface is lost when leaving the animating surface.
2025 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 300, 300)));
2026 this->leaveContributingSurface(surface
, occlusion
);
2028 this->visitLayer(layer
, occlusion
);
2029 this->enterLayer(parent
, occlusion
);
2031 // Occlusion is not added for the animating |layer|.
2032 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
2036 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity1OnMainThread
);
2038 template<class Types
, bool opaqueLayers
>
2039 class CCOcclusionTrackerTestAnimationOpacity0OnMainThread
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2043 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
2044 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300), true);
2045 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300), true);
2046 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 300), true);
2047 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 300), true);
2048 typename
Types::ContentLayerType
* parent2
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300), false);
2049 typename
Types::ContentLayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(250, 0), IntSize(50, 300), true);
2051 addOpacityTransitionToController(*layer
->layerAnimationController(), 10, 1, 0, false);
2052 addOpacityTransitionToController(*surface
->layerAnimationController(), 10, 1, 0, false);
2053 this->calcDrawEtc(parent
);
2055 EXPECT_TRUE(layer
->drawOpacityIsAnimating());
2056 EXPECT_FALSE(surface
->drawOpacityIsAnimating());
2057 EXPECT_TRUE(surface
->renderSurface()->drawOpacityIsAnimating());
2059 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2061 this->visitLayer(topmost
, occlusion
);
2062 this->enterLayer(parent2
, occlusion
);
2063 // This occlusion will affect all surfaces.
2064 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
2065 this->leaveLayer(parent2
, occlusion
);
2067 this->visitLayer(surfaceChild2
, occlusion
);
2068 this->enterLayer(surfaceChild
, occlusion
);
2069 EXPECT_RECT_EQ(IntRect(100, 0, 100, 300), occlusion
.unoccludedContentRect(surfaceChild
, IntRect(0, 0, 300, 300)));
2070 this->leaveLayer(surfaceChild
, occlusion
);
2071 this->enterLayer(surface
, occlusion
);
2072 EXPECT_RECT_EQ(IntRect(200, 0, 50, 300), occlusion
.unoccludedContentRect(surface
, IntRect(0, 0, 300, 300)));
2073 this->leaveLayer(surface
, occlusion
);
2075 this->enterContributingSurface(surface
, occlusion
);
2076 // Occlusion within the surface is lost when leaving the animating surface.
2077 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 300, 300)));
2078 this->leaveContributingSurface(surface
, occlusion
);
2080 this->visitLayer(layer
, occlusion
);
2081 this->enterLayer(parent
, occlusion
);
2083 // Occlusion is not added for the animating |layer|.
2084 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
2088 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity0OnMainThread
);
2090 template<class Types
, bool opaqueLayers
>
2091 class CCOcclusionTrackerTestAnimationTranslateOnMainThread
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2095 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
2096 typename
Types::ContentLayerType
* layer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300), true);
2097 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300), true);
2098 typename
Types::ContentLayerType
* surfaceChild
= this->createDrawingLayer(surface
, this->identityMatrix
, FloatPoint(0, 0), IntSize(200, 300), true);
2099 typename
Types::ContentLayerType
* surfaceChild2
= this->createDrawingLayer(surface
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 300), true);
2100 typename
Types::ContentLayerType
* surface2
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(50, 300), true);
2102 addAnimatedTransformToController(*layer
->layerAnimationController(), 10, 30, 0);
2103 addAnimatedTransformToController(*surface
->layerAnimationController(), 10, 30, 0);
2104 addAnimatedTransformToController(*surfaceChild
->layerAnimationController(), 10, 30, 0);
2105 this->calcDrawEtc(parent
);
2107 EXPECT_TRUE(layer
->drawTransformIsAnimating());
2108 EXPECT_TRUE(layer
->screenSpaceTransformIsAnimating());
2109 EXPECT_TRUE(surface
->renderSurface()->targetSurfaceTransformsAreAnimating());
2110 EXPECT_TRUE(surface
->renderSurface()->screenSpaceTransformsAreAnimating());
2111 // The surface owning layer doesn't animate against its own surface.
2112 EXPECT_FALSE(surface
->drawTransformIsAnimating());
2113 EXPECT_TRUE(surface
->screenSpaceTransformIsAnimating());
2114 EXPECT_TRUE(surfaceChild
->drawTransformIsAnimating());
2115 EXPECT_TRUE(surfaceChild
->screenSpaceTransformIsAnimating());
2117 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2119 this->visitLayer(surface2
, occlusion
);
2120 this->enterContributingSurface(surface2
, occlusion
);
2122 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion
.occlusionInScreenSpace().bounds());
2123 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2125 this->leaveContributingSurface(surface2
, occlusion
);
2126 this->enterLayer(surfaceChild2
, occlusion
);
2128 // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2129 // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer.
2130 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion
.unoccludedContentRect(surfaceChild2
, IntRect(0, 0, 100, 300)));
2131 EXPECT_FALSE(occlusion
.occluded(surfaceChild
, IntRect(0, 0, 50, 300)));
2133 this->leaveLayer(surfaceChild2
, occlusion
);
2134 this->enterLayer(surfaceChild
, occlusion
);
2135 EXPECT_FALSE(occlusion
.occluded(surfaceChild
, IntRect(0, 0, 100, 300)));
2136 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion
.occlusionInScreenSpace().bounds());
2137 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2138 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion
.occlusionInTargetSurface().bounds());
2139 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2140 EXPECT_RECT_EQ(IntRect(100, 0, 200, 300), occlusion
.unoccludedContentRect(surface
, IntRect(0, 0, 300, 300)));
2142 // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target and the screen, so it
2143 // can't be occluded.
2144 EXPECT_RECT_EQ(IntRect(0, 0, 200, 300), occlusion
.unoccludedContentRect(surfaceChild
, IntRect(0, 0, 200, 300)));
2145 EXPECT_FALSE(occlusion
.occluded(surfaceChild
, IntRect(0, 0, 50, 300)));
2147 this->leaveLayer(surfaceChild
, occlusion
);
2148 this->enterLayer(surface
, occlusion
);
2149 // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2150 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion
.occlusionInScreenSpace().bounds());
2151 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2152 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion
.occlusionInTargetSurface().bounds());
2153 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2154 EXPECT_RECT_EQ(IntRect(100, 0, 200, 300), occlusion
.unoccludedContentRect(surface
, IntRect(0, 0, 300, 300)));
2156 this->leaveLayer(surface
, occlusion
);
2157 // 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.
2158 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion
.occlusionInScreenSpace().bounds());
2159 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2160 EXPECT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion
.occlusionInTargetSurface().bounds());
2161 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2162 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion
.unoccludedContentRect(surface
, IntRect(0, 0, 300, 300)));
2164 this->enterContributingSurface(surface
, occlusion
);
2165 // The contributing |surface| is animating so it can't be occluded.
2166 EXPECT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 300, 300)));
2167 this->leaveContributingSurface(surface
, occlusion
);
2169 this->enterLayer(layer
, occlusion
);
2170 // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
2171 EXPECT_RECT_EQ(IntRect(50, 0, 250, 300), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
2172 this->leaveLayer(layer
, occlusion
);
2174 this->enterLayer(parent
, occlusion
);
2175 // The |layer| is animating in the screen and in its target, so no occlusion is added.
2176 EXPECT_RECT_EQ(IntRect(50, 0, 250, 300), occlusion
.unoccludedContentRect(parent
, IntRect(0, 0, 300, 300)));
2180 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationTranslateOnMainThread
);
2182 template<class Types
, bool opaqueLayers
>
2183 class CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2187 WebTransformationMatrix surfaceTransform
;
2188 surfaceTransform
.translate(300, 300);
2189 surfaceTransform
.scale(2);
2190 surfaceTransform
.translate(-150, -150);
2192 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(500, 500));
2193 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, surfaceTransform
, FloatPoint(0, 0), IntSize(300, 300), false);
2194 typename
Types::ContentLayerType
* surface2
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(50, 50), IntSize(300, 300), false);
2195 surface
->setOpaqueContentsRect(IntRect(0, 0, 400, 400));
2196 surface2
->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
2197 this->calcDrawEtc(parent
);
2199 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2201 this->visitLayer(surface2
, occlusion
);
2202 this->visitContributingSurface(surface2
, occlusion
);
2204 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion
.occlusionInScreenSpace().bounds());
2205 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2206 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion
.occlusionInTargetSurface().bounds());
2207 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2209 // Clear any stored occlusion.
2210 occlusion
.setOcclusionInScreenSpace(Region());
2211 occlusion
.setOcclusionInTargetSurface(Region());
2213 this->visitLayer(surface
, occlusion
);
2214 this->visitContributingSurface(surface
, occlusion
);
2216 EXPECT_RECT_EQ(IntRect(0, 0, 400, 400), occlusion
.occlusionInScreenSpace().bounds());
2217 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2218 EXPECT_RECT_EQ(IntRect(0, 0, 400, 400), occlusion
.occlusionInTargetSurface().bounds());
2219 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2223 // Scale transforms require main thread+commit to get contentBounds right.
2224 MAIN_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent
);
2226 template<class Types
, bool opaqueLayers
>
2227 class CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2231 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 300));
2232 parent
->setMasksToBounds(true);
2233 typename
Types::ContentLayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(500, 300), false);
2234 surface
->setOpaqueContentsRect(IntRect(0, 0, 400, 200));
2235 this->calcDrawEtc(parent
);
2237 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2239 this->visitLayer(surface
, occlusion
);
2240 this->visitContributingSurface(surface
, occlusion
);
2242 EXPECT_RECT_EQ(IntRect(0, 0, 300, 200), occlusion
.occlusionInScreenSpace().bounds());
2243 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2244 EXPECT_RECT_EQ(IntRect(0, 0, 300, 200), occlusion
.occlusionInTargetSurface().bounds());
2245 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2249 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
);
2251 template<class Types
, bool opaqueLayers
>
2252 class CCOcclusionTrackerTestReplicaOccluded
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2256 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 200));
2257 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100), true);
2258 this->createReplicaLayer(surface
, this->identityMatrix
, FloatPoint(0, 100), IntSize(100, 100));
2259 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 100), IntSize(100, 100), true);
2260 this->calcDrawEtc(parent
);
2262 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2263 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2265 // |topmost| occludes the replica, but not the surface itself.
2266 this->visitLayer(topmost
, occlusion
);
2268 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion
.occlusionInScreenSpace().bounds());
2269 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2270 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion
.occlusionInTargetSurface().bounds());
2271 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2273 this->visitLayer(surface
, occlusion
);
2275 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion
.occlusionInScreenSpace().bounds());
2276 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2277 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion
.occlusionInTargetSurface().bounds());
2278 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2280 this->enterContributingSurface(surface
, occlusion
);
2282 // Surface is not occluded so it shouldn't think it is.
2283 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 100, 100)));
2287 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaOccluded
);
2289 template<class Types
, bool opaqueLayers
>
2290 class CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2294 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 200));
2295 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100), true);
2296 this->createReplicaLayer(surface
, this->identityMatrix
, FloatPoint(0, 100), IntSize(100, 100));
2297 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 110), true);
2298 this->calcDrawEtc(parent
);
2300 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2301 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2303 // |topmost| occludes the surface, but not the entire surface's replica.
2304 this->visitLayer(topmost
, occlusion
);
2306 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion
.occlusionInScreenSpace().bounds());
2307 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2308 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion
.occlusionInTargetSurface().bounds());
2309 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2311 this->visitLayer(surface
, occlusion
);
2313 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion
.occlusionInScreenSpace().bounds());
2314 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2315 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion
.occlusionInTargetSurface().bounds());
2316 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2318 this->enterContributingSurface(surface
, occlusion
);
2320 // Surface is occluded, but only the top 10px of the replica.
2321 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 100, 100)));
2322 EXPECT_RECT_EQ(IntRect(0, 10, 100, 90), occlusion
.unoccludedContributingSurfaceContentRect(surface
, true, IntRect(0, 0, 100, 100)));
2326 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded
);
2328 template<class Types
, bool opaqueLayers
>
2329 class CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2333 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 200));
2334 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100), true);
2335 this->createReplicaLayer(surface
, this->identityMatrix
, FloatPoint(0, 100), IntSize(100, 100));
2336 typename
Types::LayerType
* overSurface
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(40, 100), true);
2337 typename
Types::LayerType
* overReplica
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 100), IntSize(50, 100), true);
2338 this->calcDrawEtc(parent
);
2340 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2341 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2343 // These occlude the surface and replica differently, so we can test each one.
2344 this->visitLayer(overReplica
, occlusion
);
2345 this->visitLayer(overSurface
, occlusion
);
2347 EXPECT_RECT_EQ(IntRect(0, 0, 50, 200), occlusion
.occlusionInScreenSpace().bounds());
2348 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
2349 EXPECT_RECT_EQ(IntRect(0, 0, 50, 200), occlusion
.occlusionInTargetSurface().bounds());
2350 EXPECT_EQ(2u, occlusion
.occlusionInTargetSurface().rects().size());
2352 this->visitLayer(surface
, occlusion
);
2354 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion
.occlusionInScreenSpace().bounds());
2355 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
2356 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion
.occlusionInTargetSurface().bounds());
2357 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2359 this->enterContributingSurface(surface
, occlusion
);
2361 // Surface and replica are occluded different amounts.
2362 EXPECT_RECT_EQ(IntRect(40, 0, 60, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 100, 100)));
2363 EXPECT_RECT_EQ(IntRect(50, 0, 50, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, true, IntRect(0, 0, 100, 100)));
2367 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
);
2369 template<class Types
, bool opaqueLayers
>
2370 class CCOcclusionTrackerTestSurfaceChildOfSurface
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2374 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2376 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 200));
2377 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100), true);
2378 typename
Types::LayerType
* surfaceChild
= this->createDrawingSurface(surface
, this->identityMatrix
, FloatPoint(0, 10), IntSize(100, 50), true);
2379 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 50), true);
2380 this->calcDrawEtc(parent
);
2382 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(-100, -100, 1000, 1000));
2384 // |topmost| occludes everything partially so we know occlusion is happening at all.
2385 this->visitLayer(topmost
, occlusion
);
2387 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion
.occlusionInScreenSpace().bounds());
2388 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2389 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion
.occlusionInTargetSurface().bounds());
2390 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2392 this->visitLayer(surfaceChild
, occlusion
);
2394 // surfaceChild increases the occlusion in the screen by a narrow sliver.
2395 EXPECT_RECT_EQ(IntRect(0, 0, 100, 60), occlusion
.occlusionInScreenSpace().bounds());
2396 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2397 // In its own surface, surfaceChild is at 0,0 as is its occlusion.
2398 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion
.occlusionInTargetSurface().bounds());
2399 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2401 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2402 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2403 // as its parent does not have a clipRect.
2405 this->enterContributingSurface(surfaceChild
, occlusion
);
2406 // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
2407 // does not get clipped away inappropriately.
2408 EXPECT_RECT_EQ(IntRect(0, 40, 100, 10), occlusion
.unoccludedContributingSurfaceContentRect(surfaceChild
, false, IntRect(0, 0, 100, 50)));
2409 this->leaveContributingSurface(surfaceChild
, occlusion
);
2411 // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
2412 this->enterLayer(surface
, occlusion
);
2413 EXPECT_RECT_EQ(IntRect(0, 0, 100, 60), occlusion
.occlusionInScreenSpace().bounds());
2414 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2415 EXPECT_RECT_EQ(IntRect(0, 10, 100, 50), occlusion
.occlusionInTargetSurface().bounds());
2416 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2417 this->leaveLayer(surface
, occlusion
);
2419 this->enterContributingSurface(surface
, occlusion
);
2420 // The surface's parent does have a clipRect as it is the root layer.
2421 EXPECT_RECT_EQ(IntRect(0, 50, 100, 50), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 100, 100)));
2425 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfSurface
);
2427 template<class Types
, bool opaqueLayers
>
2428 class CCOcclusionTrackerTestTopmostSurfaceIsClippedToViewport
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2432 // This test verifies that the top-most surface is considered occluded outside of its target's clipRect and outside the viewport rect.
2434 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 200));
2435 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 300), true);
2436 this->calcDrawEtc(parent
);
2439 // Make a viewport rect that is larger than the root layer.
2440 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2442 this->visitLayer(surface
, occlusion
);
2444 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2445 this->enterContributingSurface(surface
, occlusion
);
2446 // Make sure the parent's clipRect clips the unoccluded region of the child surface.
2447 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 100, 300)));
2449 this->resetLayerIterator();
2451 // Make a viewport rect that is smaller than the root layer.
2452 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 100, 100));
2454 this->visitLayer(surface
, occlusion
);
2456 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2457 this->enterContributingSurface(surface
, occlusion
);
2458 // Make sure the viewport rect clips the unoccluded region of the child surface.
2459 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 100, 300)));
2464 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTopmostSurfaceIsClippedToViewport
);
2466 template<class Types
, bool opaqueLayers
>
2467 class CCOcclusionTrackerTestSurfaceChildOfClippingSurface
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2471 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2473 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(80, 200));
2474 parent
->setMasksToBounds(true);
2475 typename
Types::LayerType
* surface
= this->createDrawingSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100), true);
2476 typename
Types::LayerType
* surfaceChild
= this->createDrawingSurface(surface
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 100), false);
2477 typename
Types::LayerType
* topmost
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(100, 50), true);
2478 this->calcDrawEtc(parent
);
2480 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2481 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2483 // |topmost| occludes everything partially so we know occlusion is happening at all.
2484 this->visitLayer(topmost
, occlusion
);
2486 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion
.occlusionInScreenSpace().bounds());
2487 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2488 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion
.occlusionInTargetSurface().bounds());
2489 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2491 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2492 this->visitLayer(surfaceChild
, occlusion
);
2494 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion
.occlusionInScreenSpace().bounds());
2495 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2496 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion
.occlusionInTargetSurface().bounds());
2497 EXPECT_EQ(0u, occlusion
.occlusionInTargetSurface().rects().size());
2499 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2500 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2501 // as its parent does not have a clipRect.
2503 this->enterContributingSurface(surfaceChild
, occlusion
);
2504 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
2505 EXPECT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion
.unoccludedContributingSurfaceContentRect(surfaceChild
, false, IntRect(0, 0, 100, 100)));
2506 this->leaveContributingSurface(surfaceChild
, occlusion
);
2508 this->visitLayer(surface
, occlusion
);
2509 this->enterContributingSurface(surface
, occlusion
);
2510 // The surface's parent does have a clipRect as it is the root layer.
2511 EXPECT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion
.unoccludedContributingSurfaceContentRect(surface
, false, IntRect(0, 0, 100, 100)));
2515 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfClippingSurface
);
2517 template<class Types
, bool opaqueLayers
>
2518 class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2522 WebTransformationMatrix scaleByHalf
;
2523 scaleByHalf
.scale(0.5);
2525 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2526 // 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
2527 // appears at 50, 50 and the replica at 200, 50.
2528 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 150));
2529 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, FloatPoint(50, 50), IntSize(100, 100), false);
2530 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, FloatPoint(300, 0), IntSize());
2531 typename
Types::LayerType
* occludingLayer1
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 50), true);
2532 typename
Types::LayerType
* occludingLayer2
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 100), IntSize(300, 50), true);
2533 typename
Types::LayerType
* occludingLayer3
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 50), IntSize(50, 50), true);
2534 typename
Types::LayerType
* occludingLayer4
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(100, 50), IntSize(100, 50), true);
2535 typename
Types::LayerType
* occludingLayer5
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(250, 50), IntSize(50, 50), true);
2537 // Filters make the layer own a surface.
2538 WebFilterOperations filters
;
2539 filters
.append(WebFilterOperation::createBlurFilter(10));
2540 filteredSurface
->setBackgroundFilters(filters
);
2542 // Save the distance of influence for the blur effect.
2543 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2544 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2546 this->calcDrawEtc(parent
);
2548 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2549 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2551 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2552 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2553 this->visitLayer(occludingLayer5
, occlusion
);
2554 this->visitLayer(occludingLayer4
, occlusion
);
2555 this->visitLayer(occludingLayer3
, occlusion
);
2556 this->visitLayer(occludingLayer2
, occlusion
);
2557 this->visitLayer(occludingLayer1
, occlusion
);
2559 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInScreenSpace().bounds());
2560 EXPECT_EQ(5u, occlusion
.occlusionInScreenSpace().rects().size());
2561 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInTargetSurface().bounds());
2562 EXPECT_EQ(5u, occlusion
.occlusionInTargetSurface().rects().size());
2564 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2565 this->enterLayer(filteredSurface
, occlusion
);
2566 EXPECT_RECT_EQ(IntRect(1, 0, 49, 50), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(1, 0, 50, 50)));
2567 EXPECT_RECT_EQ(IntRect(0, 1, 50, 49), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(0, 1, 50, 50)));
2568 EXPECT_RECT_EQ(IntRect(0, 0, 49, 50), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(-1, 0, 50, 50)));
2569 EXPECT_RECT_EQ(IntRect(0, 0, 50, 49), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(0, -1, 50, 50)));
2571 EXPECT_RECT_EQ(IntRect(150 + 1, 0, 49, 50), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(150 + 1, 0, 50, 50)));
2572 EXPECT_RECT_EQ(IntRect(150 + 0, 1, 50, 49), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(150 + 0, 1, 50, 50)));
2573 EXPECT_RECT_EQ(IntRect(150 + 0, 0, 49, 50), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(150 - 1, 0, 50, 50)));
2574 EXPECT_RECT_EQ(IntRect(150 + 0, 0, 50, 49), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(150 + 0, -1, 50, 50)));
2575 this->leaveLayer(filteredSurface
, occlusion
);
2577 // The filtered layer/replica does not occlude.
2578 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInScreenSpace().bounds());
2579 EXPECT_EQ(5u, occlusion
.occlusionInScreenSpace().rects().size());
2580 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion
.occlusionInTargetSurface().bounds());
2581 EXPECT_EQ(0u, occlusion
.occlusionInTargetSurface().rects().size());
2583 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2584 // it needs should be removed from the occluded area so that when we get to the parent they are drawn.
2585 this->visitContributingSurface(filteredSurface
, occlusion
);
2587 this->enterLayer(parent
, occlusion
);
2588 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInScreenSpace().bounds());
2589 EXPECT_EQ(5u, occlusion
.occlusionInScreenSpace().rects().size());
2590 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInTargetSurface().bounds());
2591 EXPECT_EQ(5u, occlusion
.occlusionInTargetSurface().rects().size());
2596 // Nothing in the blur outsets for the filteredSurface is occluded.
2597 outsetRect
= IntRect(50 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2598 testRect
= outsetRect
;
2599 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2601 // Stuff outside the blur outsets is still occluded though.
2602 testRect
= outsetRect
;
2603 testRect
.expand(1, 0);
2604 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2605 testRect
= outsetRect
;
2606 testRect
.expand(0, 1);
2607 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2608 testRect
= outsetRect
;
2609 testRect
.move(-1, 0);
2610 testRect
.expand(1, 0);
2611 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2612 testRect
= outsetRect
;
2613 testRect
.move(0, -1);
2614 testRect
.expand(0, 1);
2615 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2617 // Nothing in the blur outsets for the filteredSurface's replica is occluded.
2618 outsetRect
= IntRect(200 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2619 testRect
= outsetRect
;
2620 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2622 // Stuff outside the blur outsets is still occluded though.
2623 testRect
= outsetRect
;
2624 testRect
.expand(1, 0);
2625 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2626 testRect
= outsetRect
;
2627 testRect
.expand(0, 1);
2628 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2629 testRect
= outsetRect
;
2630 testRect
.move(-1, 0);
2631 testRect
.expand(1, 0);
2632 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2633 testRect
= outsetRect
;
2634 testRect
.move(0, -1);
2635 testRect
.expand(0, 1);
2636 EXPECT_RECT_EQ(outsetRect
, occlusion
.unoccludedContentRect(parent
, testRect
));
2640 // Scale transforms require main thread+commit to get contentBounds right.
2641 MAIN_THREAD_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
);
2643 template<class Types
, bool opaqueLayers
>
2644 class CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2648 WebTransformationMatrix scaleByHalf
;
2649 scaleByHalf
.scale(0.5);
2651 // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
2652 typename
Types::ContentLayerType
* root
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(150, 150));
2653 typename
Types::LayerType
* parent
= this->createDrawingSurface(root
, scaleByHalf
, FloatPoint(0, 0), IntSize(300, 300), false);
2654 parent
->setMasksToBounds(true);
2655 typename
Types::LayerType
* filteredSurface1
= this->createDrawingLayer(parent
, scaleByHalf
, FloatPoint(0, 0), IntSize(600, 600), false);
2656 typename
Types::LayerType
* filteredSurface2
= this->createDrawingLayer(parent
, scaleByHalf
, FloatPoint(0, 0), IntSize(600, 600), false);
2657 typename
Types::LayerType
* occludingLayerAbove
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(200, 200), IntSize(100, 100), true);
2659 // Filters make the layers own surfaces.
2660 WebFilterOperations filters
;
2661 filters
.append(WebFilterOperation::createBlurFilter(3));
2662 filteredSurface1
->setBackgroundFilters(filters
);
2663 filteredSurface2
->setBackgroundFilters(filters
);
2665 // Save the distance of influence for the blur effect.
2666 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2667 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2669 this->calcDrawEtc(root
);
2671 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2672 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2674 this->visitLayer(occludingLayerAbove
, occlusion
);
2675 EXPECT_RECT_EQ(IntRect(200 / 2, 200 / 2, 100 / 2, 100 / 2), occlusion
.occlusionInScreenSpace().bounds());
2676 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2677 EXPECT_RECT_EQ(IntRect(200 / 2, 200 / 2, 100 / 2, 100 / 2), occlusion
.occlusionInTargetSurface().bounds());
2678 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2680 this->visitLayer(filteredSurface2
, occlusion
);
2681 this->visitContributingSurface(filteredSurface2
, occlusion
);
2682 this->visitLayer(filteredSurface1
, occlusion
);
2683 this->visitContributingSurface(filteredSurface1
, occlusion
);
2685 ASSERT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
2686 ASSERT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
2688 // Test expectations in the target. The target is scaled in half so the occlusion should be scaled within its contents as well.
2689 IntRect expectedOcclusion
= IntRect(200 / 2 + outsetRight
* 2, 200 / 2 + outsetBottom
* 2, 100 / 2 - (outsetLeft
+ outsetRight
) * 2, 100 / 2 - (outsetTop
+ outsetBottom
) * 2);
2690 EXPECT_RECT_EQ(expectedOcclusion
, occlusion
.occlusionInTargetSurface().rects()[0]);
2692 // Test expectations in the screen. The parent is scaled in half so it will scale the occlusion to the screen as well.
2693 expectedOcclusion
= IntRect(200 / 2 + outsetRight
* 2, 200 / 2 + outsetBottom
* 2, 100 / 2 - (outsetLeft
+ outsetRight
) * 2, 100 / 2 - (outsetTop
+ outsetBottom
) * 2);
2694 EXPECT_RECT_EQ(expectedOcclusion
, occlusion
.occlusionInScreenSpace().rects()[0]);
2698 // Scale transforms require main thread+commit to get contentBounds right.
2699 MAIN_THREAD_TEST(CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
);
2701 template<class Types
, bool opaqueLayers
>
2702 class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2706 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2707 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 150));
2708 // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
2709 // the background filter.
2710 typename
Types::LayerType
* clippingSurface
= this->createSurface(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 70));
2711 clippingSurface
->setMasksToBounds(true);
2712 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(clippingSurface
, this->identityMatrix
, FloatPoint(50, 50), IntSize(50, 50), false);
2713 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, FloatPoint(150, 0), IntSize());
2714 typename
Types::LayerType
* occludingLayer1
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 50), true);
2715 typename
Types::LayerType
* occludingLayer2
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 100), IntSize(300, 50), true);
2716 typename
Types::LayerType
* occludingLayer3
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 50), IntSize(50, 50), true);
2717 typename
Types::LayerType
* occludingLayer4
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(100, 50), IntSize(100, 50), true);
2718 typename
Types::LayerType
* occludingLayer5
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(250, 50), IntSize(50, 50), true);
2720 // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
2721 WebFilterOperations filters
;
2722 filters
.append(WebFilterOperation::createBlurFilter(12));
2723 filteredSurface
->setBackgroundFilters(filters
);
2725 // Save the distance of influence for the blur effect.
2726 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2727 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2729 this->calcDrawEtc(parent
);
2731 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2732 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2734 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2735 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2736 this->visitLayer(occludingLayer5
, occlusion
);
2737 this->visitLayer(occludingLayer4
, occlusion
);
2738 this->visitLayer(occludingLayer3
, occlusion
);
2739 this->visitLayer(occludingLayer2
, occlusion
);
2740 this->visitLayer(occludingLayer1
, occlusion
);
2742 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInScreenSpace().bounds());
2743 EXPECT_EQ(5u, occlusion
.occlusionInScreenSpace().rects().size());
2744 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInTargetSurface().bounds());
2745 EXPECT_EQ(5u, occlusion
.occlusionInTargetSurface().rects().size());
2747 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2748 this->enterLayer(filteredSurface
, occlusion
);
2749 EXPECT_RECT_EQ(IntRect(1, 0, 49, 50), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(1, 0, 50, 50)));
2750 EXPECT_RECT_EQ(IntRect(0, 1, 50, 49), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(0, 1, 50, 50)));
2751 EXPECT_RECT_EQ(IntRect(0, 0, 49, 50), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(-1, 0, 50, 50)));
2752 EXPECT_RECT_EQ(IntRect(0, 0, 50, 49), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(0, -1, 50, 50)));
2754 EXPECT_RECT_EQ(IntRect(150 + 1, 0, 49, 50), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(150 + 1, 0, 50, 50)));
2755 EXPECT_RECT_EQ(IntRect(150 + 0, 1, 50, 49), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(150 + 0, 1, 50, 50)));
2756 EXPECT_RECT_EQ(IntRect(150 + 0, 0, 49, 50), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(150 - 1, 0, 50, 50)));
2757 EXPECT_RECT_EQ(IntRect(150 + 0, 0, 50, 49), occlusion
.unoccludedContentRect(filteredSurface
, IntRect(150 + 0, -1, 50, 50)));
2758 this->leaveLayer(filteredSurface
, occlusion
);
2760 // The filtered layer/replica does not occlude.
2761 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInScreenSpace().bounds());
2762 EXPECT_EQ(5u, occlusion
.occlusionInScreenSpace().rects().size());
2763 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion
.occlusionInTargetSurface().bounds());
2764 EXPECT_EQ(0u, occlusion
.occlusionInTargetSurface().rects().size());
2766 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2767 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2768 this->visitContributingSurface(filteredSurface
, occlusion
);
2770 this->enterContributingSurface(clippingSurface
, occlusion
);
2771 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion
.occlusionInScreenSpace().bounds());
2772 EXPECT_EQ(5u, occlusion
.occlusionInScreenSpace().rects().size());
2775 IntRect clippedOutsetRect
;
2778 // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
2779 outsetRect
= IntRect(50 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2780 clippedOutsetRect
= intersection(outsetRect
, IntRect(0 - outsetLeft
, 0 - outsetTop
, 300 + outsetLeft
+ outsetRight
, 70 + outsetTop
+ outsetBottom
));
2781 testRect
= outsetRect
;
2782 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2784 // Stuff outside the (clipped) blur outsets is still occluded though.
2785 testRect
= outsetRect
;
2786 testRect
.expand(1, 0);
2787 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2788 testRect
= outsetRect
;
2789 testRect
.expand(0, 1);
2790 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2791 testRect
= outsetRect
;
2792 testRect
.move(-1, 0);
2793 testRect
.expand(1, 0);
2794 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2795 testRect
= outsetRect
;
2796 testRect
.move(0, -1);
2797 testRect
.expand(0, 1);
2798 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2800 // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
2801 outsetRect
= IntRect(200 - outsetLeft
, 50 - outsetTop
, 50 + outsetLeft
+ outsetRight
, 50 + outsetTop
+ outsetBottom
);
2802 clippedOutsetRect
= intersection(outsetRect
, IntRect(0 - outsetLeft
, 0 - outsetTop
, 300 + outsetLeft
+ outsetRight
, 70 + outsetTop
+ outsetBottom
));
2803 testRect
= outsetRect
;
2804 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2806 // Stuff outside the (clipped) blur outsets is still occluded though.
2807 testRect
= outsetRect
;
2808 testRect
.expand(1, 0);
2809 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2810 testRect
= outsetRect
;
2811 testRect
.expand(0, 1);
2812 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2813 testRect
= outsetRect
;
2814 testRect
.move(-1, 0);
2815 testRect
.expand(1, 0);
2816 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2817 testRect
= outsetRect
;
2818 testRect
.move(0, -1);
2819 testRect
.expand(0, 1);
2820 EXPECT_RECT_EQ(clippedOutsetRect
, occlusion
.unoccludedContentRect(clippingSurface
, testRect
));
2824 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
);
2826 template<class Types
, bool opaqueLayers
>
2827 class CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2831 WebTransformationMatrix scaleByHalf
;
2832 scaleByHalf
.scale(0.5);
2834 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
2835 // 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
2836 // appears at 50, 50 and the replica at 200, 50.
2837 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 150));
2838 typename
Types::LayerType
* behindSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(60, 60), IntSize(30, 30), true);
2839 typename
Types::LayerType
* behindReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(210, 60), IntSize(30, 30), true);
2840 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, FloatPoint(50, 50), IntSize(100, 100), false);
2841 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, FloatPoint(300, 0), IntSize());
2843 // Filters make the layer own a surface.
2844 WebFilterOperations filters
;
2845 filters
.append(WebFilterOperation::createBlurFilter(3));
2846 filteredSurface
->setBackgroundFilters(filters
);
2848 this->calcDrawEtc(parent
);
2850 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2851 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2853 // The surface has a background blur, so it blurs non-opaque pixels below it.
2854 this->visitLayer(filteredSurface
, occlusion
);
2855 this->visitContributingSurface(filteredSurface
, occlusion
);
2857 this->visitLayer(behindReplicaLayer
, occlusion
);
2858 this->visitLayer(behindSurfaceLayer
, occlusion
);
2860 // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
2861 // So it should not be modified by the filter here.
2862 IntRect occlusionBehindSurface
= IntRect(60, 60, 30, 30);
2863 IntRect occlusionBehindReplica
= IntRect(210, 60, 30, 30);
2865 IntRect expectedOpaqueBounds
= unionRect(occlusionBehindSurface
, occlusionBehindReplica
);
2866 EXPECT_RECT_EQ(expectedOpaqueBounds
, occlusion
.occlusionInScreenSpace().bounds());
2867 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
2868 EXPECT_RECT_EQ(expectedOpaqueBounds
, occlusion
.occlusionInTargetSurface().bounds());
2869 EXPECT_EQ(2u, occlusion
.occlusionInTargetSurface().rects().size());
2873 // Scale transforms require main thread+commit to get contentBounds right.
2874 MAIN_THREAD_TEST(CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
);
2876 template<class Types
, bool opaqueLayers
>
2877 class CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2881 WebTransformationMatrix scaleByHalf
;
2882 scaleByHalf
.scale(0.5);
2884 // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
2885 // 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
2886 // appears at 50, 50 and the replica at 200, 50.
2887 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 150));
2888 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, FloatPoint(50, 50), IntSize(100, 100), false);
2889 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, FloatPoint(300, 0), IntSize());
2890 typename
Types::LayerType
* aboveSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(50, 50), IntSize(50, 50), true);
2891 typename
Types::LayerType
* aboveReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(200, 50), IntSize(50, 50), true);
2893 // Filters make the layer own a surface.
2894 WebFilterOperations filters
;
2895 filters
.append(WebFilterOperation::createBlurFilter(3));
2896 filteredSurface
->setBackgroundFilters(filters
);
2898 this->calcDrawEtc(parent
);
2900 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2901 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2903 this->visitLayer(aboveReplicaLayer
, occlusion
);
2904 this->visitLayer(aboveSurfaceLayer
, occlusion
);
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 // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
2911 IntRect occlusionAboveSurface
= IntRect(50, 50, 50, 50);
2912 IntRect occlusionAboveReplica
= IntRect(200, 50, 50, 50);
2914 IntRect expectedOpaqueBounds
= unionRect(occlusionAboveSurface
, occlusionAboveReplica
);
2915 EXPECT_RECT_EQ(expectedOpaqueBounds
, occlusion
.occlusionInScreenSpace().bounds());
2916 EXPECT_EQ(2u, occlusion
.occlusionInScreenSpace().rects().size());
2917 EXPECT_RECT_EQ(expectedOpaqueBounds
, occlusion
.occlusionInTargetSurface().bounds());
2918 EXPECT_EQ(2u, occlusion
.occlusionInTargetSurface().rects().size());
2922 // Scale transforms require main thread+commit to get contentBounds right.
2923 MAIN_THREAD_TEST(CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
);
2925 template<class Types
, bool opaqueLayers
>
2926 class CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
2930 WebTransformationMatrix scaleByHalf
;
2931 scaleByHalf
.scale(0.5);
2933 // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
2934 // 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
2935 // appears at 50, 50 and the replica at 200, 50.
2936 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(300, 150));
2937 typename
Types::LayerType
* filteredSurface
= this->createDrawingLayer(parent
, scaleByHalf
, FloatPoint(50, 50), IntSize(100, 100), false);
2938 this->createReplicaLayer(filteredSurface
, this->identityMatrix
, FloatPoint(300, 0), IntSize());
2939 typename
Types::LayerType
* aboveSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(70, 50), IntSize(30, 50), true);
2940 typename
Types::LayerType
* aboveReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(200, 50), IntSize(30, 50), true);
2941 typename
Types::LayerType
* besideSurfaceLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(90, 40), IntSize(10, 10), true);
2942 typename
Types::LayerType
* besideReplicaLayer
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(200, 40), IntSize(10, 10), true);
2944 // Filters make the layer own a surface.
2945 WebFilterOperations filters
;
2946 filters
.append(WebFilterOperation::createBlurFilter(3));
2947 filteredSurface
->setBackgroundFilters(filters
);
2949 // Save the distance of influence for the blur effect.
2950 int outsetTop
, outsetRight
, outsetBottom
, outsetLeft
;
2951 filters
.getOutsets(outsetTop
, outsetRight
, outsetBottom
, outsetLeft
);
2953 this->calcDrawEtc(parent
);
2955 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
2956 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2958 this->visitLayer(besideReplicaLayer
, occlusion
);
2959 this->visitLayer(besideSurfaceLayer
, occlusion
);
2960 this->visitLayer(aboveReplicaLayer
, occlusion
);
2961 this->visitLayer(aboveSurfaceLayer
, occlusion
);
2963 // The surface has a background blur, so it blurs non-opaque pixels below it.
2964 this->visitLayer(filteredSurface
, occlusion
);
2965 this->visitContributingSurface(filteredSurface
, occlusion
);
2967 // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
2968 // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
2969 // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
2970 // the occluded part of the surface.
2971 IntRect occlusionAboveSurface
= IntRect(70 + outsetRight
, 50, 30 - outsetRight
, 50);
2972 IntRect occlusionAboveReplica
= IntRect(200, 50, 30 - outsetLeft
, 50);
2973 IntRect occlusionBesideSurface
= IntRect(90, 40, 10, 10);
2974 IntRect occlusionBesideReplica
= IntRect(200, 40, 10, 10);
2976 Region expectedOcclusion
;
2977 expectedOcclusion
.unite(occlusionAboveSurface
);
2978 expectedOcclusion
.unite(occlusionAboveReplica
);
2979 expectedOcclusion
.unite(occlusionBesideSurface
);
2980 expectedOcclusion
.unite(occlusionBesideReplica
);
2982 ASSERT_EQ(expectedOcclusion
.rects().size(), occlusion
.occlusionInTargetSurface().rects().size());
2983 ASSERT_EQ(expectedOcclusion
.rects().size(), occlusion
.occlusionInScreenSpace().rects().size());
2985 for (size_t i
= 0; i
< expectedOcclusion
.rects().size(); ++i
) {
2986 IntRect expectedRect
= expectedOcclusion
.rects()[i
];
2987 IntRect screenRect
= occlusion
.occlusionInScreenSpace().rects()[i
];
2988 IntRect targetRect
= occlusion
.occlusionInTargetSurface().rects()[i
];
2989 EXPECT_EQ(expectedRect
, screenRect
);
2990 EXPECT_EQ(expectedRect
, targetRect
);
2995 // Scale transforms require main thread+commit to get contentBounds right.
2996 MAIN_THREAD_TEST(CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
);
2998 template<class Types
, bool opaqueLayers
>
2999 class CCOcclusionTrackerTestMinimumTrackingSize
: public CCOcclusionTrackerTest
<Types
, opaqueLayers
> {
3003 IntSize
trackingSize(100, 100);
3004 IntSize
belowTrackingSize(99, 99);
3006 typename
Types::ContentLayerType
* parent
= this->createRoot(this->identityMatrix
, FloatPoint(0, 0), IntSize(400, 400));
3007 typename
Types::LayerType
* large
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), trackingSize
, true);
3008 typename
Types::LayerType
* small
= this->createDrawingLayer(parent
, this->identityMatrix
, FloatPoint(0, 0), belowTrackingSize
, true);
3009 this->calcDrawEtc(parent
);
3011 TestCCOcclusionTrackerWithClip
<typename
Types::LayerType
, typename
Types::RenderSurfaceType
> occlusion(IntRect(0, 0, 1000, 1000));
3012 occlusion
.setLayerClipRect(IntRect(0, 0, 1000, 1000));
3013 occlusion
.setMinimumTrackingSize(trackingSize
);
3015 // The small layer is not tracked because it is too small.
3016 this->visitLayer(small
, occlusion
);
3018 EXPECT_RECT_EQ(IntRect(), occlusion
.occlusionInScreenSpace().bounds());
3019 EXPECT_EQ(0u, occlusion
.occlusionInScreenSpace().rects().size());
3020 EXPECT_RECT_EQ(IntRect(), occlusion
.occlusionInTargetSurface().bounds());
3021 EXPECT_EQ(0u, occlusion
.occlusionInTargetSurface().rects().size());
3023 // The large layer is tracked as it is large enough.
3024 this->visitLayer(large
, occlusion
);
3026 EXPECT_RECT_EQ(IntRect(IntPoint(), trackingSize
), occlusion
.occlusionInScreenSpace().bounds());
3027 EXPECT_EQ(1u, occlusion
.occlusionInScreenSpace().rects().size());
3028 EXPECT_RECT_EQ(IntRect(IntPoint(), trackingSize
), occlusion
.occlusionInTargetSurface().bounds());
3029 EXPECT_EQ(1u, occlusion
.occlusionInTargetSurface().rects().size());
3033 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestMinimumTrackingSize
);