blob: da3a08ad723f66ca31ef5bfda83bf93367491fa1 [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6
7#include "CCOcclusionTracker.h"
8
9#include "CCAnimationTestCommon.h"
[email protected]022cbf162012-09-01 01:15:1710#include "CCGeometryTestUtils.h"
[email protected]94f206c12012-08-25 00:09:1411#include "CCLayerAnimationController.h"
12#include "CCLayerImpl.h"
13#include "CCLayerTreeHostCommon.h"
[email protected]94f206c12012-08-25 00:09:1414#include "CCMathUtil.h"
15#include "CCOcclusionTrackerTestCommon.h"
16#include "CCOverdrawMetrics.h"
17#include "CCSingleThreadProxy.h"
18#include "LayerChromium.h"
19#include "Region.h"
[email protected]7f0c53db2012-10-02 00:23:1820#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/gtest/include/gtest/gtest.h"
[email protected]94f206c12012-08-25 00:09:1422#include <public/WebFilterOperation.h>
23#include <public/WebFilterOperations.h>
24#include <public/WebTransformationMatrix.h>
25
[email protected]9c88e562012-09-14 22:21:3026using namespace cc;
[email protected]94f206c12012-08-25 00:09:1427using namespace WebKit;
28using namespace WebKitTests;
29
30namespace {
31
32class TestContentLayerChromium : public LayerChromium {
33public:
34 TestContentLayerChromium()
35 : LayerChromium()
36 , m_overrideOpaqueContentsRect(false)
37 {
38 }
39
40 virtual bool drawsContent() const OVERRIDE { return true; }
41 virtual Region visibleContentOpaqueRegion() const OVERRIDE
42 {
43 if (m_overrideOpaqueContentsRect)
44 return intersection(m_opaqueContentsRect, visibleContentRect());
45 return LayerChromium::visibleContentOpaqueRegion();
46 }
47 void setOpaqueContentsRect(const IntRect& opaqueContentsRect)
48 {
49 m_overrideOpaqueContentsRect = true;
50 m_opaqueContentsRect = opaqueContentsRect;
51 }
52
53private:
[email protected]d58499a2012-10-09 22:27:4754 virtual ~TestContentLayerChromium()
55 {
56 }
57
[email protected]94f206c12012-08-25 00:09:1458 bool m_overrideOpaqueContentsRect;
59 IntRect m_opaqueContentsRect;
60};
61
62class TestContentLayerImpl : public CCLayerImpl {
63public:
64 TestContentLayerImpl(int id)
65 : CCLayerImpl(id)
66 , m_overrideOpaqueContentsRect(false)
67 {
68 setDrawsContent(true);
69 }
70
71 virtual Region visibleContentOpaqueRegion() const OVERRIDE
72 {
73 if (m_overrideOpaqueContentsRect)
74 return intersection(m_opaqueContentsRect, visibleContentRect());
75 return CCLayerImpl::visibleContentOpaqueRegion();
76 }
77 void setOpaqueContentsRect(const IntRect& opaqueContentsRect)
78 {
79 m_overrideOpaqueContentsRect = true;
80 m_opaqueContentsRect = opaqueContentsRect;
81 }
82
83private:
84 bool m_overrideOpaqueContentsRect;
85 IntRect m_opaqueContentsRect;
86};
87
88template<typename LayerType, typename RenderSurfaceType>
89class TestCCOcclusionTrackerWithClip : public TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType> {
90public:
91 TestCCOcclusionTrackerWithClip(IntRect viewportRect, bool recordMetricsForFrame = false)
92 : TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewportRect, recordMetricsForFrame)
93 , m_overrideLayerClipRect(false)
94 {
95 }
96
97 void setLayerClipRect(const IntRect& rect) { m_overrideLayerClipRect = true; m_layerClipRect = rect;}
98 void useDefaultLayerClipRect() { m_overrideLayerClipRect = false; }
99
100protected:
101 virtual IntRect layerClipRectInTarget(const LayerType* layer) const { return m_overrideLayerClipRect ? m_layerClipRect : CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTarget(layer); }
102
103private:
104 bool m_overrideLayerClipRect;
105 IntRect m_layerClipRect;
106};
107
108struct CCOcclusionTrackerTestMainThreadTypes {
109 typedef LayerChromium LayerType;
110 typedef RenderSurfaceChromium RenderSurfaceType;
111 typedef TestContentLayerChromium ContentLayerType;
[email protected]d58499a2012-10-09 22:27:47112 typedef scoped_refptr<LayerChromium> LayerPtrType;
113 typedef scoped_refptr<LayerChromium> PassLayerPtrType;
114 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
115 typedef scoped_refptr<ContentLayerType> PassContentLayerPtrType;
116 typedef CCLayerIterator<LayerChromium, std::vector<scoped_refptr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> LayerIterator;
[email protected]94f206c12012-08-25 00:09:14117 typedef CCOcclusionTracker OcclusionTrackerType;
118
[email protected]a96abc2d2012-10-08 07:12:23119 static PassLayerPtrType createLayer()
[email protected]94f206c12012-08-25 00:09:14120 {
121 return LayerChromium::create();
122 }
[email protected]d58499a2012-10-09 22:27:47123 static PassContentLayerPtrType createContentLayer() { return make_scoped_refptr(new ContentLayerType()); }
124
125 static void destroyLayer(LayerPtrType& layer)
126 {
127 layer = NULL;
128 }
[email protected]94f206c12012-08-25 00:09:14129};
130
131struct CCOcclusionTrackerTestImplThreadTypes {
132 typedef CCLayerImpl LayerType;
133 typedef CCRenderSurface RenderSurfaceType;
134 typedef TestContentLayerImpl ContentLayerType;
[email protected]a96abc2d2012-10-08 07:12:23135 typedef OwnPtr<CCLayerImpl> LayerPtrType;
136 typedef PassOwnPtr<CCLayerImpl> PassLayerPtrType;
137 typedef OwnPtr<ContentLayerType> ContentLayerPtrType;
138 typedef PassOwnPtr<ContentLayerType> PassContentLayerPtrType;
[email protected]d58499a2012-10-09 22:27:47139 typedef CCLayerIterator<CCLayerImpl, std::vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::FrontToBack> LayerIterator;
[email protected]94f206c12012-08-25 00:09:14140 typedef CCOcclusionTrackerImpl OcclusionTrackerType;
141
[email protected]a96abc2d2012-10-08 07:12:23142 static PassLayerPtrType createLayer() { return CCLayerImpl::create(nextCCLayerImplId++); }
143 static PassContentLayerPtrType createContentLayer() { return adoptPtr(new ContentLayerType(nextCCLayerImplId++)); }
[email protected]94f206c12012-08-25 00:09:14144 static int nextCCLayerImplId;
[email protected]d58499a2012-10-09 22:27:47145
146 static void destroyLayer(LayerPtrType& layer)
147 {
148 layer.clear();
149 }
[email protected]94f206c12012-08-25 00:09:14150};
151
152int CCOcclusionTrackerTestImplThreadTypes::nextCCLayerImplId = 1;
153
154template<typename Types, bool opaqueLayers>
155class CCOcclusionTrackerTest : public testing::Test {
156protected:
157 CCOcclusionTrackerTest()
158 : testing::Test()
159 { }
160
161 virtual void runMyTest() = 0;
162
163 virtual void TearDown()
164 {
[email protected]d58499a2012-10-09 22:27:47165 Types::destroyLayer(m_root);
[email protected]94f206c12012-08-25 00:09:14166 m_renderSurfaceLayerListChromium.clear();
167 m_renderSurfaceLayerListImpl.clear();
168 m_replicaLayers.clear();
169 m_maskLayers.clear();
170 CCLayerTreeHost::setNeedsFilterContext(false);
171 }
172
173 typename Types::ContentLayerType* createRoot(const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
174 {
175 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
176 typename Types::ContentLayerType* layerPtr = layer.get();
177 setProperties(layerPtr, transform, position, bounds);
178
179 ASSERT(!m_root);
[email protected]a96abc2d2012-10-08 07:12:23180 m_root = layer.release();
[email protected]94f206c12012-08-25 00:09:14181 return layerPtr;
182 }
183
184 typename Types::LayerType* createLayer(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
185 {
186 typename Types::LayerPtrType layer(Types::createLayer());
187 typename Types::LayerType* layerPtr = layer.get();
188 setProperties(layerPtr, transform, position, bounds);
[email protected]a96abc2d2012-10-08 07:12:23189 parent->addChild(layer.release());
[email protected]94f206c12012-08-25 00:09:14190 return layerPtr;
191 }
192
193 typename Types::LayerType* createSurface(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
194 {
195 typename Types::LayerType* layer = createLayer(parent, transform, position, bounds);
196 WebFilterOperations filters;
197 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
198 layer->setFilters(filters);
199 return layer;
200 }
201
202 typename Types::ContentLayerType* createDrawingLayer(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
203 {
204 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
205 typename Types::ContentLayerType* layerPtr = layer.get();
206 setProperties(layerPtr, transform, position, bounds);
207
208 if (opaqueLayers)
[email protected]048634c2012-10-02 22:33:14209 layerPtr->setContentsOpaque(opaque);
[email protected]94f206c12012-08-25 00:09:14210 else {
[email protected]048634c2012-10-02 22:33:14211 layerPtr->setContentsOpaque(false);
[email protected]94f206c12012-08-25 00:09:14212 if (opaque)
213 layerPtr->setOpaqueContentsRect(IntRect(IntPoint(), bounds));
214 else
215 layerPtr->setOpaqueContentsRect(IntRect());
216 }
217
[email protected]a96abc2d2012-10-08 07:12:23218 parent->addChild(layer.release());
[email protected]94f206c12012-08-25 00:09:14219 return layerPtr;
220 }
221
222 typename Types::LayerType* createReplicaLayer(typename Types::LayerType* owningLayer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
223 {
224 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
225 typename Types::ContentLayerType* layerPtr = layer.get();
226 setProperties(layerPtr, transform, position, bounds);
[email protected]a96abc2d2012-10-08 07:12:23227 setReplica(owningLayer, layer.release());
[email protected]94f206c12012-08-25 00:09:14228 return layerPtr;
229 }
230
231 typename Types::LayerType* createMaskLayer(typename Types::LayerType* owningLayer, const IntSize& bounds)
232 {
233 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
234 typename Types::ContentLayerType* layerPtr = layer.get();
235 setProperties(layerPtr, identityMatrix, FloatPoint(), bounds);
[email protected]a96abc2d2012-10-08 07:12:23236 setMask(owningLayer, layer.release());
[email protected]94f206c12012-08-25 00:09:14237 return layerPtr;
238 }
239
240 typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
241 {
242 typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque);
243 WebFilterOperations filters;
244 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
245 layer->setFilters(filters);
246 return layer;
247 }
248
249 void calcDrawEtc(TestContentLayerImpl* root)
250 {
251 ASSERT(root == m_root.get());
252 int dummyMaxTextureSize = 512;
253 CCLayerSorter layerSorter;
254
255 ASSERT(!root->renderSurface());
256
257 CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, &layerSorter, dummyMaxTextureSize, m_renderSurfaceLayerListImpl);
[email protected]94f206c12012-08-25 00:09:14258
259 m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListImpl);
260 }
261
262 void calcDrawEtc(TestContentLayerChromium* root)
263 {
264 ASSERT(root == m_root.get());
265 int dummyMaxTextureSize = 512;
266
267 ASSERT(!root->renderSurface());
268
269 CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, dummyMaxTextureSize, m_renderSurfaceLayerListChromium);
[email protected]94f206c12012-08-25 00:09:14270
271 m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListChromium);
272 }
273
274 void enterLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
275 {
276 ASSERT_EQ(layer, *m_layerIterator);
277 ASSERT_TRUE(m_layerIterator.representsItself());
278 occlusion.enterLayer(m_layerIterator);
279 }
280
281 void leaveLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
282 {
283 ASSERT_EQ(layer, *m_layerIterator);
284 ASSERT_TRUE(m_layerIterator.representsItself());
285 occlusion.leaveLayer(m_layerIterator);
286 ++m_layerIterator;
287 }
288
289 void visitLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
290 {
291 enterLayer(layer, occlusion);
292 leaveLayer(layer, occlusion);
293 }
294
295 void enterContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
296 {
297 ASSERT_EQ(layer, *m_layerIterator);
298 ASSERT_TRUE(m_layerIterator.representsTargetRenderSurface());
299 occlusion.enterLayer(m_layerIterator);
300 occlusion.leaveLayer(m_layerIterator);
301 ++m_layerIterator;
302 ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
303 occlusion.enterLayer(m_layerIterator);
304 }
305
306 void leaveContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
307 {
308 ASSERT_EQ(layer, *m_layerIterator);
309 ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
310 occlusion.leaveLayer(m_layerIterator);
311 ++m_layerIterator;
312 }
313
314 void visitContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
315 {
316 enterContributingSurface(layer, occlusion);
317 leaveContributingSurface(layer, occlusion);
318 }
319
320 void resetLayerIterator()
321 {
322 m_layerIterator = m_layerIteratorBegin;
323 }
324
325 const WebTransformationMatrix identityMatrix;
326
327private:
328 void setBaseProperties(typename Types::LayerType* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
329 {
330 layer->setTransform(transform);
331 layer->setSublayerTransform(WebTransformationMatrix());
332 layer->setAnchorPoint(FloatPoint(0, 0));
333 layer->setPosition(position);
334 layer->setBounds(bounds);
335 }
336
337 void setProperties(LayerChromium* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
338 {
339 setBaseProperties(layer, transform, position, bounds);
340 }
341
342 void setProperties(CCLayerImpl* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
343 {
344 setBaseProperties(layer, transform, position, bounds);
345
346 layer->setContentBounds(layer->bounds());
347 }
348
[email protected]d58499a2012-10-09 22:27:47349 void setReplica(LayerChromium* owningLayer, scoped_refptr<LayerChromium> layer)
[email protected]94f206c12012-08-25 00:09:14350 {
351 owningLayer->setReplicaLayer(layer.get());
[email protected]d58499a2012-10-09 22:27:47352 m_replicaLayers.push_back(layer);
[email protected]94f206c12012-08-25 00:09:14353 }
354
[email protected]a96abc2d2012-10-08 07:12:23355 void setReplica(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer)
[email protected]94f206c12012-08-25 00:09:14356 {
[email protected]a96abc2d2012-10-08 07:12:23357 owningLayer->setReplicaLayer(layer);
[email protected]94f206c12012-08-25 00:09:14358 }
359
[email protected]d58499a2012-10-09 22:27:47360 void setMask(LayerChromium* owningLayer, scoped_refptr<LayerChromium> layer)
[email protected]94f206c12012-08-25 00:09:14361 {
362 owningLayer->setMaskLayer(layer.get());
[email protected]d58499a2012-10-09 22:27:47363 m_maskLayers.push_back(layer);
[email protected]94f206c12012-08-25 00:09:14364 }
365
[email protected]a96abc2d2012-10-08 07:12:23366 void setMask(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer)
[email protected]94f206c12012-08-25 00:09:14367 {
[email protected]a96abc2d2012-10-08 07:12:23368 owningLayer->setMaskLayer(layer);
[email protected]94f206c12012-08-25 00:09:14369 }
370
371 // These hold ownership of the layers for the duration of the test.
372 typename Types::LayerPtrType m_root;
[email protected]d58499a2012-10-09 22:27:47373 std::vector<scoped_refptr<LayerChromium> > m_renderSurfaceLayerListChromium;
374 std::vector<CCLayerImpl*> m_renderSurfaceLayerListImpl;
[email protected]94f206c12012-08-25 00:09:14375 typename Types::LayerIterator m_layerIteratorBegin;
376 typename Types::LayerIterator m_layerIterator;
377 typename Types::LayerType* m_lastLayerVisited;
[email protected]d58499a2012-10-09 22:27:47378 std::vector<scoped_refptr<LayerChromium> > m_replicaLayers;
379 std::vector<scoped_refptr<LayerChromium> > m_maskLayers;
[email protected]94f206c12012-08-25 00:09:14380};
381
382#define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
383 class ClassName##MainThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestMainThreadTypes, true> { \
384 public: \
385 ClassName##MainThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestMainThreadTypes, true>() { } \
386 }; \
387 TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
388#define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
389 class ClassName##MainThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestMainThreadTypes, false> { \
390 public: \
391 ClassName##MainThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestMainThreadTypes, false>() { } \
392 }; \
393 TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
394
395#define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
396 class ClassName##ImplThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestImplThreadTypes, true> { \
397 DebugScopedSetImplThread impl; \
398 public: \
399 ClassName##ImplThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestImplThreadTypes, true>() { } \
400 }; \
401 TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
402#define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
403 class ClassName##ImplThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestImplThreadTypes, false> { \
404 DebugScopedSetImplThread impl; \
405 public: \
406 ClassName##ImplThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestImplThreadTypes, false>() { } \
407 }; \
408 TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
409
410#define ALL_CCOCCLUSIONTRACKER_TEST(ClassName) \
411 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
412 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
413 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
414 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
415
416#define MAIN_THREAD_TEST(ClassName) \
417 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
418
419#define IMPL_THREAD_TEST(ClassName) \
420 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
421
422#define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
423 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
424 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
425
426template<class Types, bool opaqueLayers>
427class CCOcclusionTrackerTestIdentityTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
428protected:
429 void runMyTest()
430 {
431 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
432 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(30, 30), IntSize(500, 500), true);
433 this->calcDrawEtc(parent);
434
435 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
436 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
437
438 this->visitLayer(layer, occlusion);
439 this->enterLayer(parent, occlusion);
440
[email protected]022cbf162012-09-01 01:15:17441 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14442 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17443 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14444 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
445
446 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
447 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
448 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
449 EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
450 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
451
452 occlusion.useDefaultLayerClipRect();
453 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
454 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
455 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
456 EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
457 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
458 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
459
460 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17461 EXPECT_RECT_EQ(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 70, 70)));
462 EXPECT_RECT_EQ(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 29, 70, 70)));
463 EXPECT_RECT_EQ(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
464 EXPECT_RECT_EQ(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 29, 70, 70)));
465 EXPECT_RECT_EQ(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 70, 70)));
466 EXPECT_RECT_EQ(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 31, 70, 70)));
467 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 31, 70, 70)));
468 EXPECT_RECT_EQ(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 31, 70, 70)));
[email protected]94f206c12012-08-25 00:09:14469 }
470};
471
472ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestIdentityTransforms);
473
474template<class Types, bool opaqueLayers>
475class CCOcclusionTrackerTestRotatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
476protected:
477 void runMyTest()
478 {
479 WebTransformationMatrix layerTransform;
480 layerTransform.translate(250, 250);
481 layerTransform.rotate(90);
482 layerTransform.translate(-250, -250);
483
484 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
485 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
486 this->calcDrawEtc(parent);
487
488 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
489 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
490
491 this->visitLayer(layer, occlusion);
492 this->enterLayer(parent, occlusion);
493
[email protected]022cbf162012-09-01 01:15:17494 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14495 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17496 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14497 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
498
499 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
500 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
501 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
502 EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
503 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
504
505 occlusion.useDefaultLayerClipRect();
506 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
507 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
508 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
509 EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
510 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
511 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
512
513 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17514 EXPECT_RECT_EQ(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 70, 70)));
515 EXPECT_RECT_EQ(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 29, 70, 70)));
516 EXPECT_RECT_EQ(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
517 EXPECT_RECT_EQ(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 29, 70, 70)));
518 EXPECT_RECT_EQ(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 70, 70)));
519 EXPECT_RECT_EQ(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 31, 70, 70)));
520 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 31, 70, 70)));
521 EXPECT_RECT_EQ(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 31, 70, 70)));
[email protected]94f206c12012-08-25 00:09:14522 }
523};
524
525ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestRotatedChild);
526
527template<class Types, bool opaqueLayers>
528class CCOcclusionTrackerTestTranslatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
529protected:
530 void runMyTest()
531 {
532 WebTransformationMatrix layerTransform;
533 layerTransform.translate(20, 20);
534
535 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
536 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
537 this->calcDrawEtc(parent);
538
539 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
540 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
541
542 this->visitLayer(layer, occlusion);
543 this->enterLayer(parent, occlusion);
544
[email protected]022cbf162012-09-01 01:15:17545 EXPECT_RECT_EQ(IntRect(50, 50, 50, 50), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14546 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17547 EXPECT_RECT_EQ(IntRect(50, 50, 50, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14548 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
549
550 EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 50, 50, 50)));
551 EXPECT_FALSE(occlusion.occluded(parent, IntRect(49, 50, 50, 50)));
552 EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 49, 50, 50)));
553 EXPECT_FALSE(occlusion.occluded(parent, IntRect(51, 50, 50, 50)));
554 EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 51, 50, 50)));
555
556 occlusion.useDefaultLayerClipRect();
557 EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 50, 50, 50)));
558 EXPECT_FALSE(occlusion.occluded(parent, IntRect(49, 50, 50, 50)));
559 EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 49, 50, 50)));
560 EXPECT_TRUE(occlusion.occluded(parent, IntRect(51, 50, 50, 50)));
561 EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 51, 50, 50)));
562 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
563
564 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 50, 50, 50)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17565 EXPECT_RECT_EQ(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 50, 50, 50)));
566 EXPECT_RECT_EQ(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 49, 50, 50)));
567 EXPECT_RECT_EQ(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 49, 50, 50)));
568 EXPECT_RECT_EQ(IntRect(51, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 49, 50, 50)));
569 EXPECT_RECT_EQ(IntRect(100, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 50, 50, 50)));
570 EXPECT_RECT_EQ(IntRect(51, 51, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 51, 50, 50)));
571 EXPECT_RECT_EQ(IntRect(50, 100, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 51, 50, 50)));
572 EXPECT_RECT_EQ(IntRect(49, 51, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 51, 50, 50)));
[email protected]94f206c12012-08-25 00:09:14573
574 occlusion.useDefaultLayerClipRect();
575 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 50, 50, 50)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17576 EXPECT_RECT_EQ(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 50, 50, 50)));
577 EXPECT_RECT_EQ(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 49, 50, 50)));
578 EXPECT_RECT_EQ(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 49, 50, 50)));
579 EXPECT_RECT_EQ(IntRect(51, 49, 49, 1), occlusion.unoccludedContentRect(parent, IntRect(51, 49, 50, 50)));
[email protected]94f206c12012-08-25 00:09:14580 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(51, 50, 50, 50)).isEmpty());
581 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(51, 51, 50, 50)).isEmpty());
582 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 51, 50, 50)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17583 EXPECT_RECT_EQ(IntRect(49, 51, 1, 49), occlusion.unoccludedContentRect(parent, IntRect(49, 51, 50, 50)));
[email protected]94f206c12012-08-25 00:09:14584 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
585 }
586};
587
588ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTranslatedChild);
589
590template<class Types, bool opaqueLayers>
591class CCOcclusionTrackerTestChildInRotatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
592protected:
593 void runMyTest()
594 {
595 WebTransformationMatrix childTransform;
596 childTransform.translate(250, 250);
597 childTransform.rotate(90);
598 childTransform.translate(-250, -250);
599
600 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
[email protected]23bbb412012-08-30 20:03:38601 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:14602 typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
603 child->setMasksToBounds(true);
604 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
605 this->calcDrawEtc(parent);
606
607 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
608 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
609
610 this->visitLayer(layer, occlusion);
611 this->enterContributingSurface(child, occlusion);
612
[email protected]022cbf162012-09-01 01:15:17613 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14614 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17615 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14616 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
617
618 this->leaveContributingSurface(child, occlusion);
619 this->enterLayer(parent, occlusion);
620
[email protected]022cbf162012-09-01 01:15:17621 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14622 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17623 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14624 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
625
626 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
627 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
628 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
629 EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 40, 70, 60)));
630 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 41, 70, 60)));
631
632 occlusion.useDefaultLayerClipRect();
633 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
634 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
635 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
636 EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 40, 70, 60)));
637 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 41, 70, 60)));
638 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
639
640
641 /* Justification for the above occlusion from |layer|:
642 100
643 +---------------------+ +---------------------+
644 | | | |30 Visible region of |layer|: /////
645 | 30 | rotate(90) | |
646 | 30 + ---------------------------------+ | +---------------------------------+
647 100 | | 10 | | ==> | | |10 |
648 | |10+---------------------------------+ | +---------------------------------+ |
649 | | | | | | | | |///////////////| 420 | |
650 | | | | | | | | |///////////////|60 | |
651 | | | | | | | | |///////////////| | |
652 +----|--|-------------+ | | +--|--|---------------+ | |
653 | | | | 20|10| 70 | |
654 | | | | | | | |
655 | | | |500 | | | |
656 | | | | | | | |
657 | | | | | | | |
658 | | | | | | | |
659 | | | | | | |10|
660 +--|-------------------------------+ | | +------------------------------|--+
661 | | | 490 |
662 +---------------------------------+ +---------------------------------+
663 500 500
664 */
665 }
666};
667
668ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestChildInRotatedChild);
669
670template<class Types, bool opaqueLayers>
671class CCOcclusionTrackerTestVisitTargetTwoTimes : public CCOcclusionTrackerTest<Types, opaqueLayers> {
672protected:
673 void runMyTest()
674 {
675 WebTransformationMatrix childTransform;
676 childTransform.translate(250, 250);
677 childTransform.rotate(90);
678 childTransform.translate(-250, -250);
679
680 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
[email protected]23bbb412012-08-30 20:03:38681 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:14682 typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
683 child->setMasksToBounds(true);
684 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
685 // |child2| makes |parent|'s surface get considered by CCOcclusionTracker first, instead of |child|'s. This exercises different code in
686 // leaveToTargetRenderSurface, as the target surface has already been seen.
687 typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(30, 30), IntSize(60, 20), true);
688 this->calcDrawEtc(parent);
689
690 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
691 occlusion.setLayerClipRect(IntRect(-10, -10, 1000, 1000));
692
693 this->visitLayer(child2, occlusion);
694
[email protected]022cbf162012-09-01 01:15:17695 EXPECT_RECT_EQ(IntRect(30, 30, 60, 20), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14696 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17697 EXPECT_RECT_EQ(IntRect(30, 30, 60, 20), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14698 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
699
700 this->visitLayer(layer, occlusion);
701
[email protected]022cbf162012-09-01 01:15:17702 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14703 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17704 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14705 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
706
707 this->enterContributingSurface(child, occlusion);
708
[email protected]022cbf162012-09-01 01:15:17709 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14710 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17711 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14712 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
713
714 // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
715 this->leaveContributingSurface(child, occlusion);
716 this->enterLayer(parent, occlusion);
717
[email protected]022cbf162012-09-01 01:15:17718 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14719 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17720 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14721 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
722
723 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
[email protected]022cbf162012-09-01 01:15:17724 EXPECT_RECT_EQ(IntRect(90, 30, 10, 10), occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)));
[email protected]94f206c12012-08-25 00:09:14725
726 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 60, 10)));
727 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 60, 10)));
728 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 60, 10)));
729 EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 60, 10)));
730 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 60, 10)));
731
732 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
733 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
734 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
735
736 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 60, 10)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17737 EXPECT_RECT_EQ(IntRect(29, 30, 1, 10), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 60, 10)));
738 EXPECT_RECT_EQ(IntRect(30, 29, 60, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 60, 10)));
739 EXPECT_RECT_EQ(IntRect(90, 30, 1, 10), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 60, 10)));
[email protected]94f206c12012-08-25 00:09:14740 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 31, 60, 10)).isEmpty());
741
742 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 40, 70, 60)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17743 EXPECT_RECT_EQ(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(29, 40, 70, 60)));
[email protected]94f206c12012-08-25 00:09:14744 // This rect is mostly occluded by |child2|.
[email protected]022cbf162012-09-01 01:15:17745 EXPECT_RECT_EQ(IntRect(90, 39, 10, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 39, 70, 60)));
[email protected]94f206c12012-08-25 00:09:14746 // This rect extends past top/right ends of |child2|.
[email protected]022cbf162012-09-01 01:15:17747 EXPECT_RECT_EQ(IntRect(30, 29, 70, 11), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
[email protected]94f206c12012-08-25 00:09:14748 // This rect extends past left/right ends of |child2|.
[email protected]022cbf162012-09-01 01:15:17749 EXPECT_RECT_EQ(IntRect(20, 39, 80, 60), occlusion.unoccludedContentRect(parent, IntRect(20, 39, 80, 60)));
750 EXPECT_RECT_EQ(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(31, 40, 70, 60)));
751 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 41, 70, 60)));
[email protected]94f206c12012-08-25 00:09:14752
753 /* Justification for the above occlusion from |layer|:
754 100
755 +---------------------+ +---------------------+
756 | | | |30 Visible region of |layer|: /////
757 | 30 | rotate(90) | 30 60 | |child2|: \\\\\
758 | 30 + ------------+--------------------+ | 30 +------------+--------------------+
759 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
760 | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
761 | + ------------+ | | | | | +------------+//| 420 | |
762 | | | | | | | | |///////////////|60 | |
763 | | | | | | | | |///////////////| | |
764 +----|--|-------------+ | | +--|--|---------------+ | |
765 | | | | 20|10| 70 | |
766 | | | | | | | |
767 | | | |500 | | | |
768 | | | | | | | |
769 | | | | | | | |
770 | | | | | | | |
771 | | | | | | |10|
772 +--|-------------------------------+ | | +------------------------------|--+
773 | | | 490 |
774 +---------------------------------+ +---------------------------------+
775 500 500
776 */
777 }
778};
779
780ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestVisitTargetTwoTimes);
781
782template<class Types, bool opaqueLayers>
783class CCOcclusionTrackerTestSurfaceRotatedOffAxis : public CCOcclusionTrackerTest<Types, opaqueLayers> {
784protected:
785 void runMyTest()
786 {
787 WebTransformationMatrix childTransform;
788 childTransform.translate(250, 250);
789 childTransform.rotate(95);
790 childTransform.translate(-250, -250);
791
792 WebTransformationMatrix layerTransform;
793 layerTransform.translate(10, 10);
794
795 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
796 typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
797 child->setMasksToBounds(true);
798 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, layerTransform, FloatPoint(0, 0), IntSize(500, 500), true);
799 this->calcDrawEtc(parent);
800
801 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
802 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
803
804 IntRect clippedLayerInChild = CCMathUtil::mapClippedRect(layerTransform, layer->visibleContentRect());
805
806 this->visitLayer(layer, occlusion);
807 this->enterContributingSurface(child, occlusion);
808
[email protected]022cbf162012-09-01 01:15:17809 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14810 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17811 EXPECT_RECT_EQ(clippedLayerInChild, occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14812 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
813
814 EXPECT_TRUE(occlusion.occluded(child, clippedLayerInChild));
815 EXPECT_TRUE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
816 clippedLayerInChild.move(-1, 0);
817 EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
818 EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
819 clippedLayerInChild.move(1, 0);
820 clippedLayerInChild.move(1, 0);
821 EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
822 EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
823 clippedLayerInChild.move(-1, 0);
824 clippedLayerInChild.move(0, -1);
825 EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
826 EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
827 clippedLayerInChild.move(0, 1);
828 clippedLayerInChild.move(0, 1);
829 EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
830 EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
831 clippedLayerInChild.move(0, -1);
832
833 this->leaveContributingSurface(child, occlusion);
834 this->enterLayer(parent, occlusion);
835
[email protected]022cbf162012-09-01 01:15:17836 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14837 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17838 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14839 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
840
841 EXPECT_FALSE(occlusion.occluded(parent, IntRect(75, 55, 1, 1)));
[email protected]022cbf162012-09-01 01:15:17842 EXPECT_RECT_EQ(IntRect(75, 55, 1, 1), occlusion.unoccludedContentRect(parent, IntRect(75, 55, 1, 1)));
[email protected]94f206c12012-08-25 00:09:14843 }
844};
845
846ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceRotatedOffAxis);
847
848template<class Types, bool opaqueLayers>
849class CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren : public CCOcclusionTrackerTest<Types, opaqueLayers> {
850protected:
851 void runMyTest()
852 {
853 WebTransformationMatrix childTransform;
854 childTransform.translate(250, 250);
855 childTransform.rotate(90);
856 childTransform.translate(-250, -250);
857
858 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
[email protected]23bbb412012-08-30 20:03:38859 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:14860 typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
861 child->setMasksToBounds(true);
862 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
863 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 450), IntSize(500, 60), true);
864 this->calcDrawEtc(parent);
865
866 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
867 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
868
869 this->visitLayer(layer2, occlusion);
870 this->visitLayer(layer1, occlusion);
871 this->enterContributingSurface(child, occlusion);
872
[email protected]022cbf162012-09-01 01:15:17873 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14874 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17875 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14876 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
877
878 EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
879 EXPECT_FALSE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
880 EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
881 EXPECT_FALSE(occlusion.occluded(child, IntRect(11, 430, 60, 70)));
882 EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 431, 60, 70)));
883
884 EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 430, 60, 70)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17885 EXPECT_RECT_EQ(IntRect(9, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 70)));
886 EXPECT_RECT_EQ(IntRect(10, 429, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 429, 60, 70)));
887 EXPECT_RECT_EQ(IntRect(70, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(11, 430, 60, 70)));
888 EXPECT_RECT_EQ(IntRect(10, 500, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 431, 60, 70)));
[email protected]94f206c12012-08-25 00:09:14889
890 this->leaveContributingSurface(child, occlusion);
891 this->enterLayer(parent, occlusion);
892
[email protected]022cbf162012-09-01 01:15:17893 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14894 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17895 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14896 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
897
898 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
899 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
900 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
901
902 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 40, 70, 60)).isEmpty());
[email protected]022cbf162012-09-01 01:15:17903 EXPECT_RECT_EQ(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(29, 40, 70, 60)));
904 EXPECT_RECT_EQ(IntRect(30, 39, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 39, 70, 60)));
905 EXPECT_RECT_EQ(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(31, 40, 70, 60)));
906 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 41, 70, 60)));
[email protected]94f206c12012-08-25 00:09:14907
908 /* Justification for the above occlusion from |layer1| and |layer2|:
909
910 +---------------------+
911 | |30 Visible region of |layer1|: /////
912 | | Visible region of |layer2|: \\\\\
913 | +---------------------------------+
914 | | |10 |
915 | +---------------+-----------------+ |
916 | | |\\\\\\\\\\\\|//| 420 | |
917 | | |\\\\\\\\\\\\|//|60 | |
918 | | |\\\\\\\\\\\\|//| | |
919 +--|--|------------|--+ | |
920 20|10| 70 | | |
921 | | | | |
922 | | | | |
923 | | | | |
924 | | | | |
925 | | | | |
926 | | | |10|
927 | +------------|-----------------|--+
928 | | 490 |
929 +---------------+-----------------+
930 60 440
931 */
932 }
933};
934
935ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
936
937template<class Types, bool opaqueLayers>
938class CCOcclusionTrackerTestOverlappingSurfaceSiblings : public CCOcclusionTrackerTest<Types, opaqueLayers> {
939protected:
940 void runMyTest()
941 {
942 WebTransformationMatrix childTransform;
943 childTransform.translate(250, 250);
944 childTransform.rotate(90);
945 childTransform.translate(-250, -250);
946
947 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
[email protected]23bbb412012-08-30 20:03:38948 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:14949 typename Types::LayerType* child1 = this->createSurface(parent, childTransform, FloatPoint(30, 30), IntSize(10, 10));
950 typename Types::LayerType* child2 = this->createSurface(parent, childTransform, FloatPoint(20, 40), IntSize(10, 10));
951 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
952 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
953 this->calcDrawEtc(parent);
954
955 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
956 occlusion.setLayerClipRect(IntRect(-20, -20, 1000, 1000));
957
958 this->visitLayer(layer2, occlusion);
959 this->enterContributingSurface(child2, occlusion);
960
[email protected]022cbf162012-09-01 01:15:17961 EXPECT_RECT_EQ(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14962 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17963 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14964 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
965
966 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
967 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
968 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
969 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
970 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
971
972 occlusion.useDefaultLayerClipRect();
973 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
974 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
975 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
976 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
977 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
978 occlusion.setLayerClipRect(IntRect(-20, -20, 1000, 1000));
979
980 // There is nothing above child2's surface in the z-order.
[email protected]022cbf162012-09-01 01:15:17981 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, IntRect(-10, 420, 70, 80)));
[email protected]94f206c12012-08-25 00:09:14982
983 this->leaveContributingSurface(child2, occlusion);
984 this->visitLayer(layer1, occlusion);
985 this->enterContributingSurface(child1, occlusion);
986
[email protected]022cbf162012-09-01 01:15:17987 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:14988 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:17989 EXPECT_RECT_EQ(IntRect(-10, 430, 80, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:14990 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
991
992 EXPECT_TRUE(occlusion.occluded(child1, IntRect(-10, 430, 80, 70)));
993 EXPECT_FALSE(occlusion.occluded(child1, IntRect(-11, 430, 80, 70)));
994 EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 429, 80, 70)));
995 EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 81, 70)));
996 EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 80, 71)));
997
998 // child2's contents will occlude child1 below it.
[email protected]022cbf162012-09-01 01:15:17999 EXPECT_RECT_EQ(IntRect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(-10, 430, 80, 70)));
[email protected]94f206c12012-08-25 00:09:141000
1001 this->leaveContributingSurface(child1, occlusion);
1002 this->enterLayer(parent, occlusion);
1003
[email protected]022cbf162012-09-01 01:15:171004 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141005 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171006 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141007 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
1008
1009 EXPECT_FALSE(occlusion.occluded(parent, IntRect(20, 20, 80, 80)));
1010
1011 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 20, 70, 80)));
1012 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 20, 70, 80)));
1013 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 19, 70, 80)));
1014
1015 EXPECT_TRUE(occlusion.occluded(parent, IntRect(20, 30, 80, 70)));
1016 EXPECT_FALSE(occlusion.occluded(parent, IntRect(19, 30, 80, 70)));
1017 EXPECT_FALSE(occlusion.occluded(parent, IntRect(20, 29, 80, 70)));
1018
1019 /* Justification for the above occlusion:
1020 100
1021 +---------------------+
1022 | 20 | layer1
1023 | 30+ ---------------------------------+
1024 100 | 30| | layer2 |
1025 |20+----------------------------------+ |
1026 | | | | | |
1027 | | | | | |
1028 | | | | | |
1029 +--|-|----------------+ | |
1030 | | | | 510
1031 | | | |
1032 | | | |
1033 | | | |
1034 | | | |
1035 | | | |
1036 | | | |
1037 | +--------------------------------|-+
1038 | |
1039 +----------------------------------+
1040 510
1041 */
1042 }
1043};
1044
1045ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblings);
1046
1047template<class Types, bool opaqueLayers>
1048class CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1049protected:
1050 void runMyTest()
1051 {
1052 WebTransformationMatrix child1Transform;
1053 child1Transform.translate(250, 250);
1054 child1Transform.rotate(-90);
1055 child1Transform.translate(-250, -250);
1056
1057 WebTransformationMatrix child2Transform;
1058 child2Transform.translate(250, 250);
1059 child2Transform.rotate(90);
1060 child2Transform.translate(-250, -250);
1061
1062 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
[email protected]23bbb412012-08-30 20:03:381063 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:141064 typename Types::LayerType* child1 = this->createSurface(parent, child1Transform, FloatPoint(30, 20), IntSize(10, 10));
1065 typename Types::LayerType* child2 = this->createDrawingSurface(parent, child2Transform, FloatPoint(20, 40), IntSize(10, 10), false);
1066 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -20), IntSize(510, 510), true);
1067 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
1068 this->calcDrawEtc(parent);
1069
1070 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1071 occlusion.setLayerClipRect(IntRect(-30, -30, 1000, 1000));
1072
1073 this->visitLayer(layer2, occlusion);
1074 this->enterLayer(child2, occlusion);
1075
[email protected]022cbf162012-09-01 01:15:171076 EXPECT_RECT_EQ(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141077 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171078 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141079 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1080
1081 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
1082 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
1083 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
1084 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
1085 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
1086
1087 this->leaveLayer(child2, occlusion);
1088 this->enterContributingSurface(child2, occlusion);
1089
1090 // There is nothing above child2's surface in the z-order.
[email protected]022cbf162012-09-01 01:15:171091 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, IntRect(-10, 420, 70, 80)));
[email protected]94f206c12012-08-25 00:09:141092
1093 this->leaveContributingSurface(child2, occlusion);
1094 this->visitLayer(layer1, occlusion);
1095 this->enterContributingSurface(child1, occlusion);
1096
[email protected]022cbf162012-09-01 01:15:171097 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141098 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171099 EXPECT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141100 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1101
1102 EXPECT_TRUE(occlusion.occluded(child1, IntRect(420, -20, 80, 90)));
1103 EXPECT_FALSE(occlusion.occluded(child1, IntRect(419, -20, 80, 90)));
1104 EXPECT_FALSE(occlusion.occluded(child1, IntRect(420, -21, 80, 90)));
1105 EXPECT_FALSE(occlusion.occluded(child1, IntRect(420, -19, 80, 90)));
1106 EXPECT_FALSE(occlusion.occluded(child1, IntRect(421, -20, 80, 90)));
1107
1108 // child2's contents will occlude child1 below it.
[email protected]022cbf162012-09-01 01:15:171109 EXPECT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -20, 80, 90)));
1110 EXPECT_RECT_EQ(IntRect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -10, 80, 90)));
1111 EXPECT_RECT_EQ(IntRect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -20, 70, 90)));
[email protected]94f206c12012-08-25 00:09:141112
1113 this->leaveContributingSurface(child1, occlusion);
1114 this->enterLayer(parent, occlusion);
1115
[email protected]022cbf162012-09-01 01:15:171116 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141117 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171118 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141119 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1120
1121 EXPECT_TRUE(occlusion.occluded(parent, IntRect(10, 20, 90, 80)));
1122 EXPECT_FALSE(occlusion.occluded(parent, IntRect(9, 20, 90, 80)));
1123 EXPECT_FALSE(occlusion.occluded(parent, IntRect(10, 19, 90, 80)));
1124 EXPECT_FALSE(occlusion.occluded(parent, IntRect(11, 20, 90, 80)));
1125 EXPECT_FALSE(occlusion.occluded(parent, IntRect(10, 21, 90, 80)));
1126
1127 /* Justification for the above occlusion:
1128 100
1129 +---------------------+
1130 |20 | layer1
1131 10+----------------------------------+
1132 100 || 30 | layer2 |
1133 |20+----------------------------------+
1134 || | | | |
1135 || | | | |
1136 || | | | |
1137 +|-|------------------+ | |
1138 | | | | 510
1139 | | 510 | |
1140 | | | |
1141 | | | |
1142 | | | |
1143 | | | |
1144 | | 520 | |
1145 +----------------------------------+ |
1146 | |
1147 +----------------------------------+
1148 510
1149 */
1150 }
1151};
1152
1153ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1154
1155template<class Types, bool opaqueLayers>
1156class CCOcclusionTrackerTestFilters : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1157protected:
1158 void runMyTest()
1159 {
1160 WebTransformationMatrix layerTransform;
1161 layerTransform.translate(250, 250);
1162 layerTransform.rotate(90);
1163 layerTransform.translate(-250, -250);
1164
1165 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
[email protected]23bbb412012-08-30 20:03:381166 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:141167 typename Types::ContentLayerType* blurLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1168 typename Types::ContentLayerType* opaqueLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1169 typename Types::ContentLayerType* opacityLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1170
1171 WebFilterOperations filters;
1172 filters.append(WebFilterOperation::createBlurFilter(10));
1173 blurLayer->setFilters(filters);
1174
1175 filters.clear();
1176 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
1177 opaqueLayer->setFilters(filters);
1178
1179 filters.clear();
1180 filters.append(WebFilterOperation::createOpacityFilter(0.5));
1181 opacityLayer->setFilters(filters);
1182
1183 this->calcDrawEtc(parent);
1184
1185 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1186 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1187
1188 // Opacity layer won't contribute to occlusion.
1189 this->visitLayer(opacityLayer, occlusion);
1190 this->enterContributingSurface(opacityLayer, occlusion);
1191
1192 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1193 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1194
1195 // And has nothing to contribute to its parent surface.
1196 this->leaveContributingSurface(opacityLayer, occlusion);
1197 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1198 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1199
1200 // Opaque layer will contribute to occlusion.
1201 this->visitLayer(opaqueLayer, occlusion);
1202 this->enterContributingSurface(opaqueLayer, occlusion);
1203
[email protected]022cbf162012-09-01 01:15:171204 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141205 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171206 EXPECT_RECT_EQ(IntRect(0, 430, 70, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141207 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1208
1209 // And it gets translated to the parent surface.
1210 this->leaveContributingSurface(opaqueLayer, occlusion);
[email protected]022cbf162012-09-01 01:15:171211 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141212 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171213 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141214 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1215
1216 // The blur layer needs to throw away any occlusion from outside its subtree.
1217 this->enterLayer(blurLayer, occlusion);
1218 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1219 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1220
1221 // And it won't contribute to occlusion.
1222 this->leaveLayer(blurLayer, occlusion);
1223 this->enterContributingSurface(blurLayer, occlusion);
1224 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1225 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1226
1227 // But the opaque layer's occlusion is preserved on the parent.
1228 this->leaveContributingSurface(blurLayer, occlusion);
1229 this->enterLayer(parent, occlusion);
[email protected]022cbf162012-09-01 01:15:171230 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141231 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171232 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141233 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1234 }
1235};
1236
1237ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestFilters);
1238
1239template<class Types, bool opaqueLayers>
1240class CCOcclusionTrackerTestReplicaDoesOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1241protected:
1242 void runMyTest()
1243 {
1244 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
1245 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1246 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1247 this->calcDrawEtc(parent);
1248
1249 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1250 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1251
1252 this->visitLayer(surface, occlusion);
1253
[email protected]022cbf162012-09-01 01:15:171254 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141255 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171256 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141257 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1258
1259 this->visitContributingSurface(surface, occlusion);
1260 this->enterLayer(parent, occlusion);
1261
1262 // The surface and replica should both be occluding the parent.
[email protected]022cbf162012-09-01 01:15:171263 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141264 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
1265 }
1266};
1267
1268ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaDoesOcclude);
1269
1270template<class Types, bool opaqueLayers>
1271class CCOcclusionTrackerTestReplicaWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1272protected:
1273 void runMyTest()
1274 {
1275 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 170));
[email protected]23bbb412012-08-30 20:03:381276 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:141277 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1278 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1279 this->calcDrawEtc(parent);
1280
1281 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1282 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1283
1284 this->visitLayer(surface, occlusion);
1285
[email protected]022cbf162012-09-01 01:15:171286 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141287 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171288 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141289 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1290
1291 this->visitContributingSurface(surface, occlusion);
1292 this->enterLayer(parent, occlusion);
1293
1294 // The surface and replica should both be occluding the parent.
[email protected]022cbf162012-09-01 01:15:171295 EXPECT_RECT_EQ(IntRect(0, 100, 100, 70), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141296 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
1297 }
1298};
1299
1300ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithClipping);
1301
1302template<class Types, bool opaqueLayers>
1303class CCOcclusionTrackerTestReplicaWithMask : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1304protected:
1305 void runMyTest()
1306 {
1307 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
1308 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1309 typename Types::LayerType* replica = this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1310 this->createMaskLayer(replica, IntSize(10, 10));
1311 this->calcDrawEtc(parent);
1312
1313 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1314 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1315
1316 this->visitLayer(surface, occlusion);
1317
[email protected]022cbf162012-09-01 01:15:171318 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141319 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:171320 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141321 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1322
1323 this->visitContributingSurface(surface, occlusion);
1324 this->enterLayer(parent, occlusion);
1325
1326 // The replica should not be occluding the parent, since it has a mask applied to it.
[email protected]022cbf162012-09-01 01:15:171327 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141328 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1329 }
1330};
1331
1332ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithMask);
1333
1334template<class Types, bool opaqueLayers>
1335class CCOcclusionTrackerTestLayerClipRectOutsideChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1336protected:
1337 void runMyTest()
1338 {
1339 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1340 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1341 this->calcDrawEtc(parent);
1342
1343 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1344 occlusion.setLayerClipRect(IntRect(200, 100, 100, 100));
1345
1346 this->enterLayer(layer, occlusion);
1347
1348 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1349 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1350 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1351 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1352 EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1353
1354 occlusion.useDefaultLayerClipRect();
1355 EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1356 occlusion.setLayerClipRect(IntRect(200, 100, 100, 100));
1357
1358 this->leaveLayer(layer, occlusion);
1359 this->visitContributingSurface(layer, occlusion);
1360 this->enterLayer(parent, occlusion);
1361
1362 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1363 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1364 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1365 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1366 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1367 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1368 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1369 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1370 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1371
[email protected]022cbf162012-09-01 01:15:171372 EXPECT_RECT_EQ(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:141373 }
1374};
1375
1376ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOutsideChild);
1377
1378template<class Types, bool opaqueLayers>
1379class CCOcclusionTrackerTestViewportRectOutsideChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1380protected:
1381 void runMyTest()
1382 {
1383 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1384 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1385 this->calcDrawEtc(parent);
1386
1387 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(200, 100, 100, 100));
1388 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1389
1390 this->enterLayer(layer, occlusion);
1391
1392 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1393 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1394 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1395 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1396 EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1397
1398 occlusion.useDefaultLayerClipRect();
1399 EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1400 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1401
1402 this->leaveLayer(layer, occlusion);
1403 this->visitContributingSurface(layer, occlusion);
1404 this->enterLayer(parent, occlusion);
1405
1406 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1407 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1408 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1409 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1410 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1411 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1412 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1413 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1414 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1415
[email protected]022cbf162012-09-01 01:15:171416 EXPECT_RECT_EQ(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:141417 }
1418};
1419
1420ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOutsideChild);
1421
1422template<class Types, bool opaqueLayers>
1423class CCOcclusionTrackerTestLayerClipRectOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1424protected:
1425 void runMyTest()
1426 {
1427 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1428 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1429 this->calcDrawEtc(parent);
1430
1431 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1432 occlusion.setLayerClipRect(IntRect(100, 100, 100, 100));
1433
1434 this->enterLayer(layer, occlusion);
1435
1436 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1437 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1438 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1439 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1440
1441 this->leaveLayer(layer, occlusion);
1442 this->visitContributingSurface(layer, occlusion);
1443 this->enterLayer(parent, occlusion);
1444
1445 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1446 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1447 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1448 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1449 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1450 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1451 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1452 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1453 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1454
1455 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1456 }
1457};
1458
1459ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOverChild);
1460
1461template<class Types, bool opaqueLayers>
1462class CCOcclusionTrackerTestViewportRectOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1463protected:
1464 void runMyTest()
1465 {
1466 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1467 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1468 this->calcDrawEtc(parent);
1469
1470 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(100, 100, 100, 100));
1471 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1472
1473 this->enterLayer(layer, occlusion);
1474
1475 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1476 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1477 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1478 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1479
1480 this->leaveLayer(layer, occlusion);
1481 this->visitContributingSurface(layer, occlusion);
1482 this->enterLayer(parent, occlusion);
1483
1484 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1485 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1486 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1487 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1488 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1489 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1490 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1491 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1492 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1493
1494 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1495 }
1496};
1497
[email protected]0a56ed52012-09-24 21:59:541498ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOverChild);
[email protected]94f206c12012-08-25 00:09:141499
1500template<class Types, bool opaqueLayers>
1501class CCOcclusionTrackerTestLayerClipRectPartlyOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1502protected:
1503 void runMyTest()
1504 {
1505 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1506 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1507 this->calcDrawEtc(parent);
1508
1509 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1510 occlusion.setLayerClipRect(IntRect(50, 50, 200, 200));
1511
1512 this->enterLayer(layer, occlusion);
1513
1514 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1515 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1516 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1517 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1518
1519 this->leaveLayer(layer, occlusion);
1520 this->visitContributingSurface(layer, occlusion);
1521 this->enterLayer(parent, occlusion);
1522
1523 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1524 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1525 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1526 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1527 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1528 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1529 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1530 EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1531 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1532
[email protected]022cbf162012-09-01 01:15:171533 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1534 EXPECT_RECT_EQ(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)));
1535 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)));
1536 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)));
1537 EXPECT_RECT_EQ(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)));
[email protected]94f206c12012-08-25 00:09:141538 }
1539};
1540
1541ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectPartlyOverChild);
1542
1543template<class Types, bool opaqueLayers>
1544class CCOcclusionTrackerTestViewportRectPartlyOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1545protected:
1546 void runMyTest()
1547 {
1548 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1549 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1550 this->calcDrawEtc(parent);
1551
1552 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(50, 50, 200, 200));
1553 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1554
1555 this->enterLayer(layer, occlusion);
1556
1557 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1558 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1559 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1560 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1561
1562 this->leaveLayer(layer, occlusion);
1563 this->visitContributingSurface(layer, occlusion);
1564 this->enterLayer(parent, occlusion);
1565
1566 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1567 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1568 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1569 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1570 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1571 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1572 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1573 EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1574 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1575
[email protected]022cbf162012-09-01 01:15:171576 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1577 EXPECT_RECT_EQ(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)));
1578 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)));
1579 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)));
1580 EXPECT_RECT_EQ(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)));
[email protected]94f206c12012-08-25 00:09:141581 }
1582};
1583
1584ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectPartlyOverChild);
1585
1586template<class Types, bool opaqueLayers>
1587class CCOcclusionTrackerTestLayerClipRectOverNothing : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1588protected:
1589 void runMyTest()
1590 {
1591 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1592 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1593 this->calcDrawEtc(parent);
1594
1595 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1596 occlusion.setLayerClipRect(IntRect(500, 500, 100, 100));
1597
1598 this->enterLayer(layer, occlusion);
1599
1600 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1601 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1602 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1603 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1604
1605 this->leaveLayer(layer, occlusion);
1606 this->visitContributingSurface(layer, occlusion);
1607 this->enterLayer(parent, occlusion);
1608
1609 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1610 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1611 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1612 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1613 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1614 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1615 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1616 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1617 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1618
1619 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1620 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)).isEmpty());
1621 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)).isEmpty());
1622 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)).isEmpty());
1623 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)).isEmpty());
1624 }
1625};
1626
1627ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOverNothing);
1628
1629template<class Types, bool opaqueLayers>
1630class CCOcclusionTrackerTestViewportRectOverNothing : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1631protected:
1632 void runMyTest()
1633 {
1634 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1635 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1636 this->calcDrawEtc(parent);
1637
1638 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(500, 500, 100, 100));
1639 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1640
1641 this->enterLayer(layer, occlusion);
1642
1643 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1644 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1645 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1646 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1647
1648 this->leaveLayer(layer, occlusion);
1649 this->visitContributingSurface(layer, occlusion);
1650 this->enterLayer(parent, occlusion);
1651
1652 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1653 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1654 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1655 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1656 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1657 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1658 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1659 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1660 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1661
1662 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1663 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)).isEmpty());
1664 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)).isEmpty());
1665 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)).isEmpty());
1666 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)).isEmpty());
1667 }
1668};
1669
1670ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOverNothing);
1671
1672template<class Types, bool opaqueLayers>
1673class CCOcclusionTrackerTestLayerClipRectForLayerOffOrigin : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1674protected:
1675 void runMyTest()
1676 {
1677 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1678 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1679 this->calcDrawEtc(parent);
1680
1681 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1682 this->enterLayer(layer, occlusion);
1683
1684 // This layer is translated when drawn into its target. So if the clip rect given from the target surface
1685 // is not in that target space, then after translating these query rects into the target, they will fall outside
1686 // the clip and be considered occluded.
1687 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1688 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1689 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1690 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1691 }
1692};
1693
1694ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectForLayerOffOrigin);
1695
1696template<class Types, bool opaqueLayers>
1697class CCOcclusionTrackerTestOpaqueContentsRegionEmpty : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1698protected:
1699 void runMyTest()
1700 {
1701 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1702 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), false);
1703 this->calcDrawEtc(parent);
1704
1705 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1706 this->enterLayer(layer, occlusion);
1707
1708 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1709 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1710 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1711 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1712
1713 // Occluded since its outside the surface bounds.
1714 EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1715
1716 // Test without any clip rect.
1717 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1718 EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1719 occlusion.useDefaultLayerClipRect();
1720
1721 this->leaveLayer(layer, occlusion);
1722 this->visitContributingSurface(layer, occlusion);
1723 this->enterLayer(parent, occlusion);
1724
1725 EXPECT_TRUE(occlusion.occlusionInScreenSpace().bounds().isEmpty());
1726 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
1727 }
1728};
1729
1730MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionEmpty);
1731
1732template<class Types, bool opaqueLayers>
1733class CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1734protected:
1735 void runMyTest()
1736 {
1737 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1738 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(200, 200), false);
1739 this->calcDrawEtc(parent);
1740
1741 {
1742 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1743 layer->setOpaqueContentsRect(IntRect(0, 0, 100, 100));
1744
1745 this->resetLayerIterator();
1746 this->visitLayer(layer, occlusion);
1747 this->enterLayer(parent, occlusion);
1748
[email protected]022cbf162012-09-01 01:15:171749 EXPECT_RECT_EQ(IntRect(100, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141750 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1751
1752 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1753 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1754 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1755 }
1756
1757 {
1758 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1759 layer->setOpaqueContentsRect(IntRect(20, 20, 180, 180));
1760
1761 this->resetLayerIterator();
1762 this->visitLayer(layer, occlusion);
1763 this->enterLayer(parent, occlusion);
1764
[email protected]022cbf162012-09-01 01:15:171765 EXPECT_RECT_EQ(IntRect(120, 120, 180, 180), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141766 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1767
1768 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1769 EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1770 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1771 }
1772
1773 {
1774 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1775 layer->setOpaqueContentsRect(IntRect(150, 150, 100, 100));
1776
1777 this->resetLayerIterator();
1778 this->visitLayer(layer, occlusion);
1779 this->enterLayer(parent, occlusion);
1780
[email protected]022cbf162012-09-01 01:15:171781 EXPECT_RECT_EQ(IntRect(250, 250, 50, 50), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141782 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1783
1784 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1785 EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1786 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1787 }
1788 }
1789};
1790
1791MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1792
1793template<class Types, bool opaqueLayers>
1794class CCOcclusionTrackerTest3dTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1795protected:
1796 void runMyTest()
1797 {
1798 WebTransformationMatrix transform;
1799 transform.rotate3d(0, 30, 0);
1800
1801 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1802 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1803 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
1804 this->calcDrawEtc(parent);
1805
1806 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1807 this->enterLayer(layer, occlusion);
1808
1809 // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
[email protected]022cbf162012-09-01 01:15:171810 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
[email protected]94f206c12012-08-25 00:09:141811 }
1812};
1813
1814MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTest3dTransform);
1815
1816template<class Types, bool opaqueLayers>
1817class CCOcclusionTrackerTestUnsorted3dLayers : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1818protected:
1819 void runMyTest()
1820 {
1821 // Currently, the main thread layer iterator does not iterate over 3d items in
1822 // sorted order, because layer sorting is not performed on the main thread.
1823 // Because of this, the occlusion tracker cannot assume that a 3d layer occludes
1824 // other layers that have not yet been iterated over. For now, the expected
1825 // behavior is that a 3d layer simply does not add any occlusion to the occlusion
1826 // tracker.
1827
1828 WebTransformationMatrix translationToFront;
1829 translationToFront.translate3d(0, 0, -10);
1830 WebTransformationMatrix translationToBack;
1831 translationToFront.translate3d(0, 0, -100);
1832
1833 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1834 typename Types::ContentLayerType* child1 = this->createDrawingLayer(parent, translationToBack, FloatPoint(0, 0), IntSize(100, 100), true);
1835 typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, translationToFront, FloatPoint(50, 50), IntSize(100, 100), true);
1836 parent->setPreserves3D(true);
1837
1838 this->calcDrawEtc(parent);
1839
1840 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1841 this->visitLayer(child2, occlusion);
1842 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1843 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1844
1845 this->visitLayer(child1, occlusion);
1846 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1847 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1848 }
1849};
1850
1851// This test will have different layer ordering on the impl thread; the test will only work on the main thread.
1852MAIN_THREAD_TEST(CCOcclusionTrackerTestUnsorted3dLayers);
1853
1854template<class Types, bool opaqueLayers>
1855class CCOcclusionTrackerTestPerspectiveTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1856protected:
1857 void runMyTest()
1858 {
1859 WebTransformationMatrix transform;
1860 transform.translate(150, 150);
1861 transform.applyPerspective(400);
1862 transform.rotate3d(1, 0, 0, -30);
1863 transform.translate(-150, -150);
1864
1865 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1866 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1867 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
1868 container->setPreserves3D(true);
1869 layer->setPreserves3D(true);
1870 this->calcDrawEtc(parent);
1871
1872 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1873 this->enterLayer(layer, occlusion);
1874
[email protected]022cbf162012-09-01 01:15:171875 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
[email protected]94f206c12012-08-25 00:09:141876 }
1877};
1878
1879// 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.
1880IMPL_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransform);
1881
1882template<class Types, bool opaqueLayers>
1883class CCOcclusionTrackerTestPerspectiveTransformBehindCamera : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1884protected:
1885 void runMyTest()
1886 {
1887 // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
1888 WebTransformationMatrix transform;
1889 transform.translate(250, 50);
1890 transform.applyPerspective(10);
1891 transform.translate(-250, -50);
1892 transform.translate(250, 50);
1893 transform.rotate3d(1, 0, 0, -167);
1894 transform.translate(-250, -50);
1895
1896 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 100));
1897 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
1898 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(0, 0), IntSize(500, 500), true);
1899 container->setPreserves3D(true);
1900 layer->setPreserves3D(true);
1901 this->calcDrawEtc(parent);
1902
1903 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1904 this->enterLayer(layer, occlusion);
1905
1906 // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
1907 // this will include many more pixels but must include at least the bottom 11 rows.
1908 EXPECT_TRUE(occlusion.unoccludedContentRect(layer, IntRect(0, 0, 500, 500)).contains(IntRect(0, 489, 500, 11)));
1909 }
1910};
1911
1912// 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.
1913IMPL_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransformBehindCamera);
1914
1915template<class Types, bool opaqueLayers>
1916class CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1917protected:
1918 void runMyTest()
1919 {
1920 WebTransformationMatrix transform;
1921 transform.translate(50, 50);
1922 transform.applyPerspective(100);
1923 transform.translate3d(0, 0, 110);
1924 transform.translate(-50, -50);
1925
1926 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1927 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true);
1928 parent->setPreserves3D(true);
1929 layer->setPreserves3D(true);
1930 this->calcDrawEtc(parent);
1931
1932 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1933
1934 // The |layer| is entirely behind the camera and should not occlude.
1935 this->visitLayer(layer, occlusion);
1936 this->enterLayer(parent, occlusion);
1937 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
1938 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
1939 }
1940};
1941
1942// 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.
1943IMPL_THREAD_TEST(CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
1944
1945template<class Types, bool opaqueLayers>
1946class CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1947protected:
1948 void runMyTest()
1949 {
1950 WebTransformationMatrix transform;
1951 transform.translate(50, 50);
1952 transform.applyPerspective(100);
1953 transform.translate3d(0, 0, 99);
1954 transform.translate(-50, -50);
1955
1956 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
[email protected]23bbb412012-08-30 20:03:381957 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:141958 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true);
1959 parent->setPreserves3D(true);
1960 layer->setPreserves3D(true);
1961 this->calcDrawEtc(parent);
1962
1963 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1964
1965 // This is very close to the camera, so pixels in its visibleContentRect will actually go outside of the layer's clipRect.
1966 // Ensure that those pixels don't occlude things outside the clipRect.
1967 this->visitLayer(layer, occlusion);
1968 this->enterLayer(parent, occlusion);
[email protected]022cbf162012-09-01 01:15:171969 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:141970 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
[email protected]022cbf162012-09-01 01:15:171971 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:141972 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1973 }
1974};
1975
1976// 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.
1977IMPL_THREAD_TEST(CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect);
1978
1979template<class Types, bool opaqueLayers>
1980class CCOcclusionTrackerTestAnimationOpacity1OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1981protected:
1982 void runMyTest()
1983 {
1984 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1985 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
1986 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
1987 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
1988 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
1989 typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false);
1990 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
1991
1992 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 0, 1, false);
1993 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 0, 1, false);
1994 this->calcDrawEtc(parent);
1995
1996 EXPECT_TRUE(layer->drawOpacityIsAnimating());
1997 EXPECT_FALSE(surface->drawOpacityIsAnimating());
1998 EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
1999
2000 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2001
2002 this->visitLayer(topmost, occlusion);
2003 this->enterLayer(parent2, occlusion);
2004 // This occlusion will affect all surfaces.
[email protected]022cbf162012-09-01 01:15:172005 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent2, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142006 this->leaveLayer(parent2, occlusion);
2007
2008 this->visitLayer(surfaceChild2, occlusion);
2009 this->enterLayer(surfaceChild, occlusion);
[email protected]022cbf162012-09-01 01:15:172010 EXPECT_RECT_EQ(IntRect(100, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142011 this->leaveLayer(surfaceChild, occlusion);
2012 this->enterLayer(surface, occlusion);
[email protected]022cbf162012-09-01 01:15:172013 EXPECT_RECT_EQ(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142014 this->leaveLayer(surface, occlusion);
2015
2016 this->enterContributingSurface(surface, occlusion);
2017 // Occlusion within the surface is lost when leaving the animating surface.
[email protected]022cbf162012-09-01 01:15:172018 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142019 this->leaveContributingSurface(surface, occlusion);
2020
2021 this->visitLayer(layer, occlusion);
2022 this->enterLayer(parent, occlusion);
2023
2024 // Occlusion is not added for the animating |layer|.
[email protected]022cbf162012-09-01 01:15:172025 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142026 }
2027};
2028
2029MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity1OnMainThread);
2030
2031template<class Types, bool opaqueLayers>
2032class CCOcclusionTrackerTestAnimationOpacity0OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2033protected:
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, 1, 0, false);
2045 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 1, 0, false);
2046 this->calcDrawEtc(parent);
2047
2048 EXPECT_TRUE(layer->drawOpacityIsAnimating());
2049 EXPECT_FALSE(surface->drawOpacityIsAnimating());
2050 EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
2051
2052 TestCCOcclusionTrackerWithClip<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.
[email protected]022cbf162012-09-01 01:15:172057 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142058 this->leaveLayer(parent2, occlusion);
2059
2060 this->visitLayer(surfaceChild2, occlusion);
2061 this->enterLayer(surfaceChild, occlusion);
[email protected]022cbf162012-09-01 01:15:172062 EXPECT_RECT_EQ(IntRect(100, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142063 this->leaveLayer(surfaceChild, occlusion);
2064 this->enterLayer(surface, occlusion);
[email protected]022cbf162012-09-01 01:15:172065 EXPECT_RECT_EQ(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142066 this->leaveLayer(surface, occlusion);
2067
2068 this->enterContributingSurface(surface, occlusion);
2069 // Occlusion within the surface is lost when leaving the animating surface.
[email protected]022cbf162012-09-01 01:15:172070 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142071 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|.
[email protected]022cbf162012-09-01 01:15:172077 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142078 }
2079};
2080
2081MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity0OnMainThread);
2082
2083template<class Types, bool opaqueLayers>
2084class CCOcclusionTrackerTestAnimationTranslateOnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2085protected:
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* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(50, 300), true);
2094
2095 addAnimatedTransformToController(*layer->layerAnimationController(), 10, 30, 0);
2096 addAnimatedTransformToController(*surface->layerAnimationController(), 10, 30, 0);
2097 addAnimatedTransformToController(*surfaceChild->layerAnimationController(), 10, 30, 0);
2098 this->calcDrawEtc(parent);
2099
2100 EXPECT_TRUE(layer->drawTransformIsAnimating());
2101 EXPECT_TRUE(layer->screenSpaceTransformIsAnimating());
2102 EXPECT_TRUE(surface->renderSurface()->targetSurfaceTransformsAreAnimating());
2103 EXPECT_TRUE(surface->renderSurface()->screenSpaceTransformsAreAnimating());
2104 // The surface owning layer doesn't animate against its own surface.
2105 EXPECT_FALSE(surface->drawTransformIsAnimating());
2106 EXPECT_TRUE(surface->screenSpaceTransformIsAnimating());
2107 EXPECT_TRUE(surfaceChild->drawTransformIsAnimating());
2108 EXPECT_TRUE(surfaceChild->screenSpaceTransformIsAnimating());
2109
2110 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2111
2112 this->visitLayer(surface2, occlusion);
2113 this->enterContributingSurface(surface2, occlusion);
2114
[email protected]022cbf162012-09-01 01:15:172115 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142116 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2117
2118 this->leaveContributingSurface(surface2, occlusion);
2119 this->enterLayer(surfaceChild2, occlusion);
2120
2121 // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2122 // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer.
[email protected]022cbf162012-09-01 01:15:172123 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild2, IntRect(0, 0, 100, 300)));
[email protected]94f206c12012-08-25 00:09:142124 EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
2125
2126 this->leaveLayer(surfaceChild2, occlusion);
2127 this->enterLayer(surfaceChild, occlusion);
2128 EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 100, 300)));
[email protected]022cbf162012-09-01 01:15:172129 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142130 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172131 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142132 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
[email protected]022cbf162012-09-01 01:15:172133 EXPECT_RECT_EQ(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142134
2135 // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target and the screen, so it
2136 // can't be occluded.
[email protected]022cbf162012-09-01 01:15:172137 EXPECT_RECT_EQ(IntRect(0, 0, 200, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 200, 300)));
[email protected]94f206c12012-08-25 00:09:142138 EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
2139
2140 this->leaveLayer(surfaceChild, occlusion);
2141 this->enterLayer(surface, occlusion);
2142 // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
[email protected]022cbf162012-09-01 01:15:172143 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142144 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172145 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142146 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
[email protected]022cbf162012-09-01 01:15:172147 EXPECT_RECT_EQ(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142148
2149 this->leaveLayer(surface, occlusion);
2150 // 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.
[email protected]022cbf162012-09-01 01:15:172151 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142152 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172153 EXPECT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142154 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
[email protected]022cbf162012-09-01 01:15:172155 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142156
2157 this->enterContributingSurface(surface, occlusion);
2158 // The contributing |surface| is animating so it can't be occluded.
[email protected]022cbf162012-09-01 01:15:172159 EXPECT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142160 this->leaveContributingSurface(surface, occlusion);
2161
2162 this->enterLayer(layer, occlusion);
2163 // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
[email protected]022cbf162012-09-01 01:15:172164 EXPECT_RECT_EQ(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142165 this->leaveLayer(layer, occlusion);
2166
2167 this->enterLayer(parent, occlusion);
2168 // The |layer| is animating in the screen and in its target, so no occlusion is added.
[email protected]022cbf162012-09-01 01:15:172169 EXPECT_RECT_EQ(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
[email protected]94f206c12012-08-25 00:09:142170 }
2171};
2172
2173MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationTranslateOnMainThread);
2174
2175template<class Types, bool opaqueLayers>
2176class CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2177protected:
2178 void runMyTest()
2179 {
2180 WebTransformationMatrix surfaceTransform;
2181 surfaceTransform.translate(300, 300);
2182 surfaceTransform.scale(2);
2183 surfaceTransform.translate(-150, -150);
2184
2185 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
2186 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, surfaceTransform, FloatPoint(0, 0), IntSize(300, 300), false);
2187 typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(300, 300), false);
2188 surface->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
2189 surface2->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
2190 this->calcDrawEtc(parent);
2191
2192 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2193
2194 this->visitLayer(surface2, occlusion);
2195 this->visitContributingSurface(surface2, occlusion);
2196
[email protected]022cbf162012-09-01 01:15:172197 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142198 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172199 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142200 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2201
2202 // Clear any stored occlusion.
2203 occlusion.setOcclusionInScreenSpace(Region());
2204 occlusion.setOcclusionInTargetSurface(Region());
2205
2206 this->visitLayer(surface, occlusion);
2207 this->visitContributingSurface(surface, occlusion);
2208
[email protected]022cbf162012-09-01 01:15:172209 EXPECT_RECT_EQ(IntRect(0, 0, 400, 400), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142210 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172211 EXPECT_RECT_EQ(IntRect(0, 0, 400, 400), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142212 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2213 }
2214};
2215
2216MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2217
2218template<class Types, bool opaqueLayers>
2219class CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2220protected:
2221 void runMyTest()
2222 {
2223 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
[email protected]23bbb412012-08-30 20:03:382224 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:142225 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 300), false);
2226 surface->setOpaqueContentsRect(IntRect(0, 0, 400, 200));
2227 this->calcDrawEtc(parent);
2228
2229 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2230
2231 this->visitLayer(surface, occlusion);
2232 this->visitContributingSurface(surface, occlusion);
2233
[email protected]022cbf162012-09-01 01:15:172234 EXPECT_RECT_EQ(IntRect(0, 0, 300, 200), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142235 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172236 EXPECT_RECT_EQ(IntRect(0, 0, 300, 200), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142237 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2238 }
2239};
2240
2241MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2242
2243template<class Types, bool opaqueLayers>
2244class CCOcclusionTrackerTestReplicaOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2245protected:
2246 void runMyTest()
2247 {
2248 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2249 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2250 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2251 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100), true);
2252 this->calcDrawEtc(parent);
2253
2254 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2255 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2256
2257 // |topmost| occludes the replica, but not the surface itself.
2258 this->visitLayer(topmost, occlusion);
2259
[email protected]022cbf162012-09-01 01:15:172260 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142261 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172262 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142263 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2264
2265 this->visitLayer(surface, occlusion);
2266
[email protected]022cbf162012-09-01 01:15:172267 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142268 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172269 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142270 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2271
2272 this->enterContributingSurface(surface, occlusion);
2273
2274 // Surface is not occluded so it shouldn't think it is.
[email protected]022cbf162012-09-01 01:15:172275 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
[email protected]94f206c12012-08-25 00:09:142276 }
2277};
2278
2279ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaOccluded);
2280
2281template<class Types, bool opaqueLayers>
2282class CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2283protected:
2284 void runMyTest()
2285 {
2286 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2287 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2288 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2289 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 110), true);
2290 this->calcDrawEtc(parent);
2291
2292 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2293 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2294
2295 // |topmost| occludes the surface, but not the entire surface's replica.
2296 this->visitLayer(topmost, occlusion);
2297
[email protected]022cbf162012-09-01 01:15:172298 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142299 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172300 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142301 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2302
2303 this->visitLayer(surface, occlusion);
2304
[email protected]022cbf162012-09-01 01:15:172305 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142306 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172307 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142308 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2309
2310 this->enterContributingSurface(surface, occlusion);
2311
2312 // Surface is occluded, but only the top 10px of the replica.
[email protected]022cbf162012-09-01 01:15:172313 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2314 EXPECT_RECT_EQ(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, true, IntRect(0, 0, 100, 100)));
[email protected]94f206c12012-08-25 00:09:142315 }
2316};
2317
2318ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2319
2320template<class Types, bool opaqueLayers>
2321class CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2322protected:
2323 void runMyTest()
2324 {
2325 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2326 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2327 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2328 typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(40, 100), true);
2329 typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 100), true);
2330 this->calcDrawEtc(parent);
2331
2332 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2333 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2334
2335 // These occlude the surface and replica differently, so we can test each one.
2336 this->visitLayer(overReplica, occlusion);
2337 this->visitLayer(overSurface, occlusion);
2338
[email protected]022cbf162012-09-01 01:15:172339 EXPECT_RECT_EQ(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142340 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172341 EXPECT_RECT_EQ(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142342 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2343
2344 this->visitLayer(surface, occlusion);
2345
[email protected]022cbf162012-09-01 01:15:172346 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142347 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172348 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142349 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2350
2351 this->enterContributingSurface(surface, occlusion);
2352
2353 // Surface and replica are occluded different amounts.
[email protected]022cbf162012-09-01 01:15:172354 EXPECT_RECT_EQ(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2355 EXPECT_RECT_EQ(IntRect(50, 0, 50, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, true, IntRect(0, 0, 100, 100)));
[email protected]94f206c12012-08-25 00:09:142356 }
2357};
2358
2359ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2360
2361template<class Types, bool opaqueLayers>
2362class CCOcclusionTrackerTestSurfaceChildOfSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2363protected:
2364 void runMyTest()
2365 {
2366 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2367
2368 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2369 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2370 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 10), IntSize(100, 50), true);
2371 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
2372 this->calcDrawEtc(parent);
2373
2374 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(-100, -100, 1000, 1000));
2375
2376 // |topmost| occludes everything partially so we know occlusion is happening at all.
2377 this->visitLayer(topmost, occlusion);
2378
[email protected]022cbf162012-09-01 01:15:172379 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142380 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172381 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142382 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2383
2384 this->visitLayer(surfaceChild, occlusion);
2385
2386 // surfaceChild increases the occlusion in the screen by a narrow sliver.
[email protected]022cbf162012-09-01 01:15:172387 EXPECT_RECT_EQ(IntRect(0, 0, 100, 60), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142388 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2389 // In its own surface, surfaceChild is at 0,0 as is its occlusion.
[email protected]022cbf162012-09-01 01:15:172390 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142391 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2392
2393 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2394 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2395 // as its parent does not have a clipRect.
2396
2397 this->enterContributingSurface(surfaceChild, occlusion);
2398 // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
2399 // does not get clipped away inappropriately.
[email protected]022cbf162012-09-01 01:15:172400 EXPECT_RECT_EQ(IntRect(0, 40, 100, 10), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, IntRect(0, 0, 100, 50)));
[email protected]94f206c12012-08-25 00:09:142401 this->leaveContributingSurface(surfaceChild, occlusion);
2402
2403 // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
2404 this->enterLayer(surface, occlusion);
[email protected]022cbf162012-09-01 01:15:172405 EXPECT_RECT_EQ(IntRect(0, 0, 100, 60), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142406 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172407 EXPECT_RECT_EQ(IntRect(0, 10, 100, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142408 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2409 this->leaveLayer(surface, occlusion);
2410
2411 this->enterContributingSurface(surface, occlusion);
2412 // The surface's parent does have a clipRect as it is the root layer.
[email protected]022cbf162012-09-01 01:15:172413 EXPECT_RECT_EQ(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
[email protected]94f206c12012-08-25 00:09:142414 }
2415};
2416
2417ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfSurface);
2418
2419template<class Types, bool opaqueLayers>
2420class CCOcclusionTrackerTestTopmostSurfaceIsClippedToViewport : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2421protected:
2422 void runMyTest()
2423 {
2424 // This test verifies that the top-most surface is considered occluded outside of its target's clipRect and outside the viewport rect.
2425
2426 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2427 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
2428 this->calcDrawEtc(parent);
2429
2430 {
2431 // Make a viewport rect that is larger than the root layer.
2432 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2433
2434 this->visitLayer(surface, occlusion);
2435
2436 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2437 this->enterContributingSurface(surface, occlusion);
2438 // Make sure the parent's clipRect clips the unoccluded region of the child surface.
[email protected]022cbf162012-09-01 01:15:172439 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 300)));
[email protected]94f206c12012-08-25 00:09:142440 }
2441 this->resetLayerIterator();
2442 {
2443 // Make a viewport rect that is smaller than the root layer.
2444 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 100, 100));
2445
2446 this->visitLayer(surface, occlusion);
2447
2448 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2449 this->enterContributingSurface(surface, occlusion);
2450 // Make sure the viewport rect clips the unoccluded region of the child surface.
[email protected]022cbf162012-09-01 01:15:172451 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 300)));
[email protected]94f206c12012-08-25 00:09:142452 }
2453 }
2454};
2455
2456ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
2457
2458template<class Types, bool opaqueLayers>
2459class CCOcclusionTrackerTestSurfaceChildOfClippingSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2460protected:
2461 void runMyTest()
2462 {
2463 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2464
2465 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(80, 200));
[email protected]23bbb412012-08-30 20:03:382466 parent->setMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:142467 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2468 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), false);
2469 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
2470 this->calcDrawEtc(parent);
2471
2472 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2473 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2474
2475 // |topmost| occludes everything partially so we know occlusion is happening at all.
2476 this->visitLayer(topmost, occlusion);
2477
[email protected]022cbf162012-09-01 01:15:172478 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142479 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172480 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142481 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2482
2483 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2484 this->visitLayer(surfaceChild, occlusion);
2485
[email protected]022cbf162012-09-01 01:15:172486 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142487 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172488 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142489 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2490
2491 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2492 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2493 // as its parent does not have a clipRect.
2494
2495 this->enterContributingSurface(surfaceChild, occlusion);
2496 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
[email protected]022cbf162012-09-01 01:15:172497 EXPECT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, IntRect(0, 0, 100, 100)));
[email protected]94f206c12012-08-25 00:09:142498 this->leaveContributingSurface(surfaceChild, occlusion);
2499
2500 this->visitLayer(surface, occlusion);
2501 this->enterContributingSurface(surface, occlusion);
2502 // The surface's parent does have a clipRect as it is the root layer.
[email protected]022cbf162012-09-01 01:15:172503 EXPECT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
[email protected]94f206c12012-08-25 00:09:142504 }
2505};
2506
2507ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfClippingSurface);
2508
2509template<class Types, bool opaqueLayers>
2510class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2511protected:
2512 void runMyTest()
2513 {
2514 WebTransformationMatrix scaleByHalf;
2515 scaleByHalf.scale(0.5);
2516
2517 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2518 // 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
2519 // appears at 50, 50 and the replica at 200, 50.
2520 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2521 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2522 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2523 typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 50), true);
2524 typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(300, 50), true);
2525 typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 50), IntSize(50, 50), true);
2526 typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 50), IntSize(100, 50), true);
2527 typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
2528
2529 // Filters make the layer own a surface.
2530 WebFilterOperations filters;
2531 filters.append(WebFilterOperation::createBlurFilter(10));
2532 filteredSurface->setBackgroundFilters(filters);
2533
2534 // Save the distance of influence for the blur effect.
2535 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2536 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2537
2538 this->calcDrawEtc(parent);
2539
2540 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2541 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2542
2543 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2544 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2545 this->visitLayer(occludingLayer5, occlusion);
2546 this->visitLayer(occludingLayer4, occlusion);
2547 this->visitLayer(occludingLayer3, occlusion);
2548 this->visitLayer(occludingLayer2, occlusion);
2549 this->visitLayer(occludingLayer1, occlusion);
2550
[email protected]022cbf162012-09-01 01:15:172551 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142552 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172553 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142554 EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2555
2556 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2557 this->enterLayer(filteredSurface, occlusion);
[email protected]022cbf162012-09-01 01:15:172558 EXPECT_RECT_EQ(IntRect(1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 100, 100)));
2559 EXPECT_RECT_EQ(IntRect(0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 100, 100)));
2560 EXPECT_RECT_EQ(IntRect(0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 100, 100)));
2561 EXPECT_RECT_EQ(IntRect(0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 100, 100)));
[email protected]94f206c12012-08-25 00:09:142562
[email protected]022cbf162012-09-01 01:15:172563 EXPECT_RECT_EQ(IntRect(300 + 1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 1, 0, 100, 100)));
2564 EXPECT_RECT_EQ(IntRect(300 + 0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, 1, 100, 100)));
2565 EXPECT_RECT_EQ(IntRect(300 + 0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 - 1, 0, 100, 100)));
2566 EXPECT_RECT_EQ(IntRect(300 + 0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, -1, 100, 100)));
[email protected]94f206c12012-08-25 00:09:142567 this->leaveLayer(filteredSurface, occlusion);
2568
2569 // The filtered layer/replica does not occlude.
[email protected]022cbf162012-09-01 01:15:172570 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142571 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172572 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142573 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2574
2575 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2576 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2577 this->visitContributingSurface(filteredSurface, occlusion);
2578
2579 this->enterLayer(parent, occlusion);
[email protected]022cbf162012-09-01 01:15:172580 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142581 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172582 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142583 EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2584
2585 IntRect outsetRect;
2586 IntRect testRect;
2587
2588 // Nothing in the blur outsets for the filteredSurface is occluded.
2589 outsetRect = IntRect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2590 testRect = outsetRect;
[email protected]022cbf162012-09-01 01:15:172591 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142592
2593 // Stuff outside the blur outsets is still occluded though.
2594 testRect = outsetRect;
2595 testRect.expand(1, 0);
[email protected]022cbf162012-09-01 01:15:172596 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142597 testRect = outsetRect;
2598 testRect.expand(0, 1);
[email protected]022cbf162012-09-01 01:15:172599 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142600 testRect = outsetRect;
2601 testRect.move(-1, 0);
2602 testRect.expand(1, 0);
[email protected]022cbf162012-09-01 01:15:172603 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142604 testRect = outsetRect;
2605 testRect.move(0, -1);
2606 testRect.expand(0, 1);
[email protected]022cbf162012-09-01 01:15:172607 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142608
2609 // Nothing in the blur outsets for the filteredSurface's replica is occluded.
2610 outsetRect = IntRect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2611 testRect = outsetRect;
[email protected]022cbf162012-09-01 01:15:172612 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142613
2614 // Stuff outside the blur outsets is still occluded though.
2615 testRect = outsetRect;
2616 testRect.expand(1, 0);
[email protected]022cbf162012-09-01 01:15:172617 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142618 testRect = outsetRect;
2619 testRect.expand(0, 1);
[email protected]022cbf162012-09-01 01:15:172620 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142621 testRect = outsetRect;
2622 testRect.move(-1, 0);
2623 testRect.expand(1, 0);
[email protected]022cbf162012-09-01 01:15:172624 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142625 testRect = outsetRect;
2626 testRect.move(0, -1);
2627 testRect.expand(0, 1);
[email protected]022cbf162012-09-01 01:15:172628 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
[email protected]94f206c12012-08-25 00:09:142629 }
2630};
2631
2632ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2633
2634template<class Types, bool opaqueLayers>
2635class CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2636protected:
2637 void runMyTest()
2638 {
2639 WebTransformationMatrix scaleByHalf;
2640 scaleByHalf.scale(0.5);
2641
2642 // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
2643 typename Types::ContentLayerType* root = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(75, 75));
2644 typename Types::LayerType* parent = this->createSurface(root, scaleByHalf, FloatPoint(0, 0), IntSize(150, 150));
2645 parent->setMasksToBounds(true);
2646 typename Types::LayerType* filteredSurface1 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
2647 typename Types::LayerType* filteredSurface2 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
2648 typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(50, 50), true);
2649
2650 // Filters make the layers own surfaces.
2651 WebFilterOperations filters;
2652 filters.append(WebFilterOperation::createBlurFilter(3));
2653 filteredSurface1->setBackgroundFilters(filters);
2654 filteredSurface2->setBackgroundFilters(filters);
2655
2656 // Save the distance of influence for the blur effect.
2657 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2658 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2659
2660 this->calcDrawEtc(root);
2661
2662 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2663 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2664
2665 this->visitLayer(occludingLayerAbove, occlusion);
[email protected]022cbf162012-09-01 01:15:172666 EXPECT_RECT_EQ(IntRect(100 / 2, 100 / 2, 50 / 2, 50 / 2), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142667 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172668 EXPECT_RECT_EQ(IntRect(100, 100, 50, 50), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142669 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2670
2671 this->visitLayer(filteredSurface2, occlusion);
2672 this->visitContributingSurface(filteredSurface2, occlusion);
2673 this->visitLayer(filteredSurface1, occlusion);
2674 this->visitContributingSurface(filteredSurface1, occlusion);
2675
2676 ASSERT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2677 ASSERT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2678
2679 // Test expectations in the target.
2680 IntRect expectedOcclusion = IntRect(100 + outsetRight * 2, 100 + outsetBottom * 2, 50 - (outsetLeft + outsetRight) * 2, 50 - (outsetTop + outsetBottom) * 2);
[email protected]022cbf162012-09-01 01:15:172681 EXPECT_RECT_EQ(expectedOcclusion, occlusion.occlusionInTargetSurface().rects()[0]);
[email protected]94f206c12012-08-25 00:09:142682
2683 // Test expectations in the screen. Take the ceiling of half of the outsets.
2684 outsetTop = (outsetTop + 1) / 2;
2685 outsetRight = (outsetRight + 1) / 2;
2686 outsetBottom = (outsetBottom + 1) / 2;
2687 outsetLeft = (outsetLeft + 1) / 2;
2688 expectedOcclusion = IntRect(100 / 2 + outsetRight * 2, 100 / 2 + outsetBottom * 2, 50 / 2 - (outsetLeft + outsetRight) * 2, 50 /2 - (outsetTop + outsetBottom) * 2);
2689
[email protected]022cbf162012-09-01 01:15:172690 EXPECT_RECT_EQ(expectedOcclusion, occlusion.occlusionInScreenSpace().rects()[0]);
[email protected]94f206c12012-08-25 00:09:142691 }
2692};
2693
2694ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
2695
2696template<class Types, bool opaqueLayers>
2697class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2698protected:
2699 void runMyTest()
2700 {
2701 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2702 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2703 // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
2704 // the background filter.
2705 typename Types::LayerType* clippingSurface = this->createSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 70));
2706 clippingSurface->setMasksToBounds(true);
2707 typename Types::LayerType* filteredSurface = this->createDrawingLayer(clippingSurface, this->identityMatrix, FloatPoint(50, 50), IntSize(50, 50), false);
2708 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(150, 0), IntSize());
2709 typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 50), true);
2710 typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(300, 50), true);
2711 typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 50), IntSize(50, 50), true);
2712 typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 50), IntSize(100, 50), true);
2713 typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
2714
2715 // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
2716 WebFilterOperations filters;
2717 filters.append(WebFilterOperation::createBlurFilter(12));
2718 filteredSurface->setBackgroundFilters(filters);
2719
2720 // Save the distance of influence for the blur effect.
2721 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2722 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2723
2724 this->calcDrawEtc(parent);
2725
2726 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2727 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2728
2729 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2730 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2731 this->visitLayer(occludingLayer5, occlusion);
2732 this->visitLayer(occludingLayer4, occlusion);
2733 this->visitLayer(occludingLayer3, occlusion);
2734 this->visitLayer(occludingLayer2, occlusion);
2735 this->visitLayer(occludingLayer1, occlusion);
2736
[email protected]022cbf162012-09-01 01:15:172737 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142738 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172739 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142740 EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2741
2742 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2743 this->enterLayer(filteredSurface, occlusion);
[email protected]022cbf162012-09-01 01:15:172744 EXPECT_RECT_EQ(IntRect(1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 50, 50)));
2745 EXPECT_RECT_EQ(IntRect(0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 50, 50)));
2746 EXPECT_RECT_EQ(IntRect(0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 50, 50)));
2747 EXPECT_RECT_EQ(IntRect(0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 50, 50)));
[email protected]94f206c12012-08-25 00:09:142748
[email protected]022cbf162012-09-01 01:15:172749 EXPECT_RECT_EQ(IntRect(150 + 1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 1, 0, 50, 50)));
2750 EXPECT_RECT_EQ(IntRect(150 + 0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, 1, 50, 50)));
2751 EXPECT_RECT_EQ(IntRect(150 + 0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 - 1, 0, 50, 50)));
2752 EXPECT_RECT_EQ(IntRect(150 + 0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, -1, 50, 50)));
[email protected]94f206c12012-08-25 00:09:142753 this->leaveLayer(filteredSurface, occlusion);
2754
2755 // The filtered layer/replica does not occlude.
[email protected]022cbf162012-09-01 01:15:172756 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142757 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172758 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142759 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2760
2761 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2762 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2763 this->visitContributingSurface(filteredSurface, occlusion);
2764
2765 this->enterContributingSurface(clippingSurface, occlusion);
[email protected]022cbf162012-09-01 01:15:172766 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142767 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2768
2769 IntRect outsetRect;
2770 IntRect clippedOutsetRect;
2771 IntRect testRect;
2772
2773 // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
2774 outsetRect = IntRect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2775 clippedOutsetRect = intersection(outsetRect, IntRect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2776 testRect = outsetRect;
[email protected]022cbf162012-09-01 01:15:172777 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142778
2779 // Stuff outside the (clipped) blur outsets is still occluded though.
2780 testRect = outsetRect;
2781 testRect.expand(1, 0);
[email protected]022cbf162012-09-01 01:15:172782 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142783 testRect = outsetRect;
2784 testRect.expand(0, 1);
[email protected]022cbf162012-09-01 01:15:172785 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142786 testRect = outsetRect;
2787 testRect.move(-1, 0);
2788 testRect.expand(1, 0);
[email protected]022cbf162012-09-01 01:15:172789 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142790 testRect = outsetRect;
2791 testRect.move(0, -1);
2792 testRect.expand(0, 1);
[email protected]022cbf162012-09-01 01:15:172793 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142794
2795 // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
2796 outsetRect = IntRect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2797 clippedOutsetRect = intersection(outsetRect, IntRect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2798 testRect = outsetRect;
[email protected]022cbf162012-09-01 01:15:172799 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142800
2801 // Stuff outside the (clipped) blur outsets is still occluded though.
2802 testRect = outsetRect;
2803 testRect.expand(1, 0);
[email protected]022cbf162012-09-01 01:15:172804 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142805 testRect = outsetRect;
2806 testRect.expand(0, 1);
[email protected]022cbf162012-09-01 01:15:172807 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142808 testRect = outsetRect;
2809 testRect.move(-1, 0);
2810 testRect.expand(1, 0);
[email protected]022cbf162012-09-01 01:15:172811 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142812 testRect = outsetRect;
2813 testRect.move(0, -1);
2814 testRect.expand(0, 1);
[email protected]022cbf162012-09-01 01:15:172815 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
[email protected]94f206c12012-08-25 00:09:142816 }
2817};
2818
2819ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
2820
2821template<class Types, bool opaqueLayers>
2822class CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2823protected:
2824 void runMyTest()
2825 {
2826 WebTransformationMatrix scaleByHalf;
2827 scaleByHalf.scale(0.5);
2828
2829 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
2830 // 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
2831 // appears at 50, 50 and the replica at 200, 50.
2832 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2833 typename Types::LayerType* behindSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(60, 60), IntSize(30, 30), true);
2834 typename Types::LayerType* behindReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(210, 60), IntSize(30, 30), true);
2835 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2836 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2837
2838 // Filters make the layer own a surface.
2839 WebFilterOperations filters;
2840 filters.append(WebFilterOperation::createBlurFilter(3));
2841 filteredSurface->setBackgroundFilters(filters);
2842
2843 this->calcDrawEtc(parent);
2844
2845 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2846 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2847
2848 // The surface has a background blur, so it blurs non-opaque pixels below it.
2849 this->visitLayer(filteredSurface, occlusion);
2850 this->visitContributingSurface(filteredSurface, occlusion);
2851
2852 this->visitLayer(behindReplicaLayer, occlusion);
2853 this->visitLayer(behindSurfaceLayer, occlusion);
2854
2855 // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
2856 // So it should not be modified by the filter here.
2857 IntRect occlusionBehindSurface = IntRect(60, 60, 30, 30);
2858 IntRect occlusionBehindReplica = IntRect(210, 60, 30, 30);
2859
2860 IntRect expectedOpaqueBounds = unionRect(occlusionBehindSurface, occlusionBehindReplica);
[email protected]022cbf162012-09-01 01:15:172861 EXPECT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142862 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172863 EXPECT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142864 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2865 }
2866};
2867
2868ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
2869
2870template<class Types, bool opaqueLayers>
2871class CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2872protected:
2873 void runMyTest()
2874 {
2875 WebTransformationMatrix scaleByHalf;
2876 scaleByHalf.scale(0.5);
2877
2878 // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
2879 // 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
2880 // appears at 50, 50 and the replica at 200, 50.
2881 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2882 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2883 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2884 typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(50, 50), true);
2885 typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(50, 50), true);
2886
2887 // Filters make the layer own a surface.
2888 WebFilterOperations filters;
2889 filters.append(WebFilterOperation::createBlurFilter(3));
2890 filteredSurface->setBackgroundFilters(filters);
2891
2892 this->calcDrawEtc(parent);
2893
2894 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2895 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2896
2897 this->visitLayer(aboveReplicaLayer, occlusion);
2898 this->visitLayer(aboveSurfaceLayer, occlusion);
2899
2900 // The surface has a background blur, so it blurs non-opaque pixels below it.
2901 this->visitLayer(filteredSurface, occlusion);
2902 this->visitContributingSurface(filteredSurface, occlusion);
2903
2904 // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
2905 IntRect occlusionAboveSurface = IntRect(50, 50, 50, 50);
2906 IntRect occlusionAboveReplica = IntRect(200, 50, 50, 50);
2907
2908 IntRect expectedOpaqueBounds = unionRect(occlusionAboveSurface, occlusionAboveReplica);
[email protected]022cbf162012-09-01 01:15:172909 EXPECT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:142910 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:172911 EXPECT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:142912 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2913 }
2914};
2915
2916ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
2917
2918template<class Types, bool opaqueLayers>
2919class CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2920protected:
2921 void runMyTest()
2922 {
2923 WebTransformationMatrix scaleByHalf;
2924 scaleByHalf.scale(0.5);
2925
2926 // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
2927 // 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
2928 // appears at 50, 50 and the replica at 200, 50.
2929 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2930 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2931 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2932 typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(70, 50), IntSize(30, 50), true);
2933 typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(30, 50), true);
2934 typename Types::LayerType* besideSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(90, 40), IntSize(10, 10), true);
2935 typename Types::LayerType* besideReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 40), IntSize(10, 10), 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 // Save the distance of influence for the blur effect.
2943 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2944 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2945
2946 this->calcDrawEtc(parent);
2947
2948 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2949 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2950
2951 this->visitLayer(besideReplicaLayer, occlusion);
2952 this->visitLayer(besideSurfaceLayer, occlusion);
2953 this->visitLayer(aboveReplicaLayer, occlusion);
2954 this->visitLayer(aboveSurfaceLayer, occlusion);
2955
2956 // The surface has a background blur, so it blurs non-opaque pixels below it.
2957 this->visitLayer(filteredSurface, occlusion);
2958 this->visitContributingSurface(filteredSurface, occlusion);
2959
2960 // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
2961 // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
2962 // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
2963 // the occluded part of the surface.
2964 IntRect occlusionAboveSurface = IntRect(70 + outsetRight, 50, 30 - outsetRight, 50);
2965 IntRect occlusionAboveReplica = IntRect(200, 50, 30 - outsetLeft, 50);
2966 IntRect occlusionBesideSurface = IntRect(90, 40, 10, 10);
2967 IntRect occlusionBesideReplica = IntRect(200, 40, 10, 10);
2968
2969 Region expectedOcclusion;
2970 expectedOcclusion.unite(occlusionAboveSurface);
2971 expectedOcclusion.unite(occlusionAboveReplica);
2972 expectedOcclusion.unite(occlusionBesideSurface);
2973 expectedOcclusion.unite(occlusionBesideReplica);
2974
2975 ASSERT_EQ(expectedOcclusion.rects().size(), occlusion.occlusionInTargetSurface().rects().size());
2976 ASSERT_EQ(expectedOcclusion.rects().size(), occlusion.occlusionInScreenSpace().rects().size());
2977
2978 for (size_t i = 0; i < expectedOcclusion.rects().size(); ++i) {
2979 IntRect expectedRect = expectedOcclusion.rects()[i];
2980 IntRect screenRect = occlusion.occlusionInScreenSpace().rects()[i];
2981 IntRect targetRect = occlusion.occlusionInTargetSurface().rects()[i];
2982 EXPECT_EQ(expectedRect, screenRect);
2983 EXPECT_EQ(expectedRect, targetRect);
2984 }
2985 }
2986};
2987
2988ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
2989
2990template<class Types, bool opaqueLayers>
2991class CCOcclusionTrackerTestMinimumTrackingSize : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2992protected:
2993 void runMyTest()
2994 {
2995 IntSize trackingSize(100, 100);
2996 IntSize belowTrackingSize(99, 99);
2997
2998 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(400, 400));
2999 typename Types::LayerType* large = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), trackingSize, true);
3000 typename Types::LayerType* small = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), belowTrackingSize, true);
3001 this->calcDrawEtc(parent);
3002
3003 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
3004 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
3005 occlusion.setMinimumTrackingSize(trackingSize);
3006
3007 // The small layer is not tracked because it is too small.
3008 this->visitLayer(small, occlusion);
3009
[email protected]022cbf162012-09-01 01:15:173010 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:143011 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:173012 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:143013 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
3014
3015 // The large layer is tracked as it is large enough.
3016 this->visitLayer(large, occlusion);
3017
[email protected]022cbf162012-09-01 01:15:173018 EXPECT_RECT_EQ(IntRect(IntPoint(), trackingSize), occlusion.occlusionInScreenSpace().bounds());
[email protected]94f206c12012-08-25 00:09:143019 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
[email protected]022cbf162012-09-01 01:15:173020 EXPECT_RECT_EQ(IntRect(IntPoint(), trackingSize), occlusion.occlusionInTargetSurface().bounds());
[email protected]94f206c12012-08-25 00:09:143021 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
3022 }
3023};
3024
3025ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestMinimumTrackingSize);
3026
3027} // namespace