summaryrefslogtreecommitdiff
path: root/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp')
-rw-r--r--Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp4681
1 files changed, 2705 insertions, 1976 deletions
diff --git a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp
index 26d52523b..73b4d8273 100644
--- a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp
+++ b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp
@@ -26,16 +26,23 @@
#include "cc/CCOcclusionTracker.h"
+#include "CCAnimationTestCommon.h"
+#include "CCOcclusionTrackerTestCommon.h"
#include "FilterOperations.h"
#include "LayerChromium.h"
#include "Region.h"
#include "TransformationMatrix.h"
+#include "TranslateTransformOperation.h"
+#include "cc/CCLayerAnimationController.h"
+#include "cc/CCLayerImpl.h"
#include "cc/CCLayerTreeHostCommon.h"
+#include "cc/CCSingleThreadProxy.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using namespace WebCore;
+using namespace WebKitTests;
#define EXPECT_EQ_RECT(a, b) \
EXPECT_EQ(a.x(), b.x()); \
@@ -45,2168 +52,2890 @@ using namespace WebCore;
namespace {
-class LayerChromiumWithForcedDrawsContent : public LayerChromium {
+class TestContentLayerChromium : public LayerChromium {
public:
- LayerChromiumWithForcedDrawsContent()
+ TestContentLayerChromium()
: LayerChromium()
+ , m_overrideOpaqueContentsRect(false)
{
}
- virtual bool drawsContent() const { return true; }
- virtual Region opaqueContentsRegion() const
+ virtual bool drawsContent() const OVERRIDE { return true; }
+ virtual Region visibleContentOpaqueRegion() const OVERRIDE
{
- return intersection(m_opaquePaintRect, visibleLayerRect());
+ if (m_overrideOpaqueContentsRect)
+ return intersection(m_opaqueContentsRect, visibleLayerRect());
+ return LayerChromium::visibleContentOpaqueRegion();
+ }
+ void setOpaqueContentsRect(const IntRect& opaqueContentsRect)
+ {
+ m_overrideOpaqueContentsRect = true;
+ m_opaqueContentsRect = opaqueContentsRect;
}
-
- void setOpaquePaintRect(const IntRect& opaquePaintRect) { m_opaquePaintRect = opaquePaintRect; }
private:
- IntRect m_opaquePaintRect;
+ bool m_overrideOpaqueContentsRect;
+ IntRect m_opaqueContentsRect;
};
-void setLayerPropertiesForTesting(LayerChromium* layer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
-{
- layer->setTransform(transform);
- layer->setSublayerTransform(TransformationMatrix());
- layer->setAnchorPoint(FloatPoint(0, 0));
- layer->setPosition(position);
- layer->setBounds(bounds);
-}
-
-void setLayerPropertiesForTesting(LayerChromiumWithForcedDrawsContent* layer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque, bool opaqueLayers)
-{
- setLayerPropertiesForTesting(layer, transform, position, bounds);
- if (opaqueLayers)
- layer->setOpaque(opaque);
- else {
- layer->setOpaque(false);
- if (opaque)
- layer->setOpaquePaintRect(IntRect(IntPoint(), bounds));
- else
- layer->setOpaquePaintRect(IntRect());
- }
-}
-
-// A subclass to expose the total current occlusion.
-class TestCCOcclusionTracker : public CCOcclusionTracker {
+class TestContentLayerImpl : public CCLayerImpl {
public:
- TestCCOcclusionTracker(IntRect screenScissorRect)
- : CCOcclusionTracker(screenScissorRect)
- , m_overrideLayerScissorRect(false)
+ TestContentLayerImpl(int id)
+ : CCLayerImpl(id)
+ , m_overrideOpaqueContentsRect(false)
{
+ setDrawsContent(true);
}
- TestCCOcclusionTracker(IntRect screenScissorRect, const CCOcclusionTrackerDamageClient* damageClient)
- : CCOcclusionTracker(screenScissorRect, damageClient)
- , m_overrideLayerScissorRect(false)
+ virtual Region visibleContentOpaqueRegion() const OVERRIDE
+ {
+ if (m_overrideOpaqueContentsRect)
+ return intersection(m_opaqueContentsRect, visibleLayerRect());
+ return CCLayerImpl::visibleContentOpaqueRegion();
+ }
+ void setOpaqueContentsRect(const IntRect& opaqueContentsRect)
{
+ m_overrideOpaqueContentsRect = true;
+ m_opaqueContentsRect = opaqueContentsRect;
}
- Region occlusionInScreenSpace() const { return CCOcclusionTracker::m_stack.last().occlusionInScreen; }
- Region occlusionInTargetSurface() const { return CCOcclusionTracker::m_stack.last().occlusionInTarget; }
+private:
+ bool m_overrideOpaqueContentsRect;
+ IntRect m_opaqueContentsRect;
+};
- void setOcclusionInScreenSpace(const Region& region) { CCOcclusionTracker::m_stack.last().occlusionInScreen = region; }
- void setOcclusionInTargetSurface(const Region& region) { CCOcclusionTracker::m_stack.last().occlusionInTarget = region; }
+template<typename LayerType, typename RenderSurfaceType>
+class TestCCOcclusionTrackerWithScissor : public TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType> {
+public:
+ TestCCOcclusionTrackerWithScissor(IntRect screenScissorRect, bool recordMetricsForFrame = false)
+ : TestCCOcclusionTrackerBase<LayerType, RenderSurfaceType>(screenScissorRect, recordMetricsForFrame)
+ , m_overrideLayerScissorRect(false)
+ {
+ }
void setLayerScissorRect(const IntRect& rect) { m_overrideLayerScissorRect = true; m_layerScissorRect = rect;}
void useDefaultLayerScissorRect() { m_overrideLayerScissorRect = false; }
protected:
- virtual IntRect layerScissorRectInTargetSurface(const LayerChromium* layer) const { return m_overrideLayerScissorRect ? m_layerScissorRect : CCOcclusionTracker::layerScissorRectInTargetSurface(layer); }
+ virtual IntRect layerScissorRectInTargetSurface(const LayerType* layer) const { return m_overrideLayerScissorRect ? m_layerScissorRect : CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerScissorRectInTargetSurface(layer); }
private:
bool m_overrideLayerScissorRect;
IntRect m_layerScissorRect;
};
-class TestDamageClient : public CCOcclusionTrackerDamageClient {
-public:
- // The interface
- virtual FloatRect damageRect(const RenderSurfaceChromium*) const { return m_damageRect; }
-
- // Testing stuff
- TestDamageClient(const FloatRect& damageRect) : m_damageRect(damageRect) { }
- void setDamageRect(const FloatRect& damageRect) { m_damageRect = damageRect; }
+struct CCOcclusionTrackerTestMainThreadTypes {
+ typedef LayerChromium LayerType;
+ typedef RenderSurfaceChromium RenderSurfaceType;
+ typedef TestContentLayerChromium ContentLayerType;
+ typedef RefPtr<LayerChromium> LayerPtrType;
+ typedef PassRefPtr<LayerChromium> PassLayerPtrType;
+ typedef RefPtr<ContentLayerType> ContentLayerPtrType;
+ typedef PassRefPtr<ContentLayerType> PassContentLayerPtrType;
+ typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> LayerIterator;
+ typedef CCOcclusionTracker OcclusionTrackerType;
+
+ static PassLayerPtrType createLayer() { return LayerChromium::create(); }
+ static PassContentLayerPtrType createContentLayer() { return adoptRef(new ContentLayerType()); }
+};
-private:
- FloatRect m_damageRect;
+struct CCOcclusionTrackerTestImplThreadTypes {
+ typedef CCLayerImpl LayerType;
+ typedef CCRenderSurface RenderSurfaceType;
+ typedef TestContentLayerImpl ContentLayerType;
+ typedef OwnPtr<CCLayerImpl> LayerPtrType;
+ typedef PassOwnPtr<CCLayerImpl> PassLayerPtrType;
+ typedef OwnPtr<ContentLayerType> ContentLayerPtrType;
+ typedef PassOwnPtr<ContentLayerType> PassContentLayerPtrType;
+ typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::FrontToBack> LayerIterator;
+ typedef CCOcclusionTrackerImpl OcclusionTrackerType;
+
+ static PassLayerPtrType createLayer() { return CCLayerImpl::create(nextCCLayerImplId++); }
+ static PassContentLayerPtrType createContentLayer() { return adoptPtr(new ContentLayerType(nextCCLayerImplId++)); }
+ static int nextCCLayerImplId;
};
-#define TEST_OPAQUE_AND_PAINTED_OPAQUE(FULLTESTNAME, SHORTTESTNAME) \
- TEST(FULLTESTNAME, opaqueLayer) \
- { \
- SHORTTESTNAME(true); \
- } \
- TEST(FULLTESTNAME, opaquePaintRect) \
- { \
- SHORTTESTNAME(false); \
+int CCOcclusionTrackerTestImplThreadTypes::nextCCLayerImplId = 0;
+
+template<typename Types, bool opaqueLayers>
+class CCOcclusionTrackerTest : public testing::Test {
+protected:
+ CCOcclusionTrackerTest()
+ : testing::Test()
+ { }
+
+ virtual void runMyTest() = 0;
+
+ virtual void TearDown()
+ {
+ m_root.clear();
+ m_renderSurfaceLayerListChromium.clear();
+ m_renderSurfaceLayerListImpl.clear();
+ m_replicaLayers.clear();
+ CCLayerTreeHost::setNeedsFilterContext(false);
}
-void layerAddedToOccludedRegion(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(layer);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(parent->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 29, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(31, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 31, 70, 70)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 29, 70, 70)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(31, 30, 70, 70)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 31, 70, 70)));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(30, 30, 70, 70)).isEmpty());
- EXPECT_EQ_RECT(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 30, 70, 70)));
- EXPECT_EQ_RECT(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 29, 70, 70)));
- EXPECT_EQ_RECT(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 29, 70, 70)));
- EXPECT_EQ_RECT(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 29, 70, 70)));
- EXPECT_EQ_RECT(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 30, 70, 70)));
- EXPECT_EQ_RECT(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 31, 70, 70)));
- EXPECT_EQ_RECT(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 31, 70, 70)));
- EXPECT_EQ_RECT(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 31, 70, 70)));
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegion, layerAddedToOccludedRegion);
-
-void layerAddedToOccludedRegionWithRotation(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(layer);
-
- TransformationMatrix layerTransform;
- layerTransform.translate(250, 250);
- layerTransform.rotate(90);
- layerTransform.translate(-250, -250);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(layer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(parent->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 29, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(31, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 31, 70, 70)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 29, 70, 70)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(31, 30, 70, 70)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 31, 70, 70)));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(30, 30, 70, 70)).isEmpty());
- EXPECT_EQ_RECT(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 30, 70, 70)));
- EXPECT_EQ_RECT(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 29, 70, 70)));
- EXPECT_EQ_RECT(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 29, 70, 70)));
- EXPECT_EQ_RECT(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 29, 70, 70)));
- EXPECT_EQ_RECT(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 30, 70, 70)));
- EXPECT_EQ_RECT(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 31, 70, 70)));
- EXPECT_EQ_RECT(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 31, 70, 70)));
- EXPECT_EQ_RECT(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 31, 70, 70)));
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithRotation, layerAddedToOccludedRegionWithRotation);
-
-void layerAddedToOccludedRegionWithTranslation(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(layer);
-
- TransformationMatrix layerTransform;
- layerTransform.translate(20, 20);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(layer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(parent->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
- EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(50, 50, 50, 50)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(49, 50, 50, 50)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(50, 49, 50, 50)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(51, 50, 50, 50)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(50, 51, 50, 50)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(50, 50, 50, 50)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(49, 50, 50, 50)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(50, 49, 50, 50)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(51, 50, 50, 50)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(50, 51, 50, 50)));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(50, 50, 50, 50)).isEmpty());
- EXPECT_EQ_RECT(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(49, 50, 50, 50)));
- EXPECT_EQ_RECT(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(49, 49, 50, 50)));
- EXPECT_EQ_RECT(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(50, 49, 50, 50)));
- EXPECT_EQ_RECT(IntRect(51, 49, 50, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(51, 49, 50, 50)));
- EXPECT_EQ_RECT(IntRect(100, 50, 1, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(51, 50, 50, 50)));
- EXPECT_EQ_RECT(IntRect(51, 51, 50, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(51, 51, 50, 50)));
- EXPECT_EQ_RECT(IntRect(50, 100, 50, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(50, 51, 50, 50)));
- EXPECT_EQ_RECT(IntRect(49, 51, 50, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(49, 51, 50, 50)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(50, 50, 50, 50)).isEmpty());
- EXPECT_EQ_RECT(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(49, 50, 50, 50)));
- EXPECT_EQ_RECT(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(49, 49, 50, 50)));
- EXPECT_EQ_RECT(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(50, 49, 50, 50)));
- EXPECT_EQ_RECT(IntRect(51, 49, 49, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(51, 49, 50, 50)));
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(51, 50, 50, 50)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(51, 51, 50, 50)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(50, 51, 50, 50)).isEmpty());
- EXPECT_EQ_RECT(IntRect(49, 51, 1, 49), occlusion.unoccludedContentRect(parent.get(), IntRect(49, 51, 50, 50)));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithTranslation, layerAddedToOccludedRegionWithTranslation);
-
-void layerAddedToOccludedRegionWithRotatedSurface(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromium> child = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(child);
- child->addChild(layer);
-
- TransformationMatrix childTransform;
- childTransform.translate(250, 250);
- childTransform.rotate(90);
- childTransform.translate(-250, -250);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(child.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true, opaqueLayers);
-
- child->setMasksToBounds(true);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(child->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
-
- EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 430, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(9, 430, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(10, 429, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(10, 430, 61, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(10, 430, 60, 71)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 430, 60, 70)));
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(9, 430, 60, 70)));
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 429, 60, 70)));
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 430, 61, 70)));
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 430, 60, 71)));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- occlusion.markOccludedBehindLayer(child.get());
- occlusion.finishedTargetRenderSurface(child.get(), child->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 39, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(31, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 41, 70, 60)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 39, 70, 60)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(31, 40, 70, 60)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 41, 70, 60)));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
-
- /* Justification for the above occlusion from |layer|:
- 100
- +---------------------+ +---------------------+
- | | | |30 Visible region of |layer|: /////
- | 30 | rotate(90) | |
- | 30 + ---------------------------------+ | +---------------------------------+
- 100 | | 10 | | ==> | | |10 |
- | |10+---------------------------------+ | +---------------------------------+ |
- | | | | | | | | |///////////////| 420 | |
- | | | | | | | | |///////////////|60 | |
- | | | | | | | | |///////////////| | |
- +----|--|-------------+ | | +--|--|---------------+ | |
- | | | | 20|10| 70 | |
- | | | | | | | |
- | | | |500 | | | |
- | | | | | | | |
- | | | | | | | |
- | | | | | | | |
- | | | | | | |10|
- +--|-------------------------------+ | | +------------------------------|--+
- | | | 490 |
- +---------------------------------+ +---------------------------------+
- 500 500
- */
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithRotatedSurface, layerAddedToOccludedRegionWithRotatedSurface);
-
-void layerAddedToOccludedRegionWithSurfaceAlreadyOnStack(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromium> child = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(child);
- child->addChild(layer);
- parent->addChild(child2);
-
- TransformationMatrix childTransform;
- childTransform.translate(250, 250);
- childTransform.rotate(90);
- childTransform.translate(-250, -250);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(child.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true, opaqueLayers);
-
- // |child2| makes |parent|'s surface get considered by CCOcclusionTracker first, instead of |child|'s. This exercises different code in
- // leaveToTargetRenderSurface, as the target surface has already been seen.
- setLayerPropertiesForTesting(child2.get(), identityMatrix, FloatPoint(30, 30), IntSize(60, 20), true, opaqueLayers);
-
- child->setMasksToBounds(true);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(-10, -10, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(parent->renderSurface());
- occlusion.markOccludedBehindLayer(child2.get());
-
- EXPECT_EQ_RECT(IntRect(30, 30, 60, 20), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(30, 30, 60, 20), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- occlusion.enterTargetRenderSurface(child->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
-
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 430, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(9, 430, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(10, 429, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(11, 430, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(10, 431, 60, 70)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 430, 60, 70)));
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(9, 430, 60, 70)));
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 429, 60, 70)));
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(11, 430, 60, 70)));
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 431, 60, 70)));
- occlusion.setLayerScissorRect(IntRect(-10, -10, 1000, 1000));
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(10, 430, 60, 70)).isEmpty());
- // This is the little piece not occluded by child2
- EXPECT_EQ_RECT(IntRect(9, 430, 1, 10), occlusion.unoccludedContentRect(child.get(), IntRect(9, 430, 60, 70)));
- // This extends past both sides of child2, so it will be the original rect.
- EXPECT_EQ_RECT(IntRect(9, 430, 60, 80), occlusion.unoccludedContentRect(child.get(), IntRect(9, 430, 60, 80)));
- // This extends past two adjacent sides of child2, and should included the unoccluded parts of each side.
- // This also demonstrates that the rect can be arbitrary and does not get clipped to the layer's visibleLayerRect().
- EXPECT_EQ_RECT(IntRect(-10, 430, 20, 70), occlusion.unoccludedContentRect(child.get(), IntRect(-10, 430, 60, 70)));
- // This extends past three adjacent sides of child2, so it should contain the unoccluded parts of each side. The left
- // and bottom edges are completely unoccluded for some row/column so we get back the original query rect.
- EXPECT_EQ_RECT(IntRect(-10, 430, 60, 80), occlusion.unoccludedContentRect(child.get(), IntRect(-10, 430, 60, 80)));
- EXPECT_EQ_RECT(IntRect(10, 429, 60, 1), occlusion.unoccludedContentRect(child.get(), IntRect(10, 429, 60, 70)));
- EXPECT_EQ_RECT(IntRect(70, 430, 1, 70), occlusion.unoccludedContentRect(child.get(), IntRect(11, 430, 60, 70)));
- EXPECT_EQ_RECT(IntRect(10, 500, 60, 1), occlusion.unoccludedContentRect(child.get(), IntRect(10, 431, 60, 70)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(10, 430, 60, 70)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(9, 430, 60, 70)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(9, 430, 60, 80)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(-10, 430, 60, 70)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(-10, 430, 60, 80)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(10, 429, 60, 70)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(11, 430, 60, 70)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(10, 431, 60, 70)).isEmpty());
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- occlusion.markOccludedBehindLayer(child.get());
- // |child2| should get merged with the surface we are leaving now
- occlusion.finishedTargetRenderSurface(child.get(), child->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
-
- Vector<IntRect> screen = occlusion.occlusionInScreenSpace().rects();
- Vector<IntRect> target = occlusion.occlusionInTargetSurface().rects();
-
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 30, 70, 70)));
- EXPECT_EQ_RECT(IntRect(90, 30, 10, 10), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 30, 70, 70)));
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 30, 60, 10)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 30, 60, 10)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 29, 60, 10)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(31, 30, 60, 10)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 31, 60, 10)));
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 39, 70, 60)));
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(30, 30, 60, 10)).isEmpty());
- EXPECT_EQ_RECT(IntRect(29, 30, 1, 10), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 30, 60, 10)));
- EXPECT_EQ_RECT(IntRect(30, 29, 60, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 29, 60, 10)));
- EXPECT_EQ_RECT(IntRect(90, 30, 1, 10), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 30, 60, 10)));
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(30, 31, 60, 10)).isEmpty());
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(30, 40, 70, 60)).isEmpty());
- EXPECT_EQ_RECT(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 40, 70, 60)));
- // This rect is mostly occluded by |child2|.
- EXPECT_EQ_RECT(IntRect(90, 39, 10, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 39, 70, 60)));
- // This rect extends past top/right ends of |child2|.
- EXPECT_EQ_RECT(IntRect(30, 29, 70, 11), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 29, 70, 70)));
- // This rect extends past left/right ends of |child2|.
- EXPECT_EQ_RECT(IntRect(20, 39, 80, 60), occlusion.unoccludedContentRect(parent.get(), IntRect(20, 39, 80, 60)));
- EXPECT_EQ_RECT(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 40, 70, 60)));
- EXPECT_EQ_RECT(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 41, 70, 60)));
-
- /* Justification for the above occlusion from |layer|:
- 100
- +---------------------+ +---------------------+
- | | | |30 Visible region of |layer|: /////
- | 30 | rotate(90) | 30 60 | |child2|: \\\\\
- | 30 + ------------+--------------------+ | 30 +------------+--------------------+
- 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
- | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
- | + ------------+ | | | | | +------------+//| 420 | |
- | | | | | | | | |///////////////|60 | |
- | | | | | | | | |///////////////| | |
- +----|--|-------------+ | | +--|--|---------------+ | |
- | | | | 20|10| 70 | |
- | | | | | | | |
- | | | |500 | | | |
- | | | | | | | |
- | | | | | | | |
- | | | | | | | |
- | | | | | | |10|
- +--|-------------------------------+ | | +------------------------------|--+
- | | | 490 |
- +---------------------------------+ +---------------------------------+
- 500 500
- */
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithSurfaceAlreadyOnStack, layerAddedToOccludedRegionWithSurfaceAlreadyOnStack);
-
-void layerAddedToOccludedRegionWithRotatedOffAxisSurface(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromium> child = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(child);
- child->addChild(layer);
-
- // Now rotate the child a little more so it is not axis-aligned. The parent will no longer be occluded by |layer|, but
- // the child's occlusion should be unchanged.
-
- TransformationMatrix childTransform;
- childTransform.translate(250, 250);
- childTransform.rotate(95);
- childTransform.translate(-250, -250);
-
- TransformationMatrix layerTransform;
- layerTransform.translate(10, 10);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(child.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
- setLayerPropertiesForTesting(layer.get(), layerTransform, FloatPoint(0, 0), IntSize(500, 500), true, opaqueLayers);
-
- child->setMasksToBounds(true);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- IntRect clippedLayerInChild = layerTransform.mapRect(layer->visibleLayerRect());
-
- occlusion.enterTargetRenderSurface(child->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
-
- EXPECT_EQ_RECT(IntRect(), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(clippedLayerInChild, occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child.get(), clippedLayerInChild));
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), clippedLayerInChild).isEmpty());
- clippedLayerInChild.move(-1, 0);
- EXPECT_FALSE(occlusion.occluded(child.get(), clippedLayerInChild));
- EXPECT_FALSE(occlusion.unoccludedContentRect(parent.get(), clippedLayerInChild).isEmpty());
- clippedLayerInChild.move(1, 0);
- clippedLayerInChild.move(1, 0);
- EXPECT_FALSE(occlusion.occluded(child.get(), clippedLayerInChild));
- EXPECT_FALSE(occlusion.unoccludedContentRect(parent.get(), clippedLayerInChild).isEmpty());
- clippedLayerInChild.move(-1, 0);
- clippedLayerInChild.move(0, -1);
- EXPECT_FALSE(occlusion.occluded(child.get(), clippedLayerInChild));
- EXPECT_FALSE(occlusion.unoccludedContentRect(parent.get(), clippedLayerInChild).isEmpty());
- clippedLayerInChild.move(0, 1);
- clippedLayerInChild.move(0, 1);
- EXPECT_FALSE(occlusion.occluded(child.get(), clippedLayerInChild));
- EXPECT_FALSE(occlusion.unoccludedContentRect(parent.get(), clippedLayerInChild).isEmpty());
- clippedLayerInChild.move(0, -1);
-
- occlusion.markOccludedBehindLayer(child.get());
- occlusion.finishedTargetRenderSurface(child.get(), child->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(75, 55, 1, 1)));
- EXPECT_EQ_RECT(IntRect(75, 55, 1, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(75, 55, 1, 1)));
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithRotatedOffAxisSurface, layerAddedToOccludedRegionWithRotatedOffAxisSurface);
-
-void layerAddedToOccludedRegionWithMultipleOpaqueLayers(bool opaqueLayers)
-{
- // This is similar to the previous test but now we make a few opaque layers inside of |child| so that the occluded parts of child are not a simple rect.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromium> child = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(child);
- child->addChild(layer1);
- child->addChild(layer2);
-
- TransformationMatrix childTransform;
- childTransform.translate(250, 250);
- childTransform.rotate(90);
- childTransform.translate(-250, -250);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(child.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
- setLayerPropertiesForTesting(layer1.get(), identityMatrix, FloatPoint(10, 10), IntSize(500, 440), true, opaqueLayers);
- setLayerPropertiesForTesting(layer2.get(), identityMatrix, FloatPoint(10, 450), IntSize(500, 60), true, opaqueLayers);
-
- child->setMasksToBounds(true);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(child->renderSurface());
- occlusion.markOccludedBehindLayer(layer2.get());
- occlusion.markOccludedBehindLayer(layer1.get());
-
- EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child.get(), IntRect(10, 430, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(9, 430, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(10, 429, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(11, 430, 60, 70)));
- EXPECT_FALSE(occlusion.occluded(child.get(), IntRect(10, 431, 60, 70)));
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(child.get(), IntRect(10, 430, 60, 70)).isEmpty());
- EXPECT_EQ_RECT(IntRect(9, 430, 1, 70), occlusion.unoccludedContentRect(child.get(), IntRect(9, 430, 60, 70)));
- EXPECT_EQ_RECT(IntRect(10, 429, 60, 1), occlusion.unoccludedContentRect(child.get(), IntRect(10, 429, 60, 70)));
- EXPECT_EQ_RECT(IntRect(70, 430, 1, 70), occlusion.unoccludedContentRect(child.get(), IntRect(11, 430, 60, 70)));
- EXPECT_EQ_RECT(IntRect(10, 500, 60, 1), occlusion.unoccludedContentRect(child.get(), IntRect(10, 431, 60, 70)));
-
- occlusion.markOccludedBehindLayer(child.get());
- occlusion.finishedTargetRenderSurface(child.get(), child->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 40, 70, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 39, 70, 60)));
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(30, 40, 70, 60)).isEmpty());
- EXPECT_EQ_RECT(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 40, 70, 60)));
- EXPECT_EQ_RECT(IntRect(30, 39, 70, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 39, 70, 60)));
- EXPECT_EQ_RECT(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent.get(), IntRect(31, 40, 70, 60)));
- EXPECT_EQ_RECT(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(30, 41, 70, 60)));
-
- /* Justification for the above occlusion from |layer1| and |layer2|:
-
- +---------------------+
- | |30 Visible region of |layer1|: /////
- | | Visible region of |layer2|: \\\\\
- | +---------------------------------+
- | | |10 |
- | +---------------+-----------------+ |
- | | |\\\\\\\\\\\\|//| 420 | |
- | | |\\\\\\\\\\\\|//|60 | |
- | | |\\\\\\\\\\\\|//| | |
- +--|--|------------|--+ | |
- 20|10| 70 | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | |10|
- | +------------|-----------------|--+
- | | 490 |
- +---------------+-----------------+
- 60 440
- */
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithMultipleOpaqueLayers, layerAddedToOccludedRegionWithMultipleOpaqueLayers);
-
-void surfaceOcclusionWithOverlappingSiblingSurfaces(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromium> child1 = LayerChromium::create();
- RefPtr<LayerChromium> child2 = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(child1);
- parent->addChild(child2);
- child1->addChild(layer1);
- child2->addChild(layer2);
-
- TransformationMatrix childTransform;
- childTransform.translate(250, 250);
- childTransform.rotate(90);
- childTransform.translate(-250, -250);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(child1.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
- setLayerPropertiesForTesting(layer1.get(), identityMatrix, FloatPoint(0, 0), IntSize(500, 500), true, opaqueLayers);
- setLayerPropertiesForTesting(child2.get(), childTransform, FloatPoint(20, 40), IntSize(500, 500));
- setLayerPropertiesForTesting(layer2.get(), identityMatrix, FloatPoint(0, 0), IntSize(500, 500), true, opaqueLayers);
-
- child1->setMasksToBounds(true);
- child2->setMasksToBounds(true);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(-10, -10, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(child2->renderSurface());
- occlusion.markOccludedBehindLayer(layer2.get());
-
- EXPECT_EQ_RECT(IntRect(20, 40, 80, 60), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(0, 420, 60, 80), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child2.get(), IntRect(0, 420, 60, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-1, 420, 60, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(0, 419, 60, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(0, 420, 61, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(0, 420, 60, 81)));
-
- occlusion.markOccludedBehindLayer(child2.get());
- occlusion.finishedTargetRenderSurface(child2.get(), child2->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(child1->renderSurface());
- occlusion.markOccludedBehindLayer(layer1.get());
-
- EXPECT_EQ_RECT(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(0, 430, 70, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child1.get(), IntRect(0, 430, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(-1, 430, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(0, 429, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(0, 430, 71, 70)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(0, 430, 70, 71)));
-
- occlusion.markOccludedBehindLayer(child1.get());
- occlusion.finishedTargetRenderSurface(child1.get(), child1->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(20, 30, 80, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(20, 30, 80, 70)));
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 30, 70, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 29, 70, 70)));
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(20, 40, 80, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(19, 40, 80, 60)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(20, 39, 80, 60)));
-
- /* Justification for the above occlusion:
- 100
- +---------------------+
- | |
- | 30 | child1
- | 30+ ---------------------------------+
- 100 | 40| | child2 |
- |20+----------------------------------+ |
- | | | | | |
- | | | | | |
- | | | | | |
- +--|-|----------------+ | |
- | | | | 500
- | | | |
- | | | |
- | | | |
- | | | |
- | | | |
- | | | |
- | +--------------------------------|-+
- | |
- +----------------------------------+
- 500
- */
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_surfaceOcclusionWithOverlappingSiblingSurfaces, surfaceOcclusionWithOverlappingSiblingSurfaces);
-
-void surfaceOcclusionInScreenSpace(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromium> child1 = LayerChromium::create();
- RefPtr<LayerChromium> child2 = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(child1);
- parent->addChild(child2);
- child1->addChild(layer1);
- child2->addChild(layer2);
-
- TransformationMatrix childTransform;
- childTransform.translate(250, 250);
- childTransform.rotate(90);
- childTransform.translate(-250, -250);
-
- // The owning layers have very different bounds from the surfaces that they own.
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(child1.get(), childTransform, FloatPoint(30, 30), IntSize(10, 10));
- setLayerPropertiesForTesting(layer1.get(), identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true, opaqueLayers);
- setLayerPropertiesForTesting(child2.get(), childTransform, FloatPoint(20, 40), IntSize(10, 10));
- setLayerPropertiesForTesting(layer2.get(), identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true, opaqueLayers);
-
- // Make them both render surfaces
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- child1->setFilters(filters);
- child2->setFilters(filters);
-
- child1->setMasksToBounds(false);
- child2->setMasksToBounds(false);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(-20, -20, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(child2->renderSurface());
- occlusion.markOccludedBehindLayer(layer2.get());
-
- EXPECT_EQ_RECT(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child2.get(), IntRect(-10, 420, 70, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-11, 420, 70, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-10, 419, 70, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-10, 420, 71, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-10, 420, 70, 81)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.occluded(child2.get(), IntRect(-10, 420, 70, 80)));
- EXPECT_TRUE(occlusion.occluded(child2.get(), IntRect(-11, 420, 70, 80)));
- EXPECT_TRUE(occlusion.occluded(child2.get(), IntRect(-10, 419, 70, 80)));
- EXPECT_TRUE(occlusion.occluded(child2.get(), IntRect(-10, 420, 71, 80)));
- EXPECT_TRUE(occlusion.occluded(child2.get(), IntRect(-10, 420, 70, 81)));
- occlusion.setLayerScissorRect(IntRect(-20, -20, 1000, 1000));
-
- occlusion.markOccludedBehindLayer(child2.get());
- occlusion.finishedTargetRenderSurface(child2.get(), child2->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(child1->renderSurface());
- occlusion.markOccludedBehindLayer(layer1.get());
-
- EXPECT_EQ_RECT(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(-10, 430, 80, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child1.get(), IntRect(-10, 430, 80, 70)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(-11, 430, 80, 70)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(-10, 429, 80, 70)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(-10, 430, 81, 70)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(-10, 430, 80, 71)));
-
- occlusion.markOccludedBehindLayer(child1.get());
- occlusion.finishedTargetRenderSurface(child1.get(), child1->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(20, 20, 80, 80), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(20, 20, 80, 80)));
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(30, 20, 70, 80)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(29, 20, 70, 80)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(30, 19, 70, 80)));
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(20, 30, 80, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(19, 30, 80, 70)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(20, 29, 80, 70)));
-
- /* Justification for the above occlusion:
- 100
- +---------------------+
- | 20 | layer1
- | 30+ ---------------------------------+
- 100 | 30| | layer2 |
- |20+----------------------------------+ |
- | | | | | |
- | | | | | |
- | | | | | |
- +--|-|----------------+ | |
- | | | | 510
- | | | |
- | | | |
- | | | |
- | | | |
- | | | |
- | | | |
- | +--------------------------------|-+
- | |
- +----------------------------------+
- 510
- */
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_surfaceOcclusionInScreenSpace, surfaceOcclusionInScreenSpace);
-
-void surfaceOcclusionInScreenSpaceDifferentTransforms(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromium> child1 = LayerChromium::create();
- RefPtr<LayerChromium> child2 = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(child1);
- parent->addChild(child2);
- child1->addChild(layer1);
- child2->addChild(layer2);
-
- TransformationMatrix child1Transform;
- child1Transform.translate(250, 250);
- child1Transform.rotate(-90);
- child1Transform.translate(-250, -250);
-
- TransformationMatrix child2Transform;
- child2Transform.translate(250, 250);
- child2Transform.rotate(90);
- child2Transform.translate(-250, -250);
-
- // The owning layers have very different bounds from the surfaces that they own.
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(child1.get(), child1Transform, FloatPoint(30, 20), IntSize(10, 10));
- setLayerPropertiesForTesting(layer1.get(), identityMatrix, FloatPoint(-10, -20), IntSize(510, 520), true, opaqueLayers);
- setLayerPropertiesForTesting(child2.get(), child2Transform, FloatPoint(20, 40), IntSize(10, 10));
- setLayerPropertiesForTesting(layer2.get(), identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true, opaqueLayers);
-
- // Make them both render surfaces
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- child1->setFilters(filters);
- child2->setFilters(filters);
-
- child1->setMasksToBounds(false);
- child2->setMasksToBounds(false);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(-30, -30, 1000, 1000));
-
- occlusion.enterTargetRenderSurface(child2->renderSurface());
- occlusion.markOccludedBehindLayer(layer2.get());
-
- EXPECT_EQ_RECT(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child2.get(), IntRect(-10, 420, 70, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-11, 420, 70, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-10, 419, 70, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-10, 420, 71, 80)));
- EXPECT_FALSE(occlusion.occluded(child2.get(), IntRect(-10, 420, 70, 81)));
-
- occlusion.markOccludedBehindLayer(child2.get());
- occlusion.finishedTargetRenderSurface(child2.get(), child2->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(child1->renderSurface());
- occlusion.markOccludedBehindLayer(layer1.get());
-
- EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(420, -20, 80, 90), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(child1.get(), IntRect(420, -20, 80, 90)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(419, -20, 80, 90)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(420, -21, 80, 90)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(420, -19, 80, 90)));
- EXPECT_FALSE(occlusion.occluded(child1.get(), IntRect(421, -20, 80, 90)));
-
- occlusion.markOccludedBehindLayer(child1.get());
- occlusion.finishedTargetRenderSurface(child1.get(), child1->renderSurface());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(10, 20, 90, 80)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(9, 20, 90, 80)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(10, 19, 90, 80)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(11, 20, 90, 80)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(10, 21, 90, 80)));
-
- /* Justification for the above occlusion:
- 100
- +---------------------+
- |20 | layer1
- 10+----------------------------------+
- 100 || 30 | layer2 |
- |20+----------------------------------+
- || | | | |
- || | | | |
- || | | | |
- +|-|------------------+ | |
- | | | | 510
- | | 510 | |
- | | | |
- | | | |
- | | | |
- | | | |
- | | 520 | |
- +----------------------------------+ |
- | |
- +----------------------------------+
- 510
- */
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_surfaceOcclusionInScreenSpaceDifferentTransforms, surfaceOcclusionInScreenSpaceDifferentTransforms);
-
-void occlusionInteractionWithFilters(bool opaqueLayers)
-{
- // This tests that the right transforms are being used.
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> blurLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> opacityLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> opaqueLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(blurLayer);
- parent->addChild(opacityLayer);
- parent->addChild(opaqueLayer);
-
- TransformationMatrix layerTransform;
- layerTransform.translate(250, 250);
- layerTransform.rotate(90);
- layerTransform.translate(-250, -250);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
- setLayerPropertiesForTesting(blurLayer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
- setLayerPropertiesForTesting(opaqueLayer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
- setLayerPropertiesForTesting(opacityLayer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
+ typename Types::ContentLayerType* createRoot(const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
+ {
+ typename Types::ContentLayerPtrType layer(Types::createContentLayer());
+ typename Types::ContentLayerType* layerPtr = layer.get();
+ setProperties(layerPtr, transform, position, bounds);
+
+ ASSERT(!m_root);
+ m_root = layer.release();
+ return layerPtr;
+ }
+
+ typename Types::LayerType* createLayer(typename Types::LayerType* parent, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
+ {
+ typename Types::LayerPtrType layer(Types::createLayer());
+ typename Types::LayerType* layerPtr = layer.get();
+ setProperties(layerPtr, transform, position, bounds);
+ parent->addChild(layer.release());
+ return layerPtr;
+ }
+ typename Types::LayerType* createSurface(typename Types::LayerType* parent, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
{
+ typename Types::LayerType* layer = createLayer(parent, transform, position, bounds);
FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(10, WebCore::Percent), FilterOperation::BLUR));
- blurLayer->setFilters(filters);
+ filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
+ layer->setFilters(filters);
+ return layer;
}
+ typename Types::ContentLayerType* createDrawingLayer(typename Types::LayerType* parent, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
{
+ typename Types::ContentLayerPtrType layer(Types::createContentLayer());
+ typename Types::ContentLayerType* layerPtr = layer.get();
+ setProperties(layerPtr, transform, position, bounds);
+
+ if (opaqueLayers)
+ layerPtr->setOpaque(opaque);
+ else {
+ layerPtr->setOpaque(false);
+ if (opaque)
+ layerPtr->setOpaqueContentsRect(IntRect(IntPoint(), bounds));
+ else
+ layerPtr->setOpaqueContentsRect(IntRect());
+ }
+
+ parent->addChild(layer.release());
+ return layerPtr;
+ }
+
+ typename Types::LayerType* createReplicaLayer(typename Types::LayerType* owningLayer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
+ {
+ typename Types::ContentLayerPtrType layer(Types::createContentLayer());
+ typename Types::ContentLayerType* layerPtr = layer.get();
+ setProperties(layerPtr, transform, position, bounds);
+ setReplica(owningLayer, layer.release());
+ return layerPtr;
+ }
+
+ typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
+ {
+ typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque);
FilterOperations filters;
filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- opaqueLayer->setFilters(filters);
+ layer->setFilters(filters);
+ return layer;
+ }
+
+ void calcDrawEtc(TestContentLayerImpl* root)
+ {
+ ASSERT(root == m_root.get());
+ Vector<CCLayerImpl*> dummyLayerList;
+ int dummyMaxTextureSize = 512;
+
+ ASSERT(!root->renderSurface());
+ root->createRenderSurface();
+ root->renderSurface()->setContentRect(IntRect(IntPoint::zero(), root->bounds()));
+ root->setClipRect(IntRect(IntPoint::zero(), root->bounds()));
+ m_renderSurfaceLayerListImpl.append(m_root.get());
+
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(root, root, identityMatrix, identityMatrix, m_renderSurfaceLayerListImpl, dummyLayerList, 0, dummyMaxTextureSize);
+ m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListImpl);
+ }
+
+ void calcDrawEtc(TestContentLayerChromium* root)
+ {
+ ASSERT(root == m_root.get());
+ Vector<RefPtr<LayerChromium> > dummyLayerList;
+ int dummyMaxTextureSize = 512;
+
+ ASSERT(!root->renderSurface());
+ root->createRenderSurface();
+ root->renderSurface()->setContentRect(IntRect(IntPoint::zero(), root->bounds()));
+ root->setClipRect(IntRect(IntPoint::zero(), root->bounds()));
+ m_renderSurfaceLayerListChromium.append(m_root);
+
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(root, root, identityMatrix, identityMatrix, m_renderSurfaceLayerListChromium, dummyLayerList, dummyMaxTextureSize);
+ m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListChromium);
}
+ void enterLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
{
+ ASSERT_EQ(layer, *m_layerIterator);
+ ASSERT_TRUE(m_layerIterator.representsItself());
+ occlusion.enterLayer(m_layerIterator);
+ }
+
+ void leaveLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
+ {
+ ASSERT_EQ(layer, *m_layerIterator);
+ ASSERT_TRUE(m_layerIterator.representsItself());
+ occlusion.leaveLayer(m_layerIterator);
+ ++m_layerIterator;
+ }
+
+ void visitLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
+ {
+ enterLayer(layer, occlusion);
+ leaveLayer(layer, occlusion);
+ }
+
+ void enterContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
+ {
+ ASSERT_EQ(layer, *m_layerIterator);
+ ASSERT_TRUE(m_layerIterator.representsTargetRenderSurface());
+ occlusion.enterLayer(m_layerIterator);
+ occlusion.leaveLayer(m_layerIterator);
+ ++m_layerIterator;
+ ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
+ occlusion.enterLayer(m_layerIterator);
+ }
+
+ void leaveContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
+ {
+ ASSERT_EQ(layer, *m_layerIterator);
+ ASSERT_TRUE(m_layerIterator.representsContributingRenderSurface());
+ occlusion.leaveLayer(m_layerIterator);
+ ++m_layerIterator;
+ }
+
+ void visitContributingSurface(typename Types::LayerType* layer, typename Types::OcclusionTrackerType& occlusion)
+ {
+ enterContributingSurface(layer, occlusion);
+ leaveContributingSurface(layer, occlusion);
+ }
+
+ void resetLayerIterator()
+ {
+ m_layerIterator = m_layerIteratorBegin;
+ }
+
+ const TransformationMatrix identityMatrix;
+
+private:
+ void setBaseProperties(typename Types::LayerType* layer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
+ {
+ layer->setTransform(transform);
+ layer->setSublayerTransform(TransformationMatrix());
+ layer->setAnchorPoint(FloatPoint(0, 0));
+ layer->setPosition(position);
+ layer->setBounds(bounds);
+ }
+
+ void setProperties(LayerChromium* layer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
+ {
+ setBaseProperties(layer, transform, position, bounds);
+ }
+
+ void setProperties(CCLayerImpl* layer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
+ {
+ setBaseProperties(layer, transform, position, bounds);
+
+ layer->setContentBounds(layer->bounds());
+ }
+
+ void setReplica(LayerChromium* owningLayer, PassRefPtr<LayerChromium> layer)
+ {
+ owningLayer->setReplicaLayer(layer.get());
+ m_replicaLayers.append(layer);
+ }
+
+ void setReplica(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer)
+ {
+ owningLayer->setReplicaLayer(layer);
+ }
+
+ // These hold ownership of the layers for the duration of the test.
+ typename Types::LayerPtrType m_root;
+ Vector<RefPtr<LayerChromium> > m_renderSurfaceLayerListChromium;
+ Vector<CCLayerImpl*> m_renderSurfaceLayerListImpl;
+ typename Types::LayerIterator m_layerIteratorBegin;
+ typename Types::LayerIterator m_layerIterator;
+ typename Types::LayerType* m_lastLayerVisited;
+ Vector<RefPtr<LayerChromium> > m_replicaLayers;
+};
+
+#define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
+ class ClassName##MainThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestMainThreadTypes, true> { \
+ public: \
+ ClassName##MainThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestMainThreadTypes, true>() { } \
+ }; \
+ TEST_F(ClassName##MainThreadOpaqueLayers, runTest) { runMyTest(); }
+#define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
+ class ClassName##MainThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestMainThreadTypes, false> { \
+ public: \
+ ClassName##MainThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestMainThreadTypes, false>() { } \
+ }; \
+ TEST_F(ClassName##MainThreadOpaquePaints, runTest) { runMyTest(); }
+
+#define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
+ class ClassName##ImplThreadOpaqueLayers : public ClassName<CCOcclusionTrackerTestImplThreadTypes, true> { \
+ DebugScopedSetImplThread impl; \
+ public: \
+ ClassName##ImplThreadOpaqueLayers() : ClassName<CCOcclusionTrackerTestImplThreadTypes, true>() { } \
+ }; \
+ TEST_F(ClassName##ImplThreadOpaqueLayers, runTest) { runMyTest(); }
+#define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
+ class ClassName##ImplThreadOpaquePaints : public ClassName<CCOcclusionTrackerTestImplThreadTypes, false> { \
+ DebugScopedSetImplThread impl; \
+ public: \
+ ClassName##ImplThreadOpaquePaints() : ClassName<CCOcclusionTrackerTestImplThreadTypes, false>() { } \
+ }; \
+ TEST_F(ClassName##ImplThreadOpaquePaints, runTest) { runMyTest(); }
+
+#define ALL_CCOCCLUSIONTRACKER_TEST(ClassName) \
+ RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
+ RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
+ RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
+ RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
+
+#define MAIN_THREAD_TEST(ClassName) \
+ RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
+
+#define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
+ RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
+ RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestIdentityTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(30, 30), IntSize(500, 500), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 29, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 29, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 31, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 31, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 31, 70, 70)));
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestIdentityTransforms);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestRotatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix layerTransform;
+ layerTransform.translate(250, 250);
+ layerTransform.rotate(90);
+ layerTransform.translate(-250, -250);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 70, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 70, 70)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 30, 70, 70)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 70, 70)));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(29, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(29, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 29, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(30, 29, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(31, 29, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 29, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(100, 30, 1, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(31, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(31, 31, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 31, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent, IntRect(29, 31, 70, 70)));
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestRotatedChild);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestTranslatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix layerTransform;
+ layerTransform.translate(20, 20);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 50, 50, 50)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(49, 50, 50, 50)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 49, 50, 50)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(51, 50, 50, 50)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 51, 50, 50)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 50, 50, 50)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(49, 50, 50, 50)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(50, 49, 50, 50)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(51, 50, 50, 50)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(50, 51, 50, 50)));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 50, 50, 50)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 50, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 49, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 49, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(51, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 49, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(100, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 50, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(51, 51, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(51, 51, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(50, 100, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 51, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(49, 51, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 51, 50, 50)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 50, 50, 50)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(49, 50, 1, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 50, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(49, 49, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(49, 49, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(50, 49, 50, 1), occlusion.unoccludedContentRect(parent, IntRect(50, 49, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(51, 49, 49, 1), occlusion.unoccludedContentRect(parent, IntRect(51, 49, 50, 50)));
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(51, 50, 50, 50)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(51, 51, 50, 50)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(50, 51, 50, 50)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(49, 51, 1, 49), occlusion.unoccludedContentRect(parent, IntRect(49, 51, 50, 50)));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTranslatedChild);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestChildInRotatedChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix childTransform;
+ childTransform.translate(250, 250);
+ childTransform.rotate(90);
+ childTransform.translate(-250, -250);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
+ child->setMasksToBounds(true);
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(layer, occlusion);
+ this->enterContributingSurface(child, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 430, 61, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 430, 60, 71)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 61, 70)));
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 71)));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->leaveContributingSurface(child, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 41, 70, 60)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(31, 40, 70, 60)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 41, 70, 60)));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+
+ /* Justification for the above occlusion from |layer|:
+ 100
+ +---------------------+ +---------------------+
+ | | | |30 Visible region of |layer|: /////
+ | 30 | rotate(90) | |
+ | 30 + ---------------------------------+ | +---------------------------------+
+ 100 | | 10 | | ==> | | |10 |
+ | |10+---------------------------------+ | +---------------------------------+ |
+ | | | | | | | | |///////////////| 420 | |
+ | | | | | | | | |///////////////|60 | |
+ | | | | | | | | |///////////////| | |
+ +----|--|-------------+ | | +--|--|---------------+ | |
+ | | | | 20|10| 70 | |
+ | | | | | | | |
+ | | | |500 | | | |
+ | | | | | | | |
+ | | | | | | | |
+ | | | | | | | |
+ | | | | | | |10|
+ +--|-------------------------------+ | | +------------------------------|--+
+ | | | 490 |
+ +---------------------------------+ +---------------------------------+
+ 500 500
+ */
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestChildInRotatedChild);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestVisitTargetTwoTimes : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix childTransform;
+ childTransform.translate(250, 250);
+ childTransform.rotate(90);
+ childTransform.translate(-250, -250);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
+ child->setMasksToBounds(true);
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
+ // |child2| makes |parent|'s surface get considered by CCOcclusionTracker first, instead of |child|'s. This exercises different code in
+ // leaveToTargetRenderSurface, as the target surface has already been seen.
+ typename Types::ContentLayerType* child2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(30, 30), IntSize(60, 20), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(-10, -10, 1000, 1000));
+
+ this->visitLayer(child2, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 30, 60, 20), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(30, 30, 60, 20), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ this->visitLayer(layer, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ this->enterContributingSurface(child, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(11, 430, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 431, 60, 70)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(11, 430, 60, 70)));
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 431, 60, 70)));
+ occlusion.setLayerScissorRect(IntRect(-10, -10, 1000, 1000));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 430, 60, 70)).isEmpty());
+ // This is the little piece not occluded by child2
+ EXPECT_EQ_RECT(IntRect(9, 430, 1, 10), occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 70)));
+ // This extends past both sides of child2, so it will be the original rect.
+ EXPECT_EQ_RECT(IntRect(9, 430, 60, 80), occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 80)));
+ // This extends past two adjacent sides of child2, and should included the unoccluded parts of each side.
+ // This also demonstrates that the rect can be arbitrary and does not get clipped to the layer's visibleLayerRect().
+ EXPECT_EQ_RECT(IntRect(-10, 430, 20, 70), occlusion.unoccludedContentRect(child, IntRect(-10, 430, 60, 70)));
+ // This extends past three adjacent sides of child2, so it should contain the unoccluded parts of each side. The left
+ // and bottom edges are completely unoccluded for some row/column so we get back the original query rect.
+ EXPECT_EQ_RECT(IntRect(-10, 430, 60, 80), occlusion.unoccludedContentRect(child, IntRect(-10, 430, 60, 80)));
+ EXPECT_EQ_RECT(IntRect(10, 429, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 429, 60, 70)));
+ EXPECT_EQ_RECT(IntRect(70, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(11, 430, 60, 70)));
+ EXPECT_EQ_RECT(IntRect(10, 500, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 431, 60, 70)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 430, 60, 70)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 70)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 80)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(-10, 430, 60, 70)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(-10, 430, 60, 80)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 429, 60, 70)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(11, 430, 60, 70)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 431, 60, 70)).isEmpty());
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ // Occlusion in |child2| should get merged with the |child| surface we are leaving now.
+ this->leaveContributingSurface(child, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 30, 70, 70)));
+ EXPECT_EQ_RECT(IntRect(90, 30, 10, 10), occlusion.unoccludedContentRect(parent, IntRect(30, 30, 70, 70)));
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 30, 60, 10)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 30, 60, 10)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 29, 60, 10)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(31, 30, 60, 10)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 31, 60, 10)));
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 30, 60, 10)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(29, 30, 1, 10), occlusion.unoccludedContentRect(parent, IntRect(29, 30, 60, 10)));
+ EXPECT_EQ_RECT(IntRect(30, 29, 60, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 60, 10)));
+ EXPECT_EQ_RECT(IntRect(90, 30, 1, 10), occlusion.unoccludedContentRect(parent, IntRect(31, 30, 60, 10)));
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 31, 60, 10)).isEmpty());
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 40, 70, 60)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(29, 40, 70, 60)));
+ // This rect is mostly occluded by |child2|.
+ EXPECT_EQ_RECT(IntRect(90, 39, 10, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 39, 70, 60)));
+ // This rect extends past top/right ends of |child2|.
+ EXPECT_EQ_RECT(IntRect(30, 29, 70, 11), occlusion.unoccludedContentRect(parent, IntRect(30, 29, 70, 70)));
+ // This rect extends past left/right ends of |child2|.
+ EXPECT_EQ_RECT(IntRect(20, 39, 80, 60), occlusion.unoccludedContentRect(parent, IntRect(20, 39, 80, 60)));
+ EXPECT_EQ_RECT(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(31, 40, 70, 60)));
+ EXPECT_EQ_RECT(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 41, 70, 60)));
+
+ /* Justification for the above occlusion from |layer|:
+ 100
+ +---------------------+ +---------------------+
+ | | | |30 Visible region of |layer|: /////
+ | 30 | rotate(90) | 30 60 | |child2|: \\\\\
+ | 30 + ------------+--------------------+ | 30 +------------+--------------------+
+ 100 | | 10 | | | ==> | |\\\\\\\\\\\\| |10 |
+ | |10+----------|----------------------+ | +--|\\\\\\\\\\\\|-----------------+ |
+ | + ------------+ | | | | | +------------+//| 420 | |
+ | | | | | | | | |///////////////|60 | |
+ | | | | | | | | |///////////////| | |
+ +----|--|-------------+ | | +--|--|---------------+ | |
+ | | | | 20|10| 70 | |
+ | | | | | | | |
+ | | | |500 | | | |
+ | | | | | | | |
+ | | | | | | | |
+ | | | | | | | |
+ | | | | | | |10|
+ +--|-------------------------------+ | | +------------------------------|--+
+ | | | 490 |
+ +---------------------------------+ +---------------------------------+
+ 500 500
+ */
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestVisitTargetTwoTimes);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestSurfaceRotatedOffAxis : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix childTransform;
+ childTransform.translate(250, 250);
+ childTransform.rotate(95);
+ childTransform.translate(-250, -250);
+
+ TransformationMatrix layerTransform;
+ layerTransform.translate(10, 10);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
+ child->setMasksToBounds(true);
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(child, layerTransform, FloatPoint(0, 0), IntSize(500, 500), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ IntRect clippedLayerInChild = layerTransform.mapRect(layer->visibleLayerRect());
+
+ this->visitLayer(layer, occlusion);
+ this->enterContributingSurface(child, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(clippedLayerInChild, occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(child, clippedLayerInChild));
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
+ clippedLayerInChild.move(-1, 0);
+ EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
+ EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
+ clippedLayerInChild.move(1, 0);
+ clippedLayerInChild.move(1, 0);
+ EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
+ EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
+ clippedLayerInChild.move(-1, 0);
+ clippedLayerInChild.move(0, -1);
+ EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
+ EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
+ clippedLayerInChild.move(0, 1);
+ clippedLayerInChild.move(0, 1);
+ EXPECT_FALSE(occlusion.occluded(child, clippedLayerInChild));
+ EXPECT_FALSE(occlusion.unoccludedContentRect(child, clippedLayerInChild).isEmpty());
+ clippedLayerInChild.move(0, -1);
+
+ this->leaveContributingSurface(child, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(75, 55, 1, 1)));
+ EXPECT_EQ_RECT(IntRect(75, 55, 1, 1), occlusion.unoccludedContentRect(parent, IntRect(75, 55, 1, 1)));
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceRotatedOffAxis);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix childTransform;
+ childTransform.translate(250, 250);
+ childTransform.rotate(90);
+ childTransform.translate(-250, -250);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500));
+ child->setMasksToBounds(true);
+ typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true);
+ typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 450), IntSize(500, 60), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(layer2, occlusion);
+ this->visitLayer(layer1, occlusion);
+ this->enterContributingSurface(child, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(10, 430, 60, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(child, IntRect(10, 430, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(9, 430, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 429, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(11, 430, 60, 70)));
+ EXPECT_FALSE(occlusion.occluded(child, IntRect(10, 431, 60, 70)));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(child, IntRect(10, 430, 60, 70)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(9, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(9, 430, 60, 70)));
+ EXPECT_EQ_RECT(IntRect(10, 429, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 429, 60, 70)));
+ EXPECT_EQ_RECT(IntRect(70, 430, 1, 70), occlusion.unoccludedContentRect(child, IntRect(11, 430, 60, 70)));
+ EXPECT_EQ_RECT(IntRect(10, 500, 60, 1), occlusion.unoccludedContentRect(child, IntRect(10, 431, 60, 70)));
+
+ this->leaveContributingSurface(child, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(30, 40, 70, 60), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 40, 70, 60)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 39, 70, 60)));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(30, 40, 70, 60)).isEmpty());
+ EXPECT_EQ_RECT(IntRect(29, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(29, 40, 70, 60)));
+ EXPECT_EQ_RECT(IntRect(30, 39, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 39, 70, 60)));
+ EXPECT_EQ_RECT(IntRect(100, 40, 1, 60), occlusion.unoccludedContentRect(parent, IntRect(31, 40, 70, 60)));
+ EXPECT_EQ_RECT(IntRect(30, 100, 70, 1), occlusion.unoccludedContentRect(parent, IntRect(30, 41, 70, 60)));
+
+ /* Justification for the above occlusion from |layer1| and |layer2|:
+
+ +---------------------+
+ | |30 Visible region of |layer1|: /////
+ | | Visible region of |layer2|: \\\\\
+ | +---------------------------------+
+ | | |10 |
+ | +---------------+-----------------+ |
+ | | |\\\\\\\\\\\\|//| 420 | |
+ | | |\\\\\\\\\\\\|//|60 | |
+ | | |\\\\\\\\\\\\|//| | |
+ +--|--|------------|--+ | |
+ 20|10| 70 | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | |10|
+ | +------------|-----------------|--+
+ | | 490 |
+ +---------------+-----------------+
+ 60 440
+ */
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestOverlappingSurfaceSiblings : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix childTransform;
+ childTransform.translate(250, 250);
+ childTransform.rotate(90);
+ childTransform.translate(-250, -250);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::LayerType* child1 = this->createSurface(parent, childTransform, FloatPoint(30, 30), IntSize(10, 10));
+ typename Types::LayerType* child2 = this->createSurface(parent, childTransform, FloatPoint(20, 40), IntSize(10, 10));
+ typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
+ typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(-20, -20, 1000, 1000));
+
+ this->visitLayer(layer2, occlusion);
+ this->enterContributingSurface(child2, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
+ EXPECT_FALSE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
+ EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
+ EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
+ EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
+ EXPECT_TRUE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
+ EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
+ EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
+ EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
+ occlusion.setLayerScissorRect(IntRect(-20, -20, 1000, 1000));
+
+ // There is nothing above child2's surface in the z-order.
+ EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2->renderSurface(), false, IntRect(-10, 420, 70, 80)));
+
+ this->leaveContributingSurface(child2, occlusion);
+ this->visitLayer(layer1, occlusion);
+ this->enterContributingSurface(child1, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(-10, 430, 80, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(child1, IntRect(-10, 430, 80, 70)));
+ EXPECT_FALSE(occlusion.occluded(child1, IntRect(-11, 430, 80, 70)));
+ EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 429, 80, 70)));
+ EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 81, 70)));
+ EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 80, 71)));
+
+ // child2's contents will occlude child1 below it.
+ EXPECT_EQ_RECT(IntRect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1->renderSurface(), false, IntRect(-10, 430, 80, 70)));
+
+ this->leaveContributingSurface(child1, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(20, 20, 80, 80), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(20, 20, 80, 80)));
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(30, 20, 70, 80)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(29, 20, 70, 80)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(30, 19, 70, 80)));
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(20, 30, 80, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(19, 30, 80, 70)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(20, 29, 80, 70)));
+
+ /* Justification for the above occlusion:
+ 100
+ +---------------------+
+ | 20 | layer1
+ | 30+ ---------------------------------+
+ 100 | 30| | layer2 |
+ |20+----------------------------------+ |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ +--|-|----------------+ | |
+ | | | | 510
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | +--------------------------------|-+
+ | |
+ +----------------------------------+
+ 510
+ */
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblings);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix child1Transform;
+ child1Transform.translate(250, 250);
+ child1Transform.rotate(-90);
+ child1Transform.translate(-250, -250);
+
+ TransformationMatrix child2Transform;
+ child2Transform.translate(250, 250);
+ child2Transform.rotate(90);
+ child2Transform.translate(-250, -250);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::LayerType* child1 = this->createSurface(parent, child1Transform, FloatPoint(30, 20), IntSize(10, 10));
+ typename Types::LayerType* child2 = this->createDrawingSurface(parent, child2Transform, FloatPoint(20, 40), IntSize(10, 10), false);
+ typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -20), IntSize(510, 510), true);
+ typename Types::ContentLayerType* layer2 = this->createDrawingLayer(child2, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(-30, -30, 1000, 1000));
+
+ this->visitLayer(layer2, occlusion);
+ this->enterLayer(child2, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(20, 30, 80, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(child2, IntRect(-10, 420, 70, 80)));
+ EXPECT_FALSE(occlusion.occluded(child2, IntRect(-11, 420, 70, 80)));
+ EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 419, 70, 80)));
+ EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 71, 80)));
+ EXPECT_FALSE(occlusion.occluded(child2, IntRect(-10, 420, 70, 81)));
+
+ this->leaveLayer(child2, occlusion);
+ this->enterContributingSurface(child2, occlusion);
+
+ // There is nothing above child2's surface in the z-order.
+ EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2->renderSurface(), false, IntRect(-10, 420, 70, 80)));
+
+ this->leaveContributingSurface(child2, occlusion);
+ this->visitLayer(layer1, occlusion);
+ this->enterContributingSurface(child1, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(420, -20, 80, 90), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(child1, IntRect(420, -20, 80, 90)));
+ EXPECT_FALSE(occlusion.occluded(child1, IntRect(419, -20, 80, 90)));
+ EXPECT_FALSE(occlusion.occluded(child1, IntRect(420, -21, 80, 90)));
+ EXPECT_FALSE(occlusion.occluded(child1, IntRect(420, -19, 80, 90)));
+ EXPECT_FALSE(occlusion.occluded(child1, IntRect(421, -20, 80, 90)));
+
+ // child2's contents will occlude child1 below it.
+ EXPECT_EQ_RECT(IntRect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1->renderSurface(), false, IntRect(420, -20, 80, 90)));
+ EXPECT_EQ_RECT(IntRect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1->renderSurface(), false, IntRect(420, -10, 80, 90)));
+ EXPECT_EQ_RECT(IntRect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1->renderSurface(), false, IntRect(420, -20, 70, 90)));
+
+ this->leaveContributingSurface(child1, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(10, 20, 90, 80)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(9, 20, 90, 80)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(10, 19, 90, 80)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(11, 20, 90, 80)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(10, 21, 90, 80)));
+
+ /* Justification for the above occlusion:
+ 100
+ +---------------------+
+ |20 | layer1
+ 10+----------------------------------+
+ 100 || 30 | layer2 |
+ |20+----------------------------------+
+ || | | | |
+ || | | | |
+ || | | | |
+ +|-|------------------+ | |
+ | | | | 510
+ | | 510 | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | 520 | |
+ +----------------------------------+ |
+ | |
+ +----------------------------------+
+ 510
+ */
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestFilters : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix layerTransform;
+ layerTransform.translate(250, 250);
+ layerTransform.rotate(90);
+ layerTransform.translate(-250, -250);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::ContentLayerType* blurLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
+ typename Types::ContentLayerType* opaqueLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
+ typename Types::ContentLayerType* opacityLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
+
FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(10, WebCore::Percent), FilterOperation::BLUR));
+ blurLayer->setFilters(filters);
+
+ filters.operations().clear();
+ filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
+ opaqueLayer->setFilters(filters);
+
+ filters.operations().clear();
filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::OPACITY));
opacityLayer->setFilters(filters);
+
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ // Opacity layer won't contribute to occlusion.
+ this->visitLayer(opacityLayer, occlusion);
+ this->enterContributingSurface(opacityLayer, occlusion);
+
+ EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
+ EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
+
+ // And has nothing to contribute to its parent surface.
+ this->leaveContributingSurface(opacityLayer, occlusion);
+ EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
+ EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
+
+ // Opaque layer will contribute to occlusion.
+ this->visitLayer(opaqueLayer, occlusion);
+ this->enterContributingSurface(opaqueLayer, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 430, 70, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // And it gets translated to the parent surface.
+ this->leaveContributingSurface(opaqueLayer, occlusion);
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // The blur layer needs to throw away any occlusion from outside its subtree.
+ this->enterLayer(blurLayer, occlusion);
+ EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
+ EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
+
+ // And it won't contribute to occlusion.
+ this->leaveLayer(blurLayer, occlusion);
+ this->enterContributingSurface(blurLayer, occlusion);
+ EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
+ EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
+
+ // But the opaque layer's occlusion is preserved on the parent.
+ this->leaveContributingSurface(blurLayer, occlusion);
+ this->enterLayer(parent, occlusion);
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
}
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestFilters);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestReplicaDoesOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
+ this->calcDrawEtc(parent);
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+ this->visitLayer(surface, occlusion);
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+ EXPECT_EQ_RECT(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+ this->visitContributingSurface(surface, occlusion);
+ this->enterLayer(parent, occlusion);
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+ // The surface and replica should both be occluding the parent.
+ EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
+ }
+};
- // Opacity layer won't contribute to occlusion.
- occlusion.enterTargetRenderSurface(opacityLayer->renderSurface());
- occlusion.markOccludedBehindLayer(opacityLayer.get());
- occlusion.finishedTargetRenderSurface(opacityLayer.get(), opacityLayer->renderSurface());
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaDoesOcclude);
- EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
- EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestReplicaWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 170));
+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true);
+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize());
+ this->calcDrawEtc(parent);
- // And has nothing to contribute to its parent surface.
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
- EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
- // Opaque layer will contribute to occlusion.
- occlusion.enterTargetRenderSurface(opaqueLayer->renderSurface());
- occlusion.markOccludedBehindLayer(opaqueLayer.get());
- occlusion.finishedTargetRenderSurface(opaqueLayer.get(), opaqueLayer->renderSurface());
+ this->visitLayer(surface, occlusion);
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(0, 430, 70, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 100, 50, 50), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- // And it gets translated to the parent surface.
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ this->visitContributingSurface(surface, occlusion);
+ this->enterLayer(parent, occlusion);
- // The blur layer needs to throw away any occlusion from outside its subtree.
- occlusion.enterTargetRenderSurface(blurLayer->renderSurface());
- EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
- EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
+ // The surface and replica should both be occluding the parent.
+ EXPECT_EQ_RECT(IntRect(0, 100, 100, 70), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
+ }
+};
- // And it won't contribute to occlusion.
- occlusion.markOccludedBehindLayer(blurLayer.get());
- occlusion.finishedTargetRenderSurface(blurLayer.get(), blurLayer->renderSurface());
- EXPECT_TRUE(occlusion.occlusionInScreenSpace().isEmpty());
- EXPECT_TRUE(occlusion.occlusionInTargetSurface().isEmpty());
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaWithClipping);
- // But the opaque layer's occlusion is preserved on the parent.
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInScreenSpace().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occlusion.occlusionInTargetSurface().bounds());
- EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
-}
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestLayerScissorRectOutsideChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(200, 100, 100, 100));
+
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
+ occlusion.setLayerScissorRect(IntRect(200, 100, 100, 100));
+
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+
+ EXPECT_EQ_RECT(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ }
+};
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_occlusionInteractionWithFilters, occlusionInteractionWithFilters);
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectOutsideChild);
-void layerScissorRectOverTile(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
-
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(200, 100, 100, 100));
-
- occlusion.enterTargetRenderSurface(layer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
-
- occlusion.useDefaultLayerScissorRect();
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
- occlusion.setLayerScissorRect(IntRect(200, 100, 100, 100));
-
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
-
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectOverTile, layerScissorRectOverTile);
-
-void screenScissorRectOverTile(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestScreenScissorRectOutsideChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(200, 100, 100, 100));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
+
+ occlusion.useDefaultLayerScissorRect();
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+
+ EXPECT_EQ_RECT(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ }
+};
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestScreenScissorRectOutsideChild);
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestLayerScissorRectOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(100, 100, 100, 100));
+
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
+ }
+};
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectOverChild);
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestScreenScissorRectOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(100, 100, 100, 100));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
+ }
+};
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestScreenScissorRectOverChild);
- TestCCOcclusionTracker occlusion(IntRect(200, 100, 100, 100));
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestLayerScissorRectPartlyOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(50, 50, 200, 200));
+
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+
+ EXPECT_EQ_RECT(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ EXPECT_EQ_RECT(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)));
+ EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)));
+ EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)));
+ }
+};
- occlusion.enterTargetRenderSurface(layer->renderSurface());
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectPartlyOverChild);
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestScreenScissorRectPartlyOverChild : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(50, 50, 200, 200));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+
+ EXPECT_EQ_RECT(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ EXPECT_EQ_RECT(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)));
+ EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)));
+ EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)));
+ }
+};
- // Occluded since its outside the surface bounds.
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestScreenScissorRectPartlyOverChild);
- // Test without any scissors.
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
- occlusion.useDefaultLayerScissorRect();
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestLayerScissorRectOverNothing : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(500, 500, 100, 100));
+
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)).isEmpty());
+ }
+};
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectOverNothing);
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestScreenScissorRectOverNothing : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(500, 500, 100, 100));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 0, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(0, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 200, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 100)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(0, 100, 300, 100)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(200, 100, 100, 100)).isEmpty());
+ EXPECT_TRUE(occlusion.unoccludedContentRect(parent, IntRect(100, 200, 100, 100)).isEmpty());
+ }
+};
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestScreenScissorRectOverNothing);
- EXPECT_EQ_RECT(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
-}
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestLayerScissorRectForLayerOffOrigin : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ this->enterLayer(layer, occlusion);
+
+ // This layer is translated when drawn into its target. So if the scissor rect given from the target surface
+ // is not in that target space, then after translating these query rects into the target, they will fall outside
+ // the scissor and be considered occluded.
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
+ }
+};
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_screenScissorRectOverTile, screenScissorRectOverTile);
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestLayerScissorRectForLayerOffOrigin);
-void layerScissorRectOverCulledTile(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestOpaqueContentsRegionEmpty : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 200), false);
+ this->calcDrawEtc(parent);
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ this->enterLayer(layer, occlusion);
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 0, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(0, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(100, 100, 100, 100)));
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+ // Occluded since its outside the surface bounds.
+ EXPECT_TRUE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+ // Test without any scissors.
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+ EXPECT_FALSE(occlusion.occluded(layer, IntRect(200, 100, 100, 100)));
+ occlusion.useDefaultLayerScissorRect();
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+ this->leaveLayer(layer, occlusion);
+ this->visitContributingSurface(layer, occlusion);
+ this->enterLayer(parent, occlusion);
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(100, 100, 100, 100));
+ EXPECT_TRUE(occlusion.occlusionInScreenSpace().bounds().isEmpty());
+ EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
+ }
+};
- occlusion.enterTargetRenderSurface(layer->renderSurface());
+MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionEmpty);
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(200, 200), false);
+ this->calcDrawEtc(parent);
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
+ {
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ layer->setOpaqueContentsRect(IntRect(0, 0, 100, 100));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
+ this->resetLayerIterator();
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ EXPECT_EQ_RECT(IntRect(100, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
-}
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+ }
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectOverCulledTile, layerScissorRectOverCulledTile);
+ {
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ layer->setOpaqueContentsRect(IntRect(20, 20, 180, 180));
-void screenScissorRectOverCulledTile(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
+ this->resetLayerIterator();
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
+ EXPECT_EQ_RECT(IntRect(120, 120, 180, 180), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_TRUE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+ }
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+ {
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ layer->setOpaqueContentsRect(IntRect(150, 150, 100, 100));
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+ this->resetLayerIterator();
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+ EXPECT_EQ_RECT(IntRect(250, 250, 50, 50), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- TestCCOcclusionTracker occlusion(IntRect(100, 100, 100, 100));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(0, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(100, 100, 100, 100)));
+ EXPECT_FALSE(occlusion.occluded(parent, IntRect(200, 200, 100, 100)));
+ }
+ }
+};
- occlusion.enterTargetRenderSurface(layer->renderSurface());
+MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty);
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTest3dTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix transform;
+ transform.rotate3d(0, 30, 0);
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
+ this->calcDrawEtc(parent);
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ this->enterLayer(layer, occlusion);
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ // The layer is rotated in 3d but without preserving 3d, so it only gets resized.
+ EXPECT_EQ_RECT(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
+ }
+};
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
-}
+MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTest3dTransform);
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_screenScissorRectOverCulledTile, screenScissorRectOverCulledTile);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestPerspectiveTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix transform;
+ transform.translate(150, 150);
+ transform.applyPerspective(400);
+ transform.rotate3d(1, 0, 0, -30);
+ transform.translate(-150, -150);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
+ container->setPreserves3D(true);
+ layer->setPreserves3D(true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ this->enterLayer(layer, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
+ }
+};
-void layerScissorRectOverPartialTiles(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
-
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(50, 50, 200, 200));
-
- occlusion.enterTargetRenderSurface(layer->renderSurface());
-
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
-
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
-
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
- EXPECT_EQ_RECT(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 100)));
- EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 100, 300, 100)));
- EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(200, 100, 100, 100)));
- EXPECT_EQ_RECT(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)));
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectOverPartialTiles, layerScissorRectOverPartialTiles);
-
-void screenScissorRectOverPartialTiles(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
-
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(50, 50, 200, 200));
-
- occlusion.enterTargetRenderSurface(layer->renderSurface());
-
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
-
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
-
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
- EXPECT_EQ_RECT(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 100)));
- EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 100, 300, 100)));
- EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(200, 100, 100, 100)));
- EXPECT_EQ_RECT(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)));
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_screenScissorRectOverPartialTiles, screenScissorRectOverPartialTiles);
-
-void layerScissorRectOverNoTiles(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
-
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.setLayerScissorRect(IntRect(500, 500, 100, 100));
-
- occlusion.enterTargetRenderSurface(layer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
-
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
-
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 100, 300, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(200, 100, 100, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)).isEmpty());
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectOverNoTiles, layerScissorRectOverNoTiles);
-
-void screenScissorRectOverNoTiles(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
-
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestCCOcclusionTracker occlusion(IntRect(500, 500, 100, 100));
-
- occlusion.enterTargetRenderSurface(layer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
-
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
-
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 100, 300, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(200, 100, 100, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)).isEmpty());
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_screenScissorRectOverNoTiles, screenScissorRectOverNoTiles);
-
-void layerScissorRectForLayerOffOrigin(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
+MAIN_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransform);
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestPerspectiveTransformBehindCamera : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
+ TransformationMatrix transform;
+ transform.translate(250, 50);
+ transform.applyPerspective(10);
+ transform.translate(-250, -50);
+ transform.translate(250, 50);
+ transform.rotate3d(1, 0, 0, -167);
+ transform.translate(-250, -50);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 100));
+ typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(0, 0), IntSize(500, 500), true);
+ container->setPreserves3D(true);
+ layer->setPreserves3D(true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ this->enterLayer(layer, occlusion);
+
+ // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
+ // this will include many more pixels but must include at least the bottom 11 rows.
+ EXPECT_TRUE(occlusion.unoccludedContentRect(layer, IntRect(0, 0, 500, 500)).contains(IntRect(0, 489, 500, 11)));
+ }
+};
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(100, 100), IntSize(200, 200), true, opaqueLayers);
+MAIN_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransformBehindCamera);
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix transform;
+ transform.translate(50, 50);
+ transform.applyPerspective(100);
+ transform.translate3d(0, 0, 110);
+ transform.translate(-50, -50);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true);
+ parent->setPreserves3D(true);
+ layer->setPreserves3D(true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+
+ // The |layer| is entirely behind the camera and should not occlude.
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+ EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
+ }
+};
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+MAIN_THREAD_TEST(CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix transform;
+ transform.translate(50, 50);
+ transform.applyPerspective(100);
+ transform.translate3d(0, 0, 99);
+ transform.translate(-50, -50);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true);
+ parent->setPreserves3D(true);
+ layer->setPreserves3D(true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+
+ // This is very close to the camera, so pixels in its visibleLayerRect will actually go outside of the layer's clipRect.
+ // Ensure that those pixels don't occlude things outside the clipRect.
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+ EXPECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ }
+};
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
+MAIN_THREAD_TEST(CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect);
- occlusion.enterTargetRenderSurface(layer->renderSurface());
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestAnimationOpacity1OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
+ typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
+ typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false);
+ typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
+
+ addOpacityTransitionToController(*layer->layerAnimationController(), 10, 0, 1, false);
+ addOpacityTransitionToController(*surface->layerAnimationController(), 10, 0, 1, false);
+ this->calcDrawEtc(parent);
+
+ EXPECT_TRUE(layer->drawOpacityIsAnimating());
+ EXPECT_FALSE(surface->drawOpacityIsAnimating());
+ EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(topmost, occlusion);
+ this->enterLayer(parent2, occlusion);
+ // This occlusion will affect all surfaces.
+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent2, IntRect(0, 0, 300, 300)));
+ this->leaveLayer(parent2, occlusion);
+
+ this->visitLayer(surfaceChild2, occlusion);
+ this->enterLayer(surfaceChild, occlusion);
+ EXPECT_EQ_RECT(IntRect(100, 0, 150, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 300, 300)));
+ this->leaveLayer(surfaceChild, occlusion);
+ this->enterLayer(surface, occlusion);
+ EXPECT_EQ_RECT(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+ this->leaveLayer(surface, occlusion);
+
+ this->enterContributingSurface(surface, occlusion);
+ // Occlusion within the surface is lost when leaving the animating surface.
+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 300, 300)));
+ this->leaveContributingSurface(surface, occlusion);
+
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ // Occlusion is not added for the animating |layer|.
+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ }
+};
- // This layer is translated when drawn into its target. So if the scissor rect given from the target surface
- // is not in that target space, then after translating these query rects into the target, they will fall outside
- // the scissor and be considered occluded.
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
-}
+MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity1OnMainThread);
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectForLayerOffOrigin, layerScissorRectForLayerOffOrigin);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestAnimationOpacity0OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
+ typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
+ typename Types::ContentLayerType* parent2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false);
+ typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
+
+ addOpacityTransitionToController(*layer->layerAnimationController(), 10, 1, 0, false);
+ addOpacityTransitionToController(*surface->layerAnimationController(), 10, 1, 0, false);
+ this->calcDrawEtc(parent);
+
+ EXPECT_TRUE(layer->drawOpacityIsAnimating());
+ EXPECT_FALSE(surface->drawOpacityIsAnimating());
+ EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(topmost, occlusion);
+ this->enterLayer(parent2, occlusion);
+ // This occlusion will affect all surfaces.
+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ this->leaveLayer(parent2, occlusion);
+
+ this->visitLayer(surfaceChild2, occlusion);
+ this->enterLayer(surfaceChild, occlusion);
+ EXPECT_EQ_RECT(IntRect(100, 0, 150, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 300, 300)));
+ this->leaveLayer(surfaceChild, occlusion);
+ this->enterLayer(surface, occlusion);
+ EXPECT_EQ_RECT(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+ this->leaveLayer(surface, occlusion);
+
+ this->enterContributingSurface(surface, occlusion);
+ // Occlusion within the surface is lost when leaving the animating surface.
+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 300, 300)));
+ this->leaveContributingSurface(surface, occlusion);
+
+ this->visitLayer(layer, occlusion);
+ this->enterLayer(parent, occlusion);
+
+ // Occlusion is not added for the animating |layer|.
+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ }
+};
-void damageRectOverTile(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
+MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity0OnMainThread);
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestAnimationTranslateOnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
+ typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
+ typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(50, 300), true);
+
+ addAnimatedTransformToController(*layer->layerAnimationController(), 10, 30, 0);
+ addAnimatedTransformToController(*surface->layerAnimationController(), 10, 30, 0);
+ addAnimatedTransformToController(*surfaceChild->layerAnimationController(), 10, 30, 0);
+ this->calcDrawEtc(parent);
+
+ EXPECT_TRUE(layer->drawTransformIsAnimating());
+ EXPECT_TRUE(layer->screenSpaceTransformIsAnimating());
+ EXPECT_TRUE(surface->renderSurface()->targetSurfaceTransformsAreAnimating());
+ EXPECT_TRUE(surface->renderSurface()->screenSpaceTransformsAreAnimating());
+ // The surface owning layer doesn't animate against its own surface.
+ EXPECT_FALSE(surface->drawTransformIsAnimating());
+ EXPECT_TRUE(surface->screenSpaceTransformIsAnimating());
+ EXPECT_TRUE(surfaceChild->drawTransformIsAnimating());
+ EXPECT_TRUE(surfaceChild->screenSpaceTransformIsAnimating());
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(surface2, occlusion);
+ this->enterContributingSurface(surface2, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
+ this->leaveContributingSurface(surface2, occlusion);
+ this->enterLayer(surfaceChild2, occlusion);
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+ // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
+ // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer.
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild2, IntRect(0, 0, 100, 300)));
+ EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+ this->leaveLayer(surfaceChild2, occlusion);
+ this->enterLayer(surfaceChild, occlusion);
+ EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 100, 300)));
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+
+ // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target and the screen, so it
+ // can't be occluded.
+ EXPECT_EQ_RECT(IntRect(0, 0, 200, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 200, 300)));
+ EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
+
+ this->leaveLayer(surfaceChild, occlusion);
+ this->enterLayer(surface, occlusion);
+ // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+ this->leaveLayer(surface, occlusion);
+ // The surface's owning layer is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+
+ this->enterContributingSurface(surface, occlusion);
+ // The contributing |surface| is animating so it can't be occluded.
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 300, 300)));
+ this->leaveContributingSurface(surface, occlusion);
+
+ this->enterLayer(layer, occlusion);
+ // The |surface| is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
+ EXPECT_EQ_RECT(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ this->leaveLayer(layer, occlusion);
+
+ this->enterLayer(parent, occlusion);
+ // The |layer| is animating in the screen and in its target, so no occlusion is added.
+ EXPECT_EQ_RECT(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ }
+};
- TestDamageClient damage(FloatRect(200, 100, 100, 100));
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000), &damage);
+MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationTranslateOnMainThread);
- occlusion.enterTargetRenderSurface(layer->renderSurface());
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix surfaceTransform;
+ surfaceTransform.translate(300, 300);
+ surfaceTransform.scale(2);
+ surfaceTransform.translate(-150, -150);
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
+ typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, surfaceTransform, FloatPoint(0, 0), IntSize(300, 300), false);
+ typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(300, 300), false);
+ surface->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
+ surface2->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
+ this->calcDrawEtc(parent);
- // Outside the layer's clip rect.
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
+ this->visitLayer(surface2, occlusion);
+ this->visitContributingSurface(surface2, occlusion);
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(50, 50, 200, 200), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(50, 50, 200, 200), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ // Clear any stored occlusion.
+ occlusion.setOcclusionInScreenSpace(Region());
+ occlusion.setOcclusionInTargetSurface(Region());
- EXPECT_EQ_RECT(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
-}
+ this->visitLayer(surface, occlusion);
+ this->visitContributingSurface(surface, occlusion);
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_damageRectOverTile, damageRectOverTile);
+ EXPECT_EQ_RECT(IntRect(0, 0, 400, 400), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 400, 400), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ }
+};
-void damageRectOverCulledTile(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
+MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 300), false);
+ surface->setOpaqueContentsRect(IntRect(0, 0, 400, 200));
+ this->calcDrawEtc(parent);
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+ this->visitLayer(surface, occlusion);
+ this->visitContributingSurface(surface, occlusion);
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 200), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 200), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ }
+};
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
- TestDamageClient damage(FloatRect(100, 100, 100, 100));
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000), &damage);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestReplicaOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
+ typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100), true);
+ this->calcDrawEtc(parent);
- occlusion.enterTargetRenderSurface(layer->renderSurface());
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
+ // |topmost| occludes the replica, but not the surface itself.
+ this->visitLayer(topmost, occlusion);
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
+ EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ this->visitLayer(surface, occlusion);
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ this->enterContributingSurface(surface, occlusion);
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
-}
+ // Surface is not occluded so it shouldn't think it is.
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100)));
+ }
+};
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_damageRectOverCulledTile, damageRectOverCulledTile);
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaOccluded);
-void damageRectOverPartialTiles(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
-
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestDamageClient damage(FloatRect(50, 50, 200, 200));
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000), &damage);
-
- occlusion.enterTargetRenderSurface(layer->renderSurface());
-
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
-
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
-
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_EQ_RECT(IntRect(50, 50, 200, 200), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
- EXPECT_EQ_RECT(IntRect(200, 50, 50, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 100)));
- EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 100, 300, 100)));
- EXPECT_EQ_RECT(IntRect(200, 100, 50, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(200, 100, 100, 100)));
- EXPECT_EQ_RECT(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)));
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_damageRectOverPartialTiles, damageRectOverPartialTiles);
-
-void damageRectOverNoTiles(bool opaqueLayers)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> parentLayer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(parentLayer);
- parent->addChild(layer);
-
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- parentLayer->setFilters(filters);
- layer->setFilters(filters);
-
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
-
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
-
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
-
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
-
- TestDamageClient damage(FloatRect(500, 500, 100, 100));
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000), &damage);
-
- occlusion.enterTargetRenderSurface(layer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
-
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
- occlusion.enterTargetRenderSurface(parentLayer->renderSurface());
-
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 200, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 200, 100, 100)));
-
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
-
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 100, 300, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(200, 100, 100, 100)).isEmpty());
- EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)).isEmpty());
-}
-
-TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_damageRectOverNoTiles, damageRectOverNoTiles);
-
-TEST(CCOcclusionTrackerTest, opaqueContentsRegionEmpty)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(layer);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
+ typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 110), true);
+ this->calcDrawEtc(parent);
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
- layer->setFilters(filters);
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), false, false);
+ // |topmost| occludes the surface, but not the entire surface's replica.
+ this->visitLayer(topmost, occlusion);
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+ this->visitLayer(surface, occlusion);
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
+ this->enterContributingSurface(surface, occlusion);
- occlusion.enterTargetRenderSurface(layer->renderSurface());
+ // Surface is occluded, but only the top 10px of the replica.
+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), true, IntRect(0, 0, 100, 100)));
+ }
+};
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded);
- // Occluded since its outside the surface bounds.
- EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
+ typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(40, 100), true);
+ typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 100), true);
+ this->calcDrawEtc(parent);
- // Test without any scissors.
- occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
- EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
- occlusion.useDefaultLayerScissorRect();
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
- occlusion.markOccludedBehindLayer(layer.get());
- occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ // These occlude the surface and replica differently, so we can test each one.
+ this->visitLayer(overReplica, occlusion);
+ this->visitLayer(overSurface, occlusion);
- EXPECT_TRUE(occlusion.occlusionInScreenSpace().bounds().isEmpty());
- EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
-}
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
-TEST(CCOcclusionTrackerTest, opaqueContentsRegionNonEmpty)
-{
- const TransformationMatrix identityMatrix;
- RefPtr<LayerChromium> parent = LayerChromium::create();
- RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
- parent->createRenderSurface();
- parent->addChild(layer);
+ this->visitLayer(surface, occlusion);
- setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
- setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(100, 100), IntSize(200, 200), false, false);
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
- Vector<RefPtr<LayerChromium> > dummyLayerList;
- int dummyMaxTextureSize = 512;
+ this->enterContributingSurface(surface, occlusion);
- parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
- parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
- renderSurfaceLayerList.append(parent);
+ // Surface and replica are occluded different amounts.
+ EXPECT_EQ_RECT(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(50, 0, 50, 100), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), true, IntRect(0, 0, 100, 100)));
+ }
+};
- CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestSurfaceChildOfSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
{
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- layer->setOpaquePaintRect(IntRect(0, 0, 100, 100));
+ // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
+ typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 10), IntSize(100, 50), true);
+ typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
+ this->calcDrawEtc(parent);
- occlusion.enterTargetRenderSurface(parent->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(-100, -100, 1000, 1000));
- EXPECT_EQ_RECT(IntRect(100, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
+ // |topmost| occludes everything partially so we know occlusion is happening at all.
+ this->visitLayer(topmost, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds());
EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ this->visitLayer(surfaceChild, occlusion);
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(0, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(100, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(200, 200, 100, 100)));
+ // surfaceChild increases the occlusion in the screen by a narrow sliver.
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 60), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ // In its own surface, surfaceChild is at 0,0 as is its occlusion.
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
+ // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
+ // as its parent does not have a clipRect.
+
+ this->enterContributingSurface(surfaceChild, occlusion);
+ // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect
+ // does not get clipped away inappropriately.
+ EXPECT_EQ_RECT(IntRect(0, 40, 100, 10), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild->renderSurface(), false, IntRect(0, 0, 100, 50)));
+ this->leaveContributingSurface(surfaceChild, occlusion);
+
+ // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also.
+ this->enterLayer(surface, occlusion);
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 60), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 10, 100, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ this->leaveLayer(surface, occlusion);
+
+ this->enterContributingSurface(surface, occlusion);
+ // The surface's parent does have a clipRect as it is the root layer.
+ EXPECT_EQ_RECT(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100)));
}
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfSurface);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestSurfaceChildOfClippingSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
{
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- layer->setOpaquePaintRect(IntRect(20, 20, 180, 180));
+ // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(80, 200));
+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
+ typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), false);
+ typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
- occlusion.enterTargetRenderSurface(parent->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
+ // |topmost| occludes everything partially so we know occlusion is happening at all.
+ this->visitLayer(topmost, occlusion);
- EXPECT_EQ_RECT(IntRect(120, 120, 180, 180), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ_RECT(IntRect(0, 0, 80, 50), occlusion.occlusionInScreenSpace().bounds());
EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 80, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(100, 100, 100, 100)));
- EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(200, 200, 100, 100)));
+ // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
+ this->visitLayer(surfaceChild, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(0, 0, 80, 50), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
+ // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
+ // as its parent does not have a clipRect.
+
+ this->enterContributingSurface(surfaceChild, occlusion);
+ // The surfaceChild's parent does not have a clipRect as it owns a render surface.
+ EXPECT_EQ_RECT(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild->renderSurface(), false, IntRect(0, 0, 100, 100)));
+ this->leaveContributingSurface(surfaceChild, occlusion);
+
+ this->visitLayer(surface, occlusion);
+ this->enterContributingSurface(surface, occlusion);
+ // The surface's parent does have a clipRect as it is the root layer.
+ EXPECT_EQ_RECT(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100)));
}
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfClippingSurface);
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
{
- TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
- layer->setOpaquePaintRect(IntRect(150, 150, 100, 100));
+ TransformationMatrix scaleByHalf;
+ scaleByHalf.scale(0.5);
+
+ // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
+ // 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
+ // appears at 50, 50 and the replica at 200, 50.
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
+ typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
+ this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
+ typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 50), true);
+ typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(300, 50), true);
+ typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 50), IntSize(50, 50), true);
+ typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 50), IntSize(100, 50), true);
+ typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
+
+ // Filters make the layer own a surface.
+ FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(10, WebCore::Fixed), FilterOperation::BLUR));
+ filteredSurface->setBackgroundFilters(filters);
+
+ // Save the distance of influence for the blur effect.
+ int outsetTop, outsetRight, outsetBottom, outsetLeft;
+ filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
+
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
+ // need to see some of the pixels (up to radius far) underneath the occludingLayers.
+ this->visitLayer(occludingLayer5, occlusion);
+ this->visitLayer(occludingLayer4, occlusion);
+ this->visitLayer(occludingLayer3, occlusion);
+ this->visitLayer(occludingLayer2, occlusion);
+ this->visitLayer(occludingLayer1, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // Everything outside the surface/replica is occluded but the surface/replica itself is not.
+ this->enterLayer(filteredSurface, occlusion);
+ EXPECT_EQ_RECT(IntRect(1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 100, 100)));
+
+ EXPECT_EQ_RECT(IntRect(300 + 1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 1, 0, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(300 + 0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, 1, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(300 + 0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 - 1, 0, 100, 100)));
+ EXPECT_EQ_RECT(IntRect(300 + 0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, -1, 100, 100)));
+ this->leaveLayer(filteredSurface, occlusion);
+
+ // The filtered layer/replica does not occlude.
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
+ // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
+ this->visitContributingSurface(filteredSurface, occlusion);
+
+ this->enterLayer(parent, occlusion);
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
+
+ IntRect outsetRect;
+ IntRect testRect;
+
+ // Nothing in the blur outsets for the filteredSurface is occluded.
+ outsetRect = IntRect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
+ testRect = outsetRect;
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+
+ // Stuff outside the blur outsets is still occluded though.
+ testRect = outsetRect;
+ testRect.expand(1, 0);
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+ testRect = outsetRect;
+ testRect.expand(0, 1);
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+ testRect = outsetRect;
+ testRect.move(-1, 0);
+ testRect.expand(1, 0);
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+ testRect = outsetRect;
+ testRect.move(0, -1);
+ testRect.expand(0, 1);
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+
+ // Nothing in the blur outsets for the filteredSurface's replica is occluded.
+ outsetRect = IntRect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
+ testRect = outsetRect;
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+
+ // Stuff outside the blur outsets is still occluded though.
+ testRect = outsetRect;
+ testRect.expand(1, 0);
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+ testRect = outsetRect;
+ testRect.expand(0, 1);
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+ testRect = outsetRect;
+ testRect.move(-1, 0);
+ testRect.expand(1, 0);
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+ testRect = outsetRect;
+ testRect.move(0, -1);
+ testRect.expand(0, 1);
+ EXPECT_EQ_RECT(outsetRect, occlusion.unoccludedContentRect(parent, testRect));
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix scaleByHalf;
+ scaleByHalf.scale(0.5);
+
+ // Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
+ typename Types::ContentLayerType* root = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(75, 75));
+ typename Types::LayerType* parent = this->createSurface(root, scaleByHalf, FloatPoint(0, 0), IntSize(150, 150));
+ parent->setMasksToBounds(true);
+ typename Types::LayerType* filteredSurface1 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
+ typename Types::LayerType* filteredSurface2 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
+ typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(50, 50), true);
+
+ // Filters make the layers own surfaces.
+ FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(3, WebCore::Fixed), FilterOperation::BLUR));
+ filteredSurface1->setBackgroundFilters(filters);
+ filteredSurface2->setBackgroundFilters(filters);
+
+ // Save the distance of influence for the blur effect.
+ int outsetTop, outsetRight, outsetBottom, outsetLeft;
+ filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
- occlusion.enterTargetRenderSurface(parent->renderSurface());
- occlusion.markOccludedBehindLayer(layer.get());
+ this->calcDrawEtc(root);
- EXPECT_EQ_RECT(IntRect(250, 250, 50, 50), occlusion.occlusionInScreenSpace().bounds());
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(occludingLayerAbove, occlusion);
+ EXPECT_EQ_RECT(IntRect(100 / 2, 100 / 2, 50 / 2, 50 / 2), occlusion.occlusionInScreenSpace().bounds());
EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(100, 100, 50, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+
+ this->visitLayer(filteredSurface2, occlusion);
+ this->visitContributingSurface(filteredSurface2, occlusion);
+ this->visitLayer(filteredSurface1, occlusion);
+ this->visitContributingSurface(filteredSurface1, occlusion);
+
+ ASSERT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ ASSERT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(0, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(100, 100, 100, 100)));
- EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(200, 200, 100, 100)));
+ // Test expectations in the target.
+ IntRect expectedOcclusion = IntRect(100 + outsetRight * 2, 100 + outsetBottom * 2, 50 - (outsetLeft + outsetRight) * 2, 50 - (outsetTop + outsetBottom) * 2);
+ EXPECT_EQ_RECT(expectedOcclusion, occlusion.occlusionInTargetSurface().rects()[0]);
+
+ // Test expectations in the screen. Take the ceiling of half of the outsets.
+ outsetTop = (outsetTop + 1) / 2;
+ outsetRight = (outsetRight + 1) / 2;
+ outsetBottom = (outsetBottom + 1) / 2;
+ outsetLeft = (outsetLeft + 1) / 2;
+ expectedOcclusion = IntRect(100 / 2 + outsetRight * 2, 100 / 2 + outsetBottom * 2, 50 / 2 - (outsetLeft + outsetRight) * 2, 50 /2 - (outsetTop + outsetBottom) * 2);
+
+ EXPECT_EQ_RECT(expectedOcclusion, occlusion.occlusionInScreenSpace().rects()[0]);
}
-}
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ // Make a surface and its replica, each 50x50, that are completely surrounded by opaque layers which are above them in the z-order.
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
+ // We stick the filtered surface inside a clipping surface so that we can make sure the clip is honored when exposing pixels for
+ // the background filter.
+ typename Types::LayerType* clippingSurface = this->createSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 70));
+ clippingSurface->setMasksToBounds(true);
+ typename Types::LayerType* filteredSurface = this->createDrawingLayer(clippingSurface, this->identityMatrix, FloatPoint(50, 50), IntSize(50, 50), false);
+ this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(150, 0), IntSize());
+ typename Types::LayerType* occludingLayer1 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 50), true);
+ typename Types::LayerType* occludingLayer2 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(300, 50), true);
+ typename Types::LayerType* occludingLayer3 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 50), IntSize(50, 50), true);
+ typename Types::LayerType* occludingLayer4 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 50), IntSize(100, 50), true);
+ typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
+
+ // Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
+ FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(12, WebCore::Fixed), FilterOperation::BLUR));
+ filteredSurface->setBackgroundFilters(filters);
+
+ // Save the distance of influence for the blur effect.
+ int outsetTop, outsetRight, outsetBottom, outsetLeft;
+ filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
+
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ // These layers occlude pixels directly beside the filteredSurface. Because filtered surface blends pixels in a radius, it will
+ // need to see some of the pixels (up to radius far) underneath the occludingLayers.
+ this->visitLayer(occludingLayer5, occlusion);
+ this->visitLayer(occludingLayer4, occlusion);
+ this->visitLayer(occludingLayer3, occlusion);
+ this->visitLayer(occludingLayer2, occlusion);
+ this->visitLayer(occludingLayer1, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // Everything outside the surface/replica is occluded but the surface/replica itself is not.
+ this->enterLayer(filteredSurface, occlusion);
+ EXPECT_EQ_RECT(IntRect(1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 50, 50)));
+
+ EXPECT_EQ_RECT(IntRect(150 + 1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 1, 0, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(150 + 0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, 1, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(150 + 0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 - 1, 0, 50, 50)));
+ EXPECT_EQ_RECT(IntRect(150 + 0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, -1, 50, 50)));
+ this->leaveLayer(filteredSurface, occlusion);
+
+ // The filtered layer/replica does not occlude.
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
+ // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
+ this->visitContributingSurface(filteredSurface, occlusion);
+
+ this->enterContributingSurface(clippingSurface, occlusion);
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 150), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(5u, occlusion.occlusionInScreenSpace().rects().size());
+
+ IntRect outsetRect;
+ IntRect clippedOutsetRect;
+ IntRect testRect;
+
+ // Nothing in the (clipped) blur outsets for the filteredSurface is occluded.
+ outsetRect = IntRect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
+ clippedOutsetRect = intersection(outsetRect, IntRect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
+ testRect = outsetRect;
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+
+ // Stuff outside the (clipped) blur outsets is still occluded though.
+ testRect = outsetRect;
+ testRect.expand(1, 0);
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+ testRect = outsetRect;
+ testRect.expand(0, 1);
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+ testRect = outsetRect;
+ testRect.move(-1, 0);
+ testRect.expand(1, 0);
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+ testRect = outsetRect;
+ testRect.move(0, -1);
+ testRect.expand(0, 1);
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+
+ // Nothing in the (clipped) blur outsets for the filteredSurface's replica is occluded.
+ outsetRect = IntRect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom);
+ clippedOutsetRect = intersection(outsetRect, IntRect(0 - outsetLeft, 0 - outsetTop, 300 + outsetLeft + outsetRight, 70 + outsetTop + outsetBottom));
+ testRect = outsetRect;
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+
+ // Stuff outside the (clipped) blur outsets is still occluded though.
+ testRect = outsetRect;
+ testRect.expand(1, 0);
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+ testRect = outsetRect;
+ testRect.expand(0, 1);
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+ testRect = outsetRect;
+ testRect.move(-1, 0);
+ testRect.expand(1, 0);
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+ testRect = outsetRect;
+ testRect.move(0, -1);
+ testRect.expand(0, 1);
+ EXPECT_EQ_RECT(clippedOutsetRect, occlusion.unoccludedContentRect(clippingSurface, testRect));
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix scaleByHalf;
+ scaleByHalf.scale(0.5);
+
+ // Make a surface and its replica, each 50x50, with a smaller 30x30 layer centered below each.
+ // 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
+ // appears at 50, 50 and the replica at 200, 50.
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
+ typename Types::LayerType* behindSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(60, 60), IntSize(30, 30), true);
+ typename Types::LayerType* behindReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(210, 60), IntSize(30, 30), true);
+ typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
+ this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
+
+ // Filters make the layer own a surface.
+ FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(3, WebCore::Fixed), FilterOperation::BLUR));
+ filteredSurface->setBackgroundFilters(filters);
+
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ // The surface has a background blur, so it blurs non-opaque pixels below it.
+ this->visitLayer(filteredSurface, occlusion);
+ this->visitContributingSurface(filteredSurface, occlusion);
+
+ this->visitLayer(behindReplicaLayer, occlusion);
+ this->visitLayer(behindSurfaceLayer, occlusion);
+
+ // The layers behind the surface are not blurred, and their occlusion does not change, until we leave the surface.
+ // So it should not be modified by the filter here.
+ IntRect occlusionBehindSurface = IntRect(60, 60, 30, 30);
+ IntRect occlusionBehindReplica = IntRect(210, 60, 30, 30);
+
+ IntRect expectedOpaqueBounds = unionRect(occlusionBehindSurface, occlusionBehindReplica);
+ EXPECT_EQ_RECT(expectedOpaqueBounds, occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(expectedOpaqueBounds, occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix scaleByHalf;
+ scaleByHalf.scale(0.5);
+
+ // Make a surface and its replica, each 50x50, that are completely occluded by opaque layers which are above them in the z-order.
+ // 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
+ // appears at 50, 50 and the replica at 200, 50.
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
+ typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
+ this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
+ typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(50, 50), true);
+ typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(50, 50), true);
+
+ // Filters make the layer own a surface.
+ FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(3, WebCore::Fixed), FilterOperation::BLUR));
+ filteredSurface->setBackgroundFilters(filters);
+
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(aboveReplicaLayer, occlusion);
+ this->visitLayer(aboveSurfaceLayer, occlusion);
+
+ // The surface has a background blur, so it blurs non-opaque pixels below it.
+ this->visitLayer(filteredSurface, occlusion);
+ this->visitContributingSurface(filteredSurface, occlusion);
+
+ // The filter is completely occluded, so it should not blur anything and reduce any occlusion.
+ IntRect occlusionAboveSurface = IntRect(50, 50, 50, 50);
+ IntRect occlusionAboveReplica = IntRect(200, 50, 50, 50);
+
+ IntRect expectedOpaqueBounds = unionRect(occlusionAboveSurface, occlusionAboveReplica);
+ EXPECT_EQ_RECT(expectedOpaqueBounds, occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(expectedOpaqueBounds, occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ TransformationMatrix scaleByHalf;
+ scaleByHalf.scale(0.5);
+
+ // Make a surface and its replica, each 50x50, that are partially occluded by opaque layers which are above them in the z-order.
+ // 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
+ // appears at 50, 50 and the replica at 200, 50.
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 150));
+ typename Types::LayerType* filteredSurface = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(50, 50), IntSize(100, 100), false);
+ this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
+ typename Types::LayerType* aboveSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(70, 50), IntSize(30, 50), true);
+ typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(30, 50), true);
+ typename Types::LayerType* besideSurfaceLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(90, 40), IntSize(10, 10), true);
+ typename Types::LayerType* besideReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 40), IntSize(10, 10), true);
+
+ // Filters make the layer own a surface.
+ FilterOperations filters;
+ filters.operations().append(BlurFilterOperation::create(Length(3, WebCore::Fixed), FilterOperation::BLUR));
+ filteredSurface->setBackgroundFilters(filters);
+
+ // Save the distance of influence for the blur effect.
+ int outsetTop, outsetRight, outsetBottom, outsetLeft;
+ filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
+
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+
+ this->visitLayer(besideReplicaLayer, occlusion);
+ this->visitLayer(besideSurfaceLayer, occlusion);
+ this->visitLayer(aboveReplicaLayer, occlusion);
+ this->visitLayer(aboveSurfaceLayer, occlusion);
+
+ // The surface has a background blur, so it blurs non-opaque pixels below it.
+ this->visitLayer(filteredSurface, occlusion);
+ this->visitContributingSurface(filteredSurface, occlusion);
+
+ // The filter in the surface and replica are partially unoccluded. Only the unoccluded parts should reduce occlusion.
+ // This means it will push back the occlusion that touches the unoccluded part (occlusionAbove___), but it will not
+ // touch occlusionBeside____ since that is not beside the unoccluded part of the surface, even though it is beside
+ // the occluded part of the surface.
+ IntRect occlusionAboveSurface = IntRect(70 + outsetRight, 50, 30 - outsetRight, 50);
+ IntRect occlusionAboveReplica = IntRect(200, 50, 30 - outsetLeft, 50);
+ IntRect occlusionBesideSurface = IntRect(90, 40, 10, 10);
+ IntRect occlusionBesideReplica = IntRect(200, 40, 10, 10);
+
+ Region expectedOcclusion;
+ expectedOcclusion.unite(occlusionAboveSurface);
+ expectedOcclusion.unite(occlusionAboveReplica);
+ expectedOcclusion.unite(occlusionBesideSurface);
+ expectedOcclusion.unite(occlusionBesideReplica);
+
+ ASSERT_EQ(expectedOcclusion.rects().size(), occlusion.occlusionInTargetSurface().rects().size());
+ ASSERT_EQ(expectedOcclusion.rects().size(), occlusion.occlusionInScreenSpace().rects().size());
+
+ for (size_t i = 0; i < expectedOcclusion.rects().size(); ++i) {
+ IntRect expectedRect = expectedOcclusion.rects()[i];
+ IntRect screenRect = occlusion.occlusionInScreenSpace().rects()[i];
+ IntRect targetRect = occlusion.occlusionInTargetSurface().rects()[i];
+ EXPECT_EQ(expectedRect, screenRect);
+ EXPECT_EQ(expectedRect, targetRect);
+ }
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestMinimumTrackingSize : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ IntSize trackingSize(100, 100);
+ IntSize belowTrackingSize(99, 99);
+
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(400, 400));
+ typename Types::LayerType* large = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), trackingSize, true);
+ typename Types::LayerType* small = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), belowTrackingSize, true);
+ this->calcDrawEtc(parent);
+
+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+ occlusion.setMinimumTrackingSize(trackingSize);
+
+ // The small layer is not tracked because it is too small.
+ this->visitLayer(small, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
+
+ // The large layer is tracked as it is large enough.
+ this->visitLayer(large, occlusion);
+
+ EXPECT_EQ_RECT(IntRect(IntPoint(), trackingSize), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(IntPoint(), trackingSize), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ }
+};
+
+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestMinimumTrackingSize);
} // namespace