Don't consider a Bluetooth adapter present until it has an address.
[chromium-blink-merge.git] / cc / CCOcclusionTrackerTest.cpp
blobe5155da52df0b37b4e06a16d12a3283a8de6670c
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "config.h"
7 #include "CCOcclusionTracker.h"
9 #include "CCAnimationTestCommon.h"
10 #include "CCGeometryTestUtils.h"
11 #include "CCLayerAnimationController.h"
12 #include "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 <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 #include <public/WebFilterOperation.h>
23 #include <public/WebFilterOperations.h>
24 #include <public/WebTransformationMatrix.h>
26 using namespace WebCore;
27 using namespace WebKit;
28 using namespace WebKitTests;
30 namespace {
32 class TestContentLayerChromium : public LayerChromium {
33 public:
34 TestContentLayerChromium()
35 : LayerChromium()
36 , m_overrideOpaqueContentsRect(false)
40 virtual bool drawsContent() const OVERRIDE { return true; }
41 virtual Region visibleContentOpaqueRegion() const OVERRIDE
43 if (m_overrideOpaqueContentsRect)
44 return intersection(m_opaqueContentsRect, visibleContentRect());
45 return LayerChromium::visibleContentOpaqueRegion();
47 void setOpaqueContentsRect(const IntRect& opaqueContentsRect)
49 m_overrideOpaqueContentsRect = true;
50 m_opaqueContentsRect = opaqueContentsRect;
53 private:
54 bool m_overrideOpaqueContentsRect;
55 IntRect m_opaqueContentsRect;
58 class TestContentLayerImpl : public CCLayerImpl {
59 public:
60 TestContentLayerImpl(int id)
61 : CCLayerImpl(id)
62 , m_overrideOpaqueContentsRect(false)
64 setDrawsContent(true);
67 virtual Region visibleContentOpaqueRegion() const OVERRIDE
69 if (m_overrideOpaqueContentsRect)
70 return intersection(m_opaqueContentsRect, visibleContentRect());
71 return CCLayerImpl::visibleContentOpaqueRegion();
73 void setOpaqueContentsRect(const IntRect& opaqueContentsRect)
75 m_overrideOpaqueContentsRect = true;
76 m_opaqueContentsRect = opaqueContentsRect;
79 private:
80 bool m_overrideOpaqueContentsRect;
81 IntRect m_opaqueContentsRect;
84 template<typename LayerType, typename RenderSurfaceType>
85 class TestCCOcclusionTrackerWithClip : public TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType> {
86 public:
87 TestCCOcclusionTrackerWithClip(IntRect viewportRect, bool recordMetricsForFrame = false)
88 : TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewportRect, recordMetricsForFrame)
89 , m_overrideLayerClipRect(false)
93 void setLayerClipRect(const IntRect& rect) { m_overrideLayerClipRect = true; m_layerClipRect = rect;}
94 void useDefaultLayerClipRect() { m_overrideLayerClipRect = false; }
96 protected:
97 virtual IntRect layerClipRectInTarget(const LayerType* layer) const { return m_overrideLayerClipRect ? m_layerClipRect : CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTarget(layer); }
99 private:
100 bool m_overrideLayerClipRect;
101 IntRect m_layerClipRect;
104 struct CCOcclusionTrackerTestMainThreadTypes {
105 typedef LayerChromium LayerType;
106 typedef RenderSurfaceChromium RenderSurfaceType;
107 typedef TestContentLayerChromium ContentLayerType;
108 typedef RefPtr<LayerChromium> LayerPtrType;
109 typedef PassRefPtr<LayerChromium> PassLayerPtrType;
110 typedef RefPtr<ContentLayerType> ContentLayerPtrType;
111 typedef PassRefPtr<ContentLayerType> PassContentLayerPtrType;
112 typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> LayerIterator;
113 typedef CCOcclusionTracker OcclusionTrackerType;
115 static PassLayerPtrType createLayer()
117 return LayerChromium::create();
119 static PassContentLayerPtrType createContentLayer() { return adoptRef(new ContentLayerType()); }
122 struct CCOcclusionTrackerTestImplThreadTypes {
123 typedef CCLayerImpl LayerType;
124 typedef CCRenderSurface RenderSurfaceType;
125 typedef TestContentLayerImpl ContentLayerType;
126 typedef OwnPtr<CCLayerImpl> LayerPtrType;
127 typedef PassOwnPtr<CCLayerImpl> PassLayerPtrType;
128 typedef OwnPtr<ContentLayerType> ContentLayerPtrType;
129 typedef PassOwnPtr<ContentLayerType> PassContentLayerPtrType;
130 typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::FrontToBack> LayerIterator;
131 typedef CCOcclusionTrackerImpl OcclusionTrackerType;
133 static PassLayerPtrType createLayer() { return CCLayerImpl::create(nextCCLayerImplId++); }
134 static PassContentLayerPtrType createContentLayer() { return adoptPtr(new ContentLayerType(nextCCLayerImplId++)); }
135 static int nextCCLayerImplId;
138 int CCOcclusionTrackerTestImplThreadTypes::nextCCLayerImplId = 1;
140 template<typename Types, bool opaqueLayers>
141 class CCOcclusionTrackerTest : public testing::Test {
142 protected:
143 CCOcclusionTrackerTest()
144 : testing::Test()
147 virtual void runMyTest() = 0;
149 virtual void TearDown()
151 m_root.clear();
152 m_renderSurfaceLayerListChromium.clear();
153 m_renderSurfaceLayerListImpl.clear();
154 m_replicaLayers.clear();
155 m_maskLayers.clear();
156 CCLayerTreeHost::setNeedsFilterContext(false);
159 typename Types::ContentLayerType* createRoot(const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
161 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
162 typename Types::ContentLayerType* layerPtr = layer.get();
163 setProperties(layerPtr, transform, position, bounds);
165 ASSERT(!m_root);
166 m_root = layer.release();
167 return layerPtr;
170 typename Types::LayerType* createLayer(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
172 typename Types::LayerPtrType layer(Types::createLayer());
173 typename Types::LayerType* layerPtr = layer.get();
174 setProperties(layerPtr, transform, position, bounds);
175 parent->addChild(layer.release());
176 return layerPtr;
179 typename Types::LayerType* createSurface(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
181 typename Types::LayerType* layer = createLayer(parent, transform, position, bounds);
182 WebFilterOperations filters;
183 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
184 layer->setFilters(filters);
185 return layer;
188 typename Types::ContentLayerType* createDrawingLayer(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
190 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
191 typename Types::ContentLayerType* layerPtr = layer.get();
192 setProperties(layerPtr, transform, position, bounds);
194 if (opaqueLayers)
195 layerPtr->setOpaque(opaque);
196 else {
197 layerPtr->setOpaque(false);
198 if (opaque)
199 layerPtr->setOpaqueContentsRect(IntRect(IntPoint(), bounds));
200 else
201 layerPtr->setOpaqueContentsRect(IntRect());
204 parent->addChild(layer.release());
205 return layerPtr;
208 typename Types::LayerType* createReplicaLayer(typename Types::LayerType* owningLayer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
210 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
211 typename Types::ContentLayerType* layerPtr = layer.get();
212 setProperties(layerPtr, transform, position, bounds);
213 setReplica(owningLayer, layer.release());
214 return layerPtr;
217 typename Types::LayerType* createMaskLayer(typename Types::LayerType* owningLayer, const IntSize& bounds)
219 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
220 typename Types::ContentLayerType* layerPtr = layer.get();
221 setProperties(layerPtr, identityMatrix, FloatPoint(), bounds);
222 setMask(owningLayer, layer.release());
223 return layerPtr;
226 typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
228 typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque);
229 WebFilterOperations filters;
230 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
231 layer->setFilters(filters);
232 return layer;
235 void calcDrawEtc(TestContentLayerImpl* root)
237 ASSERT(root == m_root.get());
238 int dummyMaxTextureSize = 512;
239 CCLayerSorter layerSorter;
241 ASSERT(!root->renderSurface());
243 CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, &layerSorter, dummyMaxTextureSize, m_renderSurfaceLayerListImpl);
244 CCLayerTreeHostCommon::calculateVisibleRects(m_renderSurfaceLayerListImpl);
246 m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListImpl);
249 void calcDrawEtc(TestContentLayerChromium* root)
251 ASSERT(root == m_root.get());
252 int dummyMaxTextureSize = 512;
254 ASSERT(!root->renderSurface());
256 CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, dummyMaxTextureSize, m_renderSurfaceLayerListChromium);
257 CCLayerTreeHostCommon::calculateVisibleRects(m_renderSurfaceLayerListChromium);
259 m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListChromium);
262 void enterLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
264 ASSERT_EQ(layer, *m_layerIterator);
265 ASSERT_TRUE(m_layerIterator.representsItself());
266 occlusion.enterLayer(m_layerIterator);
269 void leaveLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
271 ASSERT_EQ(layer, *m_layerIterator);
272 ASSERT_TRUE(m_layerIterator.representsItself());
273 occlusion.leaveLayer(m_layerIterator);
274 ++m_layerIterator;
277 void visitLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
279 enterLayer(layer, occlusion);
280 leaveLayer(layer, occlusion);
283 void enterContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
285 ASSERT_EQ(layer, *m_layerIterator);
286 ASSERT_TRUE(m_layerIterator.representsTargetRenderSurface());
287 occlusion.enterLayer(m_layerIterator);
288 occlusion.leaveLayer(m_layerIterator);
289 ++m_layerIterator;
290 ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
291 occlusion.enterLayer(m_layerIterator);
294 void leaveContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
296 ASSERT_EQ(layer, *m_layerIterator);
297 ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
298 occlusion.leaveLayer(m_layerIterator);
299 ++m_layerIterator;
302 void visitContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
304 enterContributingSurface(layer, occlusion);
305 leaveContributingSurface(layer, occlusion);
308 void resetLayerIterator()
310 m_layerIterator = m_layerIteratorBegin;
313 const WebTransformationMatrix identityMatrix;
315 private:
316 void setBaseProperties(typename Types::LayerType* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
318 layer->setTransform(transform);
319 layer->setSublayerTransform(WebTransformationMatrix());
320 layer->setAnchorPoint(FloatPoint(0, 0));
321 layer->setPosition(position);
322 layer->setBounds(bounds);
325 void setProperties(LayerChromium* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
327 setBaseProperties(layer, transform, position, bounds);
330 void setProperties(CCLayerImpl* layer, const WebTransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
332 setBaseProperties(layer, transform, position, bounds);
334 layer->setContentBounds(layer->bounds());
337 void setReplica(LayerChromium* owningLayer, PassRefPtr<LayerChromium> layer)
339 owningLayer->setReplicaLayer(layer.get());
340 m_replicaLayers.append(layer);
343 void setReplica(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer)
345 owningLayer->setReplicaLayer(layer);
348 void setMask(LayerChromium* owningLayer, PassRefPtr<LayerChromium> layer)
350 owningLayer->setMaskLayer(layer.get());
351 m_maskLayers.append(layer);
354 void setMask(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer)
356 owningLayer->setMaskLayer(layer);
359 // These hold ownership of the layers for the duration of the test.
360 typename Types::LayerPtrType m_root;
361 Vector<RefPtr<LayerChromium> > m_renderSurfaceLayerListChromium;
362 Vector<CCLayerImpl*> m_renderSurfaceLayerListImpl;
363 typename Types::LayerIterator m_layerIteratorBegin;
364 typename Types::LayerIterator m_layerIterator;
365 typename Types::LayerType* m_lastLayerVisited;
366 Vector<RefPtr<LayerChromium> > m_replicaLayers;
367 Vector<RefPtr<LayerChromium> > m_maskLayers;
370 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
371 class ClassName##MainThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestMainThreadTypes, true> { \
372 public: \
373 ClassName##MainThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestMainThreadTypes, true>() { } \
374 }; \
375 TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
376 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
377 class ClassName##MainThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestMainThreadTypes, false> { \
378 public: \
379 ClassName##MainThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestMainThreadTypes, false>() { } \
380 }; \
381 TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
383 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
384 class ClassName##ImplThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestImplThreadTypes, true> { \
385 DebugScopedSetImplThread impl; \
386 public: \
387 ClassName##ImplThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestImplThreadTypes, true>() { } \
388 }; \
389 TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
390 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
391 class ClassName##ImplThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestImplThreadTypes, false> { \
392 DebugScopedSetImplThread impl; \
393 public: \
394 ClassName##ImplThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestImplThreadTypes, false>() { } \
395 }; \
396 TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
398 #define ALL_CCOCCLUSIONTRACKER_TEST(ClassName) \
399 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
400 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
401 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
402 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
404 #define MAIN_THREAD_TEST(ClassName) \
405 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
407 #define IMPL_THREAD_TEST(ClassName) \
408 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
410 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
411 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
412 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
414 template<class Types, bool opaqueLayers>
415 class CCOcclusionTrackerTestIdentityTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
416 protected:
417 void runMyTest()
419 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
420 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(30, 30), IntSize(500, 500), true);
421 this->calcDrawEtc(parent);
423 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
424 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
426 this->visitLayer(layer, occlusion);
427 this->enterLayer(parent, occlusion);
429 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
430 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
431 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
432 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
434 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
435 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
436 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
437 EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
438 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
440 occlusion.useDefaultLayerClipRect();
441 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
442 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
443 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
444 EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
445 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
446 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
448 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)).isEmpty());
449 EXPECT_RECT_EQ(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 70, 70)));
450 EXPECT_RECT_EQ(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 29, 70, 70)));
451 EXPECT_RECT_EQ(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
452 EXPECT_RECT_EQ(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 29, 70, 70)));
453 EXPECT_RECT_EQ(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 70, 70)));
454 EXPECT_RECT_EQ(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 31, 70, 70)));
455 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 31, 70, 70)));
456 EXPECT_RECT_EQ(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 31, 70, 70)));
460 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestIdentityTransforms);
462 template<class Types, bool opaqueLayers>
463 class CCOcclusionTrackerTestRotatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
464 protected:
465 void runMyTest()
467 WebTransformationMatrix layerTransform;
468 layerTransform.translate(250, 250);
469 layerTransform.rotate(90);
470 layerTransform.translate(-250, -250);
472 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
473 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
474 this->calcDrawEtc(parent);
476 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
477 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
479 this->visitLayer(layer, occlusion);
480 this->enterLayer(parent, occlusion);
482 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
483 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
484 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
485 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
487 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
488 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
489 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
490 EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
491 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
493 occlusion.useDefaultLayerClipRect();
494 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
495 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
496 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
497 EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
498 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
499 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
501 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)).isEmpty());
502 EXPECT_RECT_EQ(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 70, 70)));
503 EXPECT_RECT_EQ(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 29, 70, 70)));
504 EXPECT_RECT_EQ(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
505 EXPECT_RECT_EQ(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 29, 70, 70)));
506 EXPECT_RECT_EQ(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 70, 70)));
507 EXPECT_RECT_EQ(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 31, 70, 70)));
508 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 31, 70, 70)));
509 EXPECT_RECT_EQ(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 31, 70, 70)));
513 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestRotatedChild);
515 template<class Types, bool opaqueLayers>
516 class CCOcclusionTrackerTestTranslatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
517 protected:
518 void runMyTest()
520 WebTransformationMatrix layerTransform;
521 layerTransform.translate(20, 20);
523 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
524 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
525 this->calcDrawEtc(parent);
527 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
528 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
530 this->visitLayer(layer, occlusion);
531 this->enterLayer(parent, occlusion);
533 EXPECT_RECT_EQ(IntRect(50, 50, 50, 50), occlusion.occlusionInScreenSpace().bounds());
534 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
535 EXPECT_RECT_EQ(IntRect(50, 50, 50, 50), occlusion.occlusionInTargetSurface().bounds());
536 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
538 EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 50, 50, 50)));
539 EXPECT_FALSE(occlusion.occluded(parent, IntRect(49, 50, 50, 50)));
540 EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 49, 50, 50)));
541 EXPECT_FALSE(occlusion.occluded(parent, IntRect(51, 50, 50, 50)));
542 EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 51, 50, 50)));
544 occlusion.useDefaultLayerClipRect();
545 EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 50, 50, 50)));
546 EXPECT_FALSE(occlusion.occluded(parent, IntRect(49, 50, 50, 50)));
547 EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 49, 50, 50)));
548 EXPECT_TRUE(occlusion.occluded(parent, IntRect(51, 50, 50, 50)));
549 EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 51, 50, 50)));
550 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
552 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 50, 50, 50)).isEmpty());
553 EXPECT_RECT_EQ(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 50, 50, 50)));
554 EXPECT_RECT_EQ(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 49, 50, 50)));
555 EXPECT_RECT_EQ(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 49, 50, 50)));
556 EXPECT_RECT_EQ(IntRect(51, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 49, 50, 50)));
557 EXPECT_RECT_EQ(IntRect(100, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 50, 50, 50)));
558 EXPECT_RECT_EQ(IntRect(51, 51, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 51, 50, 50)));
559 EXPECT_RECT_EQ(IntRect(50, 100, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 51, 50, 50)));
560 EXPECT_RECT_EQ(IntRect(49, 51, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 51, 50, 50)));
562 occlusion.useDefaultLayerClipRect();
563 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 50, 50, 50)).isEmpty());
564 EXPECT_RECT_EQ(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 50, 50, 50)));
565 EXPECT_RECT_EQ(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 49, 50, 50)));
566 EXPECT_RECT_EQ(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 49, 50, 50)));
567 EXPECT_RECT_EQ(IntRect(51, 49, 49, 1), occlusion.unoccludedContentRect(parent, IntRect(51, 49, 50, 50)));
568 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(51, 50, 50, 50)).isEmpty());
569 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(51, 51, 50, 50)).isEmpty());
570 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 51, 50, 50)).isEmpty());
571 EXPECT_RECT_EQ(IntRect(49, 51, 1, 49), occlusion.unoccludedContentRect(parent, IntRect(49, 51, 50, 50)));
572 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
576 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTranslatedChild);
578 template<class Types, bool opaqueLayers>
579 class CCOcclusionTrackerTestChildInRotatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
580 protected:
581 void runMyTest()
583 WebTransformationMatrix childTransform;
584 childTransform.translate(250, 250);
585 childTransform.rotate(90);
586 childTransform.translate(-250, -250);
588 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
589 parent->setMasksToBounds(true);
590 typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
591 child->setMasksToBounds(true);
592 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
593 this->calcDrawEtc(parent);
595 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
596 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
598 this->visitLayer(layer, occlusion);
599 this->enterContributingSurface(child, occlusion);
601 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
602 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
603 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
604 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
606 this->leaveContributingSurface(child, occlusion);
607 this->enterLayer(parent, occlusion);
609 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
610 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
611 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
612 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
614 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
615 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
616 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
617 EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 40, 70, 60)));
618 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 41, 70, 60)));
620 occlusion.useDefaultLayerClipRect();
621 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
622 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
623 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
624 EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 40, 70, 60)));
625 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 41, 70, 60)));
626 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
629 /* Justification for the above occlusion from |layer|:
631 +---------------------+ +---------------------+
632 | | | |30 Visible region of |layer|: /////
633 | 30 | rotate(90) | |
634 | 30 + ---------------------------------+ | +---------------------------------+
635 100 | | 10 | | ==> | | |10 |
636 | |10+---------------------------------+ | +---------------------------------+ |
637 | | | | | | | | |///////////////| 420 | |
638 | | | | | | | | |///////////////|60 | |
639 | | | | | | | | |///////////////| | |
640 +----|--|-------------+ | | +--|--|---------------+ | |
641 | | | | 20|10| 70 | |
642 | | | | | | | |
643 | | | |500 | | | |
644 | | | | | | | |
645 | | | | | | | |
646 | | | | | | | |
647 | | | | | | |10|
648 +--|-------------------------------+ | | +------------------------------|--+
649 | | | 490 |
650 +---------------------------------+ +---------------------------------+
651 500 500
656 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestChildInRotatedChild);
658 template<class Types, bool opaqueLayers>
659 class CCOcclusionTrackerTestVisitTargetTwoTimes : public CCOcclusionTrackerTest<Types, opaqueLayers> {
660 protected:
661 void runMyTest()
663 WebTransformationMatrix childTransform;
664 childTransform.translate(250, 250);
665 childTransform.rotate(90);
666 childTransform.translate(-250, -250);
668 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
669 parent->setMasksToBounds(true);
670 typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
671 child->setMasksToBounds(true);
672 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
673 // |child2| makes |parent|'s surface get considered by CCOcclusionTracker first, instead of |child|'s. This exercises different code in
674 // leaveToTargetRenderSurface, as the target surface has already been seen.
675 typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(30, 30), IntSize(60, 20), true);
676 this->calcDrawEtc(parent);
678 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
679 occlusion.setLayerClipRect(IntRect(-10, -10, 1000, 1000));
681 this->visitLayer(child2, occlusion);
683 EXPECT_RECT_EQ(IntRect(30, 30, 60, 20), occlusion.occlusionInScreenSpace().bounds());
684 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
685 EXPECT_RECT_EQ(IntRect(30, 30, 60, 20), occlusion.occlusionInTargetSurface().bounds());
686 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
688 this->visitLayer(layer, occlusion);
690 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
691 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
692 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
693 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
695 this->enterContributingSurface(child, occlusion);
697 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
698 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
699 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
700 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
702 // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
703 this->leaveContributingSurface(child, occlusion);
704 this->enterLayer(parent, occlusion);
706 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
707 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
708 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
709 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
711 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
712 EXPECT_RECT_EQ(IntRect(90, 30, 10, 10), occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)));
714 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 60, 10)));
715 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 60, 10)));
716 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 60, 10)));
717 EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 60, 10)));
718 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 60, 10)));
720 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
721 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
722 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
724 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 60, 10)).isEmpty());
725 EXPECT_RECT_EQ(IntRect(29, 30, 1, 10), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 60, 10)));
726 EXPECT_RECT_EQ(IntRect(30, 29, 60, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 60, 10)));
727 EXPECT_RECT_EQ(IntRect(90, 30, 1, 10), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 60, 10)));
728 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 31, 60, 10)).isEmpty());
730 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 40, 70, 60)).isEmpty());
731 EXPECT_RECT_EQ(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(29, 40, 70, 60)));
732 // This rect is mostly occluded by |child2|.
733 EXPECT_RECT_EQ(IntRect(90, 39, 10, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 39, 70, 60)));
734 // This rect extends past top/right ends of |child2|.
735 EXPECT_RECT_EQ(IntRect(30, 29, 70, 11), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
736 // This rect extends past left/right ends of |child2|.
737 EXPECT_RECT_EQ(IntRect(20, 39, 80, 60), occlusion.unoccludedContentRect(parent, IntRect(20, 39, 80, 60)));
738 EXPECT_RECT_EQ(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(31, 40, 70, 60)));
739 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 41, 70, 60)));
741 /* Justification for the above occlusion from |layer|:
743 +---------------------+ +---------------------+
744 | | | |30 Visible region of |layer|: /////
745 | 30 | rotate(90) | 30 60 | |child2|: \\\\\
746 | 30 + ------------+--------------------+ | 30 +------------+--------------------+
747 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
748 | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
749 | + ------------+ | | | | | +------------+//| 420 | |
750 | | | | | | | | |///////////////|60 | |
751 | | | | | | | | |///////////////| | |
752 +----|--|-------------+ | | +--|--|---------------+ | |
753 | | | | 20|10| 70 | |
754 | | | | | | | |
755 | | | |500 | | | |
756 | | | | | | | |
757 | | | | | | | |
758 | | | | | | | |
759 | | | | | | |10|
760 +--|-------------------------------+ | | +------------------------------|--+
761 | | | 490 |
762 +---------------------------------+ +---------------------------------+
763 500 500
768 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestVisitTargetTwoTimes);
770 template<class Types, bool opaqueLayers>
771 class CCOcclusionTrackerTestSurfaceRotatedOffAxis : public CCOcclusionTrackerTest<Types, opaqueLayers> {
772 protected:
773 void runMyTest()
775 WebTransformationMatrix childTransform;
776 childTransform.translate(250, 250);
777 childTransform.rotate(95);
778 childTransform.translate(-250, -250);
780 WebTransformationMatrix layerTransform;
781 layerTransform.translate(10, 10);
783 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
784 typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
785 child->setMasksToBounds(true);
786 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, layerTransform, FloatPoint(0, 0), IntSize(500, 500), true);
787 this->calcDrawEtc(parent);
789 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
790 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
792 IntRect clippedLayerInChild = CCMathUtil::mapClippedRect(layerTransform, layer->visibleContentRect());
794 this->visitLayer(layer, occlusion);
795 this->enterContributingSurface(child, occlusion);
797 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
798 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
799 EXPECT_RECT_EQ(clippedLayerInChild, occlusion.occlusionInTargetSurface().bounds());
800 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
802 EXPECT_TRUE(occlusion.occluded(child, clippedLayerInChild));
803 EXPECT_TRUE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
804 clippedLayerInChild.move(-1, 0);
805 EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
806 EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
807 clippedLayerInChild.move(1, 0);
808 clippedLayerInChild.move(1, 0);
809 EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
810 EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
811 clippedLayerInChild.move(-1, 0);
812 clippedLayerInChild.move(0, -1);
813 EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
814 EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
815 clippedLayerInChild.move(0, 1);
816 clippedLayerInChild.move(0, 1);
817 EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
818 EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
819 clippedLayerInChild.move(0, -1);
821 this->leaveContributingSurface(child, occlusion);
822 this->enterLayer(parent, occlusion);
824 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
825 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
826 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInTargetSurface().bounds());
827 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
829 EXPECT_FALSE(occlusion.occluded(parent, IntRect(75, 55, 1, 1)));
830 EXPECT_RECT_EQ(IntRect(75, 55, 1, 1), occlusion.unoccludedContentRect(parent, IntRect(75, 55, 1, 1)));
834 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceRotatedOffAxis);
836 template<class Types, bool opaqueLayers>
837 class CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren : public CCOcclusionTrackerTest<Types, opaqueLayers> {
838 protected:
839 void runMyTest()
841 WebTransformationMatrix childTransform;
842 childTransform.translate(250, 250);
843 childTransform.rotate(90);
844 childTransform.translate(-250, -250);
846 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
847 parent->setMasksToBounds(true);
848 typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
849 child->setMasksToBounds(true);
850 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
851 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 450), IntSize(500, 60), true);
852 this->calcDrawEtc(parent);
854 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
855 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
857 this->visitLayer(layer2, occlusion);
858 this->visitLayer(layer1, occlusion);
859 this->enterContributingSurface(child, occlusion);
861 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
862 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
863 EXPECT_RECT_EQ(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
864 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
866 EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
867 EXPECT_FALSE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
868 EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
869 EXPECT_FALSE(occlusion.occluded(child, IntRect(11, 430, 60, 70)));
870 EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 431, 60, 70)));
872 EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 430, 60, 70)).isEmpty());
873 EXPECT_RECT_EQ(IntRect(9, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 70)));
874 EXPECT_RECT_EQ(IntRect(10, 429, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 429, 60, 70)));
875 EXPECT_RECT_EQ(IntRect(70, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(11, 430, 60, 70)));
876 EXPECT_RECT_EQ(IntRect(10, 500, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 431, 60, 70)));
878 this->leaveContributingSurface(child, occlusion);
879 this->enterLayer(parent, occlusion);
881 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
882 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
883 EXPECT_RECT_EQ(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
884 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
886 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
887 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
888 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
890 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 40, 70, 60)).isEmpty());
891 EXPECT_RECT_EQ(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(29, 40, 70, 60)));
892 EXPECT_RECT_EQ(IntRect(30, 39, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 39, 70, 60)));
893 EXPECT_RECT_EQ(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(31, 40, 70, 60)));
894 EXPECT_RECT_EQ(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 41, 70, 60)));
896 /* Justification for the above occlusion from |layer1| and |layer2|:
898 +---------------------+
899 | |30 Visible region of |layer1|: /////
900 | | Visible region of |layer2|: \\\\\
901 | +---------------------------------+
902 | | |10 |
903 | +---------------+-----------------+ |
904 | | |\\\\\\\\\\\\|//| 420 | |
905 | | |\\\\\\\\\\\\|//|60 | |
906 | | |\\\\\\\\\\\\|//| | |
907 +--|--|------------|--+ | |
908 20|10| 70 | | |
909 | | | | |
910 | | | | |
911 | | | | |
912 | | | | |
913 | | | | |
914 | | | |10|
915 | +------------|-----------------|--+
916 | | 490 |
917 +---------------+-----------------+
918 60 440
923 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
925 template<class Types, bool opaqueLayers>
926 class CCOcclusionTrackerTestOverlappingSurfaceSiblings : public CCOcclusionTrackerTest<Types, opaqueLayers> {
927 protected:
928 void runMyTest()
930 WebTransformationMatrix childTransform;
931 childTransform.translate(250, 250);
932 childTransform.rotate(90);
933 childTransform.translate(-250, -250);
935 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
936 parent->setMasksToBounds(true);
937 typename Types::LayerType* child1 = this->createSurface(parent, childTransform, FloatPoint(30, 30), IntSize(10, 10));
938 typename Types::LayerType* child2 = this->createSurface(parent, childTransform, FloatPoint(20, 40), IntSize(10, 10));
939 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
940 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
941 this->calcDrawEtc(parent);
943 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
944 occlusion.setLayerClipRect(IntRect(-20, -20, 1000, 1000));
946 this->visitLayer(layer2, occlusion);
947 this->enterContributingSurface(child2, occlusion);
949 EXPECT_RECT_EQ(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
950 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
951 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
952 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
954 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
955 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
956 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
957 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
958 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
960 occlusion.useDefaultLayerClipRect();
961 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
962 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
963 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
964 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
965 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
966 occlusion.setLayerClipRect(IntRect(-20, -20, 1000, 1000));
968 // There is nothing above child2's surface in the z-order.
969 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, IntRect(-10, 420, 70, 80)));
971 this->leaveContributingSurface(child2, occlusion);
972 this->visitLayer(layer1, occlusion);
973 this->enterContributingSurface(child1, occlusion);
975 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
976 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
977 EXPECT_RECT_EQ(IntRect(-10, 430, 80, 70), occlusion.occlusionInTargetSurface().bounds());
978 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
980 EXPECT_TRUE(occlusion.occluded(child1, IntRect(-10, 430, 80, 70)));
981 EXPECT_FALSE(occlusion.occluded(child1, IntRect(-11, 430, 80, 70)));
982 EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 429, 80, 70)));
983 EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 81, 70)));
984 EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 80, 71)));
986 // child2's contents will occlude child1 below it.
987 EXPECT_RECT_EQ(IntRect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(-10, 430, 80, 70)));
989 this->leaveContributingSurface(child1, occlusion);
990 this->enterLayer(parent, occlusion);
992 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
993 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
994 EXPECT_RECT_EQ(IntRect(20, 20, 80, 80), occlusion.occlusionInTargetSurface().bounds());
995 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
997 EXPECT_FALSE(occlusion.occluded(parent, IntRect(20, 20, 80, 80)));
999 EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 20, 70, 80)));
1000 EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 20, 70, 80)));
1001 EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 19, 70, 80)));
1003 EXPECT_TRUE(occlusion.occluded(parent, IntRect(20, 30, 80, 70)));
1004 EXPECT_FALSE(occlusion.occluded(parent, IntRect(19, 30, 80, 70)));
1005 EXPECT_FALSE(occlusion.occluded(parent, IntRect(20, 29, 80, 70)));
1007 /* Justification for the above occlusion:
1009 +---------------------+
1010 | 20 | layer1
1011 | 30+ ---------------------------------+
1012 100 | 30| | layer2 |
1013 |20+----------------------------------+ |
1014 | | | | | |
1015 | | | | | |
1016 | | | | | |
1017 +--|-|----------------+ | |
1018 | | | | 510
1019 | | | |
1020 | | | |
1021 | | | |
1022 | | | |
1023 | | | |
1024 | | | |
1025 | +--------------------------------|-+
1027 +----------------------------------+
1033 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblings);
1035 template<class Types, bool opaqueLayers>
1036 class CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1037 protected:
1038 void runMyTest()
1040 WebTransformationMatrix child1Transform;
1041 child1Transform.translate(250, 250);
1042 child1Transform.rotate(-90);
1043 child1Transform.translate(-250, -250);
1045 WebTransformationMatrix child2Transform;
1046 child2Transform.translate(250, 250);
1047 child2Transform.rotate(90);
1048 child2Transform.translate(-250, -250);
1050 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1051 parent->setMasksToBounds(true);
1052 typename Types::LayerType* child1 = this->createSurface(parent, child1Transform, FloatPoint(30, 20), IntSize(10, 10));
1053 typename Types::LayerType* child2 = this->createDrawingSurface(parent, child2Transform, FloatPoint(20, 40), IntSize(10, 10), false);
1054 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -20), IntSize(510, 510), true);
1055 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
1056 this->calcDrawEtc(parent);
1058 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1059 occlusion.setLayerClipRect(IntRect(-30, -30, 1000, 1000));
1061 this->visitLayer(layer2, occlusion);
1062 this->enterLayer(child2, occlusion);
1064 EXPECT_RECT_EQ(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
1065 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1066 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
1067 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1069 EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
1070 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
1071 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
1072 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
1073 EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
1075 this->leaveLayer(child2, occlusion);
1076 this->enterContributingSurface(child2, occlusion);
1078 // There is nothing above child2's surface in the z-order.
1079 EXPECT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, IntRect(-10, 420, 70, 80)));
1081 this->leaveContributingSurface(child2, occlusion);
1082 this->visitLayer(layer1, occlusion);
1083 this->enterContributingSurface(child1, occlusion);
1085 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
1086 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1087 EXPECT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion.occlusionInTargetSurface().bounds());
1088 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1090 EXPECT_TRUE(occlusion.occluded(child1, IntRect(420, -20, 80, 90)));
1091 EXPECT_FALSE(occlusion.occluded(child1, IntRect(419, -20, 80, 90)));
1092 EXPECT_FALSE(occlusion.occluded(child1, IntRect(420, -21, 80, 90)));
1093 EXPECT_FALSE(occlusion.occluded(child1, IntRect(420, -19, 80, 90)));
1094 EXPECT_FALSE(occlusion.occluded(child1, IntRect(421, -20, 80, 90)));
1096 // child2's contents will occlude child1 below it.
1097 EXPECT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -20, 80, 90)));
1098 EXPECT_RECT_EQ(IntRect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -10, 80, 90)));
1099 EXPECT_RECT_EQ(IntRect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -20, 70, 90)));
1101 this->leaveContributingSurface(child1, occlusion);
1102 this->enterLayer(parent, occlusion);
1104 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
1105 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1106 EXPECT_RECT_EQ(IntRect(10, 20, 90, 80), occlusion.occlusionInTargetSurface().bounds());
1107 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1109 EXPECT_TRUE(occlusion.occluded(parent, IntRect(10, 20, 90, 80)));
1110 EXPECT_FALSE(occlusion.occluded(parent, IntRect(9, 20, 90, 80)));
1111 EXPECT_FALSE(occlusion.occluded(parent, IntRect(10, 19, 90, 80)));
1112 EXPECT_FALSE(occlusion.occluded(parent, IntRect(11, 20, 90, 80)));
1113 EXPECT_FALSE(occlusion.occluded(parent, IntRect(10, 21, 90, 80)));
1115 /* Justification for the above occlusion:
1117 +---------------------+
1118 |20 | layer1
1119 10+----------------------------------+
1120 100 || 30 | layer2 |
1121 |20+----------------------------------+
1122 || | | | |
1123 || | | | |
1124 || | | | |
1125 +|-|------------------+ | |
1126 | | | | 510
1127 | | 510 | |
1128 | | | |
1129 | | | |
1130 | | | |
1131 | | | |
1132 | | 520 | |
1133 +----------------------------------+ |
1135 +----------------------------------+
1141 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1143 template<class Types, bool opaqueLayers>
1144 class CCOcclusionTrackerTestFilters : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1145 protected:
1146 void runMyTest()
1148 WebTransformationMatrix layerTransform;
1149 layerTransform.translate(250, 250);
1150 layerTransform.rotate(90);
1151 layerTransform.translate(-250, -250);
1153 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1154 parent->setMasksToBounds(true);
1155 typename Types::ContentLayerType* blurLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1156 typename Types::ContentLayerType* opaqueLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1157 typename Types::ContentLayerType* opacityLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
1159 WebFilterOperations filters;
1160 filters.append(WebFilterOperation::createBlurFilter(10));
1161 blurLayer->setFilters(filters);
1163 filters.clear();
1164 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
1165 opaqueLayer->setFilters(filters);
1167 filters.clear();
1168 filters.append(WebFilterOperation::createOpacityFilter(0.5));
1169 opacityLayer->setFilters(filters);
1171 this->calcDrawEtc(parent);
1173 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1174 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1176 // Opacity layer won't contribute to occlusion.
1177 this->visitLayer(opacityLayer, occlusion);
1178 this->enterContributingSurface(opacityLayer, occlusion);
1180 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1181 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1183 // And has nothing to contribute to its parent surface.
1184 this->leaveContributingSurface(opacityLayer, occlusion);
1185 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1186 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1188 // Opaque layer will contribute to occlusion.
1189 this->visitLayer(opaqueLayer, occlusion);
1190 this->enterContributingSurface(opaqueLayer, occlusion);
1192 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
1193 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1194 EXPECT_RECT_EQ(IntRect(0, 430, 70, 70), occlusion.occlusionInTargetSurface().bounds());
1195 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1197 // And it gets translated to the parent surface.
1198 this->leaveContributingSurface(opaqueLayer, occlusion);
1199 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
1200 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1201 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
1202 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1204 // The blur layer needs to throw away any occlusion from outside its subtree.
1205 this->enterLayer(blurLayer, occlusion);
1206 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1207 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1209 // And it won't contribute to occlusion.
1210 this->leaveLayer(blurLayer, occlusion);
1211 this->enterContributingSurface(blurLayer, occlusion);
1212 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1213 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1215 // But the opaque layer's occlusion is preserved on the parent.
1216 this->leaveContributingSurface(blurLayer, occlusion);
1217 this->enterLayer(parent, occlusion);
1218 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
1219 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1220 EXPECT_RECT_EQ(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
1221 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1225 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestFilters);
1227 template<class Types, bool opaqueLayers>
1228 class CCOcclusionTrackerTestReplicaDoesOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1229 protected:
1230 void runMyTest()
1232 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
1233 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1234 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1235 this->calcDrawEtc(parent);
1237 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1238 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1240 this->visitLayer(surface, occlusion);
1242 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
1243 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1244 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
1245 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1247 this->visitContributingSurface(surface, occlusion);
1248 this->enterLayer(parent, occlusion);
1250 // The surface and replica should both be occluding the parent.
1251 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
1252 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
1256 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaDoesOcclude);
1258 template<class Types, bool opaqueLayers>
1259 class CCOcclusionTrackerTestReplicaWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1260 protected:
1261 void runMyTest()
1263 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 170));
1264 parent->setMasksToBounds(true);
1265 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1266 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1267 this->calcDrawEtc(parent);
1269 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1270 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1272 this->visitLayer(surface, occlusion);
1274 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
1275 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1276 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
1277 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1279 this->visitContributingSurface(surface, occlusion);
1280 this->enterLayer(parent, occlusion);
1282 // The surface and replica should both be occluding the parent.
1283 EXPECT_RECT_EQ(IntRect(0, 100, 100, 70), occlusion.occlusionInTargetSurface().bounds());
1284 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
1288 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithClipping);
1290 template<class Types, bool opaqueLayers>
1291 class CCOcclusionTrackerTestReplicaWithMask : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1292 protected:
1293 void runMyTest()
1295 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
1296 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
1297 typename Types::LayerType* replica = this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
1298 this->createMaskLayer(replica, IntSize(10, 10));
1299 this->calcDrawEtc(parent);
1301 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1302 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1304 this->visitLayer(surface, occlusion);
1306 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
1307 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1308 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
1309 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1311 this->visitContributingSurface(surface, occlusion);
1312 this->enterLayer(parent, occlusion);
1314 // The replica should not be occluding the parent, since it has a mask applied to it.
1315 EXPECT_RECT_EQ(IntRect(0, 100, 50, 50), occlusion.occlusionInTargetSurface().bounds());
1316 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1320 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithMask);
1322 template<class Types, bool opaqueLayers>
1323 class CCOcclusionTrackerTestLayerClipRectOutsideChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1324 protected:
1325 void runMyTest()
1327 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1328 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1329 this->calcDrawEtc(parent);
1331 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1332 occlusion.setLayerClipRect(IntRect(200, 100, 100, 100));
1334 this->enterLayer(layer, occlusion);
1336 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1337 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1338 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1339 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1340 EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1342 occlusion.useDefaultLayerClipRect();
1343 EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1344 occlusion.setLayerClipRect(IntRect(200, 100, 100, 100));
1346 this->leaveLayer(layer, occlusion);
1347 this->visitContributingSurface(layer, occlusion);
1348 this->enterLayer(parent, occlusion);
1350 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1351 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1352 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1353 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1354 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1355 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1356 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1357 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1358 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1360 EXPECT_RECT_EQ(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1364 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOutsideChild);
1366 template<class Types, bool opaqueLayers>
1367 class CCOcclusionTrackerTestViewportRectOutsideChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1368 protected:
1369 void runMyTest()
1371 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1372 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1373 this->calcDrawEtc(parent);
1375 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(200, 100, 100, 100));
1376 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1378 this->enterLayer(layer, occlusion);
1380 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1381 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1382 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1383 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1384 EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1386 occlusion.useDefaultLayerClipRect();
1387 EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1388 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1390 this->leaveLayer(layer, occlusion);
1391 this->visitContributingSurface(layer, occlusion);
1392 this->enterLayer(parent, occlusion);
1394 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1395 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1396 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1397 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1398 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1399 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1400 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1401 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1402 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1404 EXPECT_RECT_EQ(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1408 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOutsideChild);
1410 template<class Types, bool opaqueLayers>
1411 class CCOcclusionTrackerTestLayerClipRectOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1412 protected:
1413 void runMyTest()
1415 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1416 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1417 this->calcDrawEtc(parent);
1419 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1420 occlusion.setLayerClipRect(IntRect(100, 100, 100, 100));
1422 this->enterLayer(layer, occlusion);
1424 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1425 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1426 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1427 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1429 this->leaveLayer(layer, occlusion);
1430 this->visitContributingSurface(layer, occlusion);
1431 this->enterLayer(parent, occlusion);
1433 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1434 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1435 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1436 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1437 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1438 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1439 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1440 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1441 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1443 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1447 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOverChild);
1449 template<class Types, bool opaqueLayers>
1450 class CCOcclusionTrackerTestViewportRectOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1451 protected:
1452 void runMyTest()
1454 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1455 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1456 this->calcDrawEtc(parent);
1458 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(100, 100, 100, 100));
1459 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1461 this->enterLayer(layer, occlusion);
1463 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1464 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1465 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1466 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1468 this->leaveLayer(layer, occlusion);
1469 this->visitContributingSurface(layer, occlusion);
1470 this->enterLayer(parent, occlusion);
1472 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1473 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1474 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1475 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1476 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1477 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1478 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1479 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1480 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1482 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1486 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOverChild);
1488 template<class Types, bool opaqueLayers>
1489 class CCOcclusionTrackerTestLayerClipRectPartlyOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1490 protected:
1491 void runMyTest()
1493 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1494 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1495 this->calcDrawEtc(parent);
1497 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1498 occlusion.setLayerClipRect(IntRect(50, 50, 200, 200));
1500 this->enterLayer(layer, occlusion);
1502 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1503 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1504 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1505 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1507 this->leaveLayer(layer, occlusion);
1508 this->visitContributingSurface(layer, occlusion);
1509 this->enterLayer(parent, occlusion);
1511 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1512 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1513 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1514 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1515 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1516 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1517 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1518 EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1519 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1521 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1522 EXPECT_RECT_EQ(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)));
1523 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)));
1524 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)));
1525 EXPECT_RECT_EQ(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)));
1529 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectPartlyOverChild);
1531 template<class Types, bool opaqueLayers>
1532 class CCOcclusionTrackerTestViewportRectPartlyOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1533 protected:
1534 void runMyTest()
1536 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1537 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1538 this->calcDrawEtc(parent);
1540 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(50, 50, 200, 200));
1541 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1543 this->enterLayer(layer, occlusion);
1545 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1546 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1547 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1548 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1550 this->leaveLayer(layer, occlusion);
1551 this->visitContributingSurface(layer, occlusion);
1552 this->enterLayer(parent, occlusion);
1554 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1555 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1556 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1557 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1558 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1559 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1560 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1561 EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1562 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1564 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
1565 EXPECT_RECT_EQ(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)));
1566 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)));
1567 EXPECT_RECT_EQ(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)));
1568 EXPECT_RECT_EQ(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)));
1572 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectPartlyOverChild);
1574 template<class Types, bool opaqueLayers>
1575 class CCOcclusionTrackerTestLayerClipRectOverNothing : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1576 protected:
1577 void runMyTest()
1579 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1580 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1581 this->calcDrawEtc(parent);
1583 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1584 occlusion.setLayerClipRect(IntRect(500, 500, 100, 100));
1586 this->enterLayer(layer, occlusion);
1588 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1589 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1590 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1591 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1593 this->leaveLayer(layer, occlusion);
1594 this->visitContributingSurface(layer, occlusion);
1595 this->enterLayer(parent, occlusion);
1597 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1598 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1599 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1600 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1601 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1602 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1603 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1604 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1605 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1607 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1608 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)).isEmpty());
1609 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)).isEmpty());
1610 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)).isEmpty());
1611 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)).isEmpty());
1615 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectOverNothing);
1617 template<class Types, bool opaqueLayers>
1618 class CCOcclusionTrackerTestViewportRectOverNothing : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1619 protected:
1620 void runMyTest()
1622 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1623 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1624 this->calcDrawEtc(parent);
1626 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(500, 500, 100, 100));
1627 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1629 this->enterLayer(layer, occlusion);
1631 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1632 EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1633 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1634 EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1636 this->leaveLayer(layer, occlusion);
1637 this->visitContributingSurface(layer, occlusion);
1638 this->enterLayer(parent, occlusion);
1640 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
1641 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1642 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
1643 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1644 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
1645 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
1646 EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
1647 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
1648 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1650 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
1651 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)).isEmpty());
1652 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)).isEmpty());
1653 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)).isEmpty());
1654 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)).isEmpty());
1658 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestViewportRectOverNothing);
1660 template<class Types, bool opaqueLayers>
1661 class CCOcclusionTrackerTestLayerClipRectForLayerOffOrigin : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1662 protected:
1663 void runMyTest()
1665 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1666 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
1667 this->calcDrawEtc(parent);
1669 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1670 this->enterLayer(layer, occlusion);
1672 // This layer is translated when drawn into its target. So if the clip rect given from the target surface
1673 // is not in that target space, then after translating these query rects into the target, they will fall outside
1674 // the clip and be considered occluded.
1675 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1676 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1677 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1678 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1682 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerClipRectForLayerOffOrigin);
1684 template<class Types, bool opaqueLayers>
1685 class CCOcclusionTrackerTestOpaqueContentsRegionEmpty : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1686 protected:
1687 void runMyTest()
1689 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1690 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), false);
1691 this->calcDrawEtc(parent);
1693 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1694 this->enterLayer(layer, occlusion);
1696 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
1697 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
1698 EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
1699 EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
1701 // Occluded since its outside the surface bounds.
1702 EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1704 // Test without any clip rect.
1705 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
1706 EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
1707 occlusion.useDefaultLayerClipRect();
1709 this->leaveLayer(layer, occlusion);
1710 this->visitContributingSurface(layer, occlusion);
1711 this->enterLayer(parent, occlusion);
1713 EXPECT_TRUE(occlusion.occlusionInScreenSpace().bounds().isEmpty());
1714 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
1718 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionEmpty);
1720 template<class Types, bool opaqueLayers>
1721 class CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1722 protected:
1723 void runMyTest()
1725 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1726 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(200, 200), false);
1727 this->calcDrawEtc(parent);
1730 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1731 layer->setOpaqueContentsRect(IntRect(0, 0, 100, 100));
1733 this->resetLayerIterator();
1734 this->visitLayer(layer, occlusion);
1735 this->enterLayer(parent, occlusion);
1737 EXPECT_RECT_EQ(IntRect(100, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
1738 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1740 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1741 EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1742 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1746 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1747 layer->setOpaqueContentsRect(IntRect(20, 20, 180, 180));
1749 this->resetLayerIterator();
1750 this->visitLayer(layer, occlusion);
1751 this->enterLayer(parent, occlusion);
1753 EXPECT_RECT_EQ(IntRect(120, 120, 180, 180), occlusion.occlusionInScreenSpace().bounds());
1754 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1756 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1757 EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1758 EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1762 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1763 layer->setOpaqueContentsRect(IntRect(150, 150, 100, 100));
1765 this->resetLayerIterator();
1766 this->visitLayer(layer, occlusion);
1767 this->enterLayer(parent, occlusion);
1769 EXPECT_RECT_EQ(IntRect(250, 250, 50, 50), occlusion.occlusionInScreenSpace().bounds());
1770 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1772 EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
1773 EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
1774 EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
1779 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1781 template<class Types, bool opaqueLayers>
1782 class CCOcclusionTrackerTest3dTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1783 protected:
1784 void runMyTest()
1786 WebTransformationMatrix transform;
1787 transform.rotate3d(0, 30, 0);
1789 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1790 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1791 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
1792 this->calcDrawEtc(parent);
1794 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1795 this->enterLayer(layer, occlusion);
1797 // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
1798 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
1802 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTest3dTransform);
1804 template<class Types, bool opaqueLayers>
1805 class CCOcclusionTrackerTestUnsorted3dLayers : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1806 protected:
1807 void runMyTest()
1809 // Currently, the main thread layer iterator does not iterate over 3d items in
1810 // sorted order, because layer sorting is not performed on the main thread.
1811 // Because of this, the occlusion tracker cannot assume that a 3d layer occludes
1812 // other layers that have not yet been iterated over. For now, the expected
1813 // behavior is that a 3d layer simply does not add any occlusion to the occlusion
1814 // tracker.
1816 WebTransformationMatrix translationToFront;
1817 translationToFront.translate3d(0, 0, -10);
1818 WebTransformationMatrix translationToBack;
1819 translationToFront.translate3d(0, 0, -100);
1821 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1822 typename Types::ContentLayerType* child1 = this->createDrawingLayer(parent, translationToBack, FloatPoint(0, 0), IntSize(100, 100), true);
1823 typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, translationToFront, FloatPoint(50, 50), IntSize(100, 100), true);
1824 parent->setPreserves3D(true);
1826 this->calcDrawEtc(parent);
1828 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1829 this->visitLayer(child2, occlusion);
1830 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1831 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1833 this->visitLayer(child1, occlusion);
1834 EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
1835 EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
1839 // This test will have different layer ordering on the impl thread; the test will only work on the main thread.
1840 MAIN_THREAD_TEST(CCOcclusionTrackerTestUnsorted3dLayers);
1842 template<class Types, bool opaqueLayers>
1843 class CCOcclusionTrackerTestPerspectiveTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1844 protected:
1845 void runMyTest()
1847 WebTransformationMatrix transform;
1848 transform.translate(150, 150);
1849 transform.applyPerspective(400);
1850 transform.rotate3d(1, 0, 0, -30);
1851 transform.translate(-150, -150);
1853 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1854 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1855 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
1856 container->setPreserves3D(true);
1857 layer->setPreserves3D(true);
1858 this->calcDrawEtc(parent);
1860 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1861 this->enterLayer(layer, occlusion);
1863 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
1867 // This test requires accumulating occlusion of 3d layers, which are skipped by the occlusion tracker on the main thread. So this test should run on the impl thread.
1868 IMPL_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransform);
1870 template<class Types, bool opaqueLayers>
1871 class CCOcclusionTrackerTestPerspectiveTransformBehindCamera : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1872 protected:
1873 void runMyTest()
1875 // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
1876 WebTransformationMatrix transform;
1877 transform.translate(250, 50);
1878 transform.applyPerspective(10);
1879 transform.translate(-250, -50);
1880 transform.translate(250, 50);
1881 transform.rotate3d(1, 0, 0, -167);
1882 transform.translate(-250, -50);
1884 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 100));
1885 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
1886 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(0, 0), IntSize(500, 500), true);
1887 container->setPreserves3D(true);
1888 layer->setPreserves3D(true);
1889 this->calcDrawEtc(parent);
1891 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1892 this->enterLayer(layer, occlusion);
1894 // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
1895 // this will include many more pixels but must include at least the bottom 11 rows.
1896 EXPECT_TRUE(occlusion.unoccludedContentRect(layer, IntRect(0, 0, 500, 500)).contains(IntRect(0, 489, 500, 11)));
1900 // This test requires accumulating occlusion of 3d layers, which are skipped by the occlusion tracker on the main thread. So this test should run on the impl thread.
1901 IMPL_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransformBehindCamera);
1903 template<class Types, bool opaqueLayers>
1904 class CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1905 protected:
1906 void runMyTest()
1908 WebTransformationMatrix transform;
1909 transform.translate(50, 50);
1910 transform.applyPerspective(100);
1911 transform.translate3d(0, 0, 110);
1912 transform.translate(-50, -50);
1914 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1915 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true);
1916 parent->setPreserves3D(true);
1917 layer->setPreserves3D(true);
1918 this->calcDrawEtc(parent);
1920 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1922 // The |layer| is entirely behind the camera and should not occlude.
1923 this->visitLayer(layer, occlusion);
1924 this->enterLayer(parent, occlusion);
1925 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
1926 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
1930 // This test requires accumulating occlusion of 3d layers, which are skipped by the occlusion tracker on the main thread. So this test should run on the impl thread.
1931 IMPL_THREAD_TEST(CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
1933 template<class Types, bool opaqueLayers>
1934 class CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1935 protected:
1936 void runMyTest()
1938 WebTransformationMatrix transform;
1939 transform.translate(50, 50);
1940 transform.applyPerspective(100);
1941 transform.translate3d(0, 0, 99);
1942 transform.translate(-50, -50);
1944 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
1945 parent->setMasksToBounds(true);
1946 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true);
1947 parent->setPreserves3D(true);
1948 layer->setPreserves3D(true);
1949 this->calcDrawEtc(parent);
1951 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1953 // This is very close to the camera, so pixels in its visibleContentRect will actually go outside of the layer's clipRect.
1954 // Ensure that those pixels don't occlude things outside the clipRect.
1955 this->visitLayer(layer, occlusion);
1956 this->enterLayer(parent, occlusion);
1957 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
1958 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1959 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInScreenSpace().bounds());
1960 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1964 // This test requires accumulating occlusion of 3d layers, which are skipped by the occlusion tracker on the main thread. So this test should run on the impl thread.
1965 IMPL_THREAD_TEST(CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect);
1967 template<class Types, bool opaqueLayers>
1968 class CCOcclusionTrackerTestAnimationOpacity1OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1969 protected:
1970 void runMyTest()
1972 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
1973 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
1974 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
1975 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
1976 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
1977 typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false);
1978 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
1980 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 0, 1, false);
1981 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 0, 1, false);
1982 this->calcDrawEtc(parent);
1984 EXPECT_TRUE(layer->drawOpacityIsAnimating());
1985 EXPECT_FALSE(surface->drawOpacityIsAnimating());
1986 EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
1988 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1990 this->visitLayer(topmost, occlusion);
1991 this->enterLayer(parent2, occlusion);
1992 // This occlusion will affect all surfaces.
1993 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent2, IntRect(0, 0, 300, 300)));
1994 this->leaveLayer(parent2, occlusion);
1996 this->visitLayer(surfaceChild2, occlusion);
1997 this->enterLayer(surfaceChild, occlusion);
1998 EXPECT_RECT_EQ(IntRect(100, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 300, 300)));
1999 this->leaveLayer(surfaceChild, occlusion);
2000 this->enterLayer(surface, occlusion);
2001 EXPECT_RECT_EQ(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2002 this->leaveLayer(surface, occlusion);
2004 this->enterContributingSurface(surface, occlusion);
2005 // Occlusion within the surface is lost when leaving the animating surface.
2006 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
2007 this->leaveContributingSurface(surface, occlusion);
2009 this->visitLayer(layer, occlusion);
2010 this->enterLayer(parent, occlusion);
2012 // Occlusion is not added for the animating |layer|.
2013 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2017 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity1OnMainThread);
2019 template<class Types, bool opaqueLayers>
2020 class CCOcclusionTrackerTestAnimationOpacity0OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2021 protected:
2022 void runMyTest()
2024 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
2025 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2026 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2027 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
2028 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
2029 typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false);
2030 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
2032 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 1, 0, false);
2033 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 1, 0, false);
2034 this->calcDrawEtc(parent);
2036 EXPECT_TRUE(layer->drawOpacityIsAnimating());
2037 EXPECT_FALSE(surface->drawOpacityIsAnimating());
2038 EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
2040 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2042 this->visitLayer(topmost, occlusion);
2043 this->enterLayer(parent2, occlusion);
2044 // This occlusion will affect all surfaces.
2045 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2046 this->leaveLayer(parent2, occlusion);
2048 this->visitLayer(surfaceChild2, occlusion);
2049 this->enterLayer(surfaceChild, occlusion);
2050 EXPECT_RECT_EQ(IntRect(100, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 300, 300)));
2051 this->leaveLayer(surfaceChild, occlusion);
2052 this->enterLayer(surface, occlusion);
2053 EXPECT_RECT_EQ(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2054 this->leaveLayer(surface, occlusion);
2056 this->enterContributingSurface(surface, occlusion);
2057 // Occlusion within the surface is lost when leaving the animating surface.
2058 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
2059 this->leaveContributingSurface(surface, occlusion);
2061 this->visitLayer(layer, occlusion);
2062 this->enterLayer(parent, occlusion);
2064 // Occlusion is not added for the animating |layer|.
2065 EXPECT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2069 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity0OnMainThread);
2071 template<class Types, bool opaqueLayers>
2072 class CCOcclusionTrackerTestAnimationTranslateOnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2073 protected:
2074 void runMyTest()
2076 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
2077 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2078 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
2079 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
2080 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
2081 typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(50, 300), true);
2083 addAnimatedTransformToController(*layer->layerAnimationController(), 10, 30, 0);
2084 addAnimatedTransformToController(*surface->layerAnimationController(), 10, 30, 0);
2085 addAnimatedTransformToController(*surfaceChild->layerAnimationController(), 10, 30, 0);
2086 this->calcDrawEtc(parent);
2088 EXPECT_TRUE(layer->drawTransformIsAnimating());
2089 EXPECT_TRUE(layer->screenSpaceTransformIsAnimating());
2090 EXPECT_TRUE(surface->renderSurface()->targetSurfaceTransformsAreAnimating());
2091 EXPECT_TRUE(surface->renderSurface()->screenSpaceTransformsAreAnimating());
2092 // The surface owning layer doesn't animate against its own surface.
2093 EXPECT_FALSE(surface->drawTransformIsAnimating());
2094 EXPECT_TRUE(surface->screenSpaceTransformIsAnimating());
2095 EXPECT_TRUE(surfaceChild->drawTransformIsAnimating());
2096 EXPECT_TRUE(surfaceChild->screenSpaceTransformIsAnimating());
2098 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2100 this->visitLayer(surface2, occlusion);
2101 this->enterContributingSurface(surface2, occlusion);
2103 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
2104 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2106 this->leaveContributingSurface(surface2, occlusion);
2107 this->enterLayer(surfaceChild2, occlusion);
2109 // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2110 // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer.
2111 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild2, IntRect(0, 0, 100, 300)));
2112 EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
2114 this->leaveLayer(surfaceChild2, occlusion);
2115 this->enterLayer(surfaceChild, occlusion);
2116 EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 100, 300)));
2117 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
2118 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2119 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
2120 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2121 EXPECT_RECT_EQ(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2123 // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target and the screen, so it
2124 // can't be occluded.
2125 EXPECT_RECT_EQ(IntRect(0, 0, 200, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 200, 300)));
2126 EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
2128 this->leaveLayer(surfaceChild, occlusion);
2129 this->enterLayer(surface, occlusion);
2130 // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2131 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
2132 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2133 EXPECT_RECT_EQ(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
2134 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2135 EXPECT_RECT_EQ(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2137 this->leaveLayer(surface, occlusion);
2138 // 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.
2139 EXPECT_RECT_EQ(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
2140 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2141 EXPECT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion.occlusionInTargetSurface().bounds());
2142 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2143 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
2145 this->enterContributingSurface(surface, occlusion);
2146 // The contributing |surface| is animating so it can't be occluded.
2147 EXPECT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300)));
2148 this->leaveContributingSurface(surface, occlusion);
2150 this->enterLayer(layer, occlusion);
2151 // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
2152 EXPECT_RECT_EQ(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2153 this->leaveLayer(layer, occlusion);
2155 this->enterLayer(parent, occlusion);
2156 // The |layer| is animating in the screen and in its target, so no occlusion is added.
2157 EXPECT_RECT_EQ(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
2161 MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationTranslateOnMainThread);
2163 template<class Types, bool opaqueLayers>
2164 class CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2165 protected:
2166 void runMyTest()
2168 WebTransformationMatrix surfaceTransform;
2169 surfaceTransform.translate(300, 300);
2170 surfaceTransform.scale(2);
2171 surfaceTransform.translate(-150, -150);
2173 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
2174 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, surfaceTransform, FloatPoint(0, 0), IntSize(300, 300), false);
2175 typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(300, 300), false);
2176 surface->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
2177 surface2->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
2178 this->calcDrawEtc(parent);
2180 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2182 this->visitLayer(surface2, occlusion);
2183 this->visitContributingSurface(surface2, occlusion);
2185 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.occlusionInScreenSpace().bounds());
2186 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2187 EXPECT_RECT_EQ(IntRect(50, 50, 200, 200), occlusion.occlusionInTargetSurface().bounds());
2188 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2190 // Clear any stored occlusion.
2191 occlusion.setOcclusionInScreenSpace(Region());
2192 occlusion.setOcclusionInTargetSurface(Region());
2194 this->visitLayer(surface, occlusion);
2195 this->visitContributingSurface(surface, occlusion);
2197 EXPECT_RECT_EQ(IntRect(0, 0, 400, 400), occlusion.occlusionInScreenSpace().bounds());
2198 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2199 EXPECT_RECT_EQ(IntRect(0, 0, 400, 400), occlusion.occlusionInTargetSurface().bounds());
2200 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2204 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2206 template<class Types, bool opaqueLayers>
2207 class CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2208 protected:
2209 void runMyTest()
2211 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
2212 parent->setMasksToBounds(true);
2213 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 300), false);
2214 surface->setOpaqueContentsRect(IntRect(0, 0, 400, 200));
2215 this->calcDrawEtc(parent);
2217 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2219 this->visitLayer(surface, occlusion);
2220 this->visitContributingSurface(surface, occlusion);
2222 EXPECT_RECT_EQ(IntRect(0, 0, 300, 200), occlusion.occlusionInScreenSpace().bounds());
2223 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2224 EXPECT_RECT_EQ(IntRect(0, 0, 300, 200), occlusion.occlusionInTargetSurface().bounds());
2225 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2229 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2231 template<class Types, bool opaqueLayers>
2232 class CCOcclusionTrackerTestReplicaOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2233 protected:
2234 void runMyTest()
2236 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2237 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2238 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2239 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100), true);
2240 this->calcDrawEtc(parent);
2242 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2243 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2245 // |topmost| occludes the replica, but not the surface itself.
2246 this->visitLayer(topmost, occlusion);
2248 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
2249 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2250 EXPECT_RECT_EQ(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2251 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2253 this->visitLayer(surface, occlusion);
2255 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
2256 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2257 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2258 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2260 this->enterContributingSurface(surface, occlusion);
2262 // Surface is not occluded so it shouldn't think it is.
2263 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2267 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaOccluded);
2269 template<class Types, bool opaqueLayers>
2270 class CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2271 protected:
2272 void runMyTest()
2274 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2275 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2276 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2277 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 110), true);
2278 this->calcDrawEtc(parent);
2280 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2281 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2283 // |topmost| occludes the surface, but not the entire surface's replica.
2284 this->visitLayer(topmost, occlusion);
2286 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
2287 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2288 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInTargetSurface().bounds());
2289 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2291 this->visitLayer(surface, occlusion);
2293 EXPECT_RECT_EQ(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
2294 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2295 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2296 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2298 this->enterContributingSurface(surface, occlusion);
2300 // Surface is occluded, but only the top 10px of the replica.
2301 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2302 EXPECT_RECT_EQ(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, true, IntRect(0, 0, 100, 100)));
2306 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2308 template<class Types, bool opaqueLayers>
2309 class CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2310 protected:
2311 void runMyTest()
2313 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2314 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2315 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2316 typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(40, 100), true);
2317 typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 100), true);
2318 this->calcDrawEtc(parent);
2320 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2321 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2323 // These occlude the surface and replica differently, so we can test each one.
2324 this->visitLayer(overReplica, occlusion);
2325 this->visitLayer(overSurface, occlusion);
2327 EXPECT_RECT_EQ(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds());
2328 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2329 EXPECT_RECT_EQ(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds());
2330 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2332 this->visitLayer(surface, occlusion);
2334 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
2335 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2336 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2337 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2339 this->enterContributingSurface(surface, occlusion);
2341 // Surface and replica are occluded different amounts.
2342 EXPECT_RECT_EQ(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2343 EXPECT_RECT_EQ(IntRect(50, 0, 50, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, true, IntRect(0, 0, 100, 100)));
2347 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2349 template<class Types, bool opaqueLayers>
2350 class CCOcclusionTrackerTestSurfaceChildOfSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2351 protected:
2352 void runMyTest()
2354 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2356 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2357 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2358 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 10), IntSize(100, 50), true);
2359 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
2360 this->calcDrawEtc(parent);
2362 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(-100, -100, 1000, 1000));
2364 // |topmost| occludes everything partially so we know occlusion is happening at all.
2365 this->visitLayer(topmost, occlusion);
2367 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds());
2368 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2369 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
2370 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2372 this->visitLayer(surfaceChild, occlusion);
2374 // surfaceChild increases the occlusion in the screen by a narrow sliver.
2375 EXPECT_RECT_EQ(IntRect(0, 0, 100, 60), occlusion.occlusionInScreenSpace().bounds());
2376 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2377 // In its own surface, surfaceChild is at 0,0 as is its occlusion.
2378 EXPECT_RECT_EQ(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
2379 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2381 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2382 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2383 // as its parent does not have a clipRect.
2385 this->enterContributingSurface(surfaceChild, occlusion);
2386 // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
2387 // does not get clipped away inappropriately.
2388 EXPECT_RECT_EQ(IntRect(0, 40, 100, 10), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, IntRect(0, 0, 100, 50)));
2389 this->leaveContributingSurface(surfaceChild, occlusion);
2391 // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
2392 this->enterLayer(surface, occlusion);
2393 EXPECT_RECT_EQ(IntRect(0, 0, 100, 60), occlusion.occlusionInScreenSpace().bounds());
2394 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2395 EXPECT_RECT_EQ(IntRect(0, 10, 100, 50), occlusion.occlusionInTargetSurface().bounds());
2396 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2397 this->leaveLayer(surface, occlusion);
2399 this->enterContributingSurface(surface, occlusion);
2400 // The surface's parent does have a clipRect as it is the root layer.
2401 EXPECT_RECT_EQ(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2405 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfSurface);
2407 template<class Types, bool opaqueLayers>
2408 class CCOcclusionTrackerTestTopmostSurfaceIsClippedToViewport : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2409 protected:
2410 void runMyTest()
2412 // This test verifies that the top-most surface is considered occluded outside of its target's clipRect and outside the viewport rect.
2414 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2415 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
2416 this->calcDrawEtc(parent);
2419 // Make a viewport rect that is larger than the root layer.
2420 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2422 this->visitLayer(surface, occlusion);
2424 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2425 this->enterContributingSurface(surface, occlusion);
2426 // Make sure the parent's clipRect clips the unoccluded region of the child surface.
2427 EXPECT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 300)));
2429 this->resetLayerIterator();
2431 // Make a viewport rect that is smaller than the root layer.
2432 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 100, 100));
2434 this->visitLayer(surface, occlusion);
2436 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2437 this->enterContributingSurface(surface, occlusion);
2438 // Make sure the viewport rect clips the unoccluded region of the child surface.
2439 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 300)));
2444 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
2446 template<class Types, bool opaqueLayers>
2447 class CCOcclusionTrackerTestSurfaceChildOfClippingSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2448 protected:
2449 void runMyTest()
2451 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2453 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(80, 200));
2454 parent->setMasksToBounds(true);
2455 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2456 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), false);
2457 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
2458 this->calcDrawEtc(parent);
2460 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2461 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2463 // |topmost| occludes everything partially so we know occlusion is happening at all.
2464 this->visitLayer(topmost, occlusion);
2466 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInScreenSpace().bounds());
2467 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2468 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInTargetSurface().bounds());
2469 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2471 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2472 this->visitLayer(surfaceChild, occlusion);
2474 EXPECT_RECT_EQ(IntRect(0, 0, 80, 50), occlusion.occlusionInScreenSpace().bounds());
2475 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2476 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
2477 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2479 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2480 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2481 // as its parent does not have a clipRect.
2483 this->enterContributingSurface(surfaceChild, occlusion);
2484 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
2485 EXPECT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, IntRect(0, 0, 100, 100)));
2486 this->leaveContributingSurface(surfaceChild, occlusion);
2488 this->visitLayer(surface, occlusion);
2489 this->enterContributingSurface(surface, occlusion);
2490 // The surface's parent does have a clipRect as it is the root layer.
2491 EXPECT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100)));
2495 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfClippingSurface);
2497 template<class Types, bool opaqueLayers>
2498 class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2499 protected:
2500 void runMyTest()
2502 WebTransformationMatrix scaleByHalf;
2503 scaleByHalf.scale(0.5);
2505 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2506 // The surface is scaled to test that the pixel moving is done in the target space, where the background filter is applied, but the surface
2507 // appears at 50, 50 and the replica at 200, 50.
2508 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2509 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2510 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2511 typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 50), true);
2512 typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(300, 50), true);
2513 typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 50), IntSize(50, 50), true);
2514 typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 50), IntSize(100, 50), true);
2515 typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
2517 // Filters make the layer own a surface.
2518 WebFilterOperations filters;
2519 filters.append(WebFilterOperation::createBlurFilter(10));
2520 filteredSurface->setBackgroundFilters(filters);
2522 // Save the distance of influence for the blur effect.
2523 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2524 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2526 this->calcDrawEtc(parent);
2528 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2529 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2531 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2532 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2533 this->visitLayer(occludingLayer5, occlusion);
2534 this->visitLayer(occludingLayer4, occlusion);
2535 this->visitLayer(occludingLayer3, occlusion);
2536 this->visitLayer(occludingLayer2, occlusion);
2537 this->visitLayer(occludingLayer1, occlusion);
2539 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2540 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2541 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
2542 EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2544 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2545 this->enterLayer(filteredSurface, occlusion);
2546 EXPECT_RECT_EQ(IntRect(1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 100, 100)));
2547 EXPECT_RECT_EQ(IntRect(0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 100, 100)));
2548 EXPECT_RECT_EQ(IntRect(0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 100, 100)));
2549 EXPECT_RECT_EQ(IntRect(0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 100, 100)));
2551 EXPECT_RECT_EQ(IntRect(300 + 1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 1, 0, 100, 100)));
2552 EXPECT_RECT_EQ(IntRect(300 + 0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, 1, 100, 100)));
2553 EXPECT_RECT_EQ(IntRect(300 + 0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 - 1, 0, 100, 100)));
2554 EXPECT_RECT_EQ(IntRect(300 + 0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, -1, 100, 100)));
2555 this->leaveLayer(filteredSurface, occlusion);
2557 // The filtered layer/replica does not occlude.
2558 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2559 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2560 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
2561 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2563 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2564 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2565 this->visitContributingSurface(filteredSurface, occlusion);
2567 this->enterLayer(parent, occlusion);
2568 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2569 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2570 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
2571 EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2573 IntRect outsetRect;
2574 IntRect testRect;
2576 // Nothing in the blur outsets for the filteredSurface is occluded.
2577 outsetRect = IntRect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2578 testRect = outsetRect;
2579 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2581 // Stuff outside the blur outsets is still occluded though.
2582 testRect = outsetRect;
2583 testRect.expand(1, 0);
2584 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2585 testRect = outsetRect;
2586 testRect.expand(0, 1);
2587 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2588 testRect = outsetRect;
2589 testRect.move(-1, 0);
2590 testRect.expand(1, 0);
2591 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2592 testRect = outsetRect;
2593 testRect.move(0, -1);
2594 testRect.expand(0, 1);
2595 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2597 // Nothing in the blur outsets for the filteredSurface's replica is occluded.
2598 outsetRect = IntRect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2599 testRect = outsetRect;
2600 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2602 // Stuff outside the blur outsets is still occluded though.
2603 testRect = outsetRect;
2604 testRect.expand(1, 0);
2605 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2606 testRect = outsetRect;
2607 testRect.expand(0, 1);
2608 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2609 testRect = outsetRect;
2610 testRect.move(-1, 0);
2611 testRect.expand(1, 0);
2612 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2613 testRect = outsetRect;
2614 testRect.move(0, -1);
2615 testRect.expand(0, 1);
2616 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
2620 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2622 template<class Types, bool opaqueLayers>
2623 class CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2624 protected:
2625 void runMyTest()
2627 WebTransformationMatrix scaleByHalf;
2628 scaleByHalf.scale(0.5);
2630 // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
2631 typename Types::ContentLayerType* root = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(75, 75));
2632 typename Types::LayerType* parent = this->createSurface(root, scaleByHalf, FloatPoint(0, 0), IntSize(150, 150));
2633 parent->setMasksToBounds(true);
2634 typename Types::LayerType* filteredSurface1 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
2635 typename Types::LayerType* filteredSurface2 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
2636 typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(50, 50), true);
2638 // Filters make the layers own surfaces.
2639 WebFilterOperations filters;
2640 filters.append(WebFilterOperation::createBlurFilter(3));
2641 filteredSurface1->setBackgroundFilters(filters);
2642 filteredSurface2->setBackgroundFilters(filters);
2644 // Save the distance of influence for the blur effect.
2645 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2646 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2648 this->calcDrawEtc(root);
2650 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2651 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2653 this->visitLayer(occludingLayerAbove, occlusion);
2654 EXPECT_RECT_EQ(IntRect(100 / 2, 100 / 2, 50 / 2, 50 / 2), occlusion.occlusionInScreenSpace().bounds());
2655 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2656 EXPECT_RECT_EQ(IntRect(100, 100, 50, 50), occlusion.occlusionInTargetSurface().bounds());
2657 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2659 this->visitLayer(filteredSurface2, occlusion);
2660 this->visitContributingSurface(filteredSurface2, occlusion);
2661 this->visitLayer(filteredSurface1, occlusion);
2662 this->visitContributingSurface(filteredSurface1, occlusion);
2664 ASSERT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2665 ASSERT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2667 // Test expectations in the target.
2668 IntRect expectedOcclusion = IntRect(100 + outsetRight * 2, 100 + outsetBottom * 2, 50 - (outsetLeft + outsetRight) * 2, 50 - (outsetTop + outsetBottom) * 2);
2669 EXPECT_RECT_EQ(expectedOcclusion, occlusion.occlusionInTargetSurface().rects()[0]);
2671 // Test expectations in the screen. Take the ceiling of half of the outsets.
2672 outsetTop = (outsetTop + 1) / 2;
2673 outsetRight = (outsetRight + 1) / 2;
2674 outsetBottom = (outsetBottom + 1) / 2;
2675 outsetLeft = (outsetLeft + 1) / 2;
2676 expectedOcclusion = IntRect(100 / 2 + outsetRight * 2, 100 / 2 + outsetBottom * 2, 50 / 2 - (outsetLeft + outsetRight) * 2, 50 /2 - (outsetTop + outsetBottom) * 2);
2678 EXPECT_RECT_EQ(expectedOcclusion, occlusion.occlusionInScreenSpace().rects()[0]);
2682 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
2684 template<class Types, bool opaqueLayers>
2685 class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2686 protected:
2687 void runMyTest()
2689 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2690 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2691 // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
2692 // the background filter.
2693 typename Types::LayerType* clippingSurface = this->createSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 70));
2694 clippingSurface->setMasksToBounds(true);
2695 typename Types::LayerType* filteredSurface = this->createDrawingLayer(clippingSurface, this->identityMatrix, FloatPoint(50, 50), IntSize(50, 50), false);
2696 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(150, 0), IntSize());
2697 typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 50), true);
2698 typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(300, 50), true);
2699 typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 50), IntSize(50, 50), true);
2700 typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 50), IntSize(100, 50), true);
2701 typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
2703 // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
2704 WebFilterOperations filters;
2705 filters.append(WebFilterOperation::createBlurFilter(12));
2706 filteredSurface->setBackgroundFilters(filters);
2708 // Save the distance of influence for the blur effect.
2709 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2710 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2712 this->calcDrawEtc(parent);
2714 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2715 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2717 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2718 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2719 this->visitLayer(occludingLayer5, occlusion);
2720 this->visitLayer(occludingLayer4, occlusion);
2721 this->visitLayer(occludingLayer3, occlusion);
2722 this->visitLayer(occludingLayer2, occlusion);
2723 this->visitLayer(occludingLayer1, occlusion);
2725 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2726 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2727 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
2728 EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
2730 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2731 this->enterLayer(filteredSurface, occlusion);
2732 EXPECT_RECT_EQ(IntRect(1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 50, 50)));
2733 EXPECT_RECT_EQ(IntRect(0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 50, 50)));
2734 EXPECT_RECT_EQ(IntRect(0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 50, 50)));
2735 EXPECT_RECT_EQ(IntRect(0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 50, 50)));
2737 EXPECT_RECT_EQ(IntRect(150 + 1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 1, 0, 50, 50)));
2738 EXPECT_RECT_EQ(IntRect(150 + 0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, 1, 50, 50)));
2739 EXPECT_RECT_EQ(IntRect(150 + 0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 - 1, 0, 50, 50)));
2740 EXPECT_RECT_EQ(IntRect(150 + 0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, -1, 50, 50)));
2741 this->leaveLayer(filteredSurface, occlusion);
2743 // The filtered layer/replica does not occlude.
2744 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2745 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2746 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
2747 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2749 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2750 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2751 this->visitContributingSurface(filteredSurface, occlusion);
2753 this->enterContributingSurface(clippingSurface, occlusion);
2754 EXPECT_RECT_EQ(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
2755 EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
2757 IntRect outsetRect;
2758 IntRect clippedOutsetRect;
2759 IntRect testRect;
2761 // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
2762 outsetRect = IntRect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2763 clippedOutsetRect = intersection(outsetRect, IntRect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2764 testRect = outsetRect;
2765 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2767 // Stuff outside the (clipped) blur outsets is still occluded though.
2768 testRect = outsetRect;
2769 testRect.expand(1, 0);
2770 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2771 testRect = outsetRect;
2772 testRect.expand(0, 1);
2773 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2774 testRect = outsetRect;
2775 testRect.move(-1, 0);
2776 testRect.expand(1, 0);
2777 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2778 testRect = outsetRect;
2779 testRect.move(0, -1);
2780 testRect.expand(0, 1);
2781 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2783 // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
2784 outsetRect = IntRect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2785 clippedOutsetRect = intersection(outsetRect, IntRect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2786 testRect = outsetRect;
2787 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2789 // Stuff outside the (clipped) blur outsets is still occluded though.
2790 testRect = outsetRect;
2791 testRect.expand(1, 0);
2792 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2793 testRect = outsetRect;
2794 testRect.expand(0, 1);
2795 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2796 testRect = outsetRect;
2797 testRect.move(-1, 0);
2798 testRect.expand(1, 0);
2799 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2800 testRect = outsetRect;
2801 testRect.move(0, -1);
2802 testRect.expand(0, 1);
2803 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
2807 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
2809 template<class Types, bool opaqueLayers>
2810 class CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2811 protected:
2812 void runMyTest()
2814 WebTransformationMatrix scaleByHalf;
2815 scaleByHalf.scale(0.5);
2817 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
2818 // The surface is scaled to test that the pixel moving is done in the target space, where the background filter is applied, but the surface
2819 // appears at 50, 50 and the replica at 200, 50.
2820 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2821 typename Types::LayerType* behindSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(60, 60), IntSize(30, 30), true);
2822 typename Types::LayerType* behindReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(210, 60), IntSize(30, 30), true);
2823 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2824 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2826 // Filters make the layer own a surface.
2827 WebFilterOperations filters;
2828 filters.append(WebFilterOperation::createBlurFilter(3));
2829 filteredSurface->setBackgroundFilters(filters);
2831 this->calcDrawEtc(parent);
2833 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2834 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2836 // The surface has a background blur, so it blurs non-opaque pixels below it.
2837 this->visitLayer(filteredSurface, occlusion);
2838 this->visitContributingSurface(filteredSurface, occlusion);
2840 this->visitLayer(behindReplicaLayer, occlusion);
2841 this->visitLayer(behindSurfaceLayer, occlusion);
2843 // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
2844 // So it should not be modified by the filter here.
2845 IntRect occlusionBehindSurface = IntRect(60, 60, 30, 30);
2846 IntRect occlusionBehindReplica = IntRect(210, 60, 30, 30);
2848 IntRect expectedOpaqueBounds = unionRect(occlusionBehindSurface, occlusionBehindReplica);
2849 EXPECT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInScreenSpace().bounds());
2850 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2851 EXPECT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInTargetSurface().bounds());
2852 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2856 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
2858 template<class Types, bool opaqueLayers>
2859 class CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2860 protected:
2861 void runMyTest()
2863 WebTransformationMatrix scaleByHalf;
2864 scaleByHalf.scale(0.5);
2866 // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
2867 // The surface is scaled to test that the pixel moving is done in the target space, where the background filter is applied, but the surface
2868 // appears at 50, 50 and the replica at 200, 50.
2869 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2870 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2871 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2872 typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(50, 50), true);
2873 typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(50, 50), true);
2875 // Filters make the layer own a surface.
2876 WebFilterOperations filters;
2877 filters.append(WebFilterOperation::createBlurFilter(3));
2878 filteredSurface->setBackgroundFilters(filters);
2880 this->calcDrawEtc(parent);
2882 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2883 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2885 this->visitLayer(aboveReplicaLayer, occlusion);
2886 this->visitLayer(aboveSurfaceLayer, occlusion);
2888 // The surface has a background blur, so it blurs non-opaque pixels below it.
2889 this->visitLayer(filteredSurface, occlusion);
2890 this->visitContributingSurface(filteredSurface, occlusion);
2892 // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
2893 IntRect occlusionAboveSurface = IntRect(50, 50, 50, 50);
2894 IntRect occlusionAboveReplica = IntRect(200, 50, 50, 50);
2896 IntRect expectedOpaqueBounds = unionRect(occlusionAboveSurface, occlusionAboveReplica);
2897 EXPECT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInScreenSpace().bounds());
2898 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2899 EXPECT_RECT_EQ(expectedOpaqueBounds, occlusion.occlusionInTargetSurface().bounds());
2900 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2904 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
2906 template<class Types, bool opaqueLayers>
2907 class CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2908 protected:
2909 void runMyTest()
2911 WebTransformationMatrix scaleByHalf;
2912 scaleByHalf.scale(0.5);
2914 // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
2915 // The surface is scaled to test that the pixel moving is done in the target space, where the background filter is applied, but the surface
2916 // appears at 50, 50 and the replica at 200, 50.
2917 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
2918 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
2919 this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
2920 typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(70, 50), IntSize(30, 50), true);
2921 typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(30, 50), true);
2922 typename Types::LayerType* besideSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(90, 40), IntSize(10, 10), true);
2923 typename Types::LayerType* besideReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 40), IntSize(10, 10), true);
2925 // Filters make the layer own a surface.
2926 WebFilterOperations filters;
2927 filters.append(WebFilterOperation::createBlurFilter(3));
2928 filteredSurface->setBackgroundFilters(filters);
2930 // Save the distance of influence for the blur effect.
2931 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2932 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2934 this->calcDrawEtc(parent);
2936 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2937 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2939 this->visitLayer(besideReplicaLayer, occlusion);
2940 this->visitLayer(besideSurfaceLayer, occlusion);
2941 this->visitLayer(aboveReplicaLayer, occlusion);
2942 this->visitLayer(aboveSurfaceLayer, occlusion);
2944 // The surface has a background blur, so it blurs non-opaque pixels below it.
2945 this->visitLayer(filteredSurface, occlusion);
2946 this->visitContributingSurface(filteredSurface, occlusion);
2948 // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
2949 // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
2950 // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
2951 // the occluded part of the surface.
2952 IntRect occlusionAboveSurface = IntRect(70 + outsetRight, 50, 30 - outsetRight, 50);
2953 IntRect occlusionAboveReplica = IntRect(200, 50, 30 - outsetLeft, 50);
2954 IntRect occlusionBesideSurface = IntRect(90, 40, 10, 10);
2955 IntRect occlusionBesideReplica = IntRect(200, 40, 10, 10);
2957 Region expectedOcclusion;
2958 expectedOcclusion.unite(occlusionAboveSurface);
2959 expectedOcclusion.unite(occlusionAboveReplica);
2960 expectedOcclusion.unite(occlusionBesideSurface);
2961 expectedOcclusion.unite(occlusionBesideReplica);
2963 ASSERT_EQ(expectedOcclusion.rects().size(), occlusion.occlusionInTargetSurface().rects().size());
2964 ASSERT_EQ(expectedOcclusion.rects().size(), occlusion.occlusionInScreenSpace().rects().size());
2966 for (size_t i = 0; i < expectedOcclusion.rects().size(); ++i) {
2967 IntRect expectedRect = expectedOcclusion.rects()[i];
2968 IntRect screenRect = occlusion.occlusionInScreenSpace().rects()[i];
2969 IntRect targetRect = occlusion.occlusionInTargetSurface().rects()[i];
2970 EXPECT_EQ(expectedRect, screenRect);
2971 EXPECT_EQ(expectedRect, targetRect);
2976 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
2978 template<class Types, bool opaqueLayers>
2979 class CCOcclusionTrackerTestMinimumTrackingSize : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2980 protected:
2981 void runMyTest()
2983 IntSize trackingSize(100, 100);
2984 IntSize belowTrackingSize(99, 99);
2986 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(400, 400));
2987 typename Types::LayerType* large = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), trackingSize, true);
2988 typename Types::LayerType* small = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), belowTrackingSize, true);
2989 this->calcDrawEtc(parent);
2991 TestCCOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2992 occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
2993 occlusion.setMinimumTrackingSize(trackingSize);
2995 // The small layer is not tracked because it is too small.
2996 this->visitLayer(small, occlusion);
2998 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInScreenSpace().bounds());
2999 EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
3000 EXPECT_RECT_EQ(IntRect(), occlusion.occlusionInTargetSurface().bounds());
3001 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
3003 // The large layer is tracked as it is large enough.
3004 this->visitLayer(large, occlusion);
3006 EXPECT_RECT_EQ(IntRect(IntPoint(), trackingSize), occlusion.occlusionInScreenSpace().bounds());
3007 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
3008 EXPECT_RECT_EQ(IntRect(IntPoint(), trackingSize), occlusion.occlusionInTargetSurface().bounds());
3009 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
3013 ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestMinimumTrackingSize);
3015 } // namespace