WebKit Roll 139512:139548
[chromium-blink-merge.git] / cc / occlusion_tracker_unittest.cc
blobbc1b4cdc2a560a3922bf4b436ccf4ec635c9a247
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 "cc/occlusion_tracker.h"
7 #include "cc/layer.h"
8 #include "cc/layer_animation_controller.h"
9 #include "cc/layer_impl.h"
10 #include "cc/layer_tree_host_common.h"
11 #include "cc/math_util.h"
12 #include "cc/overdraw_metrics.h"
13 #include "cc/single_thread_proxy.h"
14 #include "cc/test/animation_test_common.h"
15 #include "cc/test/fake_impl_proxy.h"
16 #include "cc/test/fake_layer_tree_host_impl.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 "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.h"
22 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h"
23 #include "ui/gfx/transform.h"
25 namespace cc {
26 namespace {
28 class TestContentLayer : public Layer {
29 public:
30 TestContentLayer()
31 : Layer()
32 , m_overrideOpaqueContentsRect(false)
36 virtual bool drawsContent() const OVERRIDE { return true; }
37 virtual Region visibleContentOpaqueRegion() const OVERRIDE
39 if (m_overrideOpaqueContentsRect)
40 return gfx::IntersectRects(m_opaqueContentsRect, visibleContentRect());
41 return Layer::visibleContentOpaqueRegion();
43 void setOpaqueContentsRect(const gfx::Rect& opaqueContentsRect)
45 m_overrideOpaqueContentsRect = true;
46 m_opaqueContentsRect = opaqueContentsRect;
49 private:
50 virtual ~TestContentLayer()
54 bool m_overrideOpaqueContentsRect;
55 gfx::Rect m_opaqueContentsRect;
58 class TestContentLayerImpl : public LayerImpl {
59 public:
60 TestContentLayerImpl(LayerTreeImpl* treeImpl, int id)
61 : LayerImpl(treeImpl, id)
62 , m_overrideOpaqueContentsRect(false)
64 setDrawsContent(true);
67 virtual Region visibleContentOpaqueRegion() const OVERRIDE
69 if (m_overrideOpaqueContentsRect)
70 return gfx::IntersectRects(m_opaqueContentsRect, visibleContentRect());
71 return LayerImpl::visibleContentOpaqueRegion();
73 void setOpaqueContentsRect(const gfx::Rect& opaqueContentsRect)
75 m_overrideOpaqueContentsRect = true;
76 m_opaqueContentsRect = opaqueContentsRect;
79 private:
80 bool m_overrideOpaqueContentsRect;
81 gfx::Rect m_opaqueContentsRect;
84 static inline bool layerImplDrawTransformIsUnknown(const Layer* layer) { return layer->drawTransformIsAnimating(); }
85 static inline bool layerImplDrawTransformIsUnknown(const LayerImpl*) { return false; }
87 template<typename LayerType, typename RenderSurfaceType>
88 class TestOcclusionTrackerWithClip : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> {
89 public:
90 TestOcclusionTrackerWithClip(gfx::Rect viewportRect, bool recordMetricsForFrame = false)
91 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewportRect, recordMetricsForFrame)
92 , m_overrideLayerClipRect(false)
96 void setLayerClipRect(const gfx::Rect& rect) { m_overrideLayerClipRect = true; m_layerClipRect = rect;}
97 void useDefaultLayerClipRect() { m_overrideLayerClipRect = false; }
98 // 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.
99 bool occludedLayer(const LayerType* layer, const gfx::Rect& contentRect, bool* hasOcclusionFromOutsideTargetSurface = 0) const
101 return this->occluded(layer->renderTarget(), contentRect, layer->drawTransform(), layerImplDrawTransformIsUnknown(layer), layerClipRectInTarget(layer), hasOcclusionFromOutsideTargetSurface);
103 // Gives an unoccluded sub-rect of |contentRect| in the content space of the layer. Simple wrapper around unoccludedContentRect.
104 gfx::Rect unoccludedLayerContentRect(const LayerType* layer, const gfx::Rect& contentRect, bool* hasOcclusionFromOutsideTargetSurface = 0) const
106 return this->unoccludedContentRect(layer->renderTarget(), contentRect, layer->drawTransform(), layerImplDrawTransformIsUnknown(layer), layerClipRectInTarget(layer), hasOcclusionFromOutsideTargetSurface);
110 protected:
111 virtual gfx::Rect layerClipRectInTarget(const LayerType* layer) const { return m_overrideLayerClipRect ? m_layerClipRect : OcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTarget(layer); }
113 private:
114 bool m_overrideLayerClipRect;
115 gfx::Rect m_layerClipRect;
118 struct OcclusionTrackerTestMainThreadTypes {
119 typedef Layer LayerType;
120 typedef LayerTreeHost HostType;
121 typedef RenderSurface RenderSurfaceType;
122 typedef TestContentLayer ContentLayerType;
123 typedef scoped_refptr<Layer> LayerPtrType;
124 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
125 typedef LayerIterator<Layer, std::vector<scoped_refptr<Layer> >, RenderSurface, LayerIteratorActions::FrontToBack> TestLayerIterator;
126 typedef OcclusionTracker OcclusionTrackerType;
128 static LayerPtrType createLayer(HostType*)
130 return Layer::create();
132 static ContentLayerPtrType createContentLayer(HostType*) { return make_scoped_refptr(new ContentLayerType()); }
134 static LayerPtrType passLayerPtr(ContentLayerPtrType& layer)
136 LayerPtrType ref(layer);
137 layer = NULL;
138 return ref;
141 static LayerPtrType passLayerPtr(LayerPtrType& layer)
143 LayerPtrType ref(layer);
144 layer = NULL;
145 return ref;
148 static void destroyLayer(LayerPtrType& layer)
150 layer = NULL;
154 struct OcclusionTrackerTestImplThreadTypes {
155 typedef LayerImpl LayerType;
156 typedef LayerTreeImpl HostType;
157 typedef RenderSurfaceImpl RenderSurfaceType;
158 typedef TestContentLayerImpl ContentLayerType;
159 typedef scoped_ptr<LayerImpl> LayerPtrType;
160 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
161 typedef LayerIterator<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl, LayerIteratorActions::FrontToBack> TestLayerIterator;
162 typedef OcclusionTrackerImpl OcclusionTrackerType;
164 static LayerPtrType createLayer(HostType* host) { return LayerImpl::create(host, nextLayerImplId++); }
165 static ContentLayerPtrType createContentLayer(HostType* host) { return make_scoped_ptr(new ContentLayerType(host, nextLayerImplId++)); }
166 static int nextLayerImplId;
168 static LayerPtrType passLayerPtr(LayerPtrType& layer)
170 return layer.Pass();
173 static LayerPtrType passLayerPtr(ContentLayerPtrType& layer)
175 return layer.PassAs<LayerType>();
178 static void destroyLayer(LayerPtrType& layer)
180 layer.reset();
184 int OcclusionTrackerTestImplThreadTypes::nextLayerImplId = 1;
186 template<typename Types>
187 class OcclusionTrackerTest : public testing::Test {
188 protected:
189 OcclusionTrackerTest(bool opaqueLayers)
190 : m_hostImpl(&m_proxy)
191 , m_opaqueLayers(opaqueLayers)
195 virtual void runMyTest() = 0;
197 virtual void TearDown()
199 Types::destroyLayer(m_root);
200 m_renderSurfaceLayerList.clear();
201 m_renderSurfaceLayerListImpl.clear();
202 m_replicaLayers.clear();
203 m_maskLayers.clear();
204 LayerTreeHost::setNeedsFilterContext(false);
207 typename Types::HostType* getHost();
209 typename Types::ContentLayerType* createRoot(const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds)
211 typename Types::ContentLayerPtrType layer(Types::createContentLayer(getHost()));
212 typename Types::ContentLayerType* layerPtr = layer.get();
213 setProperties(layerPtr, transform, position, bounds);
215 DCHECK(!m_root);
216 m_root = Types::passLayerPtr(layer);
217 return layerPtr;
220 typename Types::LayerType* createLayer(typename Types::LayerType* parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds)
222 typename Types::LayerPtrType layer(Types::createLayer(getHost()));
223 typename Types::LayerType* layerPtr = layer.get();
224 setProperties(layerPtr, transform, position, bounds);
225 parent->addChild(Types::passLayerPtr(layer));
226 return layerPtr;
229 typename Types::LayerType* createSurface(typename Types::LayerType* parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds)
231 typename Types::LayerType* layer = createLayer(parent, transform, position, bounds);
232 WebKit::WebFilterOperations filters;
233 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5));
234 layer->setFilters(filters);
235 return layer;
238 typename Types::ContentLayerType* createDrawingLayer(typename Types::LayerType* parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds, bool opaque)
240 typename Types::ContentLayerPtrType layer(Types::createContentLayer(getHost()));
241 typename Types::ContentLayerType* layerPtr = layer.get();
242 setProperties(layerPtr, transform, position, bounds);
244 if (m_opaqueLayers)
245 layerPtr->setContentsOpaque(opaque);
246 else {
247 layerPtr->setContentsOpaque(false);
248 if (opaque)
249 layerPtr->setOpaqueContentsRect(gfx::Rect(gfx::Point(), bounds));
250 else
251 layerPtr->setOpaqueContentsRect(gfx::Rect());
254 parent->addChild(Types::passLayerPtr(layer));
255 return layerPtr;
258 typename Types::LayerType* createReplicaLayer(typename Types::LayerType* owningLayer, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds)
260 typename Types::ContentLayerPtrType layer(Types::createContentLayer(getHost()));
261 typename Types::ContentLayerType* layerPtr = layer.get();
262 setProperties(layerPtr, transform, position, bounds);
263 setReplica(owningLayer, Types::passLayerPtr(layer));
264 return layerPtr;
267 typename Types::LayerType* createMaskLayer(typename Types::LayerType* owningLayer, const gfx::Size& bounds)
269 typename Types::ContentLayerPtrType layer(Types::createContentLayer(getHost()));
270 typename Types::ContentLayerType* layerPtr = layer.get();
271 setProperties(layerPtr, identityMatrix, gfx::PointF(), bounds);
272 setMask(owningLayer, Types::passLayerPtr(layer));
273 return layerPtr;
276 typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds, bool opaque)
278 typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque);
279 WebKit::WebFilterOperations filters;
280 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5));
281 layer->setFilters(filters);
282 return layer;
285 void calcDrawEtc(TestContentLayerImpl* root)
287 DCHECK(root == m_root.get());
288 int dummyMaxTextureSize = 512;
290 DCHECK(!root->renderSurface());
292 LayerTreeHostCommon::calculateDrawProperties(root, root->bounds(), 1, 1, dummyMaxTextureSize, false, m_renderSurfaceLayerListImpl);
294 m_layerIterator = m_layerIteratorBegin = Types::TestLayerIterator::begin(&m_renderSurfaceLayerListImpl);
297 void calcDrawEtc(TestContentLayer* root)
299 DCHECK(root == m_root.get());
300 int dummyMaxTextureSize = 512;
302 DCHECK(!root->renderSurface());
304 LayerTreeHostCommon::calculateDrawProperties(root, root->bounds(), 1, 1, dummyMaxTextureSize, false, m_renderSurfaceLayerList);
306 m_layerIterator = m_layerIteratorBegin = Types::TestLayerIterator::begin(&m_renderSurfaceLayerList);
309 void enterLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
311 ASSERT_EQ(layer, *m_layerIterator);
312 ASSERT_TRUE(m_layerIterator.representsItself());
313 occlusion.enterLayer(m_layerIterator);
316 void leaveLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
318 ASSERT_EQ(layer, *m_layerIterator);
319 ASSERT_TRUE(m_layerIterator.representsItself());
320 occlusion.leaveLayer(m_layerIterator);
321 ++m_layerIterator;
324 void visitLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
326 enterLayer(layer, occlusion);
327 leaveLayer(layer, occlusion);
330 void enterContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
332 ASSERT_EQ(layer, *m_layerIterator);
333 ASSERT_TRUE(m_layerIterator.representsTargetRenderSurface());
334 occlusion.enterLayer(m_layerIterator);
335 occlusion.leaveLayer(m_layerIterator);
336 ++m_layerIterator;
337 ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
338 occlusion.enterLayer(m_layerIterator);
341 void leaveContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
343 ASSERT_EQ(layer, *m_layerIterator);
344 ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
345 occlusion.leaveLayer(m_layerIterator);
346 ++m_layerIterator;
349 void visitContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
351 enterContributingSurface(layer, occlusion);
352 leaveContributingSurface(layer, occlusion);
355 void resetLayerIterator()
357 m_layerIterator = m_layerIteratorBegin;
360 const gfx::Transform identityMatrix;
362 private:
363 void setBaseProperties(typename Types::LayerType* layer, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds)
365 layer->setTransform(transform);
366 layer->setSublayerTransform(gfx::Transform());
367 layer->setAnchorPoint(gfx::PointF(0, 0));
368 layer->setPosition(position);
369 layer->setBounds(bounds);
372 void setProperties(Layer* layer, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds)
374 setBaseProperties(layer, transform, position, bounds);
377 void setProperties(LayerImpl* layer, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds)
379 setBaseProperties(layer, transform, position, bounds);
381 layer->setContentBounds(layer->bounds());
384 void setReplica(Layer* owningLayer, scoped_refptr<Layer> layer)
386 owningLayer->setReplicaLayer(layer.get());
387 m_replicaLayers.push_back(layer);
390 void setReplica(LayerImpl* owningLayer, scoped_ptr<LayerImpl> layer)
392 owningLayer->setReplicaLayer(layer.Pass());
395 void setMask(Layer* owningLayer, scoped_refptr<Layer> layer)
397 owningLayer->setMaskLayer(layer.get());
398 m_maskLayers.push_back(layer);
401 void setMask(LayerImpl* owningLayer, scoped_ptr<LayerImpl> layer)
403 owningLayer->setMaskLayer(layer.Pass());
406 FakeImplProxy m_proxy;
407 FakeLayerTreeHostImpl m_hostImpl;
408 bool m_opaqueLayers;
409 // These hold ownership of the layers for the duration of the test.
410 typename Types::LayerPtrType m_root;
411 std::vector<scoped_refptr<Layer> > m_renderSurfaceLayerList;
412 std::vector<LayerImpl*> m_renderSurfaceLayerListImpl;
413 typename Types::TestLayerIterator m_layerIteratorBegin;
414 typename Types::TestLayerIterator m_layerIterator;
415 typename Types::LayerType* m_lastLayerVisited;
416 std::vector<scoped_refptr<Layer> > m_replicaLayers;
417 std::vector<scoped_refptr<Layer> > m_maskLayers;
420 template<>
421 LayerTreeHost* OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::getHost()
423 return 0;
426 template<>
427 LayerTreeImpl* OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::getHost()
429 return m_hostImpl.activeTree();
432 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
433 class ClassName##MainThreadOpaqueLayers : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
434 public: \
435 ClassName##MainThreadOpaqueLayers() : ClassName<OcclusionTrackerTestMainThreadTypes>(true) { } \
436 }; \
437 TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
438 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
439 class ClassName##MainThreadOpaquePaints : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
440 public: \
441 ClassName##MainThreadOpaquePaints() : ClassName<OcclusionTrackerTestMainThreadTypes>(false) { } \
442 }; \
443 TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
445 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
446 class ClassName##ImplThreadOpaqueLayers : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
447 public: \
448 ClassName##ImplThreadOpaqueLayers() : ClassName<OcclusionTrackerTestImplThreadTypes>(true) { } \
449 }; \
450 TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
451 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
452 class ClassName##ImplThreadOpaquePaints : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
453 public: \
454 ClassName##ImplThreadOpaquePaints() : ClassName<OcclusionTrackerTestImplThreadTypes>(false) { } \
455 }; \
456 TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
458 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
459 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
460 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
461 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
462 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
464 #define MAIN_THREAD_TEST(ClassName) \
465 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
467 #define IMPL_THREAD_TEST(ClassName) \
468 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
470 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
471 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
472 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
474 template<class Types>
475 class OcclusionTrackerTestIdentityTransforms : public OcclusionTrackerTest<Types> {
476 protected:
477 OcclusionTrackerTestIdentityTransforms(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
479 void runMyTest()
481 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
482 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(30, 30), gfx::Size(500, 500), true);
483 this->calcDrawEtc(parent);
485 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
486 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
488 this->visitLayer(layer, occlusion);
489 this->enterLayer(parent, occlusion);
491 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
492 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
494 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
495 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
496 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
497 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
498 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
500 occlusion.useDefaultLayerClipRect();
501 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
502 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
503 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
504 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
505 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
506 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
508 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
509 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 30, 70, 70)));
510 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 29, 70, 70)));
511 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 29, 70, 70)));
512 EXPECT_RECT_EQ(gfx::Rect(31, 29, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 29, 70, 70)));
513 EXPECT_RECT_EQ(gfx::Rect(100, 30, 1, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 30, 70, 70)));
514 EXPECT_RECT_EQ(gfx::Rect(31, 31, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 31, 70, 70)));
515 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 31, 70, 70)));
516 EXPECT_RECT_EQ(gfx::Rect(29, 31, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 31, 70, 70)));
520 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
522 template<class Types>
523 class OcclusionTrackerTestQuadsMismatchLayer : public OcclusionTrackerTest<Types> {
524 protected:
525 OcclusionTrackerTestQuadsMismatchLayer(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
526 void runMyTest()
528 gfx::Transform layerTransform;
529 layerTransform.Translate(10, 10);
531 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::Point(0, 0), gfx::Size(100, 100));
532 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(parent, layerTransform, gfx::PointF(0, 0), gfx::Size(90, 90), true);
533 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(layer1, layerTransform, gfx::PointF(0, 0), gfx::Size(50, 50), true);
534 this->calcDrawEtc(parent);
536 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
538 this->visitLayer(layer2, occlusion);
539 this->enterLayer(layer1, occlusion);
541 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
542 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
544 // This checks cases where the quads don't match their "containing"
545 // layers, e.g. in terms of transforms or clip rect. This is typical for
546 // DelegatedRendererLayer.
548 gfx::Transform quadTransform;
549 quadTransform.Translate(30, 30);
550 gfx::Rect clipRectInTarget(0, 0, 100, 100);
552 EXPECT_TRUE(occlusion.unoccludedContentRect(parent, gfx::Rect(0, 0, 10, 10), quadTransform, false, clipRectInTarget).IsEmpty());
553 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10), occlusion.unoccludedContentRect(parent, gfx::Rect(0, 0, 10, 10), quadTransform, true, clipRectInTarget));
554 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), occlusion.unoccludedContentRect(parent, gfx::Rect(40, 40, 10, 10), quadTransform, false, clipRectInTarget));
555 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), occlusion.unoccludedContentRect(parent, gfx::Rect(35, 30, 10, 10), quadTransform, false, clipRectInTarget));
556 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)));
560 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
562 template<class Types>
563 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
564 protected:
565 OcclusionTrackerTestRotatedChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
566 void runMyTest()
568 gfx::Transform layerTransform;
569 layerTransform.Translate(250, 250);
570 layerTransform.Rotate(90);
571 layerTransform.Translate(-250, -250);
573 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
574 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
575 this->calcDrawEtc(parent);
577 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
578 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
580 this->visitLayer(layer, occlusion);
581 this->enterLayer(parent, occlusion);
583 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
584 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
586 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
587 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
588 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
589 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
590 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
592 occlusion.useDefaultLayerClipRect();
593 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
594 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
595 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
596 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
597 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
598 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
600 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
601 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 30, 70, 70)));
602 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 29, 70, 70)));
603 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 29, 70, 70)));
604 EXPECT_RECT_EQ(gfx::Rect(31, 29, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 29, 70, 70)));
605 EXPECT_RECT_EQ(gfx::Rect(100, 30, 1, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 30, 70, 70)));
606 EXPECT_RECT_EQ(gfx::Rect(31, 31, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 31, 70, 70)));
607 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 31, 70, 70)));
608 EXPECT_RECT_EQ(gfx::Rect(29, 31, 70, 70), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 31, 70, 70)));
612 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
614 template<class Types>
615 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
616 protected:
617 OcclusionTrackerTestTranslatedChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
618 void runMyTest()
620 gfx::Transform layerTransform;
621 layerTransform.Translate(20, 20);
623 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
624 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
625 this->calcDrawEtc(parent);
627 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
628 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
630 this->visitLayer(layer, occlusion);
631 this->enterLayer(parent, occlusion);
633 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
634 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
636 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
637 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
638 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
639 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(51, 50, 50, 50)));
640 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(50, 51, 50, 50)));
642 occlusion.useDefaultLayerClipRect();
643 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
644 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
645 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
646 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(51, 50, 50, 50)));
647 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(50, 51, 50, 50)));
648 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
650 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
651 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 50, 50, 50)));
652 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 49, 50, 50)));
653 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 49, 50, 50)));
654 EXPECT_RECT_EQ(gfx::Rect(51, 49, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 49, 50, 50)));
655 EXPECT_RECT_EQ(gfx::Rect(100, 50, 1, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 50, 50, 50)));
656 EXPECT_RECT_EQ(gfx::Rect(51, 51, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 51, 50, 50)));
657 EXPECT_RECT_EQ(gfx::Rect(50, 100, 50, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 51, 50, 50)));
658 EXPECT_RECT_EQ(gfx::Rect(49, 51, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 51, 50, 50)));
660 occlusion.useDefaultLayerClipRect();
661 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
662 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 50, 50, 50)));
663 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 49, 50, 50)));
664 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 49, 50, 50)));
665 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 49, 50, 50)));
666 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 50, 50, 50)).IsEmpty());
667 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(51, 51, 50, 50)).IsEmpty());
668 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(50, 51, 50, 50)).IsEmpty());
669 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(49, 51, 50, 50)));
670 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
674 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
676 template<class Types>
677 class OcclusionTrackerTestChildInRotatedChild : public OcclusionTrackerTest<Types> {
678 protected:
679 OcclusionTrackerTestChildInRotatedChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
680 void runMyTest()
682 gfx::Transform childTransform;
683 childTransform.Translate(250, 250);
684 childTransform.Rotate(90);
685 childTransform.Translate(-250, -250);
687 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
688 parent->setMasksToBounds(true);
689 typename Types::LayerType* child = this->createLayer(parent, childTransform, gfx::PointF(30, 30), gfx::Size(500, 500));
690 child->setMasksToBounds(true);
691 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, gfx::PointF(10, 10), gfx::Size(500, 500), true);
692 this->calcDrawEtc(parent);
694 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
695 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
697 this->visitLayer(layer, occlusion);
698 this->enterContributingSurface(child, occlusion);
700 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
701 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
703 this->leaveContributingSurface(child, occlusion);
704 this->enterLayer(parent, occlusion);
706 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
707 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionFromInsideTarget().ToString());
709 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
710 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
711 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
712 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(31, 40, 70, 60)));
713 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 41, 70, 60)));
715 occlusion.useDefaultLayerClipRect();
716 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
717 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
718 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
719 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(31, 40, 70, 60)));
720 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 41, 70, 60)));
721 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
724 /* Justification for the above occlusion from |layer|:
726 +---------------------+ +---------------------+
727 | | | |30 Visible region of |layer|: /////
728 | 30 | rotate(90) | |
729 | 30 + ---------------------------------+ | +---------------------------------+
730 100 | | 10 | | ==> | | |10 |
731 | |10+---------------------------------+ | +---------------------------------+ |
732 | | | | | | | | |///////////////| 420 | |
733 | | | | | | | | |///////////////|60 | |
734 | | | | | | | | |///////////////| | |
735 +----|--|-------------+ | | +--|--|---------------+ | |
736 | | | | 20|10| 70 | |
737 | | | | | | | |
738 | | | |500 | | | |
739 | | | | | | | |
740 | | | | | | | |
741 | | | | | | | |
742 | | | | | | |10|
743 +--|-------------------------------+ | | +------------------------------|--+
744 | | | 490 |
745 +---------------------------------+ +---------------------------------+
746 500 500
751 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
753 template<class Types>
754 class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest<Types> {
755 protected:
756 OcclusionTrackerTestScaledRenderSurface(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
758 void runMyTest()
760 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200));
762 gfx::Transform layer1Matrix;
763 layer1Matrix.Scale(2, 2);
764 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(parent, layer1Matrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
765 layer1->setForceRenderSurface(true);
767 gfx::Transform layer2Matrix;
768 layer2Matrix.Translate(25, 25);
769 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(layer1, layer2Matrix, gfx::PointF(0, 0), gfx::Size(50, 50), true);
770 typename Types::ContentLayerType* occluder = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 100), gfx::Size(500, 500), true);
771 this->calcDrawEtc(parent);
773 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
775 this->visitLayer(occluder, occlusion);
776 this->enterLayer(layer2, occlusion);
778 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
779 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString());
781 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
782 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25), occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(10, 25, 25, 25)));
783 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15), occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(25, 10, 25, 25)));
784 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
788 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
790 template<class Types>
791 class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest<Types> {
792 protected:
793 OcclusionTrackerTestVisitTargetTwoTimes(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
794 void runMyTest()
796 gfx::Transform childTransform;
797 childTransform.Translate(250, 250);
798 childTransform.Rotate(90);
799 childTransform.Translate(-250, -250);
801 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
802 parent->setMasksToBounds(true);
803 typename Types::LayerType* child = this->createLayer(parent, childTransform, gfx::PointF(30, 30), gfx::Size(500, 500));
804 child->setMasksToBounds(true);
805 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, gfx::PointF(10, 10), gfx::Size(500, 500), true);
806 // |child2| makes |parent|'s surface get considered by OcclusionTracker first, instead of |child|'s. This exercises different code in
807 // leaveToTargetRenderSurface, as the target surface has already been seen.
808 typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(30, 30), gfx::Size(60, 20), true);
809 this->calcDrawEtc(parent);
811 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
812 occlusion.setLayerClipRect(gfx::Rect(-10, -10, 1000, 1000));
814 this->visitLayer(child2, occlusion);
816 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
817 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion.occlusionFromInsideTarget().ToString());
819 this->visitLayer(layer, occlusion);
821 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
822 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
824 this->enterContributingSurface(child, occlusion);
826 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
827 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
829 // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
830 this->leaveContributingSurface(child, occlusion);
831 this->enterLayer(parent, occlusion);
833 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
834 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionFromInsideTarget().ToString());
836 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
837 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 70, 70)));
839 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
840 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
841 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
842 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
843 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
845 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
846 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
847 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
849 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
850 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 30, 60, 10)));
851 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 29, 60, 10)));
852 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 30, 60, 10)));
853 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
855 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
856 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 40, 70, 60)));
857 // This rect is mostly occluded by |child2|.
858 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 39, 70, 60)));
859 // This rect extends past top/right ends of |child2|.
860 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 29, 70, 70)));
861 // This rect extends past left/right ends of |child2|.
862 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(20, 39, 80, 60)));
863 EXPECT_RECT_EQ(gfx::Rect(100, 40, 1, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 40, 70, 60)));
864 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 41, 70, 60)));
866 /* Justification for the above occlusion from |layer|:
868 +---------------------+ +---------------------+
869 | | | |30 Visible region of |layer|: /////
870 | 30 | rotate(90) | 30 60 | |child2|: \\\\\
871 | 30 + ------------+--------------------+ | 30 +------------+--------------------+
872 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
873 | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
874 | + ------------+ | | | | | +------------+//| 420 | |
875 | | | | | | | | |///////////////|60 | |
876 | | | | | | | | |///////////////| | |
877 +----|--|-------------+ | | +--|--|---------------+ | |
878 | | | | 20|10| 70 | |
879 | | | | | | | |
880 | | | |500 | | | |
881 | | | | | | | |
882 | | | | | | | |
883 | | | | | | | |
884 | | | | | | |10|
885 +--|-------------------------------+ | | +------------------------------|--+
886 | | | 490 |
887 +---------------------------------+ +---------------------------------+
888 500 500
893 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
895 template<class Types>
896 class OcclusionTrackerTestSurfaceRotatedOffAxis : public OcclusionTrackerTest<Types> {
897 protected:
898 OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
899 void runMyTest()
901 gfx::Transform childTransform;
902 childTransform.Translate(250, 250);
903 childTransform.Rotate(95);
904 childTransform.Translate(-250, -250);
906 gfx::Transform layerTransform;
907 layerTransform.Translate(10, 10);
909 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
910 typename Types::LayerType* child = this->createLayer(parent, childTransform, gfx::PointF(30, 30), gfx::Size(500, 500));
911 child->setMasksToBounds(true);
912 typename Types::ContentLayerType* layer = this->createDrawingLayer(child, layerTransform, gfx::PointF(0, 0), gfx::Size(500, 500), true);
913 this->calcDrawEtc(parent);
915 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
916 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
918 gfx::Rect clippedLayerInChild = MathUtil::mapClippedRect(layerTransform, layer->visibleContentRect());
920 this->visitLayer(layer, occlusion);
921 this->enterContributingSurface(child, occlusion);
923 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
924 EXPECT_EQ(clippedLayerInChild.ToString(), occlusion.occlusionFromInsideTarget().ToString());
926 EXPECT_TRUE(occlusion.occludedLayer(child, clippedLayerInChild));
927 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
928 clippedLayerInChild += gfx::Vector2d(-1, 0);
929 EXPECT_FALSE(occlusion.occludedLayer(child, clippedLayerInChild));
930 EXPECT_FALSE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
931 clippedLayerInChild += gfx::Vector2d(1, 0);
932 clippedLayerInChild += gfx::Vector2d(1, 0);
933 EXPECT_FALSE(occlusion.occludedLayer(child, clippedLayerInChild));
934 EXPECT_FALSE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
935 clippedLayerInChild += gfx::Vector2d(-1, 0);
936 clippedLayerInChild += gfx::Vector2d(0, -1);
937 EXPECT_FALSE(occlusion.occludedLayer(child, clippedLayerInChild));
938 EXPECT_FALSE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
939 clippedLayerInChild += gfx::Vector2d(0, 1);
940 clippedLayerInChild += gfx::Vector2d(0, 1);
941 EXPECT_FALSE(occlusion.occludedLayer(child, clippedLayerInChild));
942 EXPECT_FALSE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty());
943 clippedLayerInChild += gfx::Vector2d(0, -1);
945 this->leaveContributingSurface(child, occlusion);
946 this->enterLayer(parent, occlusion);
948 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
949 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString());
951 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
952 EXPECT_RECT_EQ(gfx::Rect(75, 55, 1, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
956 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
958 template<class Types>
959 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren : public OcclusionTrackerTest<Types> {
960 protected:
961 OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
962 void runMyTest()
964 gfx::Transform childTransform;
965 childTransform.Translate(250, 250);
966 childTransform.Rotate(90);
967 childTransform.Translate(-250, -250);
969 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
970 parent->setMasksToBounds(true);
971 typename Types::LayerType* child = this->createLayer(parent, childTransform, gfx::PointF(30, 30), gfx::Size(500, 500));
972 child->setMasksToBounds(true);
973 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child, this->identityMatrix, gfx::PointF(10, 10), gfx::Size(500, 500), true);
974 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child, this->identityMatrix, gfx::PointF(10, 450), gfx::Size(500, 60), true);
975 this->calcDrawEtc(parent);
977 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
978 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
980 this->visitLayer(layer2, occlusion);
981 this->visitLayer(layer1, occlusion);
982 this->enterContributingSurface(child, occlusion);
984 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
985 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
987 EXPECT_TRUE(occlusion.occludedLayer(child, gfx::Rect(10, 430, 60, 70)));
988 EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(9, 430, 60, 70)));
989 EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(10, 429, 60, 70)));
990 EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(11, 430, 60, 70)));
991 EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(10, 431, 60, 70)));
993 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
994 EXPECT_RECT_EQ(gfx::Rect(9, 430, 1, 70), occlusion.unoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
995 EXPECT_RECT_EQ(gfx::Rect(10, 429, 60, 1), occlusion.unoccludedLayerContentRect(child, gfx::Rect(10, 429, 60, 70)));
996 EXPECT_RECT_EQ(gfx::Rect(70, 430, 1, 70), occlusion.unoccludedLayerContentRect(child, gfx::Rect(11, 430, 60, 70)));
997 EXPECT_RECT_EQ(gfx::Rect(10, 500, 60, 1), occlusion.unoccludedLayerContentRect(child, gfx::Rect(10, 431, 60, 70)));
999 this->leaveContributingSurface(child, occlusion);
1000 this->enterLayer(parent, occlusion);
1002 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
1003 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1005 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1006 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1007 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1009 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1010 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(29, 40, 70, 60)));
1011 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 39, 70, 60)));
1012 EXPECT_RECT_EQ(gfx::Rect(100, 40, 1, 60), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(31, 40, 70, 60)));
1013 EXPECT_RECT_EQ(gfx::Rect(30, 100, 70, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 41, 70, 60)));
1015 /* Justification for the above occlusion from |layer1| and |layer2|:
1017 +---------------------+
1018 | |30 Visible region of |layer1|: /////
1019 | | Visible region of |layer2|: \\\\\
1020 | +---------------------------------+
1021 | | |10 |
1022 | +---------------+-----------------+ |
1023 | | |\\\\\\\\\\\\|//| 420 | |
1024 | | |\\\\\\\\\\\\|//|60 | |
1025 | | |\\\\\\\\\\\\|//| | |
1026 +--|--|------------|--+ | |
1027 20|10| 70 | | |
1028 | | | | |
1029 | | | | |
1030 | | | | |
1031 | | | | |
1032 | | | | |
1033 | | | |10|
1034 | +------------|-----------------|--+
1035 | | 490 |
1036 +---------------+-----------------+
1037 60 440
1042 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1044 template<class Types>
1045 class OcclusionTrackerTestOverlappingSurfaceSiblings : public OcclusionTrackerTest<Types> {
1046 protected:
1047 OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1048 void runMyTest()
1050 gfx::Transform childTransform;
1051 childTransform.Translate(250, 250);
1052 childTransform.Rotate(90);
1053 childTransform.Translate(-250, -250);
1055 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
1056 parent->setMasksToBounds(true);
1057 typename Types::LayerType* child1 = this->createSurface(parent, childTransform, gfx::PointF(30, 30), gfx::Size(10, 10));
1058 typename Types::LayerType* child2 = this->createSurface(parent, childTransform, gfx::PointF(20, 40), gfx::Size(10, 10));
1059 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1060 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1061 this->calcDrawEtc(parent);
1063 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1064 occlusion.setLayerClipRect(gfx::Rect(-20, -20, 1000, 1000));
1066 this->visitLayer(layer2, occlusion);
1067 this->enterContributingSurface(child2, occlusion);
1069 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
1070 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1072 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1073 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1074 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1075 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1076 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1078 occlusion.useDefaultLayerClipRect();
1079 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1080 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1081 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1082 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1083 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1084 occlusion.setLayerClipRect(gfx::Rect(-20, -20, 1000, 1000));
1086 // There is nothing above child2's surface in the z-order.
1087 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, gfx::Rect(-10, 420, 70, 80)));
1089 this->leaveContributingSurface(child2, occlusion);
1090 this->visitLayer(layer1, occlusion);
1091 this->enterContributingSurface(child1, occlusion);
1093 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
1094 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1096 EXPECT_TRUE(occlusion.occludedLayer(child1, gfx::Rect(-10, 430, 80, 70)));
1097 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-11, 430, 80, 70)));
1098 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-10, 429, 80, 70)));
1099 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-10, 430, 81, 70)));
1100 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-10, 430, 80, 71)));
1102 // child2's contents will occlude child1 below it.
1103 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1, false, gfx::Rect(-10, 430, 80, 70)));
1105 this->leaveContributingSurface(child1, occlusion);
1106 this->enterLayer(parent, occlusion);
1108 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
1109 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1111 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1113 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1114 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1115 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1117 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1118 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1119 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1121 /* Justification for the above occlusion:
1123 +---------------------+
1124 | 20 | layer1
1125 | 30+ ---------------------------------+
1126 100 | 30| | layer2 |
1127 |20+----------------------------------+ |
1128 | | | | | |
1129 | | | | | |
1130 | | | | | |
1131 +--|-|----------------+ | |
1132 | | | | 510
1133 | | | |
1134 | | | |
1135 | | | |
1136 | | | |
1137 | | | |
1138 | | | |
1139 | +--------------------------------|-+
1141 +----------------------------------+
1147 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1149 template<class Types>
1150 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms : public OcclusionTrackerTest<Types> {
1151 protected:
1152 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1153 void runMyTest()
1155 gfx::Transform child1Transform;
1156 child1Transform.Translate(250, 250);
1157 child1Transform.Rotate(-90);
1158 child1Transform.Translate(-250, -250);
1160 gfx::Transform child2Transform;
1161 child2Transform.Translate(250, 250);
1162 child2Transform.Rotate(90);
1163 child2Transform.Translate(-250, -250);
1165 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
1166 parent->setMasksToBounds(true);
1167 typename Types::LayerType* child1 = this->createSurface(parent, child1Transform, gfx::PointF(30, 20), gfx::Size(10, 10));
1168 typename Types::LayerType* child2 = this->createDrawingSurface(parent, child2Transform, gfx::PointF(20, 40), gfx::Size(10, 10), false);
1169 typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, gfx::PointF(-10, -20), gfx::Size(510, 510), true);
1170 typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, gfx::PointF(-10, -10), gfx::Size(510, 510), true);
1171 this->calcDrawEtc(parent);
1173 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1174 occlusion.setLayerClipRect(gfx::Rect(-30, -30, 1000, 1000));
1176 this->visitLayer(layer2, occlusion);
1177 this->enterLayer(child2, occlusion);
1179 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
1180 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1182 EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1183 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1184 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1185 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1186 EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1188 this->leaveLayer(child2, occlusion);
1189 this->enterContributingSurface(child2, occlusion);
1191 // There is nothing above child2's surface in the z-order.
1192 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, gfx::Rect(-10, 420, 70, 80)));
1194 this->leaveContributingSurface(child2, occlusion);
1195 this->visitLayer(layer1, occlusion);
1196 this->enterContributingSurface(child1, occlusion);
1198 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
1199 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1201 EXPECT_TRUE(occlusion.occludedLayer(child1, gfx::Rect(420, -20, 80, 90)));
1202 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(419, -20, 80, 90)));
1203 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(420, -21, 80, 90)));
1204 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(420, -19, 80, 90)));
1205 EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(421, -20, 80, 90)));
1207 // child2's contents will occlude child1 below it.
1208 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1, false, gfx::Rect(420, -20, 80, 90)));
1209 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1, false, gfx::Rect(420, -10, 80, 90)));
1210 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1, false, gfx::Rect(420, -20, 70, 90)));
1212 this->leaveContributingSurface(child1, occlusion);
1213 this->enterLayer(parent, occlusion);
1215 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
1216 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1218 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(10, 20, 90, 80)));
1219 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(9, 20, 90, 80)));
1220 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(10, 19, 90, 80)));
1221 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(11, 20, 90, 80)));
1222 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(10, 21, 90, 80)));
1224 /* Justification for the above occlusion:
1226 +---------------------+
1227 |20 | layer1
1228 10+----------------------------------+
1229 100 || 30 | layer2 |
1230 |20+----------------------------------+
1231 || | | | |
1232 || | | | |
1233 || | | | |
1234 +|-|------------------+ | |
1235 | | | | 510
1236 | | 510 | |
1237 | | | |
1238 | | | |
1239 | | | |
1240 | | | |
1241 | | 520 | |
1242 +----------------------------------+ |
1244 +----------------------------------+
1250 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1252 template<class Types>
1253 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1254 protected:
1255 OcclusionTrackerTestFilters(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1256 void runMyTest()
1258 gfx::Transform layerTransform;
1259 layerTransform.Translate(250, 250);
1260 layerTransform.Rotate(90);
1261 layerTransform.Translate(-250, -250);
1263 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
1264 parent->setMasksToBounds(true);
1265 typename Types::ContentLayerType* blurLayer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1266 typename Types::ContentLayerType* opaqueLayer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1267 typename Types::ContentLayerType* opacityLayer = this->createDrawingLayer(parent, layerTransform, gfx::PointF(30, 30), gfx::Size(500, 500), true);
1269 WebKit::WebFilterOperations filters;
1270 filters.append(WebKit::WebFilterOperation::createBlurFilter(10));
1271 blurLayer->setFilters(filters);
1273 filters.clear();
1274 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5));
1275 opaqueLayer->setFilters(filters);
1277 filters.clear();
1278 filters.append(WebKit::WebFilterOperation::createOpacityFilter(0.5));
1279 opacityLayer->setFilters(filters);
1281 this->calcDrawEtc(parent);
1283 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1284 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1286 // Opacity layer won't contribute to occlusion.
1287 this->visitLayer(opacityLayer, occlusion);
1288 this->enterContributingSurface(opacityLayer, occlusion);
1290 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1291 EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty());
1293 // And has nothing to contribute to its parent surface.
1294 this->leaveContributingSurface(opacityLayer, occlusion);
1295 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1296 EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty());
1298 // Opaque layer will contribute to occlusion.
1299 this->visitLayer(opaqueLayer, occlusion);
1300 this->enterContributingSurface(opaqueLayer, occlusion);
1302 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1303 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1305 // And it gets translated to the parent surface.
1306 this->leaveContributingSurface(opaqueLayer, occlusion);
1307 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1308 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1310 // The blur layer needs to throw away any occlusion from outside its subtree.
1311 this->enterLayer(blurLayer, occlusion);
1312 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1313 EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty());
1315 // And it won't contribute to occlusion.
1316 this->leaveLayer(blurLayer, occlusion);
1317 this->enterContributingSurface(blurLayer, occlusion);
1318 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1319 EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty());
1321 // But the opaque layer's occlusion is preserved on the parent.
1322 this->leaveContributingSurface(blurLayer, occlusion);
1323 this->enterLayer(parent, occlusion);
1324 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1325 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1329 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1331 template<class Types>
1332 class OcclusionTrackerTestReplicaDoesOcclude : public OcclusionTrackerTest<Types> {
1333 protected:
1334 OcclusionTrackerTestReplicaDoesOcclude(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1335 void runMyTest()
1337 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
1338 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1339 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(50, 50), gfx::Size());
1340 this->calcDrawEtc(parent);
1342 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1343 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1345 this->visitLayer(surface, occlusion);
1347 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1349 this->visitContributingSurface(surface, occlusion);
1350 this->enterLayer(parent, occlusion);
1352 // The surface and replica should both be occluding the parent.
1353 EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 50)).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1357 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1359 template<class Types>
1360 class OcclusionTrackerTestReplicaWithClipping : public OcclusionTrackerTest<Types> {
1361 protected:
1362 OcclusionTrackerTestReplicaWithClipping(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1363 void runMyTest()
1365 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 170));
1366 parent->setMasksToBounds(true);
1367 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1368 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(50, 50), gfx::Size());
1369 this->calcDrawEtc(parent);
1371 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1372 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1374 this->visitLayer(surface, occlusion);
1376 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1378 this->visitContributingSurface(surface, occlusion);
1379 this->enterLayer(parent, occlusion);
1381 // The surface and replica should both be occluding the parent.
1382 EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 20)).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1386 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1388 template<class Types>
1389 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1390 protected:
1391 OcclusionTrackerTestReplicaWithMask(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1392 void runMyTest()
1394 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
1395 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(50, 50), true);
1396 typename Types::LayerType* replica = this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(50, 50), gfx::Size());
1397 this->createMaskLayer(replica, gfx::Size(10, 10));
1398 this->calcDrawEtc(parent);
1400 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1401 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1403 this->visitLayer(surface, occlusion);
1405 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1407 this->visitContributingSurface(surface, occlusion);
1408 this->enterLayer(parent, occlusion);
1410 // The replica should not be occluding the parent, since it has a mask applied to it.
1411 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1415 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1417 template<class Types>
1418 class OcclusionTrackerTestLayerClipRectOutsideChild : public OcclusionTrackerTest<Types> {
1419 protected:
1420 OcclusionTrackerTestLayerClipRectOutsideChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1421 void runMyTest()
1423 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1424 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1425 this->calcDrawEtc(parent);
1427 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1428 occlusion.setLayerClipRect(gfx::Rect(200, 100, 100, 100));
1430 this->enterLayer(layer, occlusion);
1432 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1433 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1434 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1435 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1436 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1438 occlusion.useDefaultLayerClipRect();
1439 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1440 occlusion.setLayerClipRect(gfx::Rect(200, 100, 100, 100));
1442 this->leaveLayer(layer, occlusion);
1443 this->visitContributingSurface(layer, occlusion);
1444 this->enterLayer(parent, occlusion);
1446 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1447 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1448 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1449 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1450 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1451 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1452 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1453 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1454 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1456 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
1460 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild);
1462 template<class Types>
1463 class OcclusionTrackerTestViewportRectOutsideChild : public OcclusionTrackerTest<Types> {
1464 protected:
1465 OcclusionTrackerTestViewportRectOutsideChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1466 void runMyTest()
1468 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1469 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1470 this->calcDrawEtc(parent);
1472 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(200, 100, 100, 100));
1473 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1475 this->enterLayer(layer, occlusion);
1477 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1478 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1479 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1480 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1481 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1483 occlusion.useDefaultLayerClipRect();
1484 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1485 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1487 this->leaveLayer(layer, occlusion);
1488 this->visitContributingSurface(layer, occlusion);
1489 this->enterLayer(parent, occlusion);
1491 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1492 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1493 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1494 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1495 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1496 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1497 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1498 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1499 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1501 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
1505 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild);
1507 template<class Types>
1508 class OcclusionTrackerTestLayerClipRectOverChild : public OcclusionTrackerTest<Types> {
1509 protected:
1510 OcclusionTrackerTestLayerClipRectOverChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1511 void runMyTest()
1513 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1514 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1515 this->calcDrawEtc(parent);
1517 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1518 occlusion.setLayerClipRect(gfx::Rect(100, 100, 100, 100));
1520 this->enterLayer(layer, occlusion);
1522 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1523 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1524 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1525 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1527 this->leaveLayer(layer, occlusion);
1528 this->visitContributingSurface(layer, occlusion);
1529 this->enterLayer(parent, occlusion);
1531 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1532 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1533 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1534 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1535 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1536 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1537 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1538 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1539 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1541 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1545 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild);
1547 template<class Types>
1548 class OcclusionTrackerTestViewportRectOverChild : public OcclusionTrackerTest<Types> {
1549 protected:
1550 OcclusionTrackerTestViewportRectOverChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1551 void runMyTest()
1553 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1554 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1555 this->calcDrawEtc(parent);
1557 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(100, 100, 100, 100));
1558 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1560 this->enterLayer(layer, occlusion);
1562 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1563 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1564 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1565 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1567 this->leaveLayer(layer, occlusion);
1568 this->visitContributingSurface(layer, occlusion);
1569 this->enterLayer(parent, occlusion);
1571 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1572 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1573 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1574 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1575 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1576 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1577 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1578 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1579 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1581 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1585 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild);
1587 template<class Types>
1588 class OcclusionTrackerTestLayerClipRectPartlyOverChild : public OcclusionTrackerTest<Types> {
1589 protected:
1590 OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1591 void runMyTest()
1593 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1594 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1595 this->calcDrawEtc(parent);
1597 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1598 occlusion.setLayerClipRect(gfx::Rect(50, 50, 200, 200));
1600 this->enterLayer(layer, occlusion);
1602 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1603 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1604 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1605 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1607 this->leaveLayer(layer, occlusion);
1608 this->visitContributingSurface(layer, occlusion);
1609 this->enterLayer(parent, occlusion);
1611 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1612 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1613 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1614 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1615 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1616 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1617 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1618 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1619 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1621 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
1622 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 100)));
1623 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 100, 300, 100)));
1624 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(200, 100, 100, 100)));
1625 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(100, 200, 100, 100)));
1629 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild);
1631 template<class Types>
1632 class OcclusionTrackerTestViewportRectPartlyOverChild : public OcclusionTrackerTest<Types> {
1633 protected:
1634 OcclusionTrackerTestViewportRectPartlyOverChild(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1635 void runMyTest()
1637 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1638 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1639 this->calcDrawEtc(parent);
1641 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(50, 50, 200, 200));
1642 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1644 this->enterLayer(layer, occlusion);
1646 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1647 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1648 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1649 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1651 this->leaveLayer(layer, occlusion);
1652 this->visitContributingSurface(layer, occlusion);
1653 this->enterLayer(parent, occlusion);
1655 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1656 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1657 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1658 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1659 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1660 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1661 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1662 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1663 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1665 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
1666 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 100)));
1667 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 100, 300, 100)));
1668 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(200, 100, 100, 100)));
1669 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(100, 200, 100, 100)));
1673 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild);
1675 template<class Types>
1676 class OcclusionTrackerTestLayerClipRectOverNothing : public OcclusionTrackerTest<Types> {
1677 protected:
1678 OcclusionTrackerTestLayerClipRectOverNothing(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1679 void runMyTest()
1681 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1682 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1683 this->calcDrawEtc(parent);
1685 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1686 occlusion.setLayerClipRect(gfx::Rect(500, 500, 100, 100));
1688 this->enterLayer(layer, occlusion);
1690 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1691 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1692 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1693 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1695 this->leaveLayer(layer, occlusion);
1696 this->visitContributingSurface(layer, occlusion);
1697 this->enterLayer(parent, occlusion);
1699 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1700 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1701 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1702 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1703 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1704 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1705 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1706 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1707 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1709 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1710 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 100)).IsEmpty());
1711 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 100, 300, 100)).IsEmpty());
1712 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(200, 100, 100, 100)).IsEmpty());
1713 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(100, 200, 100, 100)).IsEmpty());
1717 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverNothing);
1719 template<class Types>
1720 class OcclusionTrackerTestViewportRectOverNothing : public OcclusionTrackerTest<Types> {
1721 protected:
1722 OcclusionTrackerTestViewportRectOverNothing(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1723 void runMyTest()
1725 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1726 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1727 this->calcDrawEtc(parent);
1729 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(500, 500, 100, 100));
1730 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1732 this->enterLayer(layer, occlusion);
1734 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1735 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1736 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1737 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1739 this->leaveLayer(layer, occlusion);
1740 this->visitContributingSurface(layer, occlusion);
1741 this->enterLayer(parent, occlusion);
1743 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1744 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1745 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1746 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1747 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1748 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1749 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1750 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1751 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1753 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1754 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 100)).IsEmpty());
1755 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 100, 300, 100)).IsEmpty());
1756 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(200, 100, 100, 100)).IsEmpty());
1757 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(parent, gfx::Rect(100, 200, 100, 100)).IsEmpty());
1761 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing);
1763 template<class Types>
1764 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin : public OcclusionTrackerTest<Types> {
1765 protected:
1766 OcclusionTrackerTestLayerClipRectForLayerOffOrigin(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1767 void runMyTest()
1769 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1770 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), true);
1771 this->calcDrawEtc(parent);
1773 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1774 this->enterLayer(layer, occlusion);
1776 // This layer is translated when drawn into its target. So if the clip rect given from the target surface
1777 // is not in that target space, then after translating these query rects into the target, they will fall outside
1778 // the clip and be considered occluded.
1779 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1780 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1781 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1782 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1786 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin);
1788 template<class Types>
1789 class OcclusionTrackerTestOpaqueContentsRegionEmpty : public OcclusionTrackerTest<Types> {
1790 protected:
1791 OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1792 void runMyTest()
1794 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1795 typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), false);
1796 this->calcDrawEtc(parent);
1798 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1799 this->enterLayer(layer, occlusion);
1801 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1802 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1803 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1804 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1806 // Occluded since its outside the surface bounds.
1807 EXPECT_TRUE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1809 // Test without any clip rect.
1810 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
1811 EXPECT_FALSE(occlusion.occludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1812 occlusion.useDefaultLayerClipRect();
1814 this->leaveLayer(layer, occlusion);
1815 this->visitContributingSurface(layer, occlusion);
1816 this->enterLayer(parent, occlusion);
1818 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1822 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1824 template<class Types>
1825 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty : public OcclusionTrackerTest<Types> {
1826 protected:
1827 OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1828 void runMyTest()
1830 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1831 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 100), gfx::Size(200, 200), false);
1832 this->calcDrawEtc(parent);
1835 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1836 layer->setOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1838 this->resetLayerIterator();
1839 this->visitLayer(layer, occlusion);
1840 this->enterLayer(parent, occlusion);
1842 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1844 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1845 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1846 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1850 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1851 layer->setOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1853 this->resetLayerIterator();
1854 this->visitLayer(layer, occlusion);
1855 this->enterLayer(parent, occlusion);
1857 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1859 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1860 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1861 EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1865 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1866 layer->setOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1868 this->resetLayerIterator();
1869 this->visitLayer(layer, occlusion);
1870 this->enterLayer(parent, occlusion);
1872 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
1874 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1875 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1876 EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1881 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1883 template<class Types>
1884 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
1885 protected:
1886 OcclusionTrackerTest3dTransform(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1887 void runMyTest()
1889 gfx::Transform transform;
1890 MathUtil::rotateEulerAngles(&transform, 0, 30, 0);
1892 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1893 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1894 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, gfx::PointF(100, 100), gfx::Size(200, 200), true);
1895 this->calcDrawEtc(parent);
1897 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1898 this->enterLayer(layer, occlusion);
1900 // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
1901 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion.unoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1905 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
1907 template<class Types>
1908 class OcclusionTrackerTestUnsorted3dLayers : public OcclusionTrackerTest<Types> {
1909 protected:
1910 OcclusionTrackerTestUnsorted3dLayers(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1911 void runMyTest()
1913 // Currently, the main thread layer iterator does not iterate over 3d items in
1914 // sorted order, because layer sorting is not performed on the main thread.
1915 // Because of this, the occlusion tracker cannot assume that a 3d layer occludes
1916 // other layers that have not yet been iterated over. For now, the expected
1917 // behavior is that a 3d layer simply does not add any occlusion to the occlusion
1918 // tracker.
1920 gfx::Transform translationToFront;
1921 translationToFront.Translate3d(0, 0, -10);
1922 gfx::Transform translationToBack;
1923 translationToFront.Translate3d(0, 0, -100);
1925 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1926 typename Types::ContentLayerType* child1 = this->createDrawingLayer(parent, translationToBack, gfx::PointF(0, 0), gfx::Size(100, 100), true);
1927 typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, translationToFront, gfx::PointF(50, 50), gfx::Size(100, 100), true);
1928 parent->setPreserves3D(true);
1930 this->calcDrawEtc(parent);
1932 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1933 this->visitLayer(child2, occlusion);
1934 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1935 EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty());
1937 this->visitLayer(child1, occlusion);
1938 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
1939 EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty());
1943 // This test will have different layer ordering on the impl thread; the test will only work on the main thread.
1944 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1946 template<class Types>
1947 class OcclusionTrackerTestPerspectiveTransform : public OcclusionTrackerTest<Types> {
1948 protected:
1949 OcclusionTrackerTestPerspectiveTransform(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1950 void runMyTest()
1952 gfx::Transform transform;
1953 transform.Translate(150, 150);
1954 transform.ApplyPerspectiveDepth(400);
1955 transform.RotateAboutXAxis(-30);
1956 transform.Translate(-150, -150);
1958 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1959 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
1960 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, gfx::PointF(100, 100), gfx::Size(200, 200), true);
1961 container->setPreserves3D(true);
1962 layer->setPreserves3D(true);
1963 this->calcDrawEtc(parent);
1965 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1966 this->enterLayer(layer, occlusion);
1968 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion.unoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1972 // 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.
1973 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
1975 template<class Types>
1976 class OcclusionTrackerTestPerspectiveTransformBehindCamera : public OcclusionTrackerTest<Types> {
1977 protected:
1978 OcclusionTrackerTestPerspectiveTransformBehindCamera(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
1979 void runMyTest()
1981 // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
1982 gfx::Transform transform;
1983 transform.Translate(250, 50);
1984 transform.ApplyPerspectiveDepth(10);
1985 transform.Translate(-250, -50);
1986 transform.Translate(250, 50);
1987 transform.RotateAboutXAxis(-167);
1988 transform.Translate(-250, -50);
1990 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(500, 100));
1991 typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(500, 500));
1992 typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, gfx::PointF(0, 0), gfx::Size(500, 500), true);
1993 container->setPreserves3D(true);
1994 layer->setPreserves3D(true);
1995 this->calcDrawEtc(parent);
1997 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
1998 this->enterLayer(layer, occlusion);
2000 // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
2001 // this will include many more pixels but must include at least the bottom 11 rows.
2002 EXPECT_TRUE(occlusion.unoccludedLayerContentRect(layer, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
2006 // 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.
2007 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2009 template<class Types>
2010 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude : public OcclusionTrackerTest<Types> {
2011 protected:
2012 OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2013 void runMyTest()
2015 gfx::Transform transform;
2016 transform.Translate(50, 50);
2017 transform.ApplyPerspectiveDepth(100);
2018 transform.Translate3d(0, 0, 110);
2019 transform.Translate(-50, -50);
2021 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
2022 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2023 parent->setPreserves3D(true);
2024 layer->setPreserves3D(true);
2025 this->calcDrawEtc(parent);
2027 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2029 // The |layer| is entirely behind the camera and should not occlude.
2030 this->visitLayer(layer, occlusion);
2031 this->enterLayer(parent, occlusion);
2032 EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty());
2033 EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty());
2037 // 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.
2038 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2040 template<class Types>
2041 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect : public OcclusionTrackerTest<Types> {
2042 protected:
2043 OcclusionTrackerTestLargePixelsOccludeInsideClipRect(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2044 void runMyTest()
2046 gfx::Transform transform;
2047 transform.Translate(50, 50);
2048 transform.ApplyPerspectiveDepth(100);
2049 transform.Translate3d(0, 0, 99);
2050 transform.Translate(-50, -50);
2052 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100));
2053 parent->setMasksToBounds(true);
2054 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2055 parent->setPreserves3D(true);
2056 layer->setPreserves3D(true);
2057 this->calcDrawEtc(parent);
2059 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2061 // This is very close to the camera, so pixels in its visibleContentRect will actually go outside of the layer's clipRect.
2062 // Ensure that those pixels don't occlude things outside the clipRect.
2063 this->visitLayer(layer, occlusion);
2064 this->enterLayer(parent, occlusion);
2065 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2066 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2070 // 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.
2071 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2073 template<class Types>
2074 class OcclusionTrackerTestAnimationOpacity1OnMainThread : public OcclusionTrackerTest<Types> {
2075 protected:
2076 OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2077 void runMyTest()
2079 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
2080 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2081 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2082 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2083 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2084 typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2085 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(250, 0), gfx::Size(50, 300), true);
2087 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 0, 1, false);
2088 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 0, 1, false);
2089 this->calcDrawEtc(parent);
2091 EXPECT_TRUE(layer->drawOpacityIsAnimating());
2092 EXPECT_FALSE(surface->drawOpacityIsAnimating());
2093 EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
2095 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2097 this->visitLayer(topmost, occlusion);
2098 this->enterLayer(parent2, occlusion);
2099 // This occlusion will affect all surfaces.
2100 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent2, gfx::Rect(0, 0, 300, 300)));
2101 this->leaveLayer(parent2, occlusion);
2103 this->visitLayer(surfaceChild2, occlusion);
2104 this->enterLayer(surfaceChild, occlusion);
2105 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), occlusion.unoccludedLayerContentRect(surfaceChild, gfx::Rect(0, 0, 300, 300)));
2106 this->leaveLayer(surfaceChild, occlusion);
2107 this->enterLayer(surface, occlusion);
2108 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2109 this->leaveLayer(surface, occlusion);
2111 this->enterContributingSurface(surface, occlusion);
2112 // Occlusion within the surface is lost when leaving the animating surface.
2113 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 300, 300)));
2114 this->leaveContributingSurface(surface, occlusion);
2116 this->visitLayer(layer, occlusion);
2117 this->enterLayer(parent, occlusion);
2119 // Occlusion is not added for the animating |layer|.
2120 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2124 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2126 template<class Types>
2127 class OcclusionTrackerTestAnimationOpacity0OnMainThread : public OcclusionTrackerTest<Types> {
2128 protected:
2129 OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2130 void runMyTest()
2132 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
2133 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2134 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2135 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2136 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2137 typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2138 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(250, 0), gfx::Size(50, 300), true);
2140 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 1, 0, false);
2141 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 1, 0, false);
2142 this->calcDrawEtc(parent);
2144 EXPECT_TRUE(layer->drawOpacityIsAnimating());
2145 EXPECT_FALSE(surface->drawOpacityIsAnimating());
2146 EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
2148 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2150 this->visitLayer(topmost, occlusion);
2151 this->enterLayer(parent2, occlusion);
2152 // This occlusion will affect all surfaces.
2153 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2154 this->leaveLayer(parent2, occlusion);
2156 this->visitLayer(surfaceChild2, occlusion);
2157 this->enterLayer(surfaceChild, occlusion);
2158 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), occlusion.unoccludedLayerContentRect(surfaceChild, gfx::Rect(0, 0, 300, 300)));
2159 this->leaveLayer(surfaceChild, occlusion);
2160 this->enterLayer(surface, occlusion);
2161 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2162 this->leaveLayer(surface, occlusion);
2164 this->enterContributingSurface(surface, occlusion);
2165 // Occlusion within the surface is lost when leaving the animating surface.
2166 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 300, 300)));
2167 this->leaveContributingSurface(surface, occlusion);
2169 this->visitLayer(layer, occlusion);
2170 this->enterLayer(parent, occlusion);
2172 // Occlusion is not added for the animating |layer|.
2173 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2177 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2179 template<class Types>
2180 class OcclusionTrackerTestAnimationTranslateOnMainThread : public OcclusionTrackerTest<Types> {
2181 protected:
2182 OcclusionTrackerTestAnimationTranslateOnMainThread(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2183 void runMyTest()
2185 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
2186 typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2187 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300), true);
2188 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 300), true);
2189 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2190 typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(50, 300), true);
2192 addAnimatedTransformToController(*layer->layerAnimationController(), 10, 30, 0);
2193 addAnimatedTransformToController(*surface->layerAnimationController(), 10, 30, 0);
2194 addAnimatedTransformToController(*surfaceChild->layerAnimationController(), 10, 30, 0);
2195 this->calcDrawEtc(parent);
2197 EXPECT_TRUE(layer->drawTransformIsAnimating());
2198 EXPECT_TRUE(layer->screenSpaceTransformIsAnimating());
2199 EXPECT_TRUE(surface->renderSurface()->targetSurfaceTransformsAreAnimating());
2200 EXPECT_TRUE(surface->renderSurface()->screenSpaceTransformsAreAnimating());
2201 // The surface owning layer doesn't animate against its own surface.
2202 EXPECT_FALSE(surface->drawTransformIsAnimating());
2203 EXPECT_TRUE(surface->screenSpaceTransformIsAnimating());
2204 EXPECT_TRUE(surfaceChild->drawTransformIsAnimating());
2205 EXPECT_TRUE(surfaceChild->screenSpaceTransformIsAnimating());
2207 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2209 this->visitLayer(surface2, occlusion);
2210 this->enterContributingSurface(surface2, occlusion);
2212 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2214 this->leaveContributingSurface(surface2, occlusion);
2215 this->enterLayer(surfaceChild2, occlusion);
2217 // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
2218 // It also means that things occluding from outside the target (e.g. surface2) cannot occlude this layer.
2219 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2221 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300), occlusion.unoccludedLayerContentRect(surfaceChild2, gfx::Rect(0, 0, 100, 300)));
2222 EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 50, 300)));
2224 this->leaveLayer(surfaceChild2, occlusion);
2225 this->enterLayer(surfaceChild, occlusion);
2226 EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 100, 300)));
2227 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2228 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2229 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2231 // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target, so it can't be occluded.
2232 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300), occlusion.unoccludedLayerContentRect(surfaceChild, gfx::Rect(0, 0, 200, 300)));
2233 EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 50, 300)));
2235 this->leaveLayer(surfaceChild, occlusion);
2236 this->enterLayer(surface, occlusion);
2237 // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen from within the target only.
2238 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2239 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2240 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2242 this->leaveLayer(surface, occlusion);
2243 // The surface's owning layer is moving in screen space but not relative to its target, so occlusion should happen within the target only.
2244 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2245 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2246 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300)));
2248 this->enterContributingSurface(surface, occlusion);
2249 // The contributing |surface| is animating so it can't be occluded.
2250 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 300, 300)));
2251 this->leaveContributingSurface(surface, occlusion);
2253 this->enterLayer(layer, occlusion);
2254 // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
2255 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2256 this->leaveLayer(layer, occlusion);
2258 this->enterLayer(parent, occlusion);
2259 // The |layer| is animating in the screen and in its target, so no occlusion is added.
2260 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(0, 0, 300, 300)));
2264 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
2266 template<class Types>
2267 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent : public OcclusionTrackerTest<Types> {
2268 protected:
2269 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2270 void runMyTest()
2272 gfx::Transform surfaceTransform;
2273 surfaceTransform.Translate(300, 300);
2274 surfaceTransform.Scale(2, 2);
2275 surfaceTransform.Translate(-150, -150);
2277 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(500, 500));
2278 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, surfaceTransform, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2279 typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(50, 50), gfx::Size(300, 300), false);
2280 surface->setOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2281 surface2->setOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2282 this->calcDrawEtc(parent);
2284 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2286 this->visitLayer(surface2, occlusion);
2287 this->visitContributingSurface(surface2, occlusion);
2289 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2290 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2292 // Clear any stored occlusion.
2293 occlusion.setOcclusionFromOutsideTarget(Region());
2294 occlusion.setOcclusionFromInsideTarget(Region());
2296 this->visitLayer(surface, occlusion);
2297 this->visitContributingSurface(surface, occlusion);
2299 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2300 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2304 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2306 template<class Types>
2307 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping : public OcclusionTrackerTest<Types> {
2308 protected:
2309 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2310 void runMyTest()
2312 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 300));
2313 parent->setMasksToBounds(true);
2314 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(500, 300), false);
2315 surface->setOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2316 this->calcDrawEtc(parent);
2318 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2320 this->visitLayer(surface, occlusion);
2321 this->visitContributingSurface(surface, occlusion);
2323 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2324 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2328 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2330 template<class Types>
2331 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
2332 protected:
2333 OcclusionTrackerTestReplicaOccluded(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2334 void runMyTest()
2336 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2337 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2338 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(100, 100));
2339 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(100, 100), true);
2340 this->calcDrawEtc(parent);
2342 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2343 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2345 // |topmost| occludes the replica, but not the surface itself.
2346 this->visitLayer(topmost, occlusion);
2348 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2349 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2351 this->visitLayer(surface, occlusion);
2353 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2354 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2356 this->enterContributingSurface(surface, occlusion);
2358 // Surface is not occluded so it shouldn't think it is.
2359 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2363 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
2365 template<class Types>
2366 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded : public OcclusionTrackerTest<Types> {
2367 protected:
2368 OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2369 void runMyTest()
2371 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2372 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2373 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(100, 100));
2374 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 110), true);
2375 this->calcDrawEtc(parent);
2377 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2378 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2380 // |topmost| occludes the surface, but not the entire surface's replica.
2381 this->visitLayer(topmost, occlusion);
2383 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2384 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2386 this->visitLayer(surface, occlusion);
2388 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2389 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2391 this->enterContributingSurface(surface, occlusion);
2393 // Surface is occluded, but only the top 10px of the replica.
2394 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2395 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, true, gfx::Rect(0, 0, 100, 100)));
2399 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2401 template<class Types>
2402 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently : public OcclusionTrackerTest<Types> {
2403 protected:
2404 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2405 void runMyTest()
2407 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2408 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2409 this->createReplicaLayer(surface, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(100, 100));
2410 typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(40, 100), true);
2411 typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(50, 100), true);
2412 this->calcDrawEtc(parent);
2414 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2415 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2417 // These occlude the surface and replica differently, so we can test each one.
2418 this->visitLayer(overReplica, occlusion);
2419 this->visitLayer(overSurface, occlusion);
2421 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2422 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2424 this->visitLayer(surface, occlusion);
2426 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2427 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2429 this->enterContributingSurface(surface, occlusion);
2431 // Surface and replica are occluded different amounts.
2432 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2433 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, true, gfx::Rect(0, 0, 100, 100)));
2437 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2439 template<class Types>
2440 class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest<Types> {
2441 protected:
2442 OcclusionTrackerTestSurfaceChildOfSurface(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2443 void runMyTest()
2445 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2447 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2448 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2449 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, gfx::PointF(0, 10), gfx::Size(100, 50), true);
2450 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 50), true);
2451 this->calcDrawEtc(parent);
2453 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(-100, -100, 1000, 1000));
2455 // |topmost| occludes everything partially so we know occlusion is happening at all.
2456 this->visitLayer(topmost, occlusion);
2458 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2459 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2461 this->visitLayer(surfaceChild, occlusion);
2463 // surfaceChild increases the occlusion in the screen by a narrow sliver.
2464 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2465 // In its own surface, surfaceChild is at 0,0 as is its occlusion.
2466 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2468 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2469 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2470 // as its parent does not have a clipRect.
2472 this->enterContributingSurface(surfaceChild, occlusion);
2473 // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
2474 // does not get clipped away inappropriately.
2475 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, gfx::Rect(0, 0, 100, 50)));
2476 this->leaveContributingSurface(surfaceChild, occlusion);
2478 // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
2479 this->enterLayer(surface, occlusion);
2480 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2481 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2482 this->leaveLayer(surface, occlusion);
2484 this->enterContributingSurface(surface, occlusion);
2485 // The surface's parent does have a clipRect as it is the root layer.
2486 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)));
2490 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2492 template<class Types>
2493 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport : public OcclusionTrackerTest<Types> {
2494 protected:
2495 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2496 void runMyTest()
2498 // This test verifies that the top-most surface is considered occluded outside of its target's clipRect and outside the viewport rect.
2500 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 200));
2501 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 300), true);
2502 this->calcDrawEtc(parent);
2505 // Make a viewport rect that is larger than the root layer.
2506 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2508 this->visitLayer(surface, occlusion);
2510 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2511 this->enterContributingSurface(surface, occlusion);
2512 // Make sure the parent's clipRect clips the unoccluded region of the child surface.
2513 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 300)));
2515 this->resetLayerIterator();
2517 // Make a viewport rect that is smaller than the root layer.
2518 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 100, 100));
2520 this->visitLayer(surface, occlusion);
2522 // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect.
2523 this->enterContributingSurface(surface, occlusion);
2524 // Make sure the viewport rect clips the unoccluded region of the child surface.
2525 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 300)));
2530 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
2532 template<class Types>
2533 class OcclusionTrackerTestSurfaceChildOfClippingSurface : public OcclusionTrackerTest<Types> {
2534 protected:
2535 OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2536 void runMyTest()
2538 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2540 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(80, 200));
2541 parent->setMasksToBounds(true);
2542 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), true);
2543 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), false);
2544 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 50), true);
2545 this->calcDrawEtc(parent);
2547 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2548 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2550 // |topmost| occludes everything partially so we know occlusion is happening at all.
2551 this->visitLayer(topmost, occlusion);
2553 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2554 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2556 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2557 this->visitLayer(surfaceChild, occlusion);
2559 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2560 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2562 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2563 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2564 // as its parent does not have a clipRect.
2566 this->enterContributingSurface(surfaceChild, occlusion);
2567 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
2568 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, gfx::Rect(0, 0, 100, 100)).ToString());
2569 this->leaveContributingSurface(surfaceChild, occlusion);
2571 this->visitLayer(surface, occlusion);
2572 this->enterContributingSurface(surface, occlusion);
2573 // The surface's parent does have a clipRect as it is the root layer.
2574 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)).ToString());
2578 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
2580 template<class Types>
2581 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter : public OcclusionTrackerTest<Types> {
2582 protected:
2583 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2584 void runMyTest()
2586 gfx::Transform scaleByHalf;
2587 scaleByHalf.Scale(0.5, 0.5);
2589 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2590 // 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
2591 // appears at 50, 50 and the replica at 200, 50.
2592 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2593 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2594 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(300, 0), gfx::Size());
2595 typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 50), true);
2596 typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(300, 50), true);
2597 typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 50), gfx::Size(50, 50), true);
2598 typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 50), gfx::Size(100, 50), true);
2599 typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(250, 50), gfx::Size(50, 50), true);
2601 // Filters make the layer own a surface.
2602 WebKit::WebFilterOperations filters;
2603 filters.append(WebKit::WebFilterOperation::createBlurFilter(10));
2604 filteredSurface->setBackgroundFilters(filters);
2606 // Save the distance of influence for the blur effect.
2607 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2608 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2610 this->calcDrawEtc(parent);
2612 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2613 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2615 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2616 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2617 this->visitLayer(occludingLayer5, occlusion);
2618 this->visitLayer(occludingLayer4, occlusion);
2619 this->visitLayer(occludingLayer3, occlusion);
2620 this->visitLayer(occludingLayer2, occlusion);
2621 this->visitLayer(occludingLayer1, occlusion);
2623 Region expectedOcclusion;
2624 expectedOcclusion.Union(gfx::Rect(0, 0, 300, 50));
2625 expectedOcclusion.Union(gfx::Rect(0, 50, 50, 50));
2626 expectedOcclusion.Union(gfx::Rect(100, 50, 100, 50));
2627 expectedOcclusion.Union(gfx::Rect(250, 50, 50, 50));
2628 expectedOcclusion.Union(gfx::Rect(0, 100, 300, 50));
2630 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString());
2631 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2633 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2634 this->enterLayer(filteredSurface, occlusion);
2635 EXPECT_RECT_EQ(gfx::Rect(1, 0, 99, 100), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(1, 0, 100, 100)));
2636 EXPECT_RECT_EQ(gfx::Rect(0, 1, 100, 99), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(0, 1, 100, 100)));
2637 EXPECT_RECT_EQ(gfx::Rect(0, 0, 99, 100), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(-1, 0, 100, 100)));
2638 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 99), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(0, -1, 100, 100)));
2640 EXPECT_RECT_EQ(gfx::Rect(300 + 1, 0, 99, 100), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(300 + 1, 0, 100, 100)));
2641 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 1, 100, 99), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(300 + 0, 1, 100, 100)));
2642 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 0, 99, 100), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(300 - 1, 0, 100, 100)));
2643 EXPECT_RECT_EQ(gfx::Rect(300 + 0, 0, 100, 99), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(300 + 0, -1, 100, 100)));
2644 this->leaveLayer(filteredSurface, occlusion);
2646 // The filtered layer/replica does not occlude.
2647 Region expectedOcclusionOutsideSurface;
2648 expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, -50, 300, 50));
2649 expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, 0, 50, 50));
2650 expectedOcclusionOutsideSurface.Union(gfx::Rect(50, 0, 100, 50));
2651 expectedOcclusionOutsideSurface.Union(gfx::Rect(200, 0, 50, 50));
2652 expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, 50, 300, 50));
2654 EXPECT_EQ(expectedOcclusionOutsideSurface.ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2655 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString());
2657 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2658 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2659 this->visitContributingSurface(filteredSurface, occlusion);
2661 this->enterLayer(parent, occlusion);
2663 Region expectedBlurredOcclusion;
2664 expectedBlurredOcclusion.Union(gfx::Rect(0, 0, 300, 50 - outsetTop));
2665 expectedBlurredOcclusion.Union(gfx::Rect(0, 50 - outsetTop, 50 - outsetLeft, 50 + outsetTop + outsetBottom));
2666 expectedBlurredOcclusion.Union(gfx::Rect(100 + outsetRight, 50 - outsetTop, 100 - outsetRight - outsetLeft, 50 + outsetTop + outsetBottom));
2667 expectedBlurredOcclusion.Union(gfx::Rect(250 + outsetRight, 50 - outsetTop, 50 - outsetRight, 50 + outsetTop + outsetBottom));
2668 expectedBlurredOcclusion.Union(gfx::Rect(0, 100 + outsetBottom, 300, 50 - outsetBottom));
2670 EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString());
2671 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2673 gfx::Rect outsetRect;
2674 gfx::Rect testRect;
2676 // Nothing in the blur outsets for the filteredSurface is occluded.
2677 outsetRect = gfx::Rect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2678 testRect = outsetRect;
2679 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2681 // Stuff outside the blur outsets is still occluded though.
2682 testRect = outsetRect;
2683 testRect.Inset(0, 0, -1, 0);
2684 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2685 testRect = outsetRect;
2686 testRect.Inset(0, 0, 0, -1);
2687 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2688 testRect = outsetRect;
2689 testRect.Inset(-1, 0, 0, 0);
2690 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2691 testRect = outsetRect;
2692 testRect.Inset(0, -1, 0, 0);
2693 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2695 // Nothing in the blur outsets for the filteredSurface's replica is occluded.
2696 outsetRect = gfx::Rect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2697 testRect = outsetRect;
2698 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2700 // Stuff outside the blur outsets is still occluded though.
2701 testRect = outsetRect;
2702 testRect.Inset(0, 0, -1, 0);
2703 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2704 testRect = outsetRect;
2705 testRect.Inset(0, 0, 0, -1);
2706 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2707 testRect = outsetRect;
2708 testRect.Inset(-1, 0, 0, 0);
2709 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2710 testRect = outsetRect;
2711 testRect.Inset(0, -1, 0, 0);
2712 EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString());
2716 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2718 template<class Types>
2719 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice : public OcclusionTrackerTest<Types> {
2720 protected:
2721 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2722 void runMyTest()
2724 gfx::Transform scaleByHalf;
2725 scaleByHalf.Scale(0.5, 0.5);
2727 // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
2728 typename Types::ContentLayerType* root = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(75, 75));
2729 typename Types::LayerType* parent = this->createSurface(root, scaleByHalf, gfx::PointF(0, 0), gfx::Size(150, 150));
2730 parent->setMasksToBounds(true);
2731 typename Types::LayerType* filteredSurface1 = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2732 typename Types::LayerType* filteredSurface2 = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(0, 0), gfx::Size(300, 300), false);
2733 typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 100), gfx::Size(50, 50), true);
2735 // Filters make the layers own surfaces.
2736 WebKit::WebFilterOperations filters;
2737 filters.append(WebKit::WebFilterOperation::createBlurFilter(1));
2738 filteredSurface1->setBackgroundFilters(filters);
2739 filteredSurface2->setBackgroundFilters(filters);
2741 // Save the distance of influence for the blur effect.
2742 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2743 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2745 this->calcDrawEtc(root);
2747 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2748 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2750 this->visitLayer(occludingLayerAbove, occlusion);
2751 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2752 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion.occlusionFromInsideTarget().ToString());
2754 this->visitLayer(filteredSurface2, occlusion);
2755 this->visitContributingSurface(filteredSurface2, occlusion);
2756 this->visitLayer(filteredSurface1, occlusion);
2757 this->visitContributingSurface(filteredSurface1, occlusion);
2759 // Test expectations in the target.
2760 gfx::Rect expectedOcclusion = gfx::Rect(100 / 2 + outsetRight * 2, 100 / 2 + outsetBottom * 2, 50 / 2 - (outsetLeft + outsetRight) * 2, 50 / 2 - (outsetTop + outsetBottom) * 2);
2761 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString());
2763 // Test expectations in the screen are the same as in the target, as the render surface is 1:1 with the screen.
2764 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2768 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
2770 template<class Types>
2771 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip : public OcclusionTrackerTest<Types> {
2772 protected:
2773 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2774 void runMyTest()
2776 // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
2777 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2778 // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
2779 // the background filter.
2780 typename Types::LayerType* clippingSurface = this->createSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 70));
2781 clippingSurface->setMasksToBounds(true);
2782 typename Types::LayerType* filteredSurface = this->createDrawingLayer(clippingSurface, this->identityMatrix, gfx::PointF(50, 50), gfx::Size(50, 50), false);
2783 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(150, 0), gfx::Size());
2784 typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 50), true);
2785 typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 100), gfx::Size(300, 50), true);
2786 typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 50), gfx::Size(50, 50), true);
2787 typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(100, 50), gfx::Size(100, 50), true);
2788 typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(250, 50), gfx::Size(50, 50), true);
2790 // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
2791 WebKit::WebFilterOperations filters;
2792 filters.append(WebKit::WebFilterOperation::createBlurFilter(12));
2793 filteredSurface->setBackgroundFilters(filters);
2795 // Save the distance of influence for the blur effect.
2796 int outsetTop, outsetRight, outsetBottom, outsetLeft;
2797 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
2799 this->calcDrawEtc(parent);
2801 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2802 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2804 // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
2805 // need to see some of the pixels (up to radius far) underneath the occludingLayers.
2806 this->visitLayer(occludingLayer5, occlusion);
2807 this->visitLayer(occludingLayer4, occlusion);
2808 this->visitLayer(occludingLayer3, occlusion);
2809 this->visitLayer(occludingLayer2, occlusion);
2810 this->visitLayer(occludingLayer1, occlusion);
2812 Region expectedOcclusion;
2813 expectedOcclusion.Union(gfx::Rect(0, 0, 300, 50));
2814 expectedOcclusion.Union(gfx::Rect(0, 50, 50, 50));
2815 expectedOcclusion.Union(gfx::Rect(100, 50, 100, 50));
2816 expectedOcclusion.Union(gfx::Rect(250, 50, 50, 50));
2817 expectedOcclusion.Union(gfx::Rect(0, 100, 300, 50));
2819 EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString());
2820 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2822 // Everything outside the surface/replica is occluded but the surface/replica itself is not.
2823 this->enterLayer(filteredSurface, occlusion);
2824 EXPECT_RECT_EQ(gfx::Rect(1, 0, 49, 50), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(1, 0, 50, 50)));
2825 EXPECT_RECT_EQ(gfx::Rect(0, 1, 50, 49), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(0, 1, 50, 50)));
2826 EXPECT_RECT_EQ(gfx::Rect(0, 0, 49, 50), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(-1, 0, 50, 50)));
2827 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 49), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(0, -1, 50, 50)));
2829 EXPECT_RECT_EQ(gfx::Rect(150 + 1, 0, 49, 50), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(150 + 1, 0, 50, 50)));
2830 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 1, 50, 49), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(150 + 0, 1, 50, 50)));
2831 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 0, 49, 50), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(150 - 1, 0, 50, 50)));
2832 EXPECT_RECT_EQ(gfx::Rect(150 + 0, 0, 50, 49), occlusion.unoccludedLayerContentRect(filteredSurface, gfx::Rect(150 + 0, -1, 50, 50)));
2833 this->leaveLayer(filteredSurface, occlusion);
2835 // The filtered layer/replica does not occlude.
2836 Region expectedOcclusionOutsideSurface;
2837 expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, -50, 300, 50));
2838 expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, 0, 50, 50));
2839 expectedOcclusionOutsideSurface.Union(gfx::Rect(50, 0, 100, 50));
2840 expectedOcclusionOutsideSurface.Union(gfx::Rect(200, 0, 50, 50));
2841 expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, 50, 300, 50));
2843 EXPECT_EQ(expectedOcclusionOutsideSurface.ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2844 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString());
2846 // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
2847 // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
2848 this->visitContributingSurface(filteredSurface, occlusion);
2850 this->enterContributingSurface(clippingSurface, occlusion);
2852 Region expectedBlurredOcclusion;
2853 expectedBlurredOcclusion.Union(gfx::Rect(0, 0, 300, 50 - outsetTop));
2854 expectedBlurredOcclusion.Union(gfx::Rect(0, 50 - outsetTop, 50 - outsetLeft, 20 + outsetTop + outsetBottom));
2855 expectedBlurredOcclusion.Union(gfx::Rect(100 + outsetRight, 50 - outsetTop, 100 - outsetRight - outsetLeft, 20 + outsetTop + outsetBottom));
2856 expectedBlurredOcclusion.Union(gfx::Rect(250 + outsetRight, 50 - outsetTop, 50 - outsetRight, 20 + outsetTop + outsetBottom));
2857 expectedBlurredOcclusion.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
2859 EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2860 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString());
2862 gfx::Rect outsetRect;
2863 gfx::Rect clippedOutsetRect;
2864 gfx::Rect testRect;
2866 // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
2867 outsetRect = gfx::Rect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2868 clippedOutsetRect = gfx::IntersectRects(outsetRect, gfx::Rect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2869 testRect = outsetRect;
2870 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2872 // Stuff outside the (clipped) blur outsets is still occluded though.
2873 testRect = outsetRect;
2874 testRect.Inset(0, 0, -1, 0);
2875 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2876 testRect = outsetRect;
2877 testRect.Inset(0, 0, 0, -1);
2878 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2879 testRect = outsetRect;
2880 testRect.Inset(-1, 0, 0, 0);
2881 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2882 testRect = outsetRect;
2883 testRect.Inset(0, -1, 0, 0);
2884 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2886 // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
2887 outsetRect = gfx::Rect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
2888 clippedOutsetRect = gfx::IntersectRects(outsetRect, gfx::Rect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
2889 testRect = outsetRect;
2890 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2892 // Stuff outside the (clipped) blur outsets is still occluded though.
2893 testRect = outsetRect;
2894 testRect.Inset(0, 0, -1, 0);
2895 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2896 testRect = outsetRect;
2897 testRect.Inset(0, 0, 0, -1);
2898 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2899 testRect = outsetRect;
2900 testRect.Inset(-1, 0, 0, 0);
2901 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2902 testRect = outsetRect;
2903 testRect.Inset(0, -1, 0, 0);
2904 EXPECT_RECT_EQ(clippedOutsetRect, occlusion.unoccludedLayerContentRect(clippingSurface, testRect));
2908 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
2910 template<class Types>
2911 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter : public OcclusionTrackerTest<Types> {
2912 protected:
2913 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2914 void runMyTest()
2916 gfx::Transform scaleByHalf;
2917 scaleByHalf.Scale(0.5, 0.5);
2919 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
2920 // 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
2921 // appears at 50, 50 and the replica at 200, 50.
2922 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2923 typename Types::LayerType* behindSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(60, 60), gfx::Size(30, 30), true);
2924 typename Types::LayerType* behindReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(210, 60), gfx::Size(30, 30), true);
2925 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2926 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(300, 0), gfx::Size());
2928 // Filters make the layer own a surface.
2929 WebKit::WebFilterOperations filters;
2930 filters.append(WebKit::WebFilterOperation::createBlurFilter(3));
2931 filteredSurface->setBackgroundFilters(filters);
2933 this->calcDrawEtc(parent);
2935 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2936 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2938 // The surface has a background blur, so it blurs non-opaque pixels below it.
2939 this->visitLayer(filteredSurface, occlusion);
2940 this->visitContributingSurface(filteredSurface, occlusion);
2942 this->visitLayer(behindReplicaLayer, occlusion);
2943 this->visitLayer(behindSurfaceLayer, occlusion);
2945 // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
2946 // So it should not be modified by the filter here.
2947 gfx::Rect occlusionBehindSurface = gfx::Rect(60, 60, 30, 30);
2948 gfx::Rect occlusionBehindReplica = gfx::Rect(210, 60, 30, 30);
2950 Region expectedOpaqueBounds = UnionRegions(occlusionBehindSurface, occlusionBehindReplica);
2951 EXPECT_EQ(expectedOpaqueBounds.ToString(), occlusion.occlusionFromInsideTarget().ToString());
2953 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
2957 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
2959 template<class Types>
2960 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded : public OcclusionTrackerTest<Types> {
2961 protected:
2962 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
2963 void runMyTest()
2965 gfx::Transform scaleByHalf;
2966 scaleByHalf.Scale(0.5, 0.5);
2968 // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
2969 // 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
2970 // appears at 50, 50 and the replica at 200, 50.
2971 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
2972 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(50, 50), gfx::Size(100, 100), false);
2973 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(300, 0), gfx::Size());
2974 typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(50, 50), gfx::Size(50, 50), true);
2975 typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(200, 50), gfx::Size(50, 50), true);
2977 // Filters make the layer own a surface.
2978 WebKit::WebFilterOperations filters;
2979 filters.append(WebKit::WebFilterOperation::createBlurFilter(3));
2980 filteredSurface->setBackgroundFilters(filters);
2982 this->calcDrawEtc(parent);
2984 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
2985 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
2987 this->visitLayer(aboveReplicaLayer, occlusion);
2988 this->visitLayer(aboveSurfaceLayer, occlusion);
2990 this->visitLayer(filteredSurface, occlusion);
2993 // The layers above the filtered surface occlude from outside.
2994 gfx::Rect occlusionAboveSurface = gfx::Rect(0, 0, 50, 50);
2995 gfx::Rect occlusionAboveReplica = gfx::Rect(150, 0, 50, 50);
2996 Region expectedOpaqueRegion = UnionRegions(occlusionAboveSurface, occlusionAboveReplica);
2998 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString());
2999 EXPECT_EQ(expectedOpaqueRegion.ToString(), occlusion.occlusionFromOutsideTarget().ToString());
3002 // The surface has a background blur, so it blurs non-opaque pixels below it.
3003 this->visitContributingSurface(filteredSurface, occlusion);
3006 // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
3007 gfx::Rect occlusionAboveSurface = gfx::Rect(50, 50, 50, 50);
3008 gfx::Rect occlusionAboveReplica = gfx::Rect(200, 50, 50, 50);
3009 Region expectedOpaqueRegion = UnionRegions(occlusionAboveSurface, occlusionAboveReplica);
3011 EXPECT_EQ(expectedOpaqueRegion.ToString(), occlusion.occlusionFromInsideTarget().ToString());
3012 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
3017 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
3019 template<class Types>
3020 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded : public OcclusionTrackerTest<Types> {
3021 protected:
3022 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
3023 void runMyTest()
3025 gfx::Transform scaleByHalf;
3026 scaleByHalf.Scale(0.5, 0.5);
3028 // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
3029 // 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
3030 // appears at 50, 50 and the replica at 200, 50.
3031 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(300, 150));
3032 typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, gfx::PointF(50, 50), gfx::Size(100, 100), false);
3033 this->createReplicaLayer(filteredSurface, this->identityMatrix, gfx::PointF(300, 0), gfx::Size());
3034 typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(70, 50), gfx::Size(30, 50), true);
3035 typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(200, 50), gfx::Size(30, 50), true);
3036 typename Types::LayerType* besideSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(90, 40), gfx::Size(10, 10), true);
3037 typename Types::LayerType* besideReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(200, 40), gfx::Size(10, 10), true);
3039 // Filters make the layer own a surface.
3040 WebKit::WebFilterOperations filters;
3041 filters.append(WebKit::WebFilterOperation::createBlurFilter(3));
3042 filteredSurface->setBackgroundFilters(filters);
3044 // Save the distance of influence for the blur effect.
3045 int outsetTop, outsetRight, outsetBottom, outsetLeft;
3046 filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
3048 this->calcDrawEtc(parent);
3050 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
3051 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
3053 this->visitLayer(besideReplicaLayer, occlusion);
3054 this->visitLayer(besideSurfaceLayer, occlusion);
3055 this->visitLayer(aboveReplicaLayer, occlusion);
3056 this->visitLayer(aboveSurfaceLayer, occlusion);
3058 // The surface has a background blur, so it blurs non-opaque pixels below it.
3059 this->visitLayer(filteredSurface, occlusion);
3060 this->visitContributingSurface(filteredSurface, occlusion);
3062 // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
3063 // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
3064 // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
3065 // the occluded part of the surface.
3066 gfx::Rect occlusionAboveSurface = gfx::Rect(70 + outsetRight, 50, 30 - outsetRight, 50);
3067 gfx::Rect occlusionAboveReplica = gfx::Rect(200, 50, 30 - outsetLeft, 50);
3068 gfx::Rect occlusionBesideSurface = gfx::Rect(90, 40, 10, 10);
3069 gfx::Rect occlusionBesideReplica = gfx::Rect(200, 40, 10, 10);
3071 Region expectedOcclusion;
3072 expectedOcclusion.Union(occlusionAboveSurface);
3073 expectedOcclusion.Union(occlusionAboveReplica);
3074 expectedOcclusion.Union(occlusionBesideSurface);
3075 expectedOcclusion.Union(occlusionBesideReplica);
3077 ASSERT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString());
3078 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
3080 Region::Iterator expectedRects(expectedOcclusion);
3081 Region::Iterator targetSurfaceRects(occlusion.occlusionFromInsideTarget());
3082 for (; expectedRects.has_rect(); expectedRects.next(), targetSurfaceRects.next()) {
3083 ASSERT_TRUE(targetSurfaceRects.has_rect());
3084 EXPECT_EQ(expectedRects.rect(), targetSurfaceRects.rect());
3089 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
3091 template<class Types>
3092 class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest<Types> {
3093 protected:
3094 OcclusionTrackerTestMinimumTrackingSize(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {}
3095 void runMyTest()
3097 gfx::Size trackingSize(100, 100);
3098 gfx::Size belowTrackingSize(99, 99);
3100 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(400, 400));
3101 typename Types::LayerType* large = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), trackingSize, true);
3102 typename Types::LayerType* small = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), belowTrackingSize, true);
3103 this->calcDrawEtc(parent);
3105 TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000));
3106 occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000));
3107 occlusion.setMinimumTrackingSize(trackingSize);
3109 // The small layer is not tracked because it is too small.
3110 this->visitLayer(small, occlusion);
3112 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
3113 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString());
3115 // The large layer is tracked as it is large enough.
3116 this->visitLayer(large, occlusion);
3118 EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString());
3119 EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize).ToString(), occlusion.occlusionFromInsideTarget().ToString());
3123 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
3125 } // namespace
3126 } // namespace cc