Add Sad Tab resources to the iOS build.
[chromium-blink-merge.git] / cc / occlusion_tracker_unittest.cc
blobbabd9cd82f10761377766e94ab6936ee63757bdc
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 "cc/occlusion_tracker.h"
9 #include "cc/layer.h"
10 #include "cc/layer_animation_controller.h"
11 #include "cc/layer_impl.h"
12 #include "cc/layer_tree_host_common.h"
13 #include "cc/math_util.h"
14 #include "cc/overdraw_metrics.h"
15 #include "cc/single_thread_proxy.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/geometry_test_utils.h"
18 #include "cc/test/occlusion_tracker_test_common.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include <public/WebFilterOperation.h>
22 #include <public/WebFilterOperations.h>
23 #include <public/WebTransformationMatrix.h>
25 using namespace cc;
26 using namespace WebKit;
27 using namespace WebKitTests;
29 namespace {
31 class TestContentLayer : public Layer {
32 public:
33 TestContentLayer()
34 : Layer()
35 , m_overrideOpaqueContentsRect(false)
39 virtual bool drawsContent() const OVERRIDE { return true; }
40 virtual Region visibleContentOpaqueRegion() const OVERRIDE
42 if (m_overrideOpaqueContentsRect)
43 return gfx::IntersectRects(m_opaqueContentsRect, visibleContentRect());
44 return Layer::visibleContentOpaqueRegion();
46 void setOpaqueContentsRect(const gfx::Rect& opaqueContentsRect)
48 m_overrideOpaqueContentsRect = true;
49 m_opaqueContentsRect = opaqueContentsRect;
52 private:
53 virtual ~TestContentLayer()
57 bool m_overrideOpaqueContentsRect;
58 gfx::Rect m_opaqueContentsRect;
61 class TestContentLayerImpl : public LayerImpl {
62 public:
63 TestContentLayerImpl(int id)
64 : LayerImpl(id)
65 , m_overrideOpaqueContentsRect(false)
67 setDrawsContent(true);
70 virtual Region visibleContentOpaqueRegion() const OVERRIDE
72 if (m_overrideOpaqueContentsRect)
73 return gfx::IntersectRects(m_opaqueContentsRect, visibleContentRect());
74 return LayerImpl::visibleContentOpaqueRegion();
76 void setOpaqueContentsRect(const gfx::Rect& opaqueContentsRect)
78 m_overrideOpaqueContentsRect = true;
79 m_opaqueContentsRect = opaqueContentsRect;
82 private:
83 bool m_overrideOpaqueContentsRect;
84 gfx::Rect m_opaqueContentsRect;
87 static inline bool layerImplDrawTransformIsUnknown(const Layer* layer) { return layer->drawTransformIsAnimating(); }
88 static inline bool layerImplDrawTransformIsUnknown(const LayerImpl*) { return false; }
90 template<typename LayerType, typename RenderSurfaceType>
91 class TestOcclusionTrackerWithClip : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> {
92 public:
93 TestOcclusionTrackerWithClip(gfx::Rect viewportRect, bool recordMetricsForFrame = false)
94 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewportRect, recordMetricsForFrame)
95 , m_overrideLayerClipRect(false)
99 void setLayerClipRect(const gfx::Rect& rect) { m_overrideLayerClipRect = true; m_layerClipRect = rect;}
100 void useDefaultLayerClipRect() { m_overrideLayerClipRect = false; }
101 // Returns true if the given rect in content space for the layer is fully occluded in either screen space or the layer's target surface.
102 bool occludedLayer(const LayerType* layer, const gfx::Rect& contentRect, bool* hasOcclusionFromOutsideTargetSurface = 0) const
104 return this->occluded(layer->renderTarget(), contentRect, layer->drawTransform(), layerImplDrawTransformIsUnknown(layer), layerClipRectInTarget(layer), hasOcclusionFromOutsideTargetSurface);
106 // Gives an unoccluded sub-rect of |contentRect| in the content space of the layer. Simple wrapper around unoccludedContentRect.
107 gfx::Rect unoccludedLayerContentRect(const LayerType* layer, const gfx::Rect& contentRect, bool* hasOcclusionFromOutsideTargetSurface = 0) const
109 return this->unoccludedContentRect(layer->renderTarget(), contentRect, layer->drawTransform(), layerImplDrawTransformIsUnknown(layer), layerClipRectInTarget(layer), hasOcclusionFromOutsideTargetSurface);
113 protected:
114 virtual gfx::Rect layerClipRectInTarget(const LayerType* layer) const { return m_overrideLayerClipRect ? m_layerClipRect : OcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTarget(layer); }
116 private:
117 bool m_overrideLayerClipRect;
118 gfx::Rect m_layerClipRect;
121 struct OcclusionTrackerTestMainThreadTypes {
122 typedef Layer LayerType;
123 typedef RenderSurface RenderSurfaceType;
124 typedef TestContentLayer ContentLayerType;
125 typedef scoped_refptr<Layer> LayerPtrType;
126 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
127 typedef LayerIterator<Layer, std::vector<scoped_refptr<Layer> >, RenderSurface, LayerIteratorActions::FrontToBack> TestLayerIterator;
128 typedef OcclusionTracker OcclusionTrackerType;
130 static LayerPtrType createLayer()
132 return Layer::create();
134 static ContentLayerPtrType createContentLayer() { return make_scoped_refptr(new ContentLayerType()); }
136 static LayerPtrType passLayerPtr(ContentLayerPtrType& layer)
138 return layer.release();
141 static LayerPtrType passLayerPtr(LayerPtrType& layer)
143 return layer.release();
146 static void destroyLayer(LayerPtrType& layer)
148 layer = NULL;
152 struct OcclusionTrackerTestImplThreadTypes {
153 typedef LayerImpl LayerType;
154 typedef RenderSurfaceImpl RenderSurfaceType;
155 typedef TestContentLayerImpl ContentLayerType;
156 typedef scoped_ptr<LayerImpl> LayerPtrType;
157 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
158 typedef LayerIterator<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl, LayerIteratorActions::FrontToBack> TestLayerIterator;
159 typedef OcclusionTrackerImpl OcclusionTrackerType;
161 static LayerPtrType createLayer() { return LayerImpl::create(nextLayerImplId++); }
162 static ContentLayerPtrType createContentLayer() { return make_scoped_ptr(new ContentLayerType(nextLayerImplId++)); }
163 static int nextLayerImplId;
165 static LayerPtrType passLayerPtr(LayerPtrType& layer)
167 return layer.Pass();
170 static LayerPtrType passLayerPtr(ContentLayerPtrType& layer)
172 return layer.PassAs<LayerType>();
175 static void destroyLayer(LayerPtrType& layer)
177 layer.reset();
181 int OcclusionTrackerTestImplThreadTypes::nextLayerImplId = 1;
183 template<typename Types>
184 class OcclusionTrackerTest : public testing::Test {
185 protected:
186 OcclusionTrackerTest(bool opaqueLayers)
187 : m_opaqueLayers(opaqueLayers)
190 virtual void runMyTest() = 0;
192 virtual void TearDown()
194 Types::destroyLayer(m_root);
195 m_renderSurfaceLayerList.clear();
196 m_renderSurfaceLayerListImpl.clear();
197 m_replicaLayers.clear();
198 m_maskLayers.clear();
199 LayerTreeHost::setNeedsFilterContext(false);
202 typename Types::ContentLayerType* createRoot(const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds)
204 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
205 typename Types::ContentLayerType* layerPtr = layer.get();
206 setProperties(layerPtr, transform, position, bounds);
208 DCHECK(!m_root);
209 m_root = Types::passLayerPtr(layer);
210 return layerPtr;
213 typename Types::LayerType* createLayer(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds)
215 typename Types::LayerPtrType layer(Types::createLayer());
216 typename Types::LayerType* layerPtr = layer.get();
217 setProperties(layerPtr, transform, position, bounds);
218 parent->addChild(Types::passLayerPtr(layer));
219 return layerPtr;
222 typename Types::LayerType* createSurface(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds)
224 typename Types::LayerType* layer = createLayer(parent, transform, position, bounds);
225 WebFilterOperations filters;
226 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
227 layer->setFilters(filters);
228 return layer;
231 typename Types::ContentLayerType* createDrawingLayer(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds, bool opaque)
233 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
234 typename Types::ContentLayerType* layerPtr = layer.get();
235 setProperties(layerPtr, transform, position, bounds);
237 if (m_opaqueLayers)
238 layerPtr->setContentsOpaque(opaque);
239 else {
240 layerPtr->setContentsOpaque(false);
241 if (opaque)
242 layerPtr->setOpaqueContentsRect(gfx::Rect(gfx::Point(), bounds));
243 else
244 layerPtr->setOpaqueContentsRect(gfx::Rect());
247 parent->addChild(Types::passLayerPtr(layer));
248 return layerPtr;
251 typename Types::LayerType* createReplicaLayer(typename Types::LayerType* owningLayer, const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds)
253 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
254 typename Types::ContentLayerType* layerPtr = layer.get();
255 setProperties(layerPtr, transform, position, bounds);
256 setReplica(owningLayer, Types::passLayerPtr(layer));
257 return layerPtr;
260 typename Types::LayerType* createMaskLayer(typename Types::LayerType* owningLayer, const gfx::Size& bounds)
262 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
263 typename Types::ContentLayerType* layerPtr = layer.get();
264 setProperties(layerPtr, identityMatrix, gfx::PointF(), bounds);
265 setMask(owningLayer, Types::passLayerPtr(layer));
266 return layerPtr;
269 typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds, bool opaque)
271 typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque);
272 WebFilterOperations filters;
273 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
274 layer->setFilters(filters);
275 return layer;
278 void calcDrawEtc(TestContentLayerImpl* root)
280 DCHECK(root == m_root.get());
281 int dummyMaxTextureSize = 512;
282 LayerSorter layerSorter;
284 DCHECK(!root->renderSurface());
286 LayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, 1, &layerSorter, dummyMaxTextureSize, m_renderSurfaceLayerListImpl);
288 m_layerIterator = m_layerIteratorBegin = Types::TestLayerIterator::begin(&m_renderSurfaceLayerListImpl);
291 void calcDrawEtc(TestContentLayer* root)
293 DCHECK(root == m_root.get());
294 int dummyMaxTextureSize = 512;
296 DCHECK(!root->renderSurface());
298 LayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, 1, dummyMaxTextureSize, m_renderSurfaceLayerList);
300 m_layerIterator = m_layerIteratorBegin = Types::TestLayerIterator::begin(&m_renderSurfaceLayerList);
303 void enterLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
305 ASSERT_EQ(layer, *m_layerIterator);
306 ASSERT_TRUE(m_layerIterator.representsItself());
307 occlusion.enterLayer(m_layerIterator);
310 void leaveLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
312 ASSERT_EQ(layer, *m_layerIterator);
313 ASSERT_TRUE(m_layerIterator.representsItself());
314 occlusion.leaveLayer(m_layerIterator);
315 ++m_layerIterator;
318 void visitLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
320 enterLayer(layer, occlusion);
321 leaveLayer(layer, occlusion);
324 void enterContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
326 ASSERT_EQ(layer, *m_layerIterator);
327 ASSERT_TRUE(m_layerIterator.representsTargetRenderSurface());
328 occlusion.enterLayer(m_layerIterator);
329 occlusion.leaveLayer(m_layerIterator);
330 ++m_layerIterator;
331 ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
332 occlusion.enterLayer(m_layerIterator);
335 void leaveContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
337 ASSERT_EQ(layer, *m_layerIterator);
338 ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
339 occlusion.leaveLayer(m_layerIterator);
340 ++m_layerIterator;
343 void visitContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
345 enterContributingSurface(layer, occlusion);
346 leaveContributingSurface(layer, occlusion);
349 void resetLayerIterator()
351 m_layerIterator = m_layerIteratorBegin;
354 const WebTransformationMatrix identityMatrix;
356 private:
357 void setBaseProperties(typename Types::LayerType* layer, const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds)
359 layer->setTransform(transform);
360 layer->setSublayerTransform(WebTransformationMatrix());
361 layer->setAnchorPoint(gfx::PointF(0, 0));
362 layer->setPosition(position);
363 layer->setBounds(bounds);
366 void setProperties(Layer* layer, const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds)
368 setBaseProperties(layer, transform, position, bounds);
371 void setProperties(LayerImpl* layer, const WebTransformationMatrix& transform, const gfx::PointF& position, const gfx::Size& bounds)
373 setBaseProperties(layer, transform, position, bounds);
375 layer->setContentBounds(layer->bounds());
378 void setReplica(Layer* owningLayer, scoped_refptr<Layer> layer)
380 owningLayer->setReplicaLayer(layer.get());
381 m_replicaLayers.push_back(layer);
384 void setReplica(LayerImpl* owningLayer, scoped_ptr<LayerImpl> layer)
386 owningLayer->setReplicaLayer(layer.Pass());
389 void setMask(Layer* owningLayer, scoped_refptr<Layer> layer)
391 owningLayer->setMaskLayer(layer.get());
392 m_maskLayers.push_back(layer);
395 void setMask(LayerImpl* owningLayer, scoped_ptr<LayerImpl> layer)
397 owningLayer->setMaskLayer(layer.Pass());
400 bool m_opaqueLayers;
401 // These hold ownership of the layers for the duration of the test.
402 typename Types::LayerPtrType m_root;
403 std::vector<scoped_refptr<Layer> > m_renderSurfaceLayerList;
404 std::vector<LayerImpl*> m_renderSurfaceLayerListImpl;
405 typename Types::TestLayerIterator m_layerIteratorBegin;
406 typename Types::TestLayerIterator m_layerIterator;
407 typename Types::LayerType* m_lastLayerVisited;
408 std::vector<scoped_refptr<Layer> > m_replicaLayers;
409 std::vector<scoped_refptr<Layer> > m_maskLayers;
412 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
413 class ClassName##MainThreadOpaqueLayers : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
414 public: \
415 ClassName##MainThreadOpaqueLayers() : ClassName<OcclusionTrackerTestMainThreadTypes>(true) { } \
416 }; \
417 TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
418 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
419 class ClassName##MainThreadOpaquePaints : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
420 public: \
421 ClassName##MainThreadOpaquePaints() : ClassName<OcclusionTrackerTestMainThreadTypes>(false) { } \
422 }; \
423 TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
425 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
426 class ClassName##ImplThreadOpaqueLayers : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
427 public: \
428 ClassName##ImplThreadOpaqueLayers() : ClassName<OcclusionTrackerTestImplThreadTypes>(true) { } \
429 }; \
430 TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
431 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
432 class ClassName##ImplThreadOpaquePaints : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
433 public: \
434 ClassName##ImplThreadOpaquePaints() : ClassName<OcclusionTrackerTestImplThreadTypes>(false) { } \
435 }; \
436 TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
438 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
439 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
440 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
441 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
442 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
444 #define MAIN_THREAD_TEST(ClassName) \
445 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
447 #define IMPL_THREAD_TEST(ClassName) \
448 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
450 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
451 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
452 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
454 template<class Types>
455 class OcclusionTrackerTestIdentityTransforms : public OcclusionTrackerTest<Types> {
456 protected:
457 OcclusionTrackerTestIdentityTransforms(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
459 void runMyTest()
461 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
462 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(30, 30), gfx::Size(500, 500), true);
463 this->calcDrawEtc(parent);
465 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
466 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
468 this->visitLayer(layer, occlusion);
469 this->enterLayer(parent, occlusion);
471 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString());
472 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
474 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
475 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
476 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
477 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
478 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
480 occlusion.useDefaultLayerClipRect();
481 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
482 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
483 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
484 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
485 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
486 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
488 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
489 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 30, 70, 70)));
490 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 29, 70, 70)));
491 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 29, 70, 70)));
492 EXPECT_RECT_EQ(gfx::Rect(31, 29, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 29, 70, 70)));
493 EXPECT_RECT_EQ(gfx::Rect(100, 30, 1, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 30, 70, 70)));
494 EXPECT_RECT_EQ(gfx::Rect(31, 31, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 31, 70, 70)));
495 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 31, 70, 70)));
496 EXPECT_RECT_EQ(gfx::Rect(29, 31, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 31, 70, 70)));
500 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
502 template<class Types>
503 class OcclusionTrackerTestQuadsMismatchLayer : public OcclusionTrackerTest<Types> {
504 protected:
505 OcclusionTrackerTestQuadsMismatchLayer(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
506 void runMyTest()
508 WebTransformationMatrix layerTransform;
509 layerTransform.translate(10, 10);
511 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::Point(0, 0), gfx::Size(100, 100));
512 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(parent, layerTransform, gfx::PointF(0, 0), gfx::Size(90, 90), true);
513 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(layer1, layerTransform, gfx::PointF(0, 0), gfx::Size(50, 50), true);
514 this->calcDrawEtc(parent);
516 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
518 this->visitLayer(layer2, occlusion);
519 this->enterLayer(layer1, occlusion);
521 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
522 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
524 // This checks cases where the quads don't match their "containing"
525 // layers, e.g. in terms of transforms or clip rect. This is typical for
526 // DelegatedRendererLayer.
528 WebTransformationMatrix quadTransform;
529 quadTransform.translate(30, 30);
530 gfx::Rect clipRectInTarget(0, 0, 100, 100);
532 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, gfx::Rect(0, 0, 10, 10), quadTransform, false, clipRectInTarget).IsEmpty());
533 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10), occlusion.unoccludedContentRect(parent, gfx::Rect(0, 0, 10, 10), quadTransform, true, clipRectInTarget));
534 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), occlusion.unoccludedContentRect(parent, gfx::Rect(40, 40, 10, 10), quadTransform, false, clipRectInTarget));
535 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), occlusion.unoccludedContentRect(parent, gfx::Rect(35, 30, 10, 10), quadTransform, false, clipRectInTarget));
536 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5), occlusion.unoccludedContentRect(parent, gfx::Rect(40, 40, 10, 10), quadTransform, false, gfx::Rect(0, 0, 75, 75)));
540 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
542 template<class Types>
543 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
544 protected:
545 OcclusionTrackerTestRotatedChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
546 void runMyTest()
548 WebTransformationMatrix layerTransform;
549 layerTransform.translate(250, 250);
550 layerTransform.rotate(90);
551 layerTransform.translate(-250, -250);
553 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
554 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
555 this->calcDrawEtc(parent);
557 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
558 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
560 this->visitLayer(layer, occlusion);
561 this->enterLayer(parent, occlusion);
563 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString());
564 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
566 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
567 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
568 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
569 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
570 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
572 occlusion.useDefaultLayerClipRect();
573 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
574 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
575 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
576 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
577 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
578 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
580 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
581 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 30, 70, 70)));
582 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 29, 70, 70)));
583 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 29, 70, 70)));
584 EXPECT_RECT_EQ(gfx::Rect(31, 29, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 29, 70, 70)));
585 EXPECT_RECT_EQ(gfx::Rect(100, 30, 1, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 30, 70, 70)));
586 EXPECT_RECT_EQ(gfx::Rect(31, 31, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 31, 70, 70)));
587 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 31, 70, 70)));
588 EXPECT_RECT_EQ(gfx::Rect(29, 31, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 31, 70, 70)));
592 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
594 template<class Types>
595 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
596 protected:
597 OcclusionTrackerTestTranslatedChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
598 void runMyTest()
600 WebTransformationMatrix layerTransform;
601 layerTransform.translate(20, 20);
603 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
604 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
605 this->calcDrawEtc(parent);
607 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
608 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
610 this->visitLayer(layer, occlusion);
611 this->enterLayer(parent, occlusion);
613 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
614 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
616 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
617 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
618 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
619 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(51, 50, 50, 50)));
620 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(50, 51, 50, 50)));
622 occlusion.useDefaultLayerClipRect();
623 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
624 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
625 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
626 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(51, 50, 50, 50)));
627 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(50, 51, 50, 50)));
628 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
630 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
631 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 50, 50, 50)));
632 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 49, 50, 50)));
633 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 49, 50, 50)));
634 EXPECT_RECT_EQ(gfx::Rect(51, 49, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 49, 50, 50)));
635 EXPECT_RECT_EQ(gfx::Rect(100, 50, 1, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 50, 50, 50)));
636 EXPECT_RECT_EQ(gfx::Rect(51, 51, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 51, 50, 50)));
637 EXPECT_RECT_EQ(gfx::Rect(50, 100, 50, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 51, 50, 50)));
638 EXPECT_RECT_EQ(gfx::Rect(49, 51, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 51, 50, 50)));
640 occlusion.useDefaultLayerClipRect();
641 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
642 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 50, 50, 50)));
643 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 49, 50, 50)));
644 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 49, 50, 50)));
645 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 49, 50, 50)));
646 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 50, 50, 50)).IsEmpty());
647 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 51, 50, 50)).IsEmpty());
648 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 51, 50, 50)).IsEmpty());
649 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 51, 50, 50)));
650 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
654 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
656 template<class Types>
657 class OcclusionTrackerTestChildInRotatedChild : public OcclusionTrackerTest<Types> {
658 protected:
659 OcclusionTrackerTestChildInRotatedChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
660 void runMyTest()
662 WebTransformationMatrix childTransform;
663 childTransform.translate(250, 250);
664 childTransform.rotate(90);
665 childTransform.translate(-250, -250);
667 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
668 parent->setMasksToBounds(true);
669 typename Types::LayerType* child = this->createLayer(parent, childTransform, gfx::PointF(30, 30), gfx::Size(500, 500));
670 child->setMasksToBounds(true);
671 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, gfx::PointF(10, 10), gfx::Size(500, 500), true);
672 this->calcDrawEtc(parent);
674 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
675 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
677 this->visitLayer(layer, occlusion);
678 this->enterContributingSurface(child, occlusion);
680 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInScreenSpace().ToString());
681 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
683 this->leaveContributingSurface(child, occlusion);
684 this->enterLayer(parent, occlusion);
686 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInScreenSpace().ToString());
687 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInTargetSurface().ToString());
689 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
690 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
691 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
692 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(31, 40, 70, 60)));
693 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 41, 70, 60)));
695 occlusion.useDefaultLayerClipRect();
696 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
697 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
698 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
699 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(31, 40, 70, 60)));
700 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 41, 70, 60)));
701 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
704 /* Justification for the above occlusion from |layer|:
706 +---------------------+ +---------------------+
707 | | | |30 Visible region of |layer|: /////
708 | 30 | rotate(90) | |
709 | 30 + ---------------------------------+ | +---------------------------------+
710 100 | | 10 | | ==> | | |10 |
711 | |10+---------------------------------+ | +---------------------------------+ |
712 | | | | | | | | |///////////////| 420 | |
713 | | | | | | | | |///////////////|60 | |
714 | | | | | | | | |///////////////| | |
715 +----|--|-------------+ | | +--|--|---------------+ | |
716 | | | | 20|10| 70 | |
717 | | | | | | | |
718 | | | |500 | | | |
719 | | | | | | | |
720 | | | | | | | |
721 | | | | | | | |
722 | | | | | | |10|
723 +--|-------------------------------+ | | +------------------------------|--+
724 | | | 490 |
725 +---------------------------------+ +---------------------------------+
726 500 500
731 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
733 template<class Types>
734 class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest<Types> {
735 protected:
736 OcclusionTrackerTestScaledRenderSurface(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
738 void runMyTest()
740 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200));
742 WebTransformationMatrix layer1Matrix;
743 layer1Matrix.scale(2);
744 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(parent, layer1Matrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
745 layer1->setForceRenderSurface(true);
747 WebTransformationMatrix layer2Matrix;
748 layer2Matrix.translate(25, 25);
749 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(layer1, layer2Matrix, gfx::PointF(0, 0), gfx::Size(50, 50), true);
750 typename Types::ContentLayerType* occluder = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 100), gfx::Size(500, 500), true);
751 this->calcDrawEtc(parent);
753 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
755 this->visitLayer(occluder, occlusion);
756 this->enterLayer(layer2, occlusion);
758 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusionInScreenSpace().ToString());
759 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString());
761 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
762 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25), occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(10, 25, 25, 25)));
763 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15), occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(25, 10, 25, 25)));
764 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
768 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
770 template<class Types>
771 class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest<Types> {
772 protected:
773 OcclusionTrackerTestVisitTargetTwoTimes(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
774 void runMyTest()
776 WebTransformationMatrix childTransform;
777 childTransform.translate(250, 250);
778 childTransform.rotate(90);
779 childTransform.translate(-250, -250);
781 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
782 parent->setMasksToBounds(true);
783 typename Types::LayerType* child = this->createLayer(parent, childTransform, gfx::PointF(30, 30), gfx::Size(500, 500));
784 child->setMasksToBounds(true);
785 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, gfx::PointF(10, 10), gfx::Size(500, 500), true);
786 // |child2| makes |parent|'s surface get considered by OcclusionTracker first, instead of |child|'s. This exercises different code in
787 // leaveToTargetRenderSurface, as the target surface has already been seen.
788 typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(30, 30), gfx::Size(60, 20), true);
789 this->calcDrawEtc(parent);
791 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
792 occlusion.setLayerClipRect(gfx::Rect(-10, -10, 1000, 1000));
794 this->visitLayer(child2, occlusion);
796 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion.occlusionInScreenSpace().ToString());
797 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion.occlusionInTargetSurface().ToString());
799 this->visitLayer(layer, occlusion);
801 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionInScreenSpace().ToString());
802 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
804 this->enterContributingSurface(child, occlusion);
806 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionInScreenSpace().ToString());
807 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
809 // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
810 this->leaveContributingSurface(child, occlusion);
811 this->enterLayer(parent, occlusion);
813 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionInScreenSpace().ToString());
814 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionInTargetSurface().ToString());
816 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
817 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 70, 70)));
819 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
820 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
821 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
822 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
823 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
825 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
826 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
827 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
829 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
830 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 30, 60, 10)));
831 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 29, 60, 10)));
832 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 30, 60, 10)));
833 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
835 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
836 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 40, 70, 60)));
837 // This rect is mostly occluded by |child2|.
838 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 39, 70, 60)));
839 // This rect extends past top/right ends of |child2|.
840 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 29, 70, 70)));
841 // This rect extends past left/right ends of |child2|.
842 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(20, 39, 80, 60)));
843 EXPECT_RECT_EQ(gfx::Rect(100, 40, 1, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 40, 70, 60)));
844 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 41, 70, 60)));
846 /* Justification for the above occlusion from |layer|:
848 +---------------------+ +---------------------+
849 | | | |30 Visible region of |layer|: /////
850 | 30 | rotate(90) | 30 60 | |child2|: \\\\\
851 | 30 + ------------+--------------------+ | 30 +------------+--------------------+
852 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
853 | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
854 | + ------------+ | | | | | +------------+//| 420 | |
855 | | | | | | | | |///////////////|60 | |
856 | | | | | | | | |///////////////| | |
857 +----|--|-------------+ | | +--|--|---------------+ | |
858 | | | | 20|10| 70 | |
859 | | | | | | | |
860 | | | |500 | | | |
861 | | | | | | | |
862 | | | | | | | |
863 | | | | | | | |
864 | | | | | | |10|
865 +--|-------------------------------+ | | +------------------------------|--+
866 | | | 490 |
867 +---------------------------------+ +---------------------------------+
868 500 500
873 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
875 template<class Types>
876 class OcclusionTrackerTestSurfaceRotatedOffAxis : public OcclusionTrackerTest<Types> {
877 protected:
878 OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
879 void runMyTest()
881 WebTransformationMatrix childTransform;
882 childTransform.translate(250, 250);
883 childTransform.rotate(95);
884 childTransform.translate(-250, -250);
886 WebTransformationMatrix layerTransform;
887 layerTransform.translate(10, 10);
889 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
890 typename Types::LayerType* child = this->createLayer(parent, childTransform, gfx::PointF(30, 30), gfx::Size(500, 500));
891 child->setMasksToBounds(true);
892 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, layerTransform, gfx::PointF(0, 0), gfx::Size(500, 500), true);
893 this->calcDrawEtc(parent);
895 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
896 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
898 gfx::Rect clippedLayerInChild = MathUtil::mapClippedRect(layerTransform, layer->visibleContentRect());
900 this->visitLayer(layer, occlusion);
901 this->enterContributingSurface(child, occlusion);
903 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInScreenSpace().ToString());
904 EXPECT_EQ(clippedLayerInChild.ToString(), occlusion.occlusionInTargetSurface().ToString());
906 EXPECT_TRUE(occlusion.occludedLayer(child, clippedLayerInChild));
907 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
908 clippedLayerInChild.Offset(-1, 0);
909 EXPECT_FALSE(occlusion.occludedLayer(child, clippedLayerInChild));
910 EXPECT_FALSE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
911 clippedLayerInChild.Offset(1, 0);
912 clippedLayerInChild.Offset(1, 0);
913 EXPECT_FALSE(occlusion.occludedLayer(child, clippedLayerInChild));
914 EXPECT_FALSE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
915 clippedLayerInChild.Offset(-1, 0);
916 clippedLayerInChild.Offset(0, -1);
917 EXPECT_FALSE(occlusion.occludedLayer(child, clippedLayerInChild));
918 EXPECT_FALSE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
919 clippedLayerInChild.Offset(0, 1);
920 clippedLayerInChild.Offset(0, 1);
921 EXPECT_FALSE(occlusion.occludedLayer(child, clippedLayerInChild));
922 EXPECT_FALSE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
923 clippedLayerInChild.Offset(0, -1);
925 this->leaveContributingSurface(child, occlusion);
926 this->enterLayer(parent, occlusion);
928 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInScreenSpace().ToString());
929 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString());
931 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
932 EXPECT_RECT_EQ(gfx::Rect(75, 55, 1, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
936 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
938 template<class Types>
939 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren : public OcclusionTrackerTest<Types> {
940 protected:
941 OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
942 void runMyTest()
944 WebTransformationMatrix childTransform;
945 childTransform.translate(250, 250);
946 childTransform.rotate(90);
947 childTransform.translate(-250, -250);
949 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
950 parent->setMasksToBounds(true);
951 typename Types::LayerType* child = this->createLayer(parent, childTransform, gfx::PointF(30, 30), gfx::Size(500, 500));
952 child->setMasksToBounds(true);
953 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child, this->identityMatrix, gfx::PointF(10, 10), gfx::Size(500, 500), true);
954 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child, this->identityMatrix, gfx::PointF(10, 450), gfx::Size(500, 60), true);
955 this->calcDrawEtc(parent);
957 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
958 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
960 this->visitLayer(layer2, occlusion);
961 this->visitLayer(layer1, occlusion);
962 this->enterContributingSurface(child, occlusion);
964 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInScreenSpace().ToString());
965 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
967 EXPECT_TRUE(occlusion.occludedLayer(child, gfx::Rect(10, 430, 60, 70)));
968 EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(9, 430, 60, 70)));
969 EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(10, 429, 60, 70)));
970 EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(11, 430, 60, 70)));
971 EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(10, 431, 60, 70)));
973 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
974 EXPECT_RECT_EQ(gfx::Rect(9, 430, 1, 70), occlusion.unoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
975 EXPECT_RECT_EQ(gfx::Rect(10, 429, 60, 1), occlusion.unoccludedLayerContentRect(child, gfx::Rect(10, 429, 60, 70)));
976 EXPECT_RECT_EQ(gfx::Rect(70, 430, 1, 70), occlusion.unoccludedLayerContentRect(child, gfx::Rect(11, 430, 60, 70)));
977 EXPECT_RECT_EQ(gfx::Rect(10, 500, 60, 1), occlusion.unoccludedLayerContentRect(child, gfx::Rect(10, 431, 60, 70)));
979 this->leaveContributingSurface(child, occlusion);
980 this->enterLayer(parent, occlusion);
982 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInScreenSpace().ToString());
983 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInTargetSurface().ToString());
985 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
986 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
987 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
989 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
990 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 40, 70, 60)));
991 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 39, 70, 60)));
992 EXPECT_RECT_EQ(gfx::Rect(100, 40, 1, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 40, 70, 60)));
993 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 41, 70, 60)));
995 /* Justification for the above occlusion from |layer1| and |layer2|:
997 +---------------------+
998 | |30 Visible region of |layer1|: /////
999 | | Visible region of |layer2|: \\\\\
1000 | +---------------------------------+
1001 | | |10 |
1002 | +---------------+-----------------+ |
1003 | | |\\\\\\\\\\\\|//| 420 | |
1004 | | |\\\\\\\\\\\\|//|60 | |
1005 | | |\\\\\\\\\\\\|//| | |
1006 +--|--|------------|--+ | |
1007 20|10| 70 | | |
1008 | | | | |
1009 | | | | |
1010 | | | | |
1011 | | | | |
1012 | | | | |
1013 | | | |10|
1014 | +------------|-----------------|--+
1015 | | 490 |
1016 +---------------+-----------------+
1017 60 440
1022 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1024 template<class Types>
1025 class OcclusionTrackerTestOverlappingSurfaceSiblings : public OcclusionTrackerTest<Types> {
1026 protected:
1027 OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1028 void runMyTest()
1030 WebTransformationMatrix childTransform;
1031 childTransform.translate(250, 250);
1032 childTransform.rotate(90);
1033 childTransform.translate(-250, -250);
1035 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
1036 parent->setMasksToBounds(true);
1037 typename Types::LayerType* child1 = this->createSurface(parent, childTransform, gfx::PointF(30, 30), gfx::Size(10, 10));
1038 typename Types::LayerType* child2 = this->createSurface(parent, childTransform, gfx::PointF(20, 40), gfx::Size(10, 10));
1039 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1040 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1041 this->calcDrawEtc(parent);
1043 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1044 occlusion.setLayerClipRect(gfx::Rect(-20, -20, 1000, 1000));
1046 this->visitLayer(layer2, occlusion);
1047 this->enterContributingSurface(child2, occlusion);
1049 EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(), occlusion.occlusionInScreenSpace().ToString());
1050 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusionInTargetSurface().ToString());
1052 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1053 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1054 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1055 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1056 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1058 occlusion.useDefaultLayerClipRect();
1059 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1060 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1061 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1062 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1063 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1064 occlusion.setLayerClipRect(gfx::Rect(-20, -20, 1000, 1000));
1066 // There is nothing above child2's surface in the z-order.
1067 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, gfx::Rect(-10, 420, 70, 80)));
1069 this->leaveContributingSurface(child2, occlusion);
1070 this->visitLayer(layer1, occlusion);
1071 this->enterContributingSurface(child1, occlusion);
1073 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion.occlusionInScreenSpace().ToString());
1074 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
1076 EXPECT_TRUE(occlusion.occludedLayer(child1, gfx::Rect(-10, 430, 80, 70)));
1077 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-11, 430, 80, 70)));
1078 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-10, 429, 80, 70)));
1079 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-10, 430, 81, 70)));
1080 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-10, 430, 80, 71)));
1082 // child2's contents will occlude child1 below it.
1083 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1, false, gfx::Rect(-10, 430, 80, 70)));
1085 this->leaveContributingSurface(child1, occlusion);
1086 this->enterLayer(parent, occlusion);
1088 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion.occlusionInScreenSpace().ToString());
1089 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion.occlusionInTargetSurface().ToString());
1091 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1093 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1094 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1095 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1097 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1098 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1099 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1101 /* Justification for the above occlusion:
1103 +---------------------+
1104 | 20 | layer1
1105 | 30+ ---------------------------------+
1106 100 | 30| | layer2 |
1107 |20+----------------------------------+ |
1108 | | | | | |
1109 | | | | | |
1110 | | | | | |
1111 +--|-|----------------+ | |
1112 | | | | 510
1113 | | | |
1114 | | | |
1115 | | | |
1116 | | | |
1117 | | | |
1118 | | | |
1119 | +--------------------------------|-+
1121 +----------------------------------+
1127 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1129 template<class Types>
1130 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms : public OcclusionTrackerTest<Types> {
1131 protected:
1132 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1133 void runMyTest()
1135 WebTransformationMatrix child1Transform;
1136 child1Transform.translate(250, 250);
1137 child1Transform.rotate(-90);
1138 child1Transform.translate(-250, -250);
1140 WebTransformationMatrix child2Transform;
1141 child2Transform.translate(250, 250);
1142 child2Transform.rotate(90);
1143 child2Transform.translate(-250, -250);
1145 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
1146 parent->setMasksToBounds(true);
1147 typename Types::LayerType* child1 = this->createSurface(parent, child1Transform, gfx::PointF(30, 20), gfx::Size(10, 10));
1148 typename Types::LayerType* child2 = this->createDrawingSurface(parent, child2Transform, gfx::PointF(20, 40), gfx::Size(10, 10), false);
1149 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, gfx::PointF(-10, -20), gfx::Size(510, 510), true);
1150 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1151 this->calcDrawEtc(parent);
1153 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1154 occlusion.setLayerClipRect(gfx::Rect(-30, -30, 1000, 1000));
1156 this->visitLayer(layer2, occlusion);
1157 this->enterLayer(child2, occlusion);
1159 EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(), occlusion.occlusionInScreenSpace().ToString());
1160 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusionInTargetSurface().ToString());
1162 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1163 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1164 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1165 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1166 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1168 this->leaveLayer(child2, occlusion);
1169 this->enterContributingSurface(child2, occlusion);
1171 // There is nothing above child2's surface in the z-order.
1172 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, gfx::Rect(-10, 420, 70, 80)));
1174 this->leaveContributingSurface(child2, occlusion);
1175 this->visitLayer(layer1, occlusion);
1176 this->enterContributingSurface(child1, occlusion);
1178 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion.occlusionInScreenSpace().ToString());
1179 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion.occlusionInTargetSurface().ToString());
1181 EXPECT_TRUE(occlusion.occludedLayer(child1, gfx::Rect(420, -20, 80, 90)));
1182 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(419, -20, 80, 90)));
1183 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(420, -21, 80, 90)));
1184 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(420, -19, 80, 90)));
1185 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(421, -20, 80, 90)));
1187 // child2's contents will occlude child1 below it.
1188 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1, false, gfx::Rect(420, -20, 80, 90)));
1189 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1, false, gfx::Rect(420, -10, 80, 90)));
1190 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1, false, gfx::Rect(420, -20, 70, 90)));
1192 this->leaveContributingSurface(child1, occlusion);
1193 this->enterLayer(parent, occlusion);
1195 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion.occlusionInScreenSpace().ToString());
1196 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion.occlusionInTargetSurface().ToString());
1198 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(10, 20, 90, 80)));
1199 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(9, 20, 90, 80)));
1200 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(10, 19, 90, 80)));
1201 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(11, 20, 90, 80)));
1202 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(10, 21, 90, 80)));
1204 /* Justification for the above occlusion:
1206 +---------------------+
1207 |20 | layer1
1208 10+----------------------------------+
1209 100 || 30 | layer2 |
1210 |20+----------------------------------+
1211 || | | | |
1212 || | | | |
1213 || | | | |
1214 +|-|------------------+ | |
1215 | | | | 510
1216 | | 510 | |
1217 | | | |
1218 | | | |
1219 | | | |
1220 | | | |
1221 | | 520 | |
1222 +----------------------------------+ |
1224 +----------------------------------+
1230 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1232 template<class Types>
1233 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1234 protected:
1235 OcclusionTrackerTestFilters(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1236 void runMyTest()
1238 WebTransformationMatrix layerTransform;
1239 layerTransform.translate(250, 250);
1240 layerTransform.rotate(90);
1241 layerTransform.translate(-250, -250);
1243 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
1244 parent->setMasksToBounds(true);
1245 typename Types::ContentLayerType* blurLayer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1246 typename Types::ContentLayerType* opaqueLayer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1247 typename Types::ContentLayerType* opacityLayer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1249 WebFilterOperations filters;
1250 filters.append(WebFilterOperation::createBlurFilter(10));
1251 blurLayer->setFilters(filters);
1253 filters.clear();
1254 filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
1255 opaqueLayer->setFilters(filters);
1257 filters.clear();
1258 filters.append(WebFilterOperation::createOpacityFilter(0.5));
1259 opacityLayer->setFilters(filters);
1261 this->calcDrawEtc(parent);
1263 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1264 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1266 // Opacity layer won't contribute to occlusion.
1267 this->visitLayer(opacityLayer, occlusion);
1268 this->enterContributingSurface(opacityLayer, occlusion);
1270 EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty());
1271 EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty());
1273 // And has nothing to contribute to its parent surface.
1274 this->leaveContributingSurface(opacityLayer, occlusion);
1275 EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty());
1276 EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty());
1278 // Opaque layer will contribute to occlusion.
1279 this->visitLayer(opaqueLayer, occlusion);
1280 this->enterContributingSurface(opaqueLayer, occlusion);
1282 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString());
1283 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
1285 // And it gets translated to the parent surface.
1286 this->leaveContributingSurface(opaqueLayer, occlusion);
1287 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString());
1288 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
1290 // The blur layer needs to throw away any occlusion from outside its subtree.
1291 this->enterLayer(blurLayer, occlusion);
1292 EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty());
1293 EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty());
1295 // And it won't contribute to occlusion.
1296 this->leaveLayer(blurLayer, occlusion);
1297 this->enterContributingSurface(blurLayer, occlusion);
1298 EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty());
1299 EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty());
1301 // But the opaque layer's occlusion is preserved on the parent.
1302 this->leaveContributingSurface(blurLayer, occlusion);
1303 this->enterLayer(parent, occlusion);
1304 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString());
1305 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString());
1309 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1311 template<class Types>
1312 class OcclusionTrackerTestReplicaDoesOcclude : public OcclusionTrackerTest<Types> {
1313 protected:
1314 OcclusionTrackerTestReplicaDoesOcclude(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1315 void runMyTest()
1317 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
1318 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1319 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(50, 50), gfx::Size());
1320 this->calcDrawEtc(parent);
1322 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1323 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1325 this->visitLayer(surface, occlusion);
1327 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
1328 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
1330 this->visitContributingSurface(surface, occlusion);
1331 this->enterLayer(parent, occlusion);
1333 // The surface and replica should both be occluding the parent.
1334 EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 50)).ToString(), occlusion.occlusionInTargetSurface().ToString());
1338 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1340 template<class Types>
1341 class OcclusionTrackerTestReplicaWithClipping : public OcclusionTrackerTest<Types> {
1342 protected:
1343 OcclusionTrackerTestReplicaWithClipping(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1344 void runMyTest()
1346 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 170));
1347 parent->setMasksToBounds(true);
1348 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1349 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(50, 50), gfx::Size());
1350 this->calcDrawEtc(parent);
1352 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1353 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1355 this->visitLayer(surface, occlusion);
1357 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
1358 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
1360 this->visitContributingSurface(surface, occlusion);
1361 this->enterLayer(parent, occlusion);
1363 // The surface and replica should both be occluding the parent.
1364 EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 20)).ToString(), occlusion.occlusionInTargetSurface().ToString());
1368 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1370 template<class Types>
1371 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1372 protected:
1373 OcclusionTrackerTestReplicaWithMask(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1374 void runMyTest()
1376 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
1377 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1378 typename Types::LayerType* replica = this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(50, 50), gfx::Size());
1379 this->createMaskLayer(replica, gfx::Size(10, 10));
1380 this->calcDrawEtc(parent);
1382 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1383 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1385 this->visitLayer(surface, occlusion);
1387 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
1388 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
1390 this->visitContributingSurface(surface, occlusion);
1391 this->enterLayer(parent, occlusion);
1393 // The replica should not be occluding the parent, since it has a mask applied to it.
1394 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
1398 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1400 template<class Types>
1401 class OcclusionTrackerTestLayerClipRectOutsideChild : public OcclusionTrackerTest<Types> {
1402 protected:
1403 OcclusionTrackerTestLayerClipRectOutsideChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1404 void runMyTest()
1406 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1407 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1408 this->calcDrawEtc(parent);
1410 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1411 occlusion.setLayerClipRect(gfx::Rect(200, 100, 100, 100));
1413 this->enterLayer(layer, occlusion);
1415 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1416 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1417 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1418 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1419 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1421 occlusion.useDefaultLayerClipRect();
1422 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1423 occlusion.setLayerClipRect(gfx::Rect(200, 100, 100, 100));
1425 this->leaveLayer(layer, occlusion);
1426 this->visitContributingSurface(layer, occlusion);
1427 this->enterLayer(parent, occlusion);
1429 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1430 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1431 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1432 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1433 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1434 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1435 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1436 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1437 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1439 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
1443 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild);
1445 template<class Types>
1446 class OcclusionTrackerTestViewportRectOutsideChild : public OcclusionTrackerTest<Types> {
1447 protected:
1448 OcclusionTrackerTestViewportRectOutsideChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1449 void runMyTest()
1451 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1452 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1453 this->calcDrawEtc(parent);
1455 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(200, 100, 100, 100));
1456 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1458 this->enterLayer(layer, occlusion);
1460 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1461 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1462 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1463 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1464 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1466 occlusion.useDefaultLayerClipRect();
1467 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1468 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1470 this->leaveLayer(layer, occlusion);
1471 this->visitContributingSurface(layer, occlusion);
1472 this->enterLayer(parent, occlusion);
1474 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1475 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1476 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1477 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1478 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1479 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1480 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1481 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1482 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1484 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
1488 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild);
1490 template<class Types>
1491 class OcclusionTrackerTestLayerClipRectOverChild : public OcclusionTrackerTest<Types> {
1492 protected:
1493 OcclusionTrackerTestLayerClipRectOverChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1494 void runMyTest()
1496 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1497 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1498 this->calcDrawEtc(parent);
1500 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1501 occlusion.setLayerClipRect(gfx::Rect(100, 100, 100, 100));
1503 this->enterLayer(layer, occlusion);
1505 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1506 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1507 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1508 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1510 this->leaveLayer(layer, occlusion);
1511 this->visitContributingSurface(layer, occlusion);
1512 this->enterLayer(parent, occlusion);
1514 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1515 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1516 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1517 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1518 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1519 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1520 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1521 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1522 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1524 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1528 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild);
1530 template<class Types>
1531 class OcclusionTrackerTestViewportRectOverChild : public OcclusionTrackerTest<Types> {
1532 protected:
1533 OcclusionTrackerTestViewportRectOverChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1534 void runMyTest()
1536 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1537 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1538 this->calcDrawEtc(parent);
1540 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(100, 100, 100, 100));
1541 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1543 this->enterLayer(layer, occlusion);
1545 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1546 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1547 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1548 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1550 this->leaveLayer(layer, occlusion);
1551 this->visitContributingSurface(layer, occlusion);
1552 this->enterLayer(parent, occlusion);
1554 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1555 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1556 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1557 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1558 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1559 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1560 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1561 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1562 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1564 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1568 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild);
1570 template<class Types>
1571 class OcclusionTrackerTestLayerClipRectPartlyOverChild : public OcclusionTrackerTest<Types> {
1572 protected:
1573 OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1574 void runMyTest()
1576 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1577 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1578 this->calcDrawEtc(parent);
1580 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1581 occlusion.setLayerClipRect(gfx::Rect(50, 50, 200, 200));
1583 this->enterLayer(layer, occlusion);
1585 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1586 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1587 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1588 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1590 this->leaveLayer(layer, occlusion);
1591 this->visitContributingSurface(layer, occlusion);
1592 this->enterLayer(parent, occlusion);
1594 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1595 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1596 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1597 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1598 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1599 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1600 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1601 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1602 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1604 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
1605 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 100)));
1606 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 100, 300, 100)));
1607 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(200, 100, 100, 100)));
1608 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(100, 200, 100, 100)));
1612 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild);
1614 template<class Types>
1615 class OcclusionTrackerTestViewportRectPartlyOverChild : public OcclusionTrackerTest<Types> {
1616 protected:
1617 OcclusionTrackerTestViewportRectPartlyOverChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1618 void runMyTest()
1620 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1621 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1622 this->calcDrawEtc(parent);
1624 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(50, 50, 200, 200));
1625 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1627 this->enterLayer(layer, occlusion);
1629 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1630 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1631 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1632 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1634 this->leaveLayer(layer, occlusion);
1635 this->visitContributingSurface(layer, occlusion);
1636 this->enterLayer(parent, occlusion);
1638 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1639 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1640 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1641 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1642 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1643 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1644 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1645 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1646 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1648 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
1649 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 100)));
1650 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 100, 300, 100)));
1651 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(200, 100, 100, 100)));
1652 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(100, 200, 100, 100)));
1656 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild);
1658 template<class Types>
1659 class OcclusionTrackerTestLayerClipRectOverNothing : public OcclusionTrackerTest<Types> {
1660 protected:
1661 OcclusionTrackerTestLayerClipRectOverNothing(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1662 void runMyTest()
1664 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1665 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1666 this->calcDrawEtc(parent);
1668 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1669 occlusion.setLayerClipRect(gfx::Rect(500, 500, 100, 100));
1671 this->enterLayer(layer, occlusion);
1673 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1674 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1675 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1676 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1678 this->leaveLayer(layer, occlusion);
1679 this->visitContributingSurface(layer, occlusion);
1680 this->enterLayer(parent, occlusion);
1682 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1683 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1684 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1685 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1686 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1687 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1688 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1689 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1690 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1692 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1693 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 100)).IsEmpty());
1694 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 100, 300, 100)).IsEmpty());
1695 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(200, 100, 100, 100)).IsEmpty());
1696 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(100, 200, 100, 100)).IsEmpty());
1700 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverNothing);
1702 template<class Types>
1703 class OcclusionTrackerTestViewportRectOverNothing : public OcclusionTrackerTest<Types> {
1704 protected:
1705 OcclusionTrackerTestViewportRectOverNothing(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1706 void runMyTest()
1708 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1709 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1710 this->calcDrawEtc(parent);
1712 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(500, 500, 100, 100));
1713 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1715 this->enterLayer(layer, occlusion);
1717 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1718 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1719 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1720 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1722 this->leaveLayer(layer, occlusion);
1723 this->visitContributingSurface(layer, occlusion);
1724 this->enterLayer(parent, occlusion);
1726 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1727 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1728 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1729 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1730 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1731 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1732 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1733 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1734 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1736 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1737 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 100)).IsEmpty());
1738 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 100, 300, 100)).IsEmpty());
1739 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(200, 100, 100, 100)).IsEmpty());
1740 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(100, 200, 100, 100)).IsEmpty());
1744 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing);
1746 template<class Types>
1747 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin : public OcclusionTrackerTest<Types> {
1748 protected:
1749 OcclusionTrackerTestLayerClipRectForLayerOffOrigin(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1750 void runMyTest()
1752 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1753 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1754 this->calcDrawEtc(parent);
1756 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1757 this->enterLayer(layer, occlusion);
1759 // This layer is translated when drawn into its target. So if the clip rect given from the target surface
1760 // is not in that target space, then after translating these query rects into the target, they will fall outside
1761 // the clip and be considered occluded.
1762 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1763 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1764 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1765 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1769 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin);
1771 template<class Types>
1772 class OcclusionTrackerTestOpaqueContentsRegionEmpty : public OcclusionTrackerTest<Types> {
1773 protected:
1774 OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1775 void runMyTest()
1777 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1778 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), false);
1779 this->calcDrawEtc(parent);
1781 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1782 this->enterLayer(layer, occlusion);
1784 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1785 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1786 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1787 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1789 // Occluded since its outside the surface bounds.
1790 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1792 // Test without any clip rect.
1793 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1794 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1795 occlusion.useDefaultLayerClipRect();
1797 this->leaveLayer(layer, occlusion);
1798 this->visitContributingSurface(layer, occlusion);
1799 this->enterLayer(parent, occlusion);
1801 EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty());
1805 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1807 template<class Types>
1808 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty : public OcclusionTrackerTest<Types> {
1809 protected:
1810 OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1811 void runMyTest()
1813 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1814 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 100), gfx::Size(200, 200), false);
1815 this->calcDrawEtc(parent);
1818 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1819 layer->setOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1821 this->resetLayerIterator();
1822 this->visitLayer(layer, occlusion);
1823 this->enterLayer(parent, occlusion);
1825 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusionInScreenSpace().ToString());
1827 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1828 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1829 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1833 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1834 layer->setOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1836 this->resetLayerIterator();
1837 this->visitLayer(layer, occlusion);
1838 this->enterLayer(parent, occlusion);
1840 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion.occlusionInScreenSpace().ToString());
1842 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1843 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1844 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1848 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1849 layer->setOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1851 this->resetLayerIterator();
1852 this->visitLayer(layer, occlusion);
1853 this->enterLayer(parent, occlusion);
1855 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
1857 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1858 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1859 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1864 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1866 template<class Types>
1867 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
1868 protected:
1869 OcclusionTrackerTest3dTransform(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1870 void runMyTest()
1872 WebTransformationMatrix transform;
1873 transform.rotate3d(0, 30, 0);
1875 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1876 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1877 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, gfx::PointF(100, 100), gfx::Size(200, 200), true);
1878 this->calcDrawEtc(parent);
1880 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1881 this->enterLayer(layer, occlusion);
1883 // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
1884 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion.unoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1888 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
1890 template<class Types>
1891 class OcclusionTrackerTestUnsorted3dLayers : public OcclusionTrackerTest<Types> {
1892 protected:
1893 OcclusionTrackerTestUnsorted3dLayers(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1894 void runMyTest()
1896 // Currently, the main thread layer iterator does not iterate over 3d items in
1897 // sorted order, because layer sorting is not performed on the main thread.
1898 // Because of this, the occlusion tracker cannot assume that a 3d layer occludes
1899 // other layers that have not yet been iterated over. For now, the expected
1900 // behavior is that a 3d layer simply does not add any occlusion to the occlusion
1901 // tracker.
1903 WebTransformationMatrix translationToFront;
1904 translationToFront.translate3d(0, 0, -10);
1905 WebTransformationMatrix translationToBack;
1906 translationToFront.translate3d(0, 0, -100);
1908 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1909 typename Types::ContentLayerType* child1 = this->createDrawingLayer(parent, translationToBack, gfx::PointF(0, 0), gfx::Size(100, 100), true);
1910 typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, translationToFront, gfx::PointF(50, 50), gfx::Size(100, 100), true);
1911 parent->setPreserves3D(true);
1913 this->calcDrawEtc(parent);
1915 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1916 this->visitLayer(child2, occlusion);
1917 EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty());
1918 EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty());
1920 this->visitLayer(child1, occlusion);
1921 EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty());
1922 EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty());
1926 // This test will have different layer ordering on the impl thread; the test will only work on the main thread.
1927 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1929 template<class Types>
1930 class OcclusionTrackerTestPerspectiveTransform : public OcclusionTrackerTest<Types> {
1931 protected:
1932 OcclusionTrackerTestPerspectiveTransform(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1933 void runMyTest()
1935 WebTransformationMatrix transform;
1936 transform.translate(150, 150);
1937 transform.applyPerspective(400);
1938 transform.rotate3d(1, 0, 0, -30);
1939 transform.translate(-150, -150);
1941 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1942 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1943 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, gfx::PointF(100, 100), gfx::Size(200, 200), true);
1944 container->setPreserves3D(true);
1945 layer->setPreserves3D(true);
1946 this->calcDrawEtc(parent);
1948 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1949 this->enterLayer(layer, occlusion);
1951 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion.unoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1955 // 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.
1956 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
1958 template<class Types>
1959 class OcclusionTrackerTestPerspectiveTransformBehindCamera : public OcclusionTrackerTest<Types> {
1960 protected:
1961 OcclusionTrackerTestPerspectiveTransformBehindCamera(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1962 void runMyTest()
1964 // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
1965 WebTransformationMatrix transform;
1966 transform.translate(250, 50);
1967 transform.applyPerspective(10);
1968 transform.translate(-250, -50);
1969 transform.translate(250, 50);
1970 transform.rotate3d(1, 0, 0, -167);
1971 transform.translate(-250, -50);
1973 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(500, 100));
1974 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(500, 500));
1975 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, gfx::PointF(0, 0), gfx::Size(500, 500), true);
1976 container->setPreserves3D(true);
1977 layer->setPreserves3D(true);
1978 this->calcDrawEtc(parent);
1980 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1981 this->enterLayer(layer, occlusion);
1983 // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
1984 // this will include many more pixels but must include at least the bottom 11 rows.
1985 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(layer, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
1989 // 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.
1990 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
1992 template<class Types>
1993 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude : public OcclusionTrackerTest<Types> {
1994 protected:
1995 OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1996 void runMyTest()
1998 WebTransformationMatrix transform;
1999 transform.translate(50, 50);
2000 transform.applyPerspective(100);
2001 transform.translate3d(0, 0, 110);
2002 transform.translate(-50, -50);
2004 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
2005 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2006 parent->setPreserves3D(true);
2007 layer->setPreserves3D(true);
2008 this->calcDrawEtc(parent);
2010 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2012 // The |layer| is entirely behind the camera and should not occlude.
2013 this->visitLayer(layer, occlusion);
2014 this->enterLayer(parent, occlusion);
2015 EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty());
2016 EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty());
2020 // 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.
2021 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2023 template<class Types>
2024 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect : public OcclusionTrackerTest<Types> {
2025 protected:
2026 OcclusionTrackerTestLargePixelsOccludeInsideClipRect(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2027 void runMyTest()
2029 WebTransformationMatrix transform;
2030 transform.translate(50, 50);
2031 transform.applyPerspective(100);
2032 transform.translate3d(0, 0, 99);
2033 transform.translate(-50, -50);
2035 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
2036 parent->setMasksToBounds(true);
2037 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2038 parent->setPreserves3D(true);
2039 layer->setPreserves3D(true);
2040 this->calcDrawEtc(parent);
2042 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2044 // This is very close to the camera, so pixels in its visibleContentRect will actually go outside of the layer's clipRect.
2045 // Ensure that those pixels don't occlude things outside the clipRect.
2046 this->visitLayer(layer, occlusion);
2047 this->enterLayer(parent, occlusion);
2048 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString());
2049 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInScreenSpace().ToString());
2053 // 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.
2054 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2056 template<class Types>
2057 class OcclusionTrackerTestAnimationOpacity1OnMainThread : public OcclusionTrackerTest<Types> {
2058 protected:
2059 OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2060 void runMyTest()
2062 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
2063 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2064 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2065 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2066 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2067 typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2068 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(250, 0), gfx::Size(50, 300), true);
2070 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 0, 1, false);
2071 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 0, 1, false);
2072 this->calcDrawEtc(parent);
2074 EXPECT_TRUE(layer->drawOpacityIsAnimating());
2075 EXPECT_FALSE(surface->drawOpacityIsAnimating());
2076 EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
2078 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2080 this->visitLayer(topmost, occlusion);
2081 this->enterLayer(parent2, occlusion);
2082 // This occlusion will affect all surfaces.
2083 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent2, gfx::Rect(0, 0, 300, 300)));
2084 this->leaveLayer(parent2, occlusion);
2086 this->visitLayer(surfaceChild2, occlusion);
2087 this->enterLayer(surfaceChild, occlusion);
2088 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), occlusion.unoccludedLayerContentRect(surfaceChild, gfx::Rect(0, 0, 300, 300)));
2089 this->leaveLayer(surfaceChild, occlusion);
2090 this->enterLayer(surface, occlusion);
2091 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2092 this->leaveLayer(surface, occlusion);
2094 this->enterContributingSurface(surface, occlusion);
2095 // Occlusion within the surface is lost when leaving the animating surface.
2096 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 300, 300)));
2097 this->leaveContributingSurface(surface, occlusion);
2099 this->visitLayer(layer, occlusion);
2100 this->enterLayer(parent, occlusion);
2102 // Occlusion is not added for the animating |layer|.
2103 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2107 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2109 template<class Types>
2110 class OcclusionTrackerTestAnimationOpacity0OnMainThread : public OcclusionTrackerTest<Types> {
2111 protected:
2112 OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2113 void runMyTest()
2115 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
2116 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2117 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2118 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2119 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2120 typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2121 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(250, 0), gfx::Size(50, 300), true);
2123 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 1, 0, false);
2124 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 1, 0, false);
2125 this->calcDrawEtc(parent);
2127 EXPECT_TRUE(layer->drawOpacityIsAnimating());
2128 EXPECT_FALSE(surface->drawOpacityIsAnimating());
2129 EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
2131 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2133 this->visitLayer(topmost, occlusion);
2134 this->enterLayer(parent2, occlusion);
2135 // This occlusion will affect all surfaces.
2136 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2137 this->leaveLayer(parent2, occlusion);
2139 this->visitLayer(surfaceChild2, occlusion);
2140 this->enterLayer(surfaceChild, occlusion);
2141 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), occlusion.unoccludedLayerContentRect(surfaceChild, gfx::Rect(0, 0, 300, 300)));
2142 this->leaveLayer(surfaceChild, occlusion);
2143 this->enterLayer(surface, occlusion);
2144 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2145 this->leaveLayer(surface, occlusion);
2147 this->enterContributingSurface(surface, occlusion);
2148 // Occlusion within the surface is lost when leaving the animating surface.
2149 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 300, 300)));
2150 this->leaveContributingSurface(surface, occlusion);
2152 this->visitLayer(layer, occlusion);
2153 this->enterLayer(parent, occlusion);
2155 // Occlusion is not added for the animating |layer|.
2156 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2160 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2162 template<class Types>
2163 class OcclusionTrackerTestAnimationTranslateOnMainThread : public OcclusionTrackerTest<Types> {
2164 protected:
2165 OcclusionTrackerTestAnimationTranslateOnMainThread(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2166 void runMyTest()
2168 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
2169 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2170 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2171 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2172 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2173 typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(50, 300), true);
2175 addAnimatedTransformToController(*layer->layerAnimationController(), 10, 30, 0);
2176 addAnimatedTransformToController(*surface->layerAnimationController(), 10, 30, 0);
2177 addAnimatedTransformToController(*surfaceChild->layerAnimationController(), 10, 30, 0);
2178 this->calcDrawEtc(parent);
2180 EXPECT_TRUE(layer->drawTransformIsAnimating());
2181 EXPECT_TRUE(layer->screenSpaceTransformIsAnimating());
2182 EXPECT_TRUE(surface->renderSurface()->targetSurfaceTransformsAreAnimating());
2183 EXPECT_TRUE(surface->renderSurface()->screenSpaceTransformsAreAnimating());
2184 // The surface owning layer doesn't animate against its own surface.
2185 EXPECT_FALSE(surface->drawTransformIsAnimating());
2186 EXPECT_TRUE(surface->screenSpaceTransformIsAnimating());
2187 EXPECT_TRUE(surfaceChild->drawTransformIsAnimating());
2188 EXPECT_TRUE(surfaceChild->screenSpaceTransformIsAnimating());
2190 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2192 this->visitLayer(surface2, occlusion);
2193 this->enterContributingSurface(surface2, occlusion);
2195 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionInScreenSpace().ToString());
2197 this->leaveContributingSurface(surface2, occlusion);
2198 this->enterLayer(surfaceChild2, occlusion);
2200 // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2201 // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer.
2202 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300), occlusion.unoccludedLayerContentRect(surfaceChild2, gfx::Rect(0, 0, 100, 300)));
2203 EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 50, 300)));
2205 this->leaveLayer(surfaceChild2, occlusion);
2206 this->enterLayer(surfaceChild, occlusion);
2207 EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 100, 300)));
2208 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionInScreenSpace().ToString());
2209 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusionInTargetSurface().ToString());
2210 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2212 // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target and the screen, so it
2213 // can't be occluded.
2214 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300), occlusion.unoccludedLayerContentRect(surfaceChild, gfx::Rect(0, 0, 200, 300)));
2215 EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 50, 300)));
2217 this->leaveLayer(surfaceChild, occlusion);
2218 this->enterLayer(surface, occlusion);
2219 // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2220 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionInScreenSpace().ToString());
2221 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusionInTargetSurface().ToString());
2222 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2224 this->leaveLayer(surface, occlusion);
2225 // 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.
2226 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionInScreenSpace().ToString());
2227 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), occlusion.occlusionInTargetSurface().ToString());
2228 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2230 this->enterContributingSurface(surface, occlusion);
2231 // The contributing |surface| is animating so it can't be occluded.
2232 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 300, 300)));
2233 this->leaveContributingSurface(surface, occlusion);
2235 this->enterLayer(layer, occlusion);
2236 // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
2237 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2238 this->leaveLayer(layer, occlusion);
2240 this->enterLayer(parent, occlusion);
2241 // The |layer| is animating in the screen and in its target, so no occlusion is added.
2242 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2246 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
2248 template<class Types>
2249 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent : public OcclusionTrackerTest<Types> {
2250 protected:
2251 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2252 void runMyTest()
2254 WebTransformationMatrix surfaceTransform;
2255 surfaceTransform.translate(300, 300);
2256 surfaceTransform.scale(2);
2257 surfaceTransform.translate(-150, -150);
2259 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(500, 500));
2260 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, surfaceTransform, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2261 typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(50, 50), gfx::Size(300, 300), false);
2262 surface->setOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2263 surface2->setOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2264 this->calcDrawEtc(parent);
2266 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2268 this->visitLayer(surface2, occlusion);
2269 this->visitContributingSurface(surface2, occlusion);
2271 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion.occlusionInScreenSpace().ToString());
2272 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion.occlusionInTargetSurface().ToString());
2274 // Clear any stored occlusion.
2275 occlusion.setOcclusionInScreenSpace(Region());
2276 occlusion.setOcclusionInTargetSurface(Region());
2278 this->visitLayer(surface, occlusion);
2279 this->visitContributingSurface(surface, occlusion);
2281 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion.occlusionInScreenSpace().ToString());
2282 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion.occlusionInTargetSurface().ToString());
2286 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2288 template<class Types>
2289 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping : public OcclusionTrackerTest<Types> {
2290 protected:
2291 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2292 void runMyTest()
2294 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
2295 parent->setMasksToBounds(true);
2296 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(500, 300), false);
2297 surface->setOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2298 this->calcDrawEtc(parent);
2300 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2302 this->visitLayer(surface, occlusion);
2303 this->visitContributingSurface(surface, occlusion);
2305 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion.occlusionInScreenSpace().ToString());
2306 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion.occlusionInTargetSurface().ToString());
2310 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2312 template<class Types>
2313 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
2314 protected:
2315 OcclusionTrackerTestReplicaOccluded(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2316 void runMyTest()
2318 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2319 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2320 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(100, 100));
2321 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(100, 100), true);
2322 this->calcDrawEtc(parent);
2324 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2325 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2327 // |topmost| occludes the replica, but not the surface itself.
2328 this->visitLayer(topmost, occlusion);
2330 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion.occlusionInScreenSpace().ToString());
2331 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString());
2333 this->visitLayer(surface, occlusion);
2335 EXPECT_EQ(gfx::Rect(0, 0, 100, 200).ToString(), occlusion.occlusionInScreenSpace().ToString());
2336 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString());
2338 this->enterContributingSurface(surface, occlusion);
2340 // Surface is not occluded so it shouldn't think it is.
2341 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2345 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
2347 template<class Types>
2348 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded : public OcclusionTrackerTest<Types> {
2349 protected:
2350 OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2351 void runMyTest()
2353 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2354 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2355 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(100, 100));
2356 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 110), true);
2357 this->calcDrawEtc(parent);
2359 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2360 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2362 // |topmost| occludes the surface, but not the entire surface's replica.
2363 this->visitLayer(topmost, occlusion);
2365 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionInScreenSpace().ToString());
2366 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionInTargetSurface().ToString());
2368 this->visitLayer(surface, occlusion);
2370 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionInScreenSpace().ToString());
2371 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString());
2373 this->enterContributingSurface(surface, occlusion);
2375 // Surface is occluded, but only the top 10px of the replica.
2376 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2377 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, true, gfx::Rect(0, 0, 100, 100)));
2381 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2383 template<class Types>
2384 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently : public OcclusionTrackerTest<Types> {
2385 protected:
2386 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2387 void runMyTest()
2389 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2390 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2391 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(100, 100));
2392 typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(40, 100), true);
2393 typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(50, 100), true);
2394 this->calcDrawEtc(parent);
2396 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2397 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2399 // These occlude the surface and replica differently, so we can test each one.
2400 this->visitLayer(overReplica, occlusion);
2401 this->visitLayer(overSurface, occlusion);
2403 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionInScreenSpace().ToString());
2404 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionInTargetSurface().ToString());
2406 this->visitLayer(surface, occlusion);
2408 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionInScreenSpace().ToString());
2409 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString());
2411 this->enterContributingSurface(surface, occlusion);
2413 // Surface and replica are occluded different amounts.
2414 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2415 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, true, gfx::Rect(0, 0, 100, 100)));
2419 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2421 template<class Types>
2422 class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest<Types> {
2423 protected:
2424 OcclusionTrackerTestSurfaceChildOfSurface(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2425 void runMyTest()
2427 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2429 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2430 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2431 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, gfx::PointF(0, 10), gfx::Size(100, 50), true);
2432 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 50), true);
2433 this->calcDrawEtc(parent);
2435 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(-100, -100, 1000, 1000));
2437 // |topmost| occludes everything partially so we know occlusion is happening at all.
2438 this->visitLayer(topmost, occlusion);
2440 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
2441 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
2443 this->visitLayer(surfaceChild, occlusion);
2445 // surfaceChild increases the occlusion in the screen by a narrow sliver.
2446 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), occlusion.occlusionInScreenSpace().ToString());
2447 // In its own surface, surfaceChild is at 0,0 as is its occlusion.
2448 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
2450 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2451 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2452 // as its parent does not have a clipRect.
2454 this->enterContributingSurface(surfaceChild, occlusion);
2455 // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
2456 // does not get clipped away inappropriately.
2457 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, gfx::Rect(0, 0, 100, 50)));
2458 this->leaveContributingSurface(surfaceChild, occlusion);
2460 // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
2461 this->enterLayer(surface, occlusion);
2462 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), occlusion.occlusionInScreenSpace().ToString());
2463 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
2464 this->leaveLayer(surface, occlusion);
2466 this->enterContributingSurface(surface, occlusion);
2467 // The surface's parent does have a clipRect as it is the root layer.
2468 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2472 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2474 template<class Types>
2475 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport : public OcclusionTrackerTest<Types> {
2476 protected:
2477 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2478 void runMyTest()
2480 // This test verifies that the top-most surface is considered occluded outside of its target's clipRect and outside the viewport rect.
2482 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2483 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2484 this->calcDrawEtc(parent);
2487 // Make a viewport rect that is larger than the root layer.
2488 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2490 this->visitLayer(surface, occlusion);
2492 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2493 this->enterContributingSurface(surface, occlusion);
2494 // Make sure the parent's clipRect clips the unoccluded region of the child surface.
2495 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 300)));
2497 this->resetLayerIterator();
2499 // Make a viewport rect that is smaller than the root layer.
2500 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 100, 100));
2502 this->visitLayer(surface, occlusion);
2504 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2505 this->enterContributingSurface(surface, occlusion);
2506 // Make sure the viewport rect clips the unoccluded region of the child surface.
2507 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 300)));
2512 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
2514 template<class Types>
2515 class OcclusionTrackerTestSurfaceChildOfClippingSurface : public OcclusionTrackerTest<Types> {
2516 protected:
2517 OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2518 void runMyTest()
2520 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2522 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(80, 200));
2523 parent->setMasksToBounds(true);
2524 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2525 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), false);
2526 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 50), true);
2527 this->calcDrawEtc(parent);
2529 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2530 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2532 // |topmost| occludes everything partially so we know occlusion is happening at all.
2533 this->visitLayer(topmost, occlusion);
2535 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
2536 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionInTargetSurface().ToString());
2538 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2539 this->visitLayer(surfaceChild, occlusion);
2541 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionInScreenSpace().ToString());
2542 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(), occlusion.occlusionInTargetSurface().ToString());
2544 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2545 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2546 // as its parent does not have a clipRect.
2548 this->enterContributingSurface(surfaceChild, occlusion);
2549 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
2550 EXPECT_RECT_EQ(gfx::Rect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, gfx::Rect(0, 0, 100, 100)));
2551 this->leaveContributingSurface(surfaceChild, occlusion);
2553 this->visitLayer(surface, occlusion);
2554 this->enterContributingSurface(surface, occlusion);
2555 // The surface's parent does have a clipRect as it is the root layer.
2556 EXPECT_RECT_EQ(gfx::Rect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2560 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
2562 template<class Types>
2563 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter : public OcclusionTrackerTest<Types> {
2564 protected:
2565 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2566 void runMyTest()
2568 WebTransformationMatrix scaleByHalf;
2569 scaleByHalf.scale(0.5);
2571 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2572 // 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
2573 // appears at 50, 50 and the replica at 200, 50.
2574 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2575 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2576 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(300, 0), gfx::Size());
2577 typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 50), true);
2578 typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(300, 50), true);
2579 typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 50), gfx::Size(50, 50), true);
2580 typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 50), gfx::Size(100, 50), true);
2581 typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(250, 50), gfx::Size(50, 50), true);
2583 // Filters make the layer own a surface.
2584 WebFilterOperations filters;
2585 filters.append(WebFilterOperation::createBlurFilter(10));
2586 filteredSurface->setBackgroundFilters(filters);
2588 // Save the distance of influence for the blur effect.
2589 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2590 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2592 this->calcDrawEtc(parent);
2594 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2595 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2597 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2598 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2599 this->visitLayer(occludingLayer5, occlusion);
2600 this->visitLayer(occludingLayer4, occlusion);
2601 this->visitLayer(occludingLayer3, occlusion);
2602 this->visitLayer(occludingLayer2, occlusion);
2603 this->visitLayer(occludingLayer1, occlusion);
2605 Region expectedOcclusion;
2606 expectedOcclusion.Union(gfx::Rect(0, 0, 300, 50));
2607 expectedOcclusion.Union(gfx::Rect(0, 50, 50, 50));
2608 expectedOcclusion.Union(gfx::Rect(100, 50, 100, 50));
2609 expectedOcclusion.Union(gfx::Rect(250, 50, 50, 50));
2610 expectedOcclusion.Union(gfx::Rect(0, 100, 300, 50));
2612 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString());
2613 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInTargetSurface().ToString());
2615 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2616 this->enterLayer(filteredSurface, occlusion);
2617 EXPECT_RECT_EQ(gfx::Rect(1, 0, 99, 100), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(1, 0, 100, 100)));
2618 EXPECT_RECT_EQ(gfx::Rect(0, 1, 100, 99), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(0, 1, 100, 100)));
2619 EXPECT_RECT_EQ(gfx::Rect(0, 0, 99, 100), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(-1, 0, 100, 100)));
2620 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 99), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(0, -1, 100, 100)));
2622 EXPECT_RECT_EQ(gfx::Rect(300 + 1, 0, 99, 100), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(300 + 1, 0, 100, 100)));
2623 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 1, 100, 99), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(300 + 0, 1, 100, 100)));
2624 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 0, 99, 100), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(300 - 1, 0, 100, 100)));
2625 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 0, 100, 99), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(300 + 0, -1, 100, 100)));
2626 this->leaveLayer(filteredSurface, occlusion);
2628 // The filtered layer/replica does not occlude.
2629 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString());
2630 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString());
2632 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2633 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2634 this->visitContributingSurface(filteredSurface, occlusion);
2636 this->enterLayer(parent, occlusion);
2638 Region expectedBlurredOcclusion;
2639 expectedBlurredOcclusion.Union(gfx::Rect(0, 0, 300, 50 - outsetTop));
2640 expectedBlurredOcclusion.Union(gfx::Rect(0, 50 - outsetTop, 50 - outsetLeft, 50 + outsetTop + outsetBottom));
2641 expectedBlurredOcclusion.Union(gfx::Rect(100 + outsetRight, 50 - outsetTop, 100 - outsetRight - outsetLeft, 50 + outsetTop + outsetBottom));
2642 expectedBlurredOcclusion.Union(gfx::Rect(250 + outsetRight, 50 - outsetTop, 50 - outsetRight, 50 + outsetTop + outsetBottom));
2643 expectedBlurredOcclusion.Union(gfx::Rect(0, 100 + outsetBottom, 300, 50 - outsetBottom));
2645 EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString());
2646 EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionInTargetSurface().ToString());
2648 gfx::Rect outsetRect;
2649 gfx::Rect testRect;
2651 // Nothing in the blur outsets for the filteredSurface is occluded.
2652 outsetRect = gfx::Rect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2653 testRect = outsetRect;
2654 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2656 // Stuff outside the blur outsets is still occluded though.
2657 testRect = outsetRect;
2658 testRect.Inset(0, 0, -1, 0);
2659 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2660 testRect = outsetRect;
2661 testRect.Inset(0, 0, 0, -1);
2662 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2663 testRect = outsetRect;
2664 testRect.Inset(-1, 0, 0, 0);
2665 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2666 testRect = outsetRect;
2667 testRect.Inset(0, -1, 0, 0);
2668 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2670 // Nothing in the blur outsets for the filteredSurface's replica is occluded.
2671 outsetRect = gfx::Rect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2672 testRect = outsetRect;
2673 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2675 // Stuff outside the blur outsets is still occluded though.
2676 testRect = outsetRect;
2677 testRect.Inset(0, 0, -1, 0);
2678 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2679 testRect = outsetRect;
2680 testRect.Inset(0, 0, 0, -1);
2681 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2682 testRect = outsetRect;
2683 testRect.Inset(-1, 0, 0, 0);
2684 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2685 testRect = outsetRect;
2686 testRect.Inset(0, -1, 0, 0);
2687 EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect));
2691 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2693 template<class Types>
2694 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice : public OcclusionTrackerTest<Types> {
2695 protected:
2696 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2697 void runMyTest()
2699 WebTransformationMatrix scaleByHalf;
2700 scaleByHalf.scale(0.5);
2702 // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
2703 typename Types::ContentLayerType* root = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(75, 75));
2704 typename Types::LayerType* parent = this->createSurface(root, scaleByHalf, gfx::PointF(0, 0), gfx::Size(150, 150));
2705 parent->setMasksToBounds(true);
2706 typename Types::LayerType* filteredSurface1 = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2707 typename Types::LayerType* filteredSurface2 = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2708 typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 100), gfx::Size(50, 50), true);
2710 // Filters make the layers own surfaces.
2711 WebFilterOperations filters;
2712 filters.append(WebFilterOperation::createBlurFilter(1));
2713 filteredSurface1->setBackgroundFilters(filters);
2714 filteredSurface2->setBackgroundFilters(filters);
2716 // Save the distance of influence for the blur effect.
2717 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2718 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2720 this->calcDrawEtc(root);
2722 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2723 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2725 this->visitLayer(occludingLayerAbove, occlusion);
2726 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion.occlusionInScreenSpace().ToString());
2727 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion.occlusionInTargetSurface().ToString());
2729 this->visitLayer(filteredSurface2, occlusion);
2730 this->visitContributingSurface(filteredSurface2, occlusion);
2731 this->visitLayer(filteredSurface1, occlusion);
2732 this->visitContributingSurface(filteredSurface1, occlusion);
2734 // Test expectations in the target.
2735 gfx::Rect expectedOcclusion = gfx::Rect(100 / 2 + outsetRight * 2, 100 / 2 + outsetBottom * 2, 50 / 2 - (outsetLeft + outsetRight) * 2, 50 / 2 - (outsetTop + outsetBottom) * 2);
2736 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInTargetSurface().ToString());
2738 // Test expectations in the screen are the same as in the target, as the render surface is 1:1 with the screen.
2739 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString());
2743 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
2745 template<class Types>
2746 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip : public OcclusionTrackerTest<Types> {
2747 protected:
2748 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2749 void runMyTest()
2751 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2752 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2753 // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
2754 // the background filter.
2755 typename Types::LayerType* clippingSurface = this->createSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 70));
2756 clippingSurface->setMasksToBounds(true);
2757 typename Types::LayerType* filteredSurface = this->createDrawingLayer(clippingSurface, this->identityMatrix, gfx::PointF(50, 50), gfx::Size(50, 50), false);
2758 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(150, 0), gfx::Size());
2759 typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 50), true);
2760 typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(300, 50), true);
2761 typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 50), gfx::Size(50, 50), true);
2762 typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 50), gfx::Size(100, 50), true);
2763 typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(250, 50), gfx::Size(50, 50), true);
2765 // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
2766 WebFilterOperations filters;
2767 filters.append(WebFilterOperation::createBlurFilter(12));
2768 filteredSurface->setBackgroundFilters(filters);
2770 // Save the distance of influence for the blur effect.
2771 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2772 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2774 this->calcDrawEtc(parent);
2776 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2777 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2779 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2780 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2781 this->visitLayer(occludingLayer5, occlusion);
2782 this->visitLayer(occludingLayer4, occlusion);
2783 this->visitLayer(occludingLayer3, occlusion);
2784 this->visitLayer(occludingLayer2, occlusion);
2785 this->visitLayer(occludingLayer1, occlusion);
2787 Region expectedOcclusion;
2788 expectedOcclusion.Union(gfx::Rect(0, 0, 300, 50));
2789 expectedOcclusion.Union(gfx::Rect(0, 50, 50, 50));
2790 expectedOcclusion.Union(gfx::Rect(100, 50, 100, 50));
2791 expectedOcclusion.Union(gfx::Rect(250, 50, 50, 50));
2792 expectedOcclusion.Union(gfx::Rect(0, 100, 300, 50));
2794 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString());
2795 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInTargetSurface().ToString());
2797 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2798 this->enterLayer(filteredSurface, occlusion);
2799 EXPECT_RECT_EQ(gfx::Rect(1, 0, 49, 50), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(1, 0, 50, 50)));
2800 EXPECT_RECT_EQ(gfx::Rect(0, 1, 50, 49), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(0, 1, 50, 50)));
2801 EXPECT_RECT_EQ(gfx::Rect(0, 0, 49, 50), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(-1, 0, 50, 50)));
2802 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 49), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(0, -1, 50, 50)));
2804 EXPECT_RECT_EQ(gfx::Rect(150 + 1, 0, 49, 50), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(150 + 1, 0, 50, 50)));
2805 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 1, 50, 49), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(150 + 0, 1, 50, 50)));
2806 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 0, 49, 50), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(150 - 1, 0, 50, 50)));
2807 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 0, 50, 49), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(150 + 0, -1, 50, 50)));
2808 this->leaveLayer(filteredSurface, occlusion);
2810 // The filtered layer/replica does not occlude.
2811 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString());
2812 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString());
2814 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2815 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2816 this->visitContributingSurface(filteredSurface, occlusion);
2818 this->enterContributingSurface(clippingSurface, occlusion);
2820 Region expectedBlurredOcclusion;
2821 expectedBlurredOcclusion.Union(gfx::Rect(0, 0, 300, 50 - outsetTop));
2822 expectedBlurredOcclusion.Union(gfx::Rect(0, 50 - outsetTop, 50 - outsetLeft, 20 + outsetTop + outsetBottom));
2823 expectedBlurredOcclusion.Union(gfx::Rect(100 + outsetRight, 50 - outsetTop, 100 - outsetRight - outsetLeft, 20 + outsetTop + outsetBottom));
2824 expectedBlurredOcclusion.Union(gfx::Rect(250 + outsetRight, 50 - outsetTop, 50 - outsetRight, 20 + outsetTop + outsetBottom));
2825 expectedBlurredOcclusion.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
2827 EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString());
2828 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString());
2830 gfx::Rect outsetRect;
2831 gfx::Rect clippedOutsetRect;
2832 gfx::Rect testRect;
2834 // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
2835 outsetRect = gfx::Rect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2836 clippedOutsetRect = gfx::IntersectRects(outsetRect, gfx::Rect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2837 testRect = outsetRect;
2838 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2840 // Stuff outside the (clipped) blur outsets is still occluded though.
2841 testRect = outsetRect;
2842 testRect.Inset(0, 0, -1, 0);
2843 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2844 testRect = outsetRect;
2845 testRect.Inset(0, 0, 0, -1);
2846 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2847 testRect = outsetRect;
2848 testRect.Inset(-1, 0, 0, 0);
2849 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2850 testRect = outsetRect;
2851 testRect.Inset(0, -1, 0, 0);
2852 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2854 // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
2855 outsetRect = gfx::Rect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2856 clippedOutsetRect = gfx::IntersectRects(outsetRect, gfx::Rect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2857 testRect = outsetRect;
2858 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2860 // Stuff outside the (clipped) blur outsets is still occluded though.
2861 testRect = outsetRect;
2862 testRect.Inset(0, 0, -1, 0);
2863 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2864 testRect = outsetRect;
2865 testRect.Inset(0, 0, 0, -1);
2866 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2867 testRect = outsetRect;
2868 testRect.Inset(-1, 0, 0, 0);
2869 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2870 testRect = outsetRect;
2871 testRect.Inset(0, -1, 0, 0);
2872 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2876 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
2878 template<class Types>
2879 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter : public OcclusionTrackerTest<Types> {
2880 protected:
2881 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2882 void runMyTest()
2884 WebTransformationMatrix scaleByHalf;
2885 scaleByHalf.scale(0.5);
2887 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
2888 // 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
2889 // appears at 50, 50 and the replica at 200, 50.
2890 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2891 typename Types::LayerType* behindSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(60, 60), gfx::Size(30, 30), true);
2892 typename Types::LayerType* behindReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(210, 60), gfx::Size(30, 30), true);
2893 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2894 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(300, 0), gfx::Size());
2896 // Filters make the layer own a surface.
2897 WebFilterOperations filters;
2898 filters.append(WebFilterOperation::createBlurFilter(3));
2899 filteredSurface->setBackgroundFilters(filters);
2901 this->calcDrawEtc(parent);
2903 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2904 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2906 // The surface has a background blur, so it blurs non-opaque pixels below it.
2907 this->visitLayer(filteredSurface, occlusion);
2908 this->visitContributingSurface(filteredSurface, occlusion);
2910 this->visitLayer(behindReplicaLayer, occlusion);
2911 this->visitLayer(behindSurfaceLayer, occlusion);
2913 // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
2914 // So it should not be modified by the filter here.
2915 gfx::Rect occlusionBehindSurface = gfx::Rect(60, 60, 30, 30);
2916 gfx::Rect occlusionBehindReplica = gfx::Rect(210, 60, 30, 30);
2918 Region expectedOpaqueBounds = UnionRegions(occlusionBehindSurface, occlusionBehindReplica);
2919 EXPECT_EQ(expectedOpaqueBounds.ToString(), occlusion.occlusionInScreenSpace().ToString());
2920 EXPECT_EQ(expectedOpaqueBounds.ToString(), occlusion.occlusionInTargetSurface().ToString());
2924 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
2926 template<class Types>
2927 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded : public OcclusionTrackerTest<Types> {
2928 protected:
2929 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2930 void runMyTest()
2932 WebTransformationMatrix scaleByHalf;
2933 scaleByHalf.scale(0.5);
2935 // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
2936 // 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
2937 // appears at 50, 50 and the replica at 200, 50.
2938 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2939 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2940 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(300, 0), gfx::Size());
2941 typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(50, 50), gfx::Size(50, 50), true);
2942 typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(200, 50), gfx::Size(50, 50), true);
2944 // Filters make the layer own a surface.
2945 WebFilterOperations filters;
2946 filters.append(WebFilterOperation::createBlurFilter(3));
2947 filteredSurface->setBackgroundFilters(filters);
2949 this->calcDrawEtc(parent);
2951 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2952 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2954 this->visitLayer(aboveReplicaLayer, occlusion);
2955 this->visitLayer(aboveSurfaceLayer, occlusion);
2957 // The surface has a background blur, so it blurs non-opaque pixels below it.
2958 this->visitLayer(filteredSurface, occlusion);
2959 this->visitContributingSurface(filteredSurface, occlusion);
2961 // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
2962 gfx::Rect occlusionAboveSurface = gfx::Rect(50, 50, 50, 50);
2963 gfx::Rect occlusionAboveReplica = gfx::Rect(200, 50, 50, 50);
2965 Region expectedOpaqueRegion = UnionRegions(occlusionAboveSurface, occlusionAboveReplica);
2966 EXPECT_EQ(expectedOpaqueRegion, occlusion.occlusionInScreenSpace());
2967 EXPECT_EQ(expectedOpaqueRegion, occlusion.occlusionInTargetSurface());
2971 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
2973 template<class Types>
2974 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded : public OcclusionTrackerTest<Types> {
2975 protected:
2976 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2977 void runMyTest()
2979 WebTransformationMatrix scaleByHalf;
2980 scaleByHalf.scale(0.5);
2982 // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
2983 // 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
2984 // appears at 50, 50 and the replica at 200, 50.
2985 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2986 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2987 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(300, 0), gfx::Size());
2988 typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(70, 50), gfx::Size(30, 50), true);
2989 typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(200, 50), gfx::Size(30, 50), true);
2990 typename Types::LayerType* besideSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(90, 40), gfx::Size(10, 10), true);
2991 typename Types::LayerType* besideReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(200, 40), gfx::Size(10, 10), true);
2993 // Filters make the layer own a surface.
2994 WebFilterOperations filters;
2995 filters.append(WebFilterOperation::createBlurFilter(3));
2996 filteredSurface->setBackgroundFilters(filters);
2998 // Save the distance of influence for the blur effect.
2999 int outsetTop, outsetRight, outsetBottom, outsetLeft;
3000 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
3002 this->calcDrawEtc(parent);
3004 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
3005 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
3007 this->visitLayer(besideReplicaLayer, occlusion);
3008 this->visitLayer(besideSurfaceLayer, occlusion);
3009 this->visitLayer(aboveReplicaLayer, occlusion);
3010 this->visitLayer(aboveSurfaceLayer, occlusion);
3012 // The surface has a background blur, so it blurs non-opaque pixels below it.
3013 this->visitLayer(filteredSurface, occlusion);
3014 this->visitContributingSurface(filteredSurface, occlusion);
3016 // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
3017 // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
3018 // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
3019 // the occluded part of the surface.
3020 gfx::Rect occlusionAboveSurface = gfx::Rect(70 + outsetRight, 50, 30 - outsetRight, 50);
3021 gfx::Rect occlusionAboveReplica = gfx::Rect(200, 50, 30 - outsetLeft, 50);
3022 gfx::Rect occlusionBesideSurface = gfx::Rect(90, 40, 10, 10);
3023 gfx::Rect occlusionBesideReplica = gfx::Rect(200, 40, 10, 10);
3025 Region expectedOcclusion;
3026 expectedOcclusion.Union(occlusionAboveSurface);
3027 expectedOcclusion.Union(occlusionAboveReplica);
3028 expectedOcclusion.Union(occlusionBesideSurface);
3029 expectedOcclusion.Union(occlusionBesideReplica);
3031 ASSERT_EQ(expectedOcclusion, occlusion.occlusionInTargetSurface());
3032 ASSERT_EQ(expectedOcclusion, occlusion.occlusionInScreenSpace());
3034 Region::Iterator expectedRects(expectedOcclusion);
3035 Region::Iterator screenSpaceRects(occlusion.occlusionInScreenSpace());
3036 Region::Iterator targetSurfaceRects(occlusion.occlusionInTargetSurface());
3037 for (; expectedRects.has_rect(); expectedRects.next(), screenSpaceRects.next(), targetSurfaceRects.next()) {
3038 ASSERT_TRUE(screenSpaceRects.has_rect());
3039 ASSERT_TRUE(targetSurfaceRects.has_rect());
3040 EXPECT_EQ(expectedRects.rect(), screenSpaceRects.rect());
3041 EXPECT_EQ(expectedRects.rect(), targetSurfaceRects.rect());
3046 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
3048 template<class Types>
3049 class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest<Types> {
3050 protected:
3051 OcclusionTrackerTestMinimumTrackingSize(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
3052 void runMyTest()
3054 gfx::Size trackingSize(100, 100);
3055 gfx::Size belowTrackingSize(99, 99);
3057 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(400, 400));
3058 typename Types::LayerType* large = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), trackingSize, true);
3059 typename Types::LayerType* small = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), belowTrackingSize, true);
3060 this->calcDrawEtc(parent);
3062 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
3063 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
3064 occlusion.setMinimumTrackingSize(trackingSize);
3066 // The small layer is not tracked because it is too small.
3067 this->visitLayer(small, occlusion);
3069 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInScreenSpace().ToString());
3070 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString());
3072 // The large layer is tracked as it is large enough.
3073 this->visitLayer(large, occlusion);
3075 EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize).ToString(), occlusion.occlusionInScreenSpace().ToString());
3076 EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize).ToString(), occlusion.occlusionInTargetSurface().ToString());
3080 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
3082 } // anonymous namespace