596b0692cab799338e5cc36589c32942c2a5a71f
[WebKit-https.git] / Source / WebKit / chromium / tests / CCOcclusionTrackerTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "cc/CCOcclusionTracker.h"
28
29 #include "CCAnimationTestCommon.h"
30 #include "CCLayerTreeTestCommon.h"
31 #include "CCOcclusionTrackerTestCommon.h"
32 #include "LayerChromium.h"
33 #include "Region.h"
34 #include "TranslateTransformOperation.h"
35 #include "cc/CCLayerAnimationController.h"
36 #include "cc/CCLayerImpl.h"
37 #include "cc/CCLayerTreeHostCommon.h"
38 #include "cc/CCMathUtil.h"
39 #include "cc/CCOverdrawMetrics.h"
40 #include "cc/CCSingleThreadProxy.h"
41 #include <gmock/gmock.h>
42 #include <gtest/gtest.h>
43 #include <public/WebFilterOperation.h>
44 #include <public/WebFilterOperations.h>
45 #include <public/WebTransformationMatrix.h>
46
47 using namespace WebCore;
48 using namespace WebKit;
49 using namespace WebKitTests;
50
51 namespace {
52
53 class TestContentLayerChromium : public LayerChromium {
54 public:
55     TestContentLayerChromium()
56         : LayerChromium()
57         , m_overrideOpaqueContentsRect(false)
58     {
59     }
60
61     virtual bool drawsContent() const OVERRIDE { return true; }
62     virtual Region visibleContentOpaqueRegion() const OVERRIDE
63     {
64         if (m_overrideOpaqueContentsRect)
65             return intersection(m_opaqueContentsRect, visibleContentRect());
66         return LayerChromium::visibleContentOpaqueRegion();
67     }
68     void setOpaqueContentsRect(const IntRect& opaqueContentsRect)
69     {
70         m_overrideOpaqueContentsRect = true;
71         m_opaqueContentsRect = opaqueContentsRect;
72     }
73
74 private:
75     bool m_overrideOpaqueContentsRect;
76     IntRect m_opaqueContentsRect;
77 };
78
79 class TestContentLayerImpl : public CCLayerImpl {
80 public:
81     TestContentLayerImpl(int id)
82         : CCLayerImpl(id)
83         , m_overrideOpaqueContentsRect(false)
84     {
85         setDrawsContent(true);
86     }
87
88     virtual Region visibleContentOpaqueRegion() const OVERRIDE
89     {
90         if (m_overrideOpaqueContentsRect)
91             return intersection(m_opaqueContentsRect, visibleContentRect());
92         return CCLayerImpl::visibleContentOpaqueRegion();
93     }
94     void setOpaqueContentsRect(const IntRect& opaqueContentsRect)
95     {
96         m_overrideOpaqueContentsRect = true;
97         m_opaqueContentsRect = opaqueContentsRect;
98     }
99
100 private:
101     bool m_overrideOpaqueContentsRect;
102     IntRect m_opaqueContentsRect;
103 };
104
105 template<typename LayerType, typename RenderSurfaceType>
106 class TestCCOcclusionTrackerWithScissor : public TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType> {
107 public:
108     TestCCOcclusionTrackerWithScissor(IntRect screenScissorRect, bool recordMetricsForFrame = false)
109         : TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType>(screenScissorRect, recordMetricsForFrame)
110         , m_overrideLayerScissorRect(false)
111     {
112     }
113
114     void setLayerScissorRect(const IntRect& rect) { m_overrideLayerScissorRect = true; m_layerScissorRect = rect;}
115     void useDefaultLayerScissorRect() { m_overrideLayerScissorRect = false; }
116
117 protected:
118     virtual IntRect layerScissorRectInTargetSurface(const LayerType* layer) const { return m_overrideLayerScissorRect ? m_layerScissorRect : CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerScissorRectInTargetSurface(layer); }
119
120 private:
121     bool m_overrideLayerScissorRect;
122     IntRect m_layerScissorRect;
123 };
124
125 struct CCOcclusionTrackerTestMainThreadTypes {
126     typedef LayerChromium LayerType;
127     typedef RenderSurfaceChromium RenderSurfaceType;
128     typedef TestContentLayerChromium ContentLayerType;
129     typedef RefPtr<LayerChromium> LayerPtrType;
130     typedef PassRefPtr<LayerChromium> PassLayerPtrType;
131     typedef RefPtr<ContentLayerType> ContentLayerPtrType;
132     typedef PassRefPtr<ContentLayerType> PassContentLayerPtrType;
133     typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> LayerIterator;
134     typedef CCOcclusionTracker OcclusionTrackerType;
135
136     static PassLayerPtrType createLayer()
137     {
138         return LayerChromium::create();
139     }
140     static PassContentLayerPtrType createContentLayer() { return adoptRef(new ContentLayerType()); }
141 };
142
143 struct CCOcclusionTrackerTestImplThreadTypes {
144     typedef CCLayerImpl LayerType;
145     typedef CCRenderSurface RenderSurfaceType;
146     typedef TestContentLayerImpl ContentLayerType;
147     typedef OwnPtr<CCLayerImpl> LayerPtrType;
148     typedef PassOwnPtr<CCLayerImpl> PassLayerPtrType;
149     typedef OwnPtr<ContentLayerType> ContentLayerPtrType;
150     typedef PassOwnPtr<ContentLayerType> PassContentLayerPtrType;
151     typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::FrontToBack> LayerIterator;
152     typedef CCOcclusionTrackerImpl OcclusionTrackerType;
153
154     static PassLayerPtrType createLayer() { return CCLayerImpl::create(nextCCLayerImplId++); }
155     static PassContentLayerPtrType createContentLayer() { return adoptPtr(new ContentLayerType(nextCCLayerImplId++)); }
156     static int nextCCLayerImplId;
157 };
158
159 int CCOcclusionTrackerTestImplThreadTypes::nextCCLayerImplId = 1;
160
161 template<typename Types, bool opaqueLayers>
162 class CCOcclusionTrackerTest : public testing::Test {
163 protected:
164     CCOcclusionTrackerTest()
165         : testing::Test()
166     { }
167
168     virtual void runMyTest() = 0;
169
170     virtual void TearDown()
171     {
172         m_root.clear();
173         m_renderSurfaceLayerListChromium.clear();
174         m_renderSurfaceLayerListImpl.clear();
175         m_replicaLayers.clear();
176         m_maskLayers.clear();
177         CCLayerTreeHost::setNeedsFilterContext(false);
178     }
179
180     typename Types::ContentLayerType* createRoot(const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
181     {
182         typename Types::ContentLayerPtrType layer(Types::createContentLayer());
183         typename Types::ContentLayerType* layerPtr = layer.get();
184         setProperties(layerPtr, transform, position, bounds);
185
186         ASSERT(!m_root);
187         m_root = layer.release();
188         return layerPtr;
189     }
190
191     typename Types::LayerType* createLayer(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
192     {
193         typename Types::LayerPtrType layer(Types::createLayer());
194         typename Types::LayerType* layerPtr = layer.get();
195         setProperties(layerPtr, transform, position, bounds);
196         parent->addChild(layer.release());
197         return layerPtr;
198     }
199
200     typename Types::LayerType* createSurface(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
201     {
202         typename Types::LayerType* layer = createLayer(parent, transform, position, bounds);
203         WebFilterOperations filters;
204         filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
205         layer->setFilters(filters);
206         return layer;
207     }
208
209     typename Types::ContentLayerType* createDrawingLayer(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
210     {
211         typename Types::ContentLayerPtrType layer(Types::createContentLayer());
212         typename Types::ContentLayerType* layerPtr = layer.get();
213         setProperties(layerPtr, transform, position, bounds);
214
215         if (opaqueLayers)
216             layerPtr->setOpaque(opaque);
217         else {
218             layerPtr->setOpaque(false);
219             if (opaque)
220                 layerPtr->setOpaqueContentsRect(IntRect(IntPoint(), bounds));
221             else
222                 layerPtr->setOpaqueContentsRect(IntRect());
223         }
224
225         parent->addChild(layer.release());
226         return layerPtr;
227     }
228
229     typename Types::LayerType* createReplicaLayer(typename Types::LayerType* owningLayer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
230     {
231         typename Types::ContentLayerPtrType layer(Types::createContentLayer());
232         typename Types::ContentLayerType* layerPtr = layer.get();
233         setProperties(layerPtr, transform, position, bounds);
234         setReplica(owningLayer, layer.release());
235         return layerPtr;
236     }
237
238     typename Types::LayerType* createMaskLayer(typename Types::LayerType* owningLayer, const IntSize& bounds)
239     {
240         typename Types::ContentLayerPtrType layer(Types::createContentLayer());
241         typename Types::ContentLayerType* layerPtr = layer.get();
242         setProperties(layerPtr, identityMatrix, FloatPoint(), bounds);
243         setMask(owningLayer, layer.release());
244         return layerPtr;
245     }
246
247     typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
248     {
249         typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque);
250         WebFilterOperations filters;
251         filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
252         layer->setFilters(filters);
253         return layer;
254     }
255
256     void calcDrawEtc(TestContentLayerImpl* root)
257     {
258         ASSERT(root == m_root.get());
259         int dummyMaxTextureSize = 512;
260         CCLayerSorter layerSorter;
261
262         ASSERT(!root->renderSurface());
263
264         CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, &layerSorter, dummyMaxTextureSize, m_renderSurfaceLayerListImpl);
265
266         CCLayerTreeHostCommon::calculateVisibleAndScissorRects(m_renderSurfaceLayerListImpl, root->renderSurface()->contentRect());
267
268         m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListImpl);
269     }
270
271     void calcDrawEtc(TestContentLayerChromium* root)
272     {
273         ASSERT(root == m_root.get());
274         int dummyMaxTextureSize = 512;
275
276         ASSERT(!root->renderSurface());
277
278         CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, dummyMaxTextureSize, m_renderSurfaceLayerListChromium);
279
280         CCLayerTreeHostCommon::calculateVisibleAndScissorRects(m_renderSurfaceLayerListChromium, root->renderSurface()->contentRect());
281
282         m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListChromium);
283     }
284
285     void enterLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
286     {
287         ASSERT_EQ(layer, *m_layerIterator);
288         ASSERT_TRUE(m_layerIterator.representsItself());
289         occlusion.enterLayer(m_layerIterator);
290     }
291
292     void leaveLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
293     {
294         ASSERT_EQ(layer, *m_layerIterator);
295         ASSERT_TRUE(m_layerIterator.representsItself());
296         occlusion.leaveLayer(m_layerIterator);
297         ++m_layerIterator;
298     }
299
300     void visitLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
301     {
302         enterLayer(layer, occlusion);
303         leaveLayer(layer, occlusion);
304     }
305
306     void enterContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
307     {
308         ASSERT_EQ(layer, *m_layerIterator);
309         ASSERT_TRUE(m_layerIterator.representsTargetRenderSurface());
310         occlusion.enterLayer(m_layerIterator);
311         occlusion.leaveLayer(m_layerIterator);
312         ++m_layerIterator;
313         ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
314         occlusion.enterLayer(m_layerIterator);
315     }
316
317     void leaveContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
318     {
319         ASSERT_EQ(layer, *m_layerIterator);
320         ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
321         occlusion.leaveLayer(m_layerIterator);
322         ++m_layerIterator;
323     }
324
325     void visitContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
326     {
327         enterContributingSurface(layer, occlusion);
328         leaveContributingSurface(layer, occlusion);
329     }
330
331     void resetLayerIterator()
332     {
333         m_layerIterator = m_layerIteratorBegin;
334     }
335
336     const WebTransformationMatrix identityMatrix;
337
338 private:
339     void setBaseProperties(typename Types::LayerType* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
340     {
341         layer->setTransform(transform);
342         layer->setSublayerTransform(WebTransformationMatrix());
343         layer->setAnchorPoint(FloatPoint(0, 0));
344         layer->setPosition(position);
345         layer->setBounds(bounds);
346     }
347
348     void setProperties(LayerChromium* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
349     {
350         setBaseProperties(layer, transform, position, bounds);
351     }
352
353     void setProperties(CCLayerImpl* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
354     {
355         setBaseProperties(layer, transform, position, bounds);
356
357         layer->setContentBounds(layer->bounds());
358     }
359
360     void setReplica(LayerChromium* owningLayer, PassRefPtr<LayerChromium> layer)
361     {
362         owningLayer->setReplicaLayer(layer.get());
363         m_replicaLayers.append(layer);
364     }
365
366     void setReplica(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer)
367     {
368         owningLayer->setReplicaLayer(layer);
369     }
370
371     void setMask(LayerChromium* owningLayer, PassRefPtr<LayerChromium> layer)
372     {
373         owningLayer->setMaskLayer(layer.get());
374         m_maskLayers.append(layer);
375     }
376
377     void setMask(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer)
378     {
379         owningLayer->setMaskLayer(layer);
380     }
381
382     // These hold ownership of the layers for the duration of the test.
383     typename Types::LayerPtrType m_root;
384     Vector<RefPtr<LayerChromium> > m_renderSurfaceLayerListChromium;
385     Vector<CCLayerImpl*> m_renderSurfaceLayerListImpl;
386     typename Types::LayerIterator m_layerIteratorBegin;
387     typename Types::LayerIterator m_layerIterator;
388     typename Types::LayerType* m_lastLayerVisited;
389     Vector<RefPtr<LayerChromium> > m_replicaLayers;
390     Vector<RefPtr<LayerChromium> > m_maskLayers;
391 };
392
393 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
394     class ClassName##MainThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestMainThreadTypes, true> { \
395     public: \
396         ClassName##MainThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestMainThreadTypes, true>() { } \
397     }; \
398     TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
399 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
400     class ClassName##MainThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestMainThreadTypes, false> { \
401     public: \
402         ClassName##MainThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestMainThreadTypes, false>() { } \
403     }; \
404     TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
405
406 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
407     class ClassName##ImplThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestImplThreadTypes, true> { \
408         DebugScopedSetImplThread impl; \
409     public: \
410         ClassName##ImplThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestImplThreadTypes, true>() { } \
411     }; \
412     TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
413 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
414     class ClassName##ImplThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestImplThreadTypes, false> { \
415         DebugScopedSetImplThread impl; \
416     public: \
417         ClassName##ImplThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestImplThreadTypes, false>() { } \
418     }; \
419     TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
420
421 #define ALL_CCOCCLUSIONTRACKER_TEST(ClassName) \
422     RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
423     RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
424     RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
425     RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
426
427 #define MAIN_THREAD_TEST(ClassName) \
428     RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
429
430 #define IMPL_THREAD_TEST(ClassName) \
431     RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
432
433 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
434     RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
435     RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
436
437 template<class Types, bool opaqueLayers>
438 class CCOcclusionTrackerTestIdentityTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
439 protected:
440     void runMyTest()
441     {
442         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
443         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(30, 30), IntSize(500, 500), true);
444         this->calcDrawEtc(parent);
445
446         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
447         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
448
449         this->visitLayer(layer, occlusion);
450         this->enterLayer(parent, occlusion);
451
452         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
453         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
454         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
455         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
456
457         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
458         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
459         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
460         EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
461         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
462
463         occlusion.useDefaultLayerScissorRect();
464         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
465         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
466         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
467         EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
468         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
469         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
470
471         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)).isEmpty());
472         EXPECT_INT_RECT_EQ(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 70, 70)));
473         EXPECT_INT_RECT_EQ(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 29, 70, 70)));
474         EXPECT_INT_RECT_EQ(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
475         EXPECT_INT_RECT_EQ(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 29, 70, 70)));
476         EXPECT_INT_RECT_EQ(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 70, 70)));
477         EXPECT_INT_RECT_EQ(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 31, 70, 70)));
478         EXPECT_INT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 31, 70, 70)));
479         EXPECT_INT_RECT_EQ(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 31, 70, 70)));
480     }
481 };
482
483 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestIdentityTransforms);
484
485 template<class Types, bool opaqueLayers>
486 class CCOcclusionTrackerTestRotatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
487 protected:
488     void runMyTest()
489     {
490         WebTransformationMatrix layerTransform;
491         layerTransform.translate(250, 250);
492         layerTransform.rotate(90);
493         layerTransform.translate(-250, -250);
494
495         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
496         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
497         this->calcDrawEtc(parent);
498
499         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
500         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
501
502         this->visitLayer(layer, occlusion);
503         this->enterLayer(parent, occlusion);
504
505         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
506         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
507         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
508         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
509
510         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
511         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
512         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
513         EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
514         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
515
516         occlusion.useDefaultLayerScissorRect();
517         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
518         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
519         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
520         EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
521         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
522         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
523
524         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)).isEmpty());
525         EXPECT_INT_RECT_EQ(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 70, 70)));
526         EXPECT_INT_RECT_EQ(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 29, 70, 70)));
527         EXPECT_INT_RECT_EQ(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
528         EXPECT_INT_RECT_EQ(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 29, 70, 70)));
529         EXPECT_INT_RECT_EQ(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 70, 70)));
530         EXPECT_INT_RECT_EQ(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 31, 70, 70)));
531         EXPECT_INT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 31, 70, 70)));
532         EXPECT_INT_RECT_EQ(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 31, 70, 70)));
533     }
534 };
535
536 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestRotatedChild);
537
538 template<class Types, bool opaqueLayers>
539 class CCOcclusionTrackerTestTranslatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
540 protected:
541     void runMyTest()
542     {
543         WebTransformationMatrix layerTransform;
544         layerTransform.translate(20, 20);
545
546         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
547         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
548         this->calcDrawEtc(parent);
549
550         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
551         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
552
553         this->visitLayer(layer, occlusion);
554         this->enterLayer(parent, occlusion);
555
556         EXPECT_INT_RECT_EQ(IntRect(50, 50, 50, 50), occlusion.occlusionInScreenSpace().bounds());
557         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
558         EXPECT_INT_RECT_EQ(IntRect(50, 50, 50, 50), occlusion.occlusionInTargetSurface().bounds());
559         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
560
561         EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 50, 50, 50)));
562         EXPECT_FALSE(occlusion.occluded(parent, IntRect(49, 50, 50, 50)));
563         EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 49, 50, 50)));
564         EXPECT_FALSE(occlusion.occluded(parent, IntRect(51, 50, 50, 50)));
565         EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 51, 50, 50)));
566
567         occlusion.useDefaultLayerScissorRect();
568         EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 50, 50, 50)));
569         EXPECT_FALSE(occlusion.occluded(parent, IntRect(49, 50, 50, 50)));
570         EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 49, 50, 50)));
571         EXPECT_TRUE(occlusion.occluded(parent, IntRect(51, 50, 50, 50)));
572         EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 51, 50, 50)));
573         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
574
575         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 50, 50, 50)).isEmpty());
576         EXPECT_INT_RECT_EQ(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 50, 50, 50)));
577         EXPECT_INT_RECT_EQ(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 49, 50, 50)));
578         EXPECT_INT_RECT_EQ(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 49, 50, 50)));
579         EXPECT_INT_RECT_EQ(IntRect(51, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 49, 50, 50)));
580         EXPECT_INT_RECT_EQ(IntRect(100, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 50, 50, 50)));
581         EXPECT_INT_RECT_EQ(IntRect(51, 51, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 51, 50, 50)));
582         EXPECT_INT_RECT_EQ(IntRect(50, 100, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 51, 50, 50)));
583         EXPECT_INT_RECT_EQ(IntRect(49, 51, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 51, 50, 50)));
584
585         occlusion.useDefaultLayerScissorRect();
586         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 50, 50, 50)).isEmpty());
587         EXPECT_INT_RECT_EQ(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 50, 50, 50)));
588         EXPECT_INT_RECT_EQ(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 49, 50, 50)));
589         EXPECT_INT_RECT_EQ(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 49, 50, 50)));
590         EXPECT_INT_RECT_EQ(IntRect(51, 49, 49, 1), occlusion.unoccludedContentRect(parent, IntRect(51, 49, 50, 50)));
591         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(51, 50, 50, 50)).isEmpty());
592         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(51, 51, 50, 50)).isEmpty());
593         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 51, 50, 50)).isEmpty());
594         EXPECT_INT_RECT_EQ(IntRect(49, 51, 1, 49), occlusion.unoccludedContentRect(parent, IntRect(49, 51, 50, 50)));
595         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
596     }
597 };
598
599 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTranslatedChild);
600
601 template<class Types, bool opaqueLayers>
602 class CCOcclusionTrackerTestChildInRotatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
603 protected:
604     void runMyTest()
605     {
606         WebTransformationMatrix childTransform;
607         childTransform.translate(250, 250);
608         childTransform.rotate(90);
609         childTransform.translate(-250, -250);
610
611         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
612         typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
613         child->setMasksToBounds(true);
614         typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
615         this->calcDrawEtc(parent);
616
617         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
618         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
619
620         this->visitLayer(layer, occlusion);
621         this->enterContributingSurface(child, occlusion);
622
623         EXPECT_INT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
624         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
625         EXPECT_INT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
626         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
627
628         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
629         EXPECT_FALSE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
630         EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
631         EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 430, 61, 70)));
632         EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 430, 60, 71)));
633
634         occlusion.useDefaultLayerScissorRect();
635         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
636         EXPECT_TRUE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
637         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
638         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 61, 70)));
639         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 71)));
640         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
641
642         this->leaveContributingSurface(child, occlusion);
643         this->enterLayer(parent, occlusion);
644
645         EXPECT_INT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
646         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
647         EXPECT_INT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
648         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
649
650         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
651         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
652         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
653         EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 40, 70, 60)));
654         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 41, 70, 60)));
655
656         occlusion.useDefaultLayerScissorRect();
657         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
658         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
659         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
660         EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 40, 70, 60)));
661         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 41, 70, 60)));
662         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
663
664
665         /* Justification for the above occlusion from |layer|:
666                    100
667           +---------------------+                                      +---------------------+
668           |                     |                                      |                     |30  Visible region of |layer|: /////
669           |    30               |           rotate(90)                 |                     |
670           | 30 + ---------------------------------+                    |     +---------------------------------+
671       100 |    |  10            |                 |            ==>     |     |               |10               |
672           |    |10+---------------------------------+                  |  +---------------------------------+  |
673           |    |  |             |                 | |                  |  |  |///////////////|     420      |  |
674           |    |  |             |                 | |                  |  |  |///////////////|60            |  |
675           |    |  |             |                 | |                  |  |  |///////////////|              |  |
676           +----|--|-------------+                 | |                  +--|--|---------------+              |  |
677                |  |                               | |                   20|10|     70                       |  |
678                |  |                               | |                     |  |                              |  |
679                |  |                               | |500                  |  |                              |  |
680                |  |                               | |                     |  |                              |  |
681                |  |                               | |                     |  |                              |  |
682                |  |                               | |                     |  |                              |  |
683                |  |                               | |                     |  |                              |10|
684                +--|-------------------------------+ |                     |  +------------------------------|--+
685                   |                                 |                     |                 490             |
686                   +---------------------------------+                     +---------------------------------+
687                                  500                                                     500
688          */
689     }
690 };
691
692 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestChildInRotatedChild);
693
694 template<class Types, bool opaqueLayers>
695 class CCOcclusionTrackerTestVisitTargetTwoTimes : public CCOcclusionTrackerTest<Types, opaqueLayers> {
696 protected:
697     void runMyTest()
698     {
699         WebTransformationMatrix childTransform;
700         childTransform.translate(250, 250);
701         childTransform.rotate(90);
702         childTransform.translate(-250, -250);
703
704         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
705         typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
706         child->setMasksToBounds(true);
707         typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
708         // |child2| makes |parent|'s surface get considered by CCOcclusionTracker first, instead of |child|'s. This exercises different code in
709         // leaveToTargetRenderSurface, as the target surface has already been seen.
710         typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(30, 30), IntSize(60, 20), true);
711         this->calcDrawEtc(parent);
712
713         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
714         occlusion.setLayerScissorRect(IntRect(-10, -10, 1000, 1000));
715
716         this->visitLayer(child2, occlusion);
717
718         EXPECT_INT_RECT_EQ(IntRect(30, 30, 60, 20), occlusion.occlusionInScreenSpace().bounds());
719         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
720         EXPECT_INT_RECT_EQ(IntRect(30, 30, 60, 20), occlusion.occlusionInTargetSurface().bounds());
721         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
722
723         this->visitLayer(layer, occlusion);
724
725         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
726         EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
727         EXPECT_INT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
728         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
729
730         this->enterContributingSurface(child, occlusion);
731
732         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
733         EXPECT_FALSE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
734         EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
735         EXPECT_FALSE(occlusion.occluded(child, IntRect(11, 430, 60, 70)));
736         EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 431, 60, 70)));
737
738         occlusion.useDefaultLayerScissorRect();
739         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
740         EXPECT_TRUE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
741         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
742         EXPECT_TRUE(occlusion.occluded(child, IntRect(11, 430, 60, 70)));
743         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 431, 60, 70)));
744         occlusion.setLayerScissorRect(IntRect(-10, -10, 1000, 1000));
745
746         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 430, 60, 70)).isEmpty());
747         // This is the little piece not occluded by child2
748         EXPECT_INT_RECT_EQ(IntRect(9, 430, 1, 10), occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 70)));
749         // This extends past both sides of child2, so it will be the original rect.
750         EXPECT_INT_RECT_EQ(IntRect(9, 430, 60, 80), occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 80)));
751         // This extends past two adjacent sides of child2, and should included the unoccluded parts of each side.
752         // This also demonstrates that the rect can be arbitrary and does not get clipped to the layer's visibleContentRect().
753         EXPECT_INT_RECT_EQ(IntRect(-10, 430, 20, 70), occlusion.unoccludedContentRect(child, IntRect(-10, 430, 60, 70)));
754         // This extends past three adjacent sides of child2, so it should contain the unoccluded parts of each side. The left
755         // and bottom edges are completely unoccluded for some row/column so we get back the original query rect.
756         EXPECT_INT_RECT_EQ(IntRect(-10, 430, 60, 80), occlusion.unoccludedContentRect(child, IntRect(-10, 430, 60, 80)));
757         EXPECT_INT_RECT_EQ(IntRect(10, 429, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 429, 60, 70)));
758         EXPECT_INT_RECT_EQ(IntRect(70, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(11, 430, 60, 70)));
759         EXPECT_INT_RECT_EQ(IntRect(10, 500, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 431, 60, 70)));
760
761         occlusion.useDefaultLayerScissorRect();
762         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 430, 60, 70)).isEmpty());
763         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 70)).isEmpty());
764         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 80)).isEmpty());
765         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(-10, 430, 60, 70)).isEmpty());
766         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(-10, 430, 60, 80)).isEmpty());
767         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 429, 60, 70)).isEmpty());
768         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(11, 430, 60, 70)).isEmpty());
769         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 431, 60, 70)).isEmpty());
770         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
771
772         // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
773         this->leaveContributingSurface(child, occlusion);
774         this->enterLayer(parent, occlusion);
775
776         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
777         EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
778         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
779         EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
780
781         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
782         EXPECT_INT_RECT_EQ(IntRect(90, 30, 10, 10), occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)));
783
784         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 60, 10)));
785         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 60, 10)));
786         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 60, 10)));
787         EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 60, 10)));
788         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 60, 10)));
789
790         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
791         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
792         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
793
794         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 60, 10)).isEmpty());
795         EXPECT_INT_RECT_EQ(IntRect(29, 30, 1, 10), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 60, 10)));
796         EXPECT_INT_RECT_EQ(IntRect(30, 29, 60, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 60, 10)));
797         EXPECT_INT_RECT_EQ(IntRect(90, 30, 1, 10), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 60, 10)));
798         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 31, 60, 10)).isEmpty());
799
800         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 40, 70, 60)).isEmpty());
801         EXPECT_INT_RECT_EQ(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(29, 40, 70, 60)));
802         // This rect is mostly occluded by |child2|.
803         EXPECT_INT_RECT_EQ(IntRect(90, 39, 10, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 39, 70, 60)));
804         // This rect extends past top/right ends of |child2|.
805         EXPECT_INT_RECT_EQ(IntRect(30, 29, 70, 11), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
806         // This rect extends past left/right ends of |child2|.
807         EXPECT_INT_RECT_EQ(IntRect(20, 39, 80, 60), occlusion.unoccludedContentRect(parent, IntRect(20, 39, 80, 60)));
808         EXPECT_INT_RECT_EQ(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(31, 40, 70, 60)));
809         EXPECT_INT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 41, 70, 60)));
810
811         /* Justification for the above occlusion from |layer|:
812                    100
813           +---------------------+                                      +---------------------+
814           |                     |                                      |                     |30  Visible region of |layer|: /////
815           |    30               |           rotate(90)                 |     30   60         |    |child2|: \\\\\
816           | 30 + ------------+--------------------+                    |  30 +------------+--------------------+
817       100 |    |  10         |  |                 |            ==>     |     |\\\\\\\\\\\\|  |10               |
818           |    |10+----------|----------------------+                  |  +--|\\\\\\\\\\\\|-----------------+  |
819           |    + ------------+  |                 | |                  |  |  +------------+//|     420      |  |
820           |    |  |             |                 | |                  |  |  |///////////////|60            |  |
821           |    |  |             |                 | |                  |  |  |///////////////|              |  |
822           +----|--|-------------+                 | |                  +--|--|---------------+              |  |
823                |  |                               | |                   20|10|     70                       |  |
824                |  |                               | |                     |  |                              |  |
825                |  |                               | |500                  |  |                              |  |
826                |  |                               | |                     |  |                              |  |
827                |  |                               | |                     |  |                              |  |
828                |  |                               | |                     |  |                              |  |
829                |  |                               | |                     |  |                              |10|
830                +--|-------------------------------+ |                     |  +------------------------------|--+
831                   |                                 |                     |                 490             |
832                   +---------------------------------+                     +---------------------------------+
833                                  500                                                     500
834          */
835     }
836 };
837
838 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestVisitTargetTwoTimes);
839
840 template<class Types, bool opaqueLayers>
841 class CCOcclusionTrackerTestSurfaceRotatedOffAxis : public CCOcclusionTrackerTest<Types, opaqueLayers> {
842 protected:
843     void runMyTest()
844     {
845         WebTransformationMatrix childTransform;
846         childTransform.translate(250, 250);
847         childTransform.rotate(95);
848         childTransform.translate(-250, -250);
849
850         WebTransformationMatrix layerTransform;
851         layerTransform.translate(10, 10);
852
853         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
854         typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
855         child->setMasksToBounds(true);
856         typename Types::ContentLayerType* layer = this->createDrawingLayer(child, layerTransform, FloatPoint(0, 0), IntSize(500, 500), true);
857         this->calcDrawEtc(parent);
858
859         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
860         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
861
862         IntRect clippedLayerInChild = CCMathUtil::mapClippedRect(layerTransform, layer->visibleContentRect());
863
864         this->visitLayer(layer, occlusion);
865         this->enterContributingSurface(child, occlusion);
866
867         EXPECT_INT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
868         EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
869         EXPECT_INT_RECT_EQ(clippedLayerInChild, occlusion.occlusionInTargetSurface().bounds());
870         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
871
872         EXPECT_TRUE(occlusion.occluded(child, clippedLayerInChild));
873         EXPECT_TRUE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
874         clippedLayerInChild.move(-1, 0);
875         EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
876         EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
877         clippedLayerInChild.move(1, 0);
878         clippedLayerInChild.move(1, 0);
879         EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
880         EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
881         clippedLayerInChild.move(-1, 0);
882         clippedLayerInChild.move(0, -1);
883         EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
884         EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
885         clippedLayerInChild.move(0, 1);
886         clippedLayerInChild.move(0, 1);
887         EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
888         EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
889         clippedLayerInChild.move(0, -1);
890
891         this->leaveContributingSurface(child, occlusion);
892         this->enterLayer(parent, occlusion);
893
894         EXPECT_INT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
895         EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
896         EXPECT_INT_RECT_EQ(IntRect(), occlusion.occlusionInTargetSurface().bounds());
897         EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
898
899         EXPECT_FALSE(occlusion.occluded(parent, IntRect(75, 55, 1, 1)));
900         EXPECT_INT_RECT_EQ(IntRect(75, 55, 1, 1), occlusion.unoccludedContentRect(parent, IntRect(75, 55, 1, 1)));
901     }
902 };
903
904 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceRotatedOffAxis);
905
906 template<class Types, bool opaqueLayers>
907 class CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren : public CCOcclusionTrackerTest<Types, opaqueLayers> {
908 protected:
909     void runMyTest()
910     {
911         WebTransformationMatrix childTransform;
912         childTransform.translate(250, 250);
913         childTransform.rotate(90);
914         childTransform.translate(-250, -250);
915
916         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
917         typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
918         child->setMasksToBounds(true);
919         typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
920         typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 450), IntSize(500, 60), true);
921         this->calcDrawEtc(parent);
922
923         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
924         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
925
926         this->visitLayer(layer2, occlusion);
927         this->visitLayer(layer1, occlusion);
928         this->enterContributingSurface(child, occlusion);
929
930         EXPECT_INT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
931         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
932         EXPECT_INT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
933         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
934
935         EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
936         EXPECT_FALSE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
937         EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
938         EXPECT_FALSE(occlusion.occluded(child, IntRect(11, 430, 60, 70)));
939         EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 431, 60, 70)));
940
941         EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 430, 60, 70)).isEmpty());
942         EXPECT_INT_RECT_EQ(IntRect(9, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 70)));
943         EXPECT_INT_RECT_EQ(IntRect(10, 429, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 429, 60, 70)));
944         EXPECT_INT_RECT_EQ(IntRect(70, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(11, 430, 60, 70)));
945         EXPECT_INT_RECT_EQ(IntRect(10, 500, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 431, 60, 70)));
946
947         this->leaveContributingSurface(child, occlusion);
948         this->enterLayer(parent, occlusion);
949
950         EXPECT_INT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
951         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
952         EXPECT_INT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
953         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
954
955         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
956         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
957         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
958
959         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 40, 70, 60)).isEmpty());
960         EXPECT_INT_RECT_EQ(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(29, 40, 70, 60)));
961         EXPECT_INT_RECT_EQ(IntRect(30, 39, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 39, 70, 60)));
962         EXPECT_INT_RECT_EQ(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(31, 40, 70, 60)));
963         EXPECT_INT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 41, 70, 60)));
964
965         /* Justification for the above occlusion from |layer1| and |layer2|:
966
967            +---------------------+
968            |                     |30  Visible region of |layer1|: /////
969            |                     |    Visible region of |layer2|: \\\\\
970            |     +---------------------------------+
971            |     |               |10               |
972            |  +---------------+-----------------+  |
973            |  |  |\\\\\\\\\\\\|//|     420      |  |
974            |  |  |\\\\\\\\\\\\|//|60            |  |
975            |  |  |\\\\\\\\\\\\|//|              |  |
976            +--|--|------------|--+              |  |
977             20|10|     70     |                 |  |
978               |  |            |                 |  |
979               |  |            |                 |  |
980               |  |            |                 |  |
981               |  |            |                 |  |
982               |  |            |                 |  |
983               |  |            |                 |10|
984               |  +------------|-----------------|--+
985               |               | 490             |
986               +---------------+-----------------+
987                      60               440
988          */
989     }
990 };
991
992 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
993
994 template<class Types, bool opaqueLayers>
995 class CCOcclusionTrackerTestOverlappingSurfaceSiblings : public CCOcclusionTrackerTest<Types, opaqueLayers> {
996 protected:
997     void runMyTest()
998     {
999         WebTransformationMatrix childTransform;
1000         childTransform.translate(250, 250);
1001         childTransform.rotate(90);
1002         childTransform.translate(-250, -250);
1003
1004         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1005         typename Types::LayerType* child1 = this->createSurface(parent, childTransform, FloatPoint(30, 30), IntSize(10, 10));
1006         typename Types::LayerType* child2 = this->createSurface(parent, childTransform, FloatPoint(20, 40), IntSize(10, 10));
1007         typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
1008         typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
1009         this->calcDrawEtc(parent);
1010
1011         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1012         occlusion.setLayerScissorRect(IntRect(-20, -20, 1000, 1000));
1013
1014         this->visitLayer(layer2, occlusion);
1015         this->enterContributingSurface(child2, occlusion);
1016
1017         EXPECT_INT_RECT_EQ(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
1018         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1019         EXPECT_INT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
1020         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1021
1022         EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
1023         EXPECT_FALSE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
1024         EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
1025         EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
1026         EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
1027
1028         occlusion.useDefaultLayerScissorRect();
1029         EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
1030         EXPECT_TRUE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
1031         EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
1032         EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
1033         EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
1034         occlusion.setLayerScissorRect(IntRect(-20, -20, 1000, 1000));
1035
1036         // There is nothing above child2's surface in the z-order.
1037         EXPECT_INT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, IntRect(-10, 420, 70, 80)));
1038
1039         this->leaveContributingSurface(child2, occlusion);
1040         this->visitLayer(layer1, occlusion);
1041         this->enterContributingSurface(child1, occlusion);
1042
1043         EXPECT_INT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
1044         EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
1045         EXPECT_INT_RECT_EQ(IntRect(-10, 430, 80, 70), occlusion.occlusionInTargetSurface().bounds());
1046         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1047
1048         EXPECT_TRUE(occlusion.occluded(child1, IntRect(-10, 430, 80, 70)));
1049         EXPECT_FALSE(occlusion.occluded(child1, IntRect(-11, 430, 80, 70)));
1050         EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 429, 80, 70)));
1051         EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 81, 70)));
1052         EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 80, 71)));
1053
1054         // child2's contents will occlude child1 below it.
1055         EXPECT_INT_RECT_EQ(IntRect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(-10, 430, 80, 70)));
1056
1057         this->leaveContributingSurface(child1, occlusion);
1058         this->enterLayer(parent, occlusion);
1059
1060         EXPECT_INT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
1061         EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
1062         EXPECT_INT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInTargetSurface().bounds());
1063         EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
1064
1065         EXPECT_FALSE(occlusion.occluded(parent, IntRect(20, 20, 80, 80)));
1066
1067         EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 20, 70, 80)));
1068         EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 20, 70, 80)));
1069         EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 19, 70, 80)));
1070
1071         EXPECT_TRUE(occlusion.occluded(parent, IntRect(20, 30, 80, 70)));
1072         EXPECT_FALSE(occlusion.occluded(parent, IntRect(19, 30, 80, 70)));
1073         EXPECT_FALSE(occlusion.occluded(parent, IntRect(20, 29, 80, 70)));
1074
1075         /* Justification for the above occlusion:
1076                    100
1077           +---------------------+
1078           |    20               |       layer1
1079           |  30+ ---------------------------------+
1080       100 |  30|                |     layer2      |
1081           |20+----------------------------------+ |
1082           |  | |                |               | |
1083           |  | |                |               | |
1084           |  | |                |               | |
1085           +--|-|----------------+               | |
1086              | |                                | | 510
1087              | |                                | |
1088              | |                                | |
1089              | |                                | |
1090              | |                                | |
1091              | |                                | |
1092              | |                                | |
1093              | +--------------------------------|-+
1094              |                                  |
1095              +----------------------------------+
1096                              510
1097          */
1098     }
1099 };
1100
1101 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblings);
1102
1103 template<class Types, bool opaqueLayers>
1104 class CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1105 protected:
1106     void runMyTest()
1107     {
1108         WebTransformationMatrix child1Transform;
1109         child1Transform.translate(250, 250);
1110         child1Transform.rotate(-90);
1111         child1Transform.translate(-250, -250);
1112
1113         WebTransformationMatrix child2Transform;
1114         child2Transform.translate(250, 250);
1115         child2Transform.rotate(90);
1116         child2Transform.translate(-250, -250);
1117
1118         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1119         typename Types::LayerType* child1 = this->createSurface(parent, child1Transform, FloatPoint(30, 20), IntSize(10, 10));
1120         typename Types::LayerType* child2 = this->createDrawingSurface(parent, child2Transform, FloatPoint(20, 40), IntSize(10, 10), false);
1121         typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -20), IntSize(510, 510), true);
1122         typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
1123         this->calcDrawEtc(parent);
1124
1125         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1126         occlusion.setLayerScissorRect(IntRect(-30, -30, 1000, 1000));
1127
1128         this->visitLayer(layer2, occlusion);
1129         this->enterLayer(child2, occlusion);
1130
1131         EXPECT_INT_RECT_EQ(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
1132         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1133         EXPECT_INT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
1134         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1135
1136         EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
1137         EXPECT_FALSE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
1138         EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
1139         EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
1140         EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
1141
1142         this->leaveLayer(child2, occlusion);
1143         this->enterContributingSurface(child2, occlusion);
1144
1145         // There is nothing above child2's surface in the z-order.
1146         EXPECT_INT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, IntRect(-10, 420, 70, 80)));
1147
1148         this->leaveContributingSurface(child2, occlusion);
1149         this->visitLayer(layer1, occlusion);
1150         this->enterContributingSurface(child1, occlusion);
1151
1152         EXPECT_INT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
1153         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1154         EXPECT_INT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion.occlusionInTargetSurface().bounds());
1155         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1156
1157         EXPECT_TRUE(occlusion.occluded(child1, IntRect(420, -20, 80, 90)));
1158         EXPECT_FALSE(occlusion.occluded(child1, IntRect(419, -20, 80, 90)));
1159         EXPECT_FALSE(occlusion.occluded(child1, IntRect(420, -21, 80, 90)));
1160         EXPECT_FALSE(occlusion.occluded(child1, IntRect(420, -19, 80, 90)));
1161         EXPECT_FALSE(occlusion.occluded(child1, IntRect(421, -20, 80, 90)));
1162
1163         // child2's contents will occlude child1 below it.
1164         EXPECT_INT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -20, 80, 90)));
1165         EXPECT_INT_RECT_EQ(IntRect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -10, 80, 90)));
1166         EXPECT_INT_RECT_EQ(IntRect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -20, 70, 90)));
1167
1168         this->leaveContributingSurface(child1, occlusion);
1169         this->enterLayer(parent, occlusion);
1170
1171         EXPECT_INT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
1172         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1173         EXPECT_INT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInTargetSurface().bounds());
1174         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1175
1176         EXPECT_TRUE(occlusion.occluded(parent, IntRect(10, 20, 90, 80)));
1177         EXPECT_FALSE(occlusion.occluded(parent, IntRect(9, 20, 90, 80)));
1178         EXPECT_FALSE(occlusion.occluded(parent, IntRect(10, 19, 90, 80)));
1179         EXPECT_FALSE(occlusion.occluded(parent, IntRect(11, 20, 90, 80)));
1180         EXPECT_FALSE(occlusion.occluded(parent, IntRect(10, 21, 90, 80)));
1181
1182         /* Justification for the above occlusion:
1183                       100
1184             +---------------------+
1185             |20                   |       layer1
1186            10+----------------------------------+
1187         100 || 30                 |     layer2  |
1188             |20+----------------------------------+
1189             || |                  |             | |
1190             || |                  |             | |
1191             || |                  |             | |
1192             +|-|------------------+             | |
1193              | |                                | | 510
1194              | |                            510 | |
1195              | |                                | |
1196              | |                                | |
1197              | |                                | |
1198              | |                                | |
1199              | |                520             | |
1200              +----------------------------------+ |
1201                |                                  |
1202                +----------------------------------+
1203                                510
1204          */
1205     }
1206 };
1207
1208 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1209
1210 template<class Types, bool opaqueLayers>
1211 class CCOcclusionTrackerTestFilters : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1212 protected:
1213     void runMyTest()
1214     {
1215         WebTransformationMatrix layerTransform;
1216         layerTransform.translate(250, 250);
1217         layerTransform.rotate(90);
1218         layerTransform.translate(-250, -250);
1219
1220         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1221         typename Types::ContentLayerType* blurLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1222         typename Types::ContentLayerType* opaqueLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1223         typename Types::ContentLayerType* opacityLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1224
1225         WebFilterOperations filters;
1226         filters.append(WebFilterOperation::createBlurFilter(10));
1227         blurLayer->setFilters(filters);
1228
1229         filters.clear();
1230         filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
1231         opaqueLayer->setFilters(filters);
1232
1233         filters.clear();
1234         filters.append(WebFilterOperation::createOpacityFilter(0.5));
1235         opacityLayer->setFilters(filters);
1236
1237         this->calcDrawEtc(parent);
1238
1239         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1240         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1241
1242         // Opacity layer won't contribute to occlusion.
1243         this->visitLayer(opacityLayer, occlusion);
1244         this->enterContributingSurface(opacityLayer, occlusion);
1245
1246         EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1247         EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1248
1249         // And has nothing to contribute to its parent surface.
1250         this->leaveContributingSurface(opacityLayer, occlusion);
1251         EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1252         EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1253
1254         // Opaque layer will contribute to occlusion.
1255         this->visitLayer(opaqueLayer, occlusion);
1256         this->enterContributingSurface(opaqueLayer, occlusion);
1257
1258         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
1259         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1260         EXPECT_INT_RECT_EQ(IntRect(0, 430, 70, 70), occlusion.occlusionInTargetSurface().bounds());
1261         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1262
1263         // And it gets translated to the parent surface.
1264         this->leaveContributingSurface(opaqueLayer, occlusion);
1265         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
1266         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1267         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
1268         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1269
1270         // The blur layer needs to throw away any occlusion from outside its subtree.
1271         this->enterLayer(blurLayer, occlusion);
1272         EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1273         EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1274
1275         // And it won't contribute to occlusion.
1276         this->leaveLayer(blurLayer, occlusion);
1277         this->enterContributingSurface(blurLayer, occlusion);
1278         EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1279         EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1280
1281         // But the opaque layer's occlusion is preserved on the parent. 
1282         this->leaveContributingSurface(blurLayer, occlusion);
1283         this->enterLayer(parent, occlusion);
1284         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
1285         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1286         EXPECT_INT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
1287         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1288     }
1289 };
1290
1291 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestFilters);
1292
1293 template<class Types, bool opaqueLayers>
1294 class CCOcclusionTrackerTestReplicaDoesOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1295 protected:
1296     void runMyTest()
1297     {
1298         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
1299         typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1300         this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1301         this->calcDrawEtc(parent);
1302
1303         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1304         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1305
1306         this->visitLayer(surface, occlusion);
1307
1308         EXPECT_INT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
1309         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1310         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
1311         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1312
1313         this->visitContributingSurface(surface, occlusion);
1314         this->enterLayer(parent, occlusion);
1315
1316         // The surface and replica should both be occluding the parent.
1317         EXPECT_INT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
1318         EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
1319     }
1320 };
1321
1322 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaDoesOcclude);
1323
1324 template<class Types, bool opaqueLayers>
1325 class CCOcclusionTrackerTestReplicaWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1326 protected:
1327     void runMyTest()
1328     {
1329         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 170));
1330         typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1331         this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1332         this->calcDrawEtc(parent);
1333
1334         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1335         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1336
1337         this->visitLayer(surface, occlusion);
1338
1339         EXPECT_INT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
1340         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1341         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
1342         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1343
1344         this->visitContributingSurface(surface, occlusion);
1345         this->enterLayer(parent, occlusion);
1346
1347         // The surface and replica should both be occluding the parent.
1348         EXPECT_INT_RECT_EQ(IntRect(0, 100, 100, 70), occlusion.occlusionInTargetSurface().bounds());
1349         EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
1350     }
1351 };
1352
1353 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithClipping);
1354
1355 template<class Types, bool opaqueLayers>
1356 class CCOcclusionTrackerTestReplicaWithMask : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1357 protected:
1358     void runMyTest()
1359     {
1360         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
1361         typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1362         typename Types::LayerType* replica = this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1363         this->createMaskLayer(replica, IntSize(10, 10));
1364         this->calcDrawEtc(parent);
1365
1366         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1367         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1368
1369         this->visitLayer(surface, occlusion);
1370
1371         EXPECT_INT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
1372         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1373         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
1374         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1375
1376         this->visitContributingSurface(surface, occlusion);
1377         this->enterLayer(parent, occlusion);
1378
1379         // The replica should not be occluding the parent, since it has a mask applied to it.
1380         EXPECT_INT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInTargetSurface().bounds());
1381         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1382     }
1383 };
1384
1385 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithMask);
1386
1387 template<class Types, bool opaqueLayers>
1388 class CCOcclusionTrackerTestLayerScissorRectOutsideChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1389 protected:
1390     void runMyTest()
1391     {
1392         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1393         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1394         this->calcDrawEtc(parent);
1395
1396         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1397         occlusion.setLayerScissorRect(IntRect(200, 100, 100, 100));
1398
1399         this->enterLayer(layer, occlusion);
1400
1401         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1402         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1403         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1404         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1405         EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1406
1407         occlusion.useDefaultLayerScissorRect();
1408         EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1409         occlusion.setLayerScissorRect(IntRect(200, 100, 100, 100));
1410
1411         this->leaveLayer(layer, occlusion);
1412         this->visitContributingSurface(layer, occlusion);
1413         this->enterLayer(parent, occlusion);
1414
1415         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1416         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1417         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1418         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1419         EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1420         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1421         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1422         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1423         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1424
1425         EXPECT_INT_RECT_EQ(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1426     }
1427 };
1428
1429 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectOutsideChild);
1430
1431 template<class Types, bool opaqueLayers>
1432 class CCOcclusionTrackerTestScreenScissorRectOutsideChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1433 protected:
1434     void runMyTest()
1435     {
1436         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1437         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1438         this->calcDrawEtc(parent);
1439
1440         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(200, 100, 100, 100));
1441         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1442
1443         this->enterLayer(layer, occlusion);
1444
1445         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1446         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1447         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1448         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1449         EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1450
1451         occlusion.useDefaultLayerScissorRect();
1452         EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1453         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1454
1455         this->leaveLayer(layer, occlusion);
1456         this->visitContributingSurface(layer, occlusion);
1457         this->enterLayer(parent, occlusion);
1458
1459         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1460         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1461         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1462         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1463         EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1464         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1465         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1466         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1467         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1468
1469         EXPECT_INT_RECT_EQ(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1470     }
1471 };
1472
1473 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestScreenScissorRectOutsideChild);
1474
1475 template<class Types, bool opaqueLayers>
1476 class CCOcclusionTrackerTestLayerScissorRectOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1477 protected:
1478     void runMyTest()
1479     {
1480         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1481         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1482         this->calcDrawEtc(parent);
1483
1484         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1485         occlusion.setLayerScissorRect(IntRect(100, 100, 100, 100));
1486
1487         this->enterLayer(layer, occlusion);
1488
1489         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1490         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1491         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1492         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1493
1494         this->leaveLayer(layer, occlusion);
1495         this->visitContributingSurface(layer, occlusion);
1496         this->enterLayer(parent, occlusion);
1497
1498         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1499         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1500         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1501         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1502         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1503         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1504         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1505         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1506         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1507
1508         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1509     }
1510 };
1511
1512 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectOverChild);
1513
1514 template<class Types, bool opaqueLayers>
1515 class CCOcclusionTrackerTestScreenScissorRectOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1516 protected:
1517     void runMyTest()
1518     {
1519         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1520         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1521         this->calcDrawEtc(parent);
1522
1523         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(100, 100, 100, 100));
1524         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1525
1526         this->enterLayer(layer, occlusion);
1527
1528         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1529         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1530         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1531         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1532
1533         this->leaveLayer(layer, occlusion);
1534         this->visitContributingSurface(layer, occlusion);
1535         this->enterLayer(parent, occlusion);
1536
1537         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1538         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1539         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1540         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1541         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1542         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1543         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1544         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1545         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1546
1547         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1548     }
1549 };
1550
1551 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestScreenScissorRectOverChild);
1552
1553 template<class Types, bool opaqueLayers>
1554 class CCOcclusionTrackerTestLayerScissorRectPartlyOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1555 protected:
1556     void runMyTest()
1557     {
1558         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1559         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1560         this->calcDrawEtc(parent);
1561
1562         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1563         occlusion.setLayerScissorRect(IntRect(50, 50, 200, 200));
1564
1565         this->enterLayer(layer, occlusion);
1566
1567         EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1568         EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1569         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1570         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1571
1572         this->leaveLayer(layer, occlusion);
1573         this->visitContributingSurface(layer, occlusion);
1574         this->enterLayer(parent, occlusion);
1575
1576         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1577         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1578         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1579         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1580         EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1581         EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1582         EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1583         EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1584         EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1585
1586         EXPECT_INT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1587         EXPECT_INT_RECT_EQ(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)));
1588         EXPECT_INT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)));
1589         EXPECT_INT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)));
1590         EXPECT_INT_RECT_EQ(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)));
1591     }
1592 };
1593
1594 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectPartlyOverChild);
1595
1596 template<class Types, bool opaqueLayers>
1597 class CCOcclusionTrackerTestScreenScissorRectPartlyOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1598 protected:
1599     void runMyTest()
1600     {
1601         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1602         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1603         this->calcDrawEtc(parent);
1604
1605         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(50, 50, 200, 200));
1606         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1607
1608         this->enterLayer(layer, occlusion);
1609
1610         EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1611         EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1612         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1613         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1614
1615         this->leaveLayer(layer, occlusion);
1616         this->visitContributingSurface(layer, occlusion);
1617         this->enterLayer(parent, occlusion);
1618
1619         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1620         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1621         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1622         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1623         EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1624         EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1625         EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1626         EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1627         EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1628
1629         EXPECT_INT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1630         EXPECT_INT_RECT_EQ(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)));
1631         EXPECT_INT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)));
1632         EXPECT_INT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)));
1633         EXPECT_INT_RECT_EQ(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)));
1634     }
1635 };
1636
1637 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestScreenScissorRectPartlyOverChild);
1638
1639 template<class Types, bool opaqueLayers>
1640 class CCOcclusionTrackerTestLayerScissorRectOverNothing : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1641 protected:
1642     void runMyTest()
1643     {
1644         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1645         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1646         this->calcDrawEtc(parent);
1647
1648         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1649         occlusion.setLayerScissorRect(IntRect(500, 500, 100, 100));
1650
1651         this->enterLayer(layer, occlusion);
1652
1653         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1654         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1655         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1656         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1657
1658         this->leaveLayer(layer, occlusion);
1659         this->visitContributingSurface(layer, occlusion);
1660         this->enterLayer(parent, occlusion);
1661
1662         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1663         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1664         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1665         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1666         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1667         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1668         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1669         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1670         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1671
1672         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1673         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)).isEmpty());
1674         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)).isEmpty());
1675         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)).isEmpty());
1676         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)).isEmpty());
1677     }
1678 };
1679
1680 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectOverNothing);
1681
1682 template<class Types, bool opaqueLayers>
1683 class CCOcclusionTrackerTestScreenScissorRectOverNothing : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1684 protected:
1685     void runMyTest()
1686     {
1687         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1688         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1689         this->calcDrawEtc(parent);
1690
1691         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(500, 500, 100, 100));
1692         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1693
1694         this->enterLayer(layer, occlusion);
1695
1696         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1697         EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1698         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1699         EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1700
1701         this->leaveLayer(layer, occlusion);
1702         this->visitContributingSurface(layer, occlusion);
1703         this->enterLayer(parent, occlusion);
1704
1705         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1706         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1707         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1708         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1709         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1710         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1711         EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1712         EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1713         EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1714
1715         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1716         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)).isEmpty());
1717         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)).isEmpty());
1718         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)).isEmpty());
1719         EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)).isEmpty());
1720     }
1721 };
1722
1723 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestScreenScissorRectOverNothing);
1724
1725 template<class Types, bool opaqueLayers>
1726 class CCOcclusionTrackerTestLayerScissorRectForLayerOffOrigin : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1727 protected:
1728     void runMyTest()
1729     {
1730         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1731         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1732         this->calcDrawEtc(parent);
1733
1734         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1735         this->enterLayer(layer, occlusion);
1736
1737         // This layer is translated when drawn into its target. So if the scissor rect given from the target surface
1738         // is not in that target space, then after translating these query rects into the target, they will fall outside
1739         // the scissor and be considered occluded.
1740         EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1741         EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1742         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1743         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1744     }
1745 };
1746
1747 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectForLayerOffOrigin);
1748
1749 template<class Types, bool opaqueLayers>
1750 class CCOcclusionTrackerTestOpaqueContentsRegionEmpty : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1751 protected:
1752     void runMyTest()
1753     {
1754         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1755         typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), false);
1756         this->calcDrawEtc(parent);
1757
1758         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1759         this->enterLayer(layer, occlusion);
1760
1761         EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1762         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1763         EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1764         EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1765
1766         // Occluded since its outside the surface bounds.
1767         EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1768
1769         // Test without any scissors.
1770         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1771         EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1772         occlusion.useDefaultLayerScissorRect();
1773
1774         this->leaveLayer(layer, occlusion);
1775         this->visitContributingSurface(layer, occlusion);
1776         this->enterLayer(parent, occlusion);
1777
1778         EXPECT_TRUE(occlusion.occlusionInScreenSpace().bounds().isEmpty());
1779         EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
1780     }
1781 };
1782
1783 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionEmpty);
1784
1785 template<class Types, bool opaqueLayers>
1786 class CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1787 protected:
1788     void runMyTest()
1789     {
1790         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1791         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(200, 200), false);
1792         this->calcDrawEtc(parent);
1793
1794         {
1795             TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1796             layer->setOpaqueContentsRect(IntRect(0, 0, 100, 100));
1797
1798             this->resetLayerIterator();
1799             this->visitLayer(layer, occlusion);
1800             this->enterLayer(parent, occlusion);
1801
1802             EXPECT_INT_RECT_EQ(IntRect(100, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
1803             EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1804
1805             EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1806             EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1807             EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1808         }
1809
1810         {
1811             TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1812             layer->setOpaqueContentsRect(IntRect(20, 20, 180, 180));
1813
1814             this->resetLayerIterator();
1815             this->visitLayer(layer, occlusion);
1816             this->enterLayer(parent, occlusion);
1817
1818             EXPECT_INT_RECT_EQ(IntRect(120, 120, 180, 180), occlusion.occlusionInScreenSpace().bounds());
1819             EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1820
1821             EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1822             EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1823             EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1824         }
1825
1826         {
1827             TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1828             layer->setOpaqueContentsRect(IntRect(150, 150, 100, 100));
1829
1830             this->resetLayerIterator();
1831             this->visitLayer(layer, occlusion);
1832             this->enterLayer(parent, occlusion);
1833
1834             EXPECT_INT_RECT_EQ(IntRect(250, 250, 50, 50), occlusion.occlusionInScreenSpace().bounds());
1835             EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1836
1837             EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1838             EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1839             EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1840         }
1841     }
1842 };
1843
1844 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1845
1846 template<class Types, bool opaqueLayers>
1847 class CCOcclusionTrackerTest3dTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1848 protected:
1849     void runMyTest()
1850     {
1851         WebTransformationMatrix transform;
1852         transform.rotate3d(0, 30, 0);
1853
1854         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1855         typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1856         typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
1857         this->calcDrawEtc(parent);
1858
1859         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1860         this->enterLayer(layer, occlusion);
1861
1862         // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
1863         EXPECT_INT_RECT_EQ(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
1864     }
1865 };
1866
1867 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTest3dTransform);
1868
1869 template<class Types, bool opaqueLayers>
1870 class CCOcclusionTrackerTestUnsorted3dLayers : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1871 protected:
1872     void runMyTest()
1873     {
1874         // Currently, the main thread layer iterator does not iterate over 3d items in
1875         // sorted order, because layer sorting is not performed on the main thread.
1876         // Because of this, the occlusion tracker cannot assume that a 3d layer occludes
1877         // other layers that have not yet been iterated over. For now, the expected
1878         // behavior is that a 3d layer simply does not add any occlusion to the occlusion
1879         // tracker.
1880
1881         WebTransformationMatrix translationToFront;
1882         translationToFront.translate3d(0, 0, -10);
1883         WebTransformationMatrix translationToBack;
1884         translationToFront.translate3d(0, 0, -100);
1885
1886         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1887         typename Types::ContentLayerType* child1 = this->createDrawingLayer(parent, translationToBack, FloatPoint(0, 0), IntSize(100, 100), true);
1888         typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, translationToFront, FloatPoint(50, 50), IntSize(100, 100), true);
1889         parent->setPreserves3D(true);
1890
1891         this->calcDrawEtc(parent);
1892
1893         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1894         this->visitLayer(child2, occlusion);
1895         EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1896         EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1897
1898         this->visitLayer(child1, occlusion);
1899         EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1900         EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1901     }
1902 };
1903
1904 // This test will have different layer ordering on the impl thread; the test will only work on the main thread.
1905 MAIN_THREAD_TEST(CCOcclusionTrackerTestUnsorted3dLayers);
1906
1907 template<class Types, bool opaqueLayers>
1908 class CCOcclusionTrackerTestPerspectiveTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1909 protected:
1910     void runMyTest()
1911     {
1912         WebTransformationMatrix transform;
1913         transform.translate(150, 150);
1914         transform.applyPerspective(400);
1915         transform.rotate3d(1, 0, 0, -30);
1916         transform.translate(-150, -150);
1917
1918         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1919         typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1920         typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
1921         container->setPreserves3D(true);
1922         layer->setPreserves3D(true);
1923         this->calcDrawEtc(parent);
1924
1925         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1926         this->enterLayer(layer, occlusion);
1927
1928         EXPECT_INT_RECT_EQ(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
1929     }
1930 };
1931
1932 // 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.
1933 IMPL_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransform);
1934
1935 template<class Types, bool opaqueLayers>
1936 class CCOcclusionTrackerTestPerspectiveTransformBehindCamera : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1937 protected:
1938     void runMyTest()
1939     {
1940         // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
1941         WebTransformationMatrix transform;
1942         transform.translate(250, 50);
1943         transform.applyPerspective(10);
1944         transform.translate(-250, -50);
1945         transform.translate(250, 50);
1946         transform.rotate3d(1, 0, 0, -167);
1947         transform.translate(-250, -50);
1948
1949         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 100));
1950         typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
1951         typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(0, 0), IntSize(500, 500), true);
1952         container->setPreserves3D(true);
1953         layer->setPreserves3D(true);
1954         this->calcDrawEtc(parent);
1955
1956         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1957         this->enterLayer(layer, occlusion);
1958
1959         // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
1960         // this will include many more pixels but must include at least the bottom 11 rows.
1961         EXPECT_TRUE(occlusion.unoccludedContentRect(layer, IntRect(0, 0, 500, 500)).contains(IntRect(0, 489, 500, 11)));
1962     }
1963 };
1964
1965 // 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.
1966 IMPL_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransformBehindCamera);
1967
1968 template<class Types, bool opaqueLayers>
1969 class CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1970 protected:
1971     void runMyTest()
1972     {
1973         WebTransformationMatrix transform;
1974         transform.translate(50, 50);
1975         transform.applyPerspective(100);
1976         transform.translate3d(0, 0, 110);
1977         transform.translate(-50, -50);
1978
1979         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1980         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true);
1981         parent->setPreserves3D(true);
1982         layer->setPreserves3D(true);
1983         this->calcDrawEtc(parent);
1984
1985         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1986
1987         // The |layer| is entirely behind the camera and should not occlude.
1988         this->visitLayer(layer, occlusion);
1989         this->enterLayer(parent, occlusion);
1990         EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
1991         EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
1992     }
1993 };
1994
1995 // 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.
1996 IMPL_THREAD_TEST(CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
1997
1998 template<class Types, bool opaqueLayers>
1999 class CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2000 protected:
2001     void runMyTest()
2002     {
2003         WebTransformationMatrix transform;
2004         transform.translate(50, 50);
2005         transform.applyPerspective(100);
2006         transform.translate3d(0, 0, 99);
2007         transform.translate(-50, -50);
2008
2009         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
2010         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true);
2011         parent->setPreserves3D(true);
2012         layer->setPreserves3D(true);
2013         this->calcDrawEtc(parent);
2014
2015         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2016
2017         // This is very close to the camera, so pixels in its visibleContentRect will actually go outside of the layer's clipRect.
2018         // Ensure that those pixels don't occlude things outside the clipRect.
2019         this->visitLayer(layer, occlusion);
2020         this->enterLayer(parent, occlusion);
2021         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2022         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2023         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInScreenSpace().bounds());
2024         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2025     }
2026 };
2027
2028 // 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.
2029 IMPL_THREAD_TEST(CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2030
2031 template<class Types, bool opaqueLayers>
2032 class CCOcclusionTrackerTestAnimationOpacity1OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2033 protected:
2034     void runMyTest()
2035     {
2036         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
2037         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2038         typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2039         typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
2040         typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
2041         typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false);
2042         typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
2043
2044         addOpacityTransitionToController(*layer->layerAnimationController(), 10, 0, 1, false);
2045         addOpacityTransitionToController(*surface->layerAnimationController(), 10, 0, 1, false);
2046         this->calcDrawEtc(parent);
2047
2048         EXPECT_TRUE(layer->drawOpacityIsAnimating());
2049         EXPECT_FALSE(surface->drawOpacityIsAnimating());
2050         EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
2051
2052         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2053
2054         this->visitLayer(topmost, occlusion);
2055         this->enterLayer(parent2, occlusion);
2056         // This occlusion will affect all surfaces.
2057         EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent2, IntRect(0, 0, 300, 300)));
2058         this->leaveLayer(parent2, occlusion);
2059
2060         this->visitLayer(surfaceChild2, occlusion);
2061         this->enterLayer(surfaceChild, occlusion);
2062         EXPECT_INT_RECT_EQ(IntRect(100, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 300, 300)));
2063         this->leaveLayer(surfaceChild, occlusion);
2064         this->enterLayer(surface, occlusion);
2065         EXPECT_INT_RECT_EQ(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2066         this->leaveLayer(surface, occlusion);
2067
2068         this->enterContributingSurface(surface, occlusion);
2069         // Occlusion within the surface is lost when leaving the animating surface.
2070         EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
2071         this->leaveContributingSurface(surface, occlusion);
2072
2073         this->visitLayer(layer, occlusion);
2074         this->enterLayer(parent, occlusion);
2075
2076         // Occlusion is not added for the animating |layer|.
2077         EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2078     }
2079 };
2080
2081 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity1OnMainThread);
2082
2083 template<class Types, bool opaqueLayers>
2084 class CCOcclusionTrackerTestAnimationOpacity0OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2085 protected:
2086     void runMyTest()
2087     {
2088         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
2089         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2090         typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2091         typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
2092         typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
2093         typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false);
2094         typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
2095
2096         addOpacityTransitionToController(*layer->layerAnimationController(), 10, 1, 0, false);
2097         addOpacityTransitionToController(*surface->layerAnimationController(), 10, 1, 0, false);
2098         this->calcDrawEtc(parent);
2099
2100         EXPECT_TRUE(layer->drawOpacityIsAnimating());
2101         EXPECT_FALSE(surface->drawOpacityIsAnimating());
2102         EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
2103
2104         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2105
2106         this->visitLayer(topmost, occlusion);
2107         this->enterLayer(parent2, occlusion);
2108         // This occlusion will affect all surfaces.
2109         EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2110         this->leaveLayer(parent2, occlusion);
2111
2112         this->visitLayer(surfaceChild2, occlusion);
2113         this->enterLayer(surfaceChild, occlusion);
2114         EXPECT_INT_RECT_EQ(IntRect(100, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 300, 300)));
2115         this->leaveLayer(surfaceChild, occlusion);
2116         this->enterLayer(surface, occlusion);
2117         EXPECT_INT_RECT_EQ(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2118         this->leaveLayer(surface, occlusion);
2119
2120         this->enterContributingSurface(surface, occlusion);
2121         // Occlusion within the surface is lost when leaving the animating surface.
2122         EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
2123         this->leaveContributingSurface(surface, occlusion);
2124
2125         this->visitLayer(layer, occlusion);
2126         this->enterLayer(parent, occlusion);
2127
2128         // Occlusion is not added for the animating |layer|.
2129         EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2130     }
2131 };
2132
2133 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity0OnMainThread);
2134
2135 template<class Types, bool opaqueLayers>
2136 class CCOcclusionTrackerTestAnimationTranslateOnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2137 protected:
2138     void runMyTest()
2139     {
2140         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
2141         typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2142         typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2143         typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
2144         typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
2145         typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(50, 300), true);
2146
2147         addAnimatedTransformToController(*layer->layerAnimationController(), 10, 30, 0);
2148         addAnimatedTransformToController(*surface->layerAnimationController(), 10, 30, 0);
2149         addAnimatedTransformToController(*surfaceChild->layerAnimationController(), 10, 30, 0);
2150         this->calcDrawEtc(parent);
2151
2152         EXPECT_TRUE(layer->drawTransformIsAnimating());
2153         EXPECT_TRUE(layer->screenSpaceTransformIsAnimating());
2154         EXPECT_TRUE(surface->renderSurface()->targetSurfaceTransformsAreAnimating());
2155         EXPECT_TRUE(surface->renderSurface()->screenSpaceTransformsAreAnimating());
2156         // The surface owning layer doesn't animate against its own surface.
2157         EXPECT_FALSE(surface->drawTransformIsAnimating());
2158         EXPECT_TRUE(surface->screenSpaceTransformIsAnimating());
2159         EXPECT_TRUE(surfaceChild->drawTransformIsAnimating());
2160         EXPECT_TRUE(surfaceChild->screenSpaceTransformIsAnimating());
2161
2162         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2163
2164         this->visitLayer(surface2, occlusion);
2165         this->enterContributingSurface(surface2, occlusion);
2166
2167         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
2168         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2169
2170         this->leaveContributingSurface(surface2, occlusion);
2171         this->enterLayer(surfaceChild2, occlusion);
2172
2173         // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2174         // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer.
2175         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild2, IntRect(0, 0, 100, 300)));
2176         EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
2177
2178         this->leaveLayer(surfaceChild2, occlusion);
2179         this->enterLayer(surfaceChild, occlusion);
2180         EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 100, 300)));
2181         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
2182         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2183         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
2184         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2185         EXPECT_INT_RECT_EQ(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2186
2187         // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target and the screen, so it
2188         // can't be occluded.
2189         EXPECT_INT_RECT_EQ(IntRect(0, 0, 200, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 200, 300)));
2190         EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
2191
2192         this->leaveLayer(surfaceChild, occlusion);
2193         this->enterLayer(surface, occlusion);
2194         // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2195         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
2196         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2197         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
2198         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2199         EXPECT_INT_RECT_EQ(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2200
2201         this->leaveLayer(surface, occlusion);
2202         // 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.
2203         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
2204         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2205         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion.occlusionInTargetSurface().bounds());
2206         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2207         EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2208
2209         this->enterContributingSurface(surface, occlusion);
2210         // The contributing |surface| is animating so it can't be occluded.
2211         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
2212         this->leaveContributingSurface(surface, occlusion);
2213
2214         this->enterLayer(layer, occlusion);
2215         // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
2216         EXPECT_INT_RECT_EQ(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2217         this->leaveLayer(layer, occlusion);
2218
2219         this->enterLayer(parent, occlusion);
2220         // The |layer| is animating in the screen and in its target, so no occlusion is added.
2221         EXPECT_INT_RECT_EQ(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2222     }
2223 };
2224
2225 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationTranslateOnMainThread);
2226
2227 template<class Types, bool opaqueLayers>
2228 class CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2229 protected:
2230     void runMyTest()
2231     {
2232         WebTransformationMatrix surfaceTransform;
2233         surfaceTransform.translate(300, 300);
2234         surfaceTransform.scale(2);
2235         surfaceTransform.translate(-150, -150);
2236
2237         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
2238         typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, surfaceTransform, FloatPoint(0, 0), IntSize(300, 300), false);
2239         typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(300, 300), false);
2240         surface->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
2241         surface2->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
2242         this->calcDrawEtc(parent);
2243
2244         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2245
2246         this->visitLayer(surface2, occlusion);
2247         this->visitContributingSurface(surface2, occlusion);
2248
2249         EXPECT_INT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.occlusionInScreenSpace().bounds());
2250         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2251         EXPECT_INT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.occlusionInTargetSurface().bounds());
2252         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2253
2254         // Clear any stored occlusion.
2255         occlusion.setOcclusionInScreenSpace(Region());
2256         occlusion.setOcclusionInTargetSurface(Region());
2257
2258         this->visitLayer(surface, occlusion);
2259         this->visitContributingSurface(surface, occlusion);
2260
2261         EXPECT_INT_RECT_EQ(IntRect(0, 0, 400, 400), occlusion.occlusionInScreenSpace().bounds());
2262         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2263         EXPECT_INT_RECT_EQ(IntRect(0, 0, 400, 400), occlusion.occlusionInTargetSurface().bounds());
2264         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2265     }
2266 };
2267
2268 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2269
2270 template<class Types, bool opaqueLayers>
2271 class CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2272 protected:
2273     void runMyTest()
2274     {
2275         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
2276         typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 300), false);
2277         surface->setOpaqueContentsRect(IntRect(0, 0, 400, 200));
2278         this->calcDrawEtc(parent);
2279
2280         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2281
2282         this->visitLayer(surface, occlusion);
2283         this->visitContributingSurface(surface, occlusion);
2284
2285         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 200), occlusion.occlusionInScreenSpace().bounds());
2286         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2287         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 200), occlusion.occlusionInTargetSurface().bounds());
2288         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2289     }
2290 };
2291
2292 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2293
2294 template<class Types, bool opaqueLayers>
2295 class CCOcclusionTrackerTestReplicaOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2296 protected:
2297     void runMyTest()
2298     {
2299         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2300         typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2301         this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2302         typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100), true);
2303         this->calcDrawEtc(parent);
2304
2305         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2306         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2307
2308         // |topmost| occludes the replica, but not the surface itself.
2309         this->visitLayer(topmost, occlusion);
2310
2311         EXPECT_INT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
2312         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2313         EXPECT_INT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2314         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2315
2316         this->visitLayer(surface, occlusion);
2317
2318         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
2319         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2320         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2321         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2322
2323         this->enterContributingSurface(surface, occlusion);
2324
2325         // Surface is not occluded so it shouldn't think it is.
2326         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2327     }
2328 };
2329
2330 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaOccluded);
2331
2332 template<class Types, bool opaqueLayers>
2333 class CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2334 protected:
2335     void runMyTest()
2336     {
2337         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2338         typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2339         this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2340         typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 110), true);
2341         this->calcDrawEtc(parent);
2342
2343         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2344         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2345
2346         // |topmost| occludes the surface, but not the entire surface's replica.
2347         this->visitLayer(topmost, occlusion);
2348
2349         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
2350         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2351         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInTargetSurface().bounds());
2352         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2353
2354         this->visitLayer(surface, occlusion);
2355
2356         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
2357         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2358         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2359         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2360
2361         this->enterContributingSurface(surface, occlusion);
2362
2363         // Surface is occluded, but only the top 10px of the replica.
2364         EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2365         EXPECT_INT_RECT_EQ(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, true, IntRect(0, 0, 100, 100)));
2366     }
2367 };
2368
2369 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2370
2371 template<class Types, bool opaqueLayers>
2372 class CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2373 protected:
2374     void runMyTest()
2375     {
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         this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2379         typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(40, 100), true);
2380         typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 100), true);
2381         this->calcDrawEtc(parent);
2382
2383         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2384         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2385
2386         // These occlude the surface and replica differently, so we can test each one.
2387         this->visitLayer(overReplica, occlusion);
2388         this->visitLayer(overSurface, occlusion);
2389
2390         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds());
2391         EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2392         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds());
2393         EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2394
2395         this->visitLayer(surface, occlusion);
2396
2397         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
2398         EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2399         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2400         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2401
2402         this->enterContributingSurface(surface, occlusion);
2403
2404         // Surface and replica are occluded different amounts.
2405         EXPECT_INT_RECT_EQ(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2406         EXPECT_INT_RECT_EQ(IntRect(50, 0, 50, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, true, IntRect(0, 0, 100, 100)));
2407     }
2408 };
2409
2410 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2411
2412 template<class Types, bool opaqueLayers>
2413 class CCOcclusionTrackerTestSurfaceChildOfSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2414 protected:
2415     void runMyTest()
2416     {
2417         // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2418
2419         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2420         typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2421         typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 10), IntSize(100, 50), true);
2422         typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
2423         this->calcDrawEtc(parent);
2424
2425         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(-100, -100, 1000, 1000));
2426
2427         // |topmost| occludes everything partially so we know occlusion is happening at all.
2428         this->visitLayer(topmost, occlusion);
2429
2430         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds());
2431         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2432         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
2433         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2434
2435         this->visitLayer(surfaceChild, occlusion);
2436
2437         // surfaceChild increases the occlusion in the screen by a narrow sliver.
2438         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 60), occlusion.occlusionInScreenSpace().bounds());
2439         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2440         // In its own surface, surfaceChild is at 0,0 as is its occlusion.
2441         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
2442         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2443
2444         // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2445         // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2446         // as its parent does not have a clipRect.
2447
2448         this->enterContributingSurface(surfaceChild, occlusion);
2449         // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
2450         // does not get clipped away inappropriately.
2451         EXPECT_INT_RECT_EQ(IntRect(0, 40, 100, 10), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, IntRect(0, 0, 100, 50)));
2452         this->leaveContributingSurface(surfaceChild, occlusion);
2453
2454         // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
2455         this->enterLayer(surface, occlusion);
2456         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 60), occlusion.occlusionInScreenSpace().bounds());
2457         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2458         EXPECT_INT_RECT_EQ(IntRect(0, 10, 100, 50), occlusion.occlusionInTargetSurface().bounds());
2459         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2460         this->leaveLayer(surface, occlusion);
2461
2462         this->enterContributingSurface(surface, occlusion);
2463         // The surface's parent does have a clipRect as it is the root layer.
2464         EXPECT_INT_RECT_EQ(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2465     }
2466 };
2467
2468 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfSurface);
2469
2470 template<class Types, bool opaqueLayers>
2471 class CCOcclusionTrackerTestTopmostSurfaceIsClippedToScissor : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2472 protected:
2473     void runMyTest()
2474     {
2475         // This test verifies that the top-most surface is considered occluded outside of its scissor rect and outside the screen's scissor rect.
2476
2477         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2478         typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
2479         this->calcDrawEtc(parent);
2480
2481         {
2482             // Make a screen scissor rect that is larger than the root layer's.
2483             TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2484
2485             this->visitLayer(surface, occlusion);
2486
2487             // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2488             this->enterContributingSurface(surface, occlusion);
2489             // Make sure the parent's clipRect clips the unoccluded region of the child surface.
2490             EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 300)));
2491         }
2492         this->resetLayerIterator();
2493         {
2494             // Make a screen scissor rect that is smaller than the root layer's.
2495             TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 100, 100));
2496
2497             this->visitLayer(surface, occlusion);
2498
2499             // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2500             this->enterContributingSurface(surface, occlusion);
2501             // Make sure the screen scissor rect clips the unoccluded region of the child surface.
2502             EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 300)));
2503         }
2504     }
2505 };
2506
2507 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTopmostSurfaceIsClippedToScissor);
2508
2509 template<class Types, bool opaqueLayers>
2510 class CCOcclusionTrackerTestSurfaceChildOfClippingSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2511 protected:
2512     void runMyTest()
2513     {
2514         // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2515
2516         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(80, 200));
2517         typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2518         typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), false);
2519         typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
2520         this->calcDrawEtc(parent);
2521
2522         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2523         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2524
2525         // |topmost| occludes everything partially so we know occlusion is happening at all.
2526         this->visitLayer(topmost, occlusion);
2527
2528         EXPECT_INT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInScreenSpace().bounds());
2529         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2530         EXPECT_INT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInTargetSurface().bounds());
2531         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2532
2533         // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2534         this->visitLayer(surfaceChild, occlusion);
2535
2536         EXPECT_INT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInScreenSpace().bounds());
2537         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2538         EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
2539         EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2540
2541         // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2542         // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2543         // as its parent does not have a clipRect.
2544
2545         this->enterContributingSurface(surfaceChild, occlusion);
2546         // The surfaceChild's parent does not have a clipRect as it owns a render surface.
2547         EXPECT_INT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, IntRect(0, 0, 100, 100)));
2548         this->leaveContributingSurface(surfaceChild, occlusion);
2549
2550         this->visitLayer(surface, occlusion);
2551         this->enterContributingSurface(surface, occlusion);
2552         // The surface's parent does have a clipRect as it is the root layer.
2553         EXPECT_INT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2554     }
2555 };
2556
2557 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfClippingSurface);
2558
2559 template<class Types, bool opaqueLayers>
2560 class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2561 protected:
2562     void runMyTest()
2563     {
2564         WebTransformationMatrix scaleByHalf;
2565         scaleByHalf.scale(0.5);
2566
2567         // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2568         // 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
2569         // appears at 50, 50 and the replica at 200, 50.
2570         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2571         typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2572         this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2573         typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 50), true);
2574         typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(300, 50), true);
2575         typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 50), IntSize(50, 50), true);
2576         typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 50), IntSize(100, 50), true);
2577         typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
2578
2579         // Filters make the layer own a surface.
2580         WebFilterOperations filters;
2581         filters.append(WebFilterOperation::createBlurFilter(10));
2582         filteredSurface->setBackgroundFilters(filters);
2583
2584         // Save the distance of influence for the blur effect.
2585         int outsetTop, outsetRight, outsetBottom, outsetLeft;
2586         filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2587
2588         this->calcDrawEtc(parent);
2589
2590         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2591         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2592
2593         // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2594         // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2595         this->visitLayer(occludingLayer5, occlusion);
2596         this->visitLayer(occludingLayer4, occlusion);
2597         this->visitLayer(occludingLayer3, occlusion);
2598         this->visitLayer(occludingLayer2, occlusion);
2599         this->visitLayer(occludingLayer1, occlusion);
2600
2601         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2602         EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2603         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
2604         EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2605
2606         // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2607         this->enterLayer(filteredSurface, occlusion);
2608         EXPECT_INT_RECT_EQ(IntRect(1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 100, 100)));
2609         EXPECT_INT_RECT_EQ(IntRect(0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 100, 100)));
2610         EXPECT_INT_RECT_EQ(IntRect(0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 100, 100)));
2611         EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 100, 100)));
2612
2613         EXPECT_INT_RECT_EQ(IntRect(300 + 1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 1, 0, 100, 100)));
2614         EXPECT_INT_RECT_EQ(IntRect(300 + 0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, 1, 100, 100)));
2615         EXPECT_INT_RECT_EQ(IntRect(300 + 0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 - 1, 0, 100, 100)));
2616         EXPECT_INT_RECT_EQ(IntRect(300 + 0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, -1, 100, 100)));
2617         this->leaveLayer(filteredSurface, occlusion);
2618
2619         // The filtered layer/replica does not occlude.
2620         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2621         EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2622         EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
2623         EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2624
2625         // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2626         // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2627         this->visitContributingSurface(filteredSurface, occlusion);
2628
2629         this->enterLayer(parent, occlusion);
2630         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2631         EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2632         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
2633         EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2634
2635         IntRect outsetRect;
2636         IntRect testRect;
2637
2638         // Nothing in the blur outsets for the filteredSurface is occluded.
2639         outsetRect = IntRect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2640         testRect = outsetRect;
2641         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2642
2643         // Stuff outside the blur outsets is still occluded though.
2644         testRect = outsetRect;
2645         testRect.expand(1, 0);
2646         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2647         testRect = outsetRect;
2648         testRect.expand(0, 1);
2649         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2650         testRect = outsetRect;
2651         testRect.move(-1, 0);
2652         testRect.expand(1, 0);
2653         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2654         testRect = outsetRect;
2655         testRect.move(0, -1);
2656         testRect.expand(0, 1);
2657         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2658
2659         // Nothing in the blur outsets for the filteredSurface's replica is occluded.
2660         outsetRect = IntRect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2661         testRect = outsetRect;
2662         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2663
2664         // Stuff outside the blur outsets is still occluded though.
2665         testRect = outsetRect;
2666         testRect.expand(1, 0);
2667         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2668         testRect = outsetRect;
2669         testRect.expand(0, 1);
2670         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2671         testRect = outsetRect;
2672         testRect.move(-1, 0);
2673         testRect.expand(1, 0);
2674         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2675         testRect = outsetRect;
2676         testRect.move(0, -1);
2677         testRect.expand(0, 1);
2678         EXPECT_INT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2679     }
2680 };
2681
2682 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2683
2684 template<class Types, bool opaqueLayers>
2685 class CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2686 protected:
2687     void runMyTest()
2688     {
2689         WebTransformationMatrix scaleByHalf;
2690         scaleByHalf.scale(0.5);
2691
2692         // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
2693         typename Types::ContentLayerType* root = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(75, 75));
2694         typename Types::LayerType* parent = this->createSurface(root, scaleByHalf, FloatPoint(0, 0), IntSize(150, 150));
2695         parent->setMasksToBounds(true);
2696         typename Types::LayerType* filteredSurface1 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
2697         typename Types::LayerType* filteredSurface2 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
2698         typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(50, 50), true);
2699
2700         // Filters make the layers own surfaces.
2701         WebFilterOperations filters;
2702         filters.append(WebFilterOperation::createBlurFilter(3));
2703         filteredSurface1->setBackgroundFilters(filters);
2704         filteredSurface2->setBackgroundFilters(filters);
2705
2706         // Save the distance of influence for the blur effect.
2707         int outsetTop, outsetRight, outsetBottom, outsetLeft;
2708         filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2709
2710         this->calcDrawEtc(root);
2711
2712         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2713         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2714
2715         this->visitLayer(occludingLayerAbove, occlusion);
2716         EXPECT_INT_RECT_EQ(IntRect(100 / 2, 100 / 2, 50 / 2, 50 / 2), occlusion.occlusionInScreenSpace().bounds());
2717         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2718         EXPECT_INT_RECT_EQ(IntRect(100, 100, 50, 50), occlusion.occlusionInTargetSurface().bounds());
2719         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2720
2721         this->visitLayer(filteredSurface2, occlusion);
2722         this->visitContributingSurface(filteredSurface2, occlusion);
2723         this->visitLayer(filteredSurface1, occlusion);
2724         this->visitContributingSurface(filteredSurface1, occlusion);
2725
2726         ASSERT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2727         ASSERT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2728
2729         // Test expectations in the target.
2730         IntRect expectedOcclusion = IntRect(100 + outsetRight * 2, 100 + outsetBottom * 2, 50 - (outsetLeft + outsetRight) * 2, 50 - (outsetTop + outsetBottom) * 2);
2731         EXPECT_INT_RECT_EQ(expectedOcclusion, occlusion.occlusionInTargetSurface().rects()[0]);
2732
2733         // Test expectations in the screen. Take the ceiling of half of the outsets.
2734         outsetTop = (outsetTop + 1) / 2;
2735         outsetRight = (outsetRight + 1) / 2;
2736         outsetBottom = (outsetBottom + 1) / 2;
2737         outsetLeft = (outsetLeft + 1) / 2;
2738         expectedOcclusion = IntRect(100 / 2 + outsetRight * 2, 100 / 2 + outsetBottom * 2, 50 / 2 - (outsetLeft + outsetRight) * 2, 50 /2 - (outsetTop + outsetBottom) * 2);
2739
2740         EXPECT_INT_RECT_EQ(expectedOcclusion, occlusion.occlusionInScreenSpace().rects()[0]);
2741     }
2742 };
2743
2744 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
2745
2746 template<class Types, bool opaqueLayers>
2747 class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2748 protected:
2749     void runMyTest()
2750     {
2751         // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2752         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2753         // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
2754         // the background filter.
2755         typename Types::LayerType* clippingSurface = this->createSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 70));
2756         clippingSurface->setMasksToBounds(true);
2757         typename Types::LayerType* filteredSurface = this->createDrawingLayer(clippingSurface, this->identityMatrix, FloatPoint(50, 50), IntSize(50, 50), false);
2758         this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(150, 0), IntSize());
2759         typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 50), true);
2760         typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(300, 50), true);
2761         typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 50), IntSize(50, 50), true);
2762         typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 50), IntSize(100, 50), true);
2763         typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
2764
2765         // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
2766         WebFilterOperations filters;
2767         filters.append(WebFilterOperation::createBlurFilter(12));
2768         filteredSurface->setBackgroundFilters(filters);
2769
2770         // Save the distance of influence for the blur effect.
2771         int outsetTop, outsetRight, outsetBottom, outsetLeft;
2772         filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2773
2774         this->calcDrawEtc(parent);
2775
2776         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2777         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2778
2779         // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2780         // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2781         this->visitLayer(occludingLayer5, occlusion);
2782         this->visitLayer(occludingLayer4, occlusion);
2783         this->visitLayer(occludingLayer3, occlusion);
2784         this->visitLayer(occludingLayer2, occlusion);
2785         this->visitLayer(occludingLayer1, occlusion);
2786
2787         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2788         EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2789         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
2790         EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2791
2792         // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2793         this->enterLayer(filteredSurface, occlusion);
2794         EXPECT_INT_RECT_EQ(IntRect(1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 50, 50)));
2795         EXPECT_INT_RECT_EQ(IntRect(0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 50, 50)));
2796         EXPECT_INT_RECT_EQ(IntRect(0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 50, 50)));
2797         EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 50, 50)));
2798
2799         EXPECT_INT_RECT_EQ(IntRect(150 + 1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 1, 0, 50, 50)));
2800         EXPECT_INT_RECT_EQ(IntRect(150 + 0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, 1, 50, 50)));
2801         EXPECT_INT_RECT_EQ(IntRect(150 + 0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 - 1, 0, 50, 50)));
2802         EXPECT_INT_RECT_EQ(IntRect(150 + 0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, -1, 50, 50)));
2803         this->leaveLayer(filteredSurface, occlusion);
2804
2805         // The filtered layer/replica does not occlude.
2806         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2807         EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2808         EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
2809         EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2810
2811         // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2812         // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2813         this->visitContributingSurface(filteredSurface, occlusion);
2814
2815         this->enterContributingSurface(clippingSurface, occlusion);
2816         EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2817         EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2818
2819         IntRect outsetRect;
2820         IntRect clippedOutsetRect;
2821         IntRect testRect;
2822
2823         // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
2824         outsetRect = IntRect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2825         clippedOutsetRect = intersection(outsetRect, IntRect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2826         testRect = outsetRect;
2827         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2828
2829         // Stuff outside the (clipped) blur outsets is still occluded though.
2830         testRect = outsetRect;
2831         testRect.expand(1, 0);
2832         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2833         testRect = outsetRect;
2834         testRect.expand(0, 1);
2835         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2836         testRect = outsetRect;
2837         testRect.move(-1, 0);
2838         testRect.expand(1, 0);
2839         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2840         testRect = outsetRect;
2841         testRect.move(0, -1);
2842         testRect.expand(0, 1);
2843         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2844
2845         // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
2846         outsetRect = IntRect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2847         clippedOutsetRect = intersection(outsetRect, IntRect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2848         testRect = outsetRect;
2849         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2850
2851         // Stuff outside the (clipped) blur outsets is still occluded though.
2852         testRect = outsetRect;
2853         testRect.expand(1, 0);
2854         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2855         testRect = outsetRect;
2856         testRect.expand(0, 1);
2857         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2858         testRect = outsetRect;
2859         testRect.move(-1, 0);
2860         testRect.expand(1, 0);
2861         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2862         testRect = outsetRect;
2863         testRect.move(0, -1);
2864         testRect.expand(0, 1);
2865         EXPECT_INT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2866     }
2867 };
2868
2869 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
2870
2871 template<class Types, bool opaqueLayers>
2872 class CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2873 protected:
2874     void runMyTest()
2875     {
2876         WebTransformationMatrix scaleByHalf;
2877         scaleByHalf.scale(0.5);
2878
2879         // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
2880         // 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
2881         // appears at 50, 50 and the replica at 200, 50.
2882         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2883         typename Types::LayerType* behindSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(60, 60), IntSize(30, 30), true);
2884         typename Types::LayerType* behindReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(210, 60), IntSize(30, 30), true);
2885         typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2886         this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2887
2888         // Filters make the layer own a surface.
2889         WebFilterOperations filters;
2890         filters.append(WebFilterOperation::createBlurFilter(3));
2891         filteredSurface->setBackgroundFilters(filters);
2892
2893         this->calcDrawEtc(parent);
2894
2895         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2896         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2897
2898         // The surface has a background blur, so it blurs non-opaque pixels below it.
2899         this->visitLayer(filteredSurface, occlusion);
2900         this->visitContributingSurface(filteredSurface, occlusion);
2901
2902         this->visitLayer(behindReplicaLayer, occlusion);
2903         this->visitLayer(behindSurfaceLayer, occlusion);
2904
2905         // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
2906         // So it should not be modified by the filter here.
2907         IntRect occlusionBehindSurface = IntRect(60, 60, 30, 30);
2908         IntRect occlusionBehindReplica = IntRect(210, 60, 30, 30);
2909
2910         IntRect expectedOpaqueBounds = unionRect(occlusionBehindSurface, occlusionBehindReplica);
2911         EXPECT_INT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInScreenSpace().bounds());
2912         EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2913         EXPECT_INT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInTargetSurface().bounds());
2914         EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2915     }
2916 };
2917
2918 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
2919
2920 template<class Types, bool opaqueLayers>
2921 class CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2922 protected:
2923     void runMyTest()
2924     {
2925         WebTransformationMatrix scaleByHalf;
2926         scaleByHalf.scale(0.5);
2927
2928         // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
2929         // 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
2930         // appears at 50, 50 and the replica at 200, 50.
2931         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2932         typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2933         this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2934         typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(50, 50), true);
2935         typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(50, 50), true);
2936
2937         // Filters make the layer own a surface.
2938         WebFilterOperations filters;
2939         filters.append(WebFilterOperation::createBlurFilter(3));
2940         filteredSurface->setBackgroundFilters(filters);
2941
2942         this->calcDrawEtc(parent);
2943
2944         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2945         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2946
2947         this->visitLayer(aboveReplicaLayer, occlusion);
2948         this->visitLayer(aboveSurfaceLayer, occlusion);
2949
2950         // The surface has a background blur, so it blurs non-opaque pixels below it.
2951         this->visitLayer(filteredSurface, occlusion);
2952         this->visitContributingSurface(filteredSurface, occlusion);
2953
2954         // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
2955         IntRect occlusionAboveSurface = IntRect(50, 50, 50, 50);
2956         IntRect occlusionAboveReplica = IntRect(200, 50, 50, 50);
2957
2958         IntRect expectedOpaqueBounds = unionRect(occlusionAboveSurface, occlusionAboveReplica);
2959         EXPECT_INT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInScreenSpace().bounds());
2960         EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2961         EXPECT_INT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInTargetSurface().bounds());
2962         EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2963     }
2964 };
2965
2966 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
2967
2968 template<class Types, bool opaqueLayers>
2969 class CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2970 protected:
2971     void runMyTest()
2972     {
2973         WebTransformationMatrix scaleByHalf;
2974         scaleByHalf.scale(0.5);
2975
2976         // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
2977         // 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
2978         // appears at 50, 50 and the replica at 200, 50.
2979         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2980         typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2981         this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2982         typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(70, 50), IntSize(30, 50), true);
2983         typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(30, 50), true);
2984         typename Types::LayerType* besideSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(90, 40), IntSize(10, 10), true);
2985         typename Types::LayerType* besideReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 40), IntSize(10, 10), true);
2986
2987         // Filters make the layer own a surface.
2988         WebFilterOperations filters;
2989         filters.append(WebFilterOperation::createBlurFilter(3));
2990         filteredSurface->setBackgroundFilters(filters);
2991
2992         // Save the distance of influence for the blur effect.
2993         int outsetTop, outsetRight, outsetBottom, outsetLeft;
2994         filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2995
2996         this->calcDrawEtc(parent);
2997
2998         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2999         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
3000
3001         this->visitLayer(besideReplicaLayer, occlusion);
3002         this->visitLayer(besideSurfaceLayer, occlusion);
3003         this->visitLayer(aboveReplicaLayer, occlusion);
3004         this->visitLayer(aboveSurfaceLayer, occlusion);
3005
3006         // The surface has a background blur, so it blurs non-opaque pixels below it.
3007         this->visitLayer(filteredSurface, occlusion);
3008         this->visitContributingSurface(filteredSurface, occlusion);
3009
3010         // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
3011         // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
3012         // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
3013         // the occluded part of the surface.
3014         IntRect occlusionAboveSurface = IntRect(70 + outsetRight, 50, 30 - outsetRight, 50);
3015         IntRect occlusionAboveReplica = IntRect(200, 50, 30 - outsetLeft, 50);
3016         IntRect occlusionBesideSurface = IntRect(90, 40, 10, 10);
3017         IntRect occlusionBesideReplica = IntRect(200, 40, 10, 10);
3018
3019         Region expectedOcclusion;
3020         expectedOcclusion.unite(occlusionAboveSurface);
3021         expectedOcclusion.unite(occlusionAboveReplica);
3022         expectedOcclusion.unite(occlusionBesideSurface);
3023         expectedOcclusion.unite(occlusionBesideReplica);
3024
3025         ASSERT_EQ(expectedOcclusion.rects().size(), occlusion.occlusionInTargetSurface().rects().size());
3026         ASSERT_EQ(expectedOcclusion.rects().size(), occlusion.occlusionInScreenSpace().rects().size());
3027
3028         for (size_t i = 0; i < expectedOcclusion.rects().size(); ++i) {
3029             IntRect expectedRect = expectedOcclusion.rects()[i];
3030             IntRect screenRect = occlusion.occlusionInScreenSpace().rects()[i];
3031             IntRect targetRect = occlusion.occlusionInTargetSurface().rects()[i];
3032             EXPECT_EQ(expectedRect, screenRect);
3033             EXPECT_EQ(expectedRect, targetRect);
3034         }
3035     }
3036 };
3037
3038 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
3039
3040 template<class Types, bool opaqueLayers>
3041 class CCOcclusionTrackerTestMinimumTrackingSize : public CCOcclusionTrackerTest<Types, opaqueLayers> {
3042 protected:
3043     void runMyTest()
3044     {
3045         IntSize trackingSize(100, 100);
3046         IntSize belowTrackingSize(99, 99);
3047
3048         typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(400, 400));
3049         typename Types::LayerType* large = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), trackingSize, true);
3050         typename Types::LayerType* small = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), belowTrackingSize, true);
3051         this->calcDrawEtc(parent);
3052
3053         TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
3054         occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
3055         occlusion.setMinimumTrackingSize(trackingSize);
3056
3057         // The small layer is not tracked because it is too small.
3058         this->visitLayer(small, occlusion);
3059
3060         EXPECT_INT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
3061         EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
3062         EXPECT_INT_RECT_EQ(IntRect(), occlusion.occlusionInTargetSurface().bounds());
3063         EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
3064
3065         // The large layer is tracked as it is large enough.
3066         this->visitLayer(large, occlusion);
3067
3068         EXPECT_INT_RECT_EQ(IntRect(IntPoint(), trackingSize), occlusion.occlusionInScreenSpace().bounds());
3069         EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
3070         EXPECT_INT_RECT_EQ(IntRect(IntPoint(), trackingSize), occlusion.occlusionInTargetSurface().bounds());
3071         EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
3072     }
3073 };
3074
3075 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestMinimumTrackingSize);
3076
3077 } // namespace