Revert 161482 - [cc] Store CCLayerImpls as scoped_ptrs
[chromium-blink-merge.git] / cc / CCOcclusionTrackerTest.cpp
blob18bb243d5d766db57ff5a6ba7bb6893e1ab2cd01
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "config.h"
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"
18 #include "Region.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>
26 using namespace cc;
27 using namespace WebKit;
28 using namespace WebKitTests;
30 namespace {
32 class TestContentLayerChromium : public TiledLayerChromium {
33 public:
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 { }
56 private:
57 virtual ~TestContentLayerChromium()
61 bool m_overrideOpaqueContentsRect;
62 IntRect m_opaqueContentsRect;
65 class TestContentLayerImpl : public CCTiledLayerImpl {
66 public:
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;
86 private:
87 bool m_overrideOpaqueContentsRect;
88 IntRect m_opaqueContentsRect;
91 template<typename LayerType, typename RenderSurfaceType>
92 class TestCCOcclusionTrackerWithClip : public TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType> {
93 public:
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; }
103 protected:
104 virtual IntRect layerClipRectInTarget(const LayerType* layer) const { return m_overrideLayerClipRect ? m_layerClipRect : CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTarget(layer); }
106 private:
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)
130 layer = NULL;
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)
151 layer.clear();
155 int CCOcclusionTrackerTestImplThreadTypes::nextCCLayerImplId = 1;
157 template<typename Types, bool opaqueLayers>
158 class CCOcclusionTrackerTest : public testing::Test {
159 protected:
160 CCOcclusionTrackerTest()
161 : testing::Test()
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);
182 ASSERT(!m_root);
183 m_root = layer.release();
184 return layerPtr;
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());
193 return layerPtr;
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);
202 return layer;
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);
211 if (opaqueLayers)
212 layerPtr->setContentsOpaque(opaque);
213 else {
214 layerPtr->setContentsOpaque(false);
215 if (opaque)
216 layerPtr->setOpaqueContentsRect(IntRect(IntPoint(), bounds));
217 else
218 layerPtr->setOpaqueContentsRect(IntRect());
221 parent->addChild(layer.release());
222 return layerPtr;
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());
231 return layerPtr;
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());
240 return layerPtr;
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);
249 return layer;
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);
289 ++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);
304 ++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);
314 ++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;
330 private:
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> { \
387 public: \
388 ClassName##MainThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestMainThreadTypes, true>() { } \
389 }; \
390 TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
391 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
392 class ClassName##MainThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestMainThreadTypes, false> { \
393 public: \
394 ClassName##MainThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestMainThreadTypes, false>() { } \
395 }; \
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; \
401 public: \
402 ClassName##ImplThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestImplThreadTypes, true>() { } \
403 }; \
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; \
408 public: \
409 ClassName##ImplThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestImplThreadTypes, false>() { } \
410 }; \
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> {
435 protected:
436 void runMyTest()
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> {
483 protected:
484 void runMyTest()
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> {
536 protected:
537 void runMyTest()
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> {
599 protected:
600 void runMyTest()
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 | |
661 | | | | | | | |
662 | | | |500 | | | |
663 | | | | | | | |
664 | | | | | | | |
665 | | | | | | | |
666 | | | | | | |10|
667 +--|-------------------------------+ | | +------------------------------|--+
668 | | | 490 |
669 +---------------------------------+ +---------------------------------+
670 500 500
675 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestChildInRotatedChild);
677 template<class Types, bool opaqueLayers>
678 class CCOcclusionTrackerTestVisitTargetTwoTimes : public CCOcclusionTrackerTest<Types, opaqueLayers> {
679 protected:
680 void runMyTest()
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 | |
773 | | | | | | | |
774 | | | |500 | | | |
775 | | | | | | | |
776 | | | | | | | |
777 | | | | | | | |
778 | | | | | | |10|
779 +--|-------------------------------+ | | +------------------------------|--+
780 | | | 490 |
781 +---------------------------------+ +---------------------------------+
782 500 500
787 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestVisitTargetTwoTimes);
789 template<class Types, bool opaqueLayers>
790 class CCOcclusionTrackerTestSurfaceRotatedOffAxis : public CCOcclusionTrackerTest<Types, opaqueLayers> {
791 protected:
792 void runMyTest()
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> {
857 protected:
858 void runMyTest()
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 | +---------------------------------+
921 | | |10 |
922 | +---------------+-----------------+ |
923 | | |\\\\\\\\\\\\|//| 420 | |
924 | | |\\\\\\\\\\\\|//|60 | |
925 | | |\\\\\\\\\\\\|//| | |
926 +--|--|------------|--+ | |
927 20|10| 70 | | |
928 | | | | |
929 | | | | |
930 | | | | |
931 | | | | |
932 | | | | |
933 | | | |10|
934 | +------------|-----------------|--+
935 | | 490 |
936 +---------------+-----------------+
937 60 440
942 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
944 template<class Types, bool opaqueLayers>
945 class CCOcclusionTrackerTestOverlappingSurfaceSiblings : public CCOcclusionTrackerTest<Types, opaqueLayers> {
946 protected:
947 void runMyTest()
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 +---------------------+
1029 | 20 | layer1
1030 | 30+ ---------------------------------+
1031 100 | 30| | layer2 |
1032 |20+----------------------------------+ |
1033 | | | | | |
1034 | | | | | |
1035 | | | | | |
1036 +--|-|----------------+ | |
1037 | | | | 510
1038 | | | |
1039 | | | |
1040 | | | |
1041 | | | |
1042 | | | |
1043 | | | |
1044 | +--------------------------------|-+
1046 +----------------------------------+
1052 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblings);
1054 template<class Types, bool opaqueLayers>
1055 class CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1056 protected:
1057 void runMyTest()
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 +---------------------+
1137 |20 | layer1
1138 10+----------------------------------+
1139 100 || 30 | layer2 |
1140 |20+----------------------------------+
1141 || | | | |
1142 || | | | |
1143 || | | | |
1144 +|-|------------------+ | |
1145 | | | | 510
1146 | | 510 | |
1147 | | | |
1148 | | | |
1149 | | | |
1150 | | | |
1151 | | 520 | |
1152 +----------------------------------+ |
1154 +----------------------------------+
1160 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1162 template<class Types, bool opaqueLayers>
1163 class CCOcclusionTrackerTestFilters : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1164 protected:
1165 void runMyTest()
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);
1182 filters.clear();
1183 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
1184 opaqueLayer->setFilters(filters);
1186 filters.clear();
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> {
1248 protected:
1249 void runMyTest()
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> {
1279 protected:
1280 void runMyTest()
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> {
1311 protected:
1312 void runMyTest()
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> {
1343 protected:
1344 void runMyTest()
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> {
1387 protected:
1388 void runMyTest()
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> {
1431 protected:
1432 void runMyTest()
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> {
1470 protected:
1471 void runMyTest()
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> {
1509 protected:
1510 void runMyTest()
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> {
1552 protected:
1553 void runMyTest()
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> {
1595 protected:
1596 void runMyTest()
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> {
1638 protected:
1639 void runMyTest()
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> {
1681 protected:
1682 void runMyTest()
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> {
1705 protected:
1706 void runMyTest()
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> {
1741 protected:
1742 void runMyTest()
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> {
1802 protected:
1803 void runMyTest()
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> {
1825 protected:
1826 void runMyTest()
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
1833 // tracker.
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> {
1863 protected:
1864 void runMyTest()
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> {
1891 protected:
1892 void runMyTest()
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> {
1924 protected:
1925 void runMyTest()
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> {
1954 protected:
1955 void runMyTest()
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> {
1988 protected:
1989 void runMyTest()
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> {
2040 protected:
2041 void runMyTest()
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> {
2092 protected:
2093 void runMyTest()
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> {
2184 protected:
2185 void runMyTest()
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> {
2228 protected:
2229 void runMyTest()
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> {
2253 protected:
2254 void runMyTest()
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> {
2291 protected:
2292 void runMyTest()
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> {
2330 protected:
2331 void runMyTest()
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> {
2371 protected:
2372 void runMyTest()
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> {
2429 protected:
2430 void runMyTest()
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> {
2468 protected:
2469 void runMyTest()
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> {
2519 protected:
2520 void runMyTest()
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());
2593 IntRect outsetRect;
2594 IntRect testRect;
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> {
2645 protected:
2646 void runMyTest()
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> {
2703 protected:
2704 void runMyTest()
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());
2774 IntRect outsetRect;
2775 IntRect clippedOutsetRect;
2776 IntRect testRect;
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> {
2828 protected:
2829 void runMyTest()
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> {
2878 protected:
2879 void runMyTest()
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> {
2927 protected:
2928 void runMyTest()
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> {
3000 protected:
3001 void runMyTest()
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);
3035 } // namespace