Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Side by Side Diff: cc/CCOcclusionTrackerTest.cpp

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

Powered by Google App Engine
This is Rietveld 408576698