1974template<class Types, bool opaqueLayers>
1975class CCOcclusionTrackerTestReplicaOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
1976protected:
1977 void runMyTest()
1978 {
1979 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
1980 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
1981 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
1982 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100), true);
1983 this->calcDrawEtc(parent);
1984
1985 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
1986 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
1987
1988 // This occludes the replica, but not the surface itself.
1989 occlusion.enterTargetRenderSurface(parent->renderSurface());
1990 occlusion.markOccludedBehindLayer(topmost);
1991
1992 EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
1993 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
1994 EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
1995 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
1996
1997 occlusion.enterTargetRenderSurface(surface->renderSurface());
1998 occlusion.markOccludedBehindLayer(surface);
1999
2000 EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
2001 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2002 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2003 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2004
2005 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
2006
2007 // Surface is not occluded so it shouldn't think it is.
2008 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
2009 }
2010};
2011
2012ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaOccluded);
2013
2014template<class Types, bool opaqueLayers>
2015class CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2016protected:
2017 void runMyTest()
2018 {
2019 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2020 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2021 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2022 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 110), true);
2023 this->calcDrawEtc(parent);
2024
2025 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2026 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2027
2028 // This occludes the surface, but not the entire surface's replica.
2029 occlusion.enterTargetRenderSurface(parent->renderSurface());
2030 occlusion.markOccludedBehindLayer(topmost);
2031
2032 EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
2033 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2034 EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInTargetSurface().bounds());
2035 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2036
2037 occlusion.enterTargetRenderSurface(surface->renderSurface());
2038 occlusion.markOccludedBehindLayer(surface);
2039
2040 EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
2041 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2042 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2043 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2044
2045 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
2046
2047 // Surface is occluded, but only the top 10px of the replica, so the rest of the surface should not consider itself occluded.
2048 EXPECT_EQ_RECT(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
2049 }
2050};
2051
2052ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2053
2054template<class Types, bool opaqueLayers>
2055class CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2056protected:
2057 void runMyTest()
2058 {
2059 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2060 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2061 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2062 typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(40, 100), true);
2063 typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 100), true);
2064 this->calcDrawEtc(parent);
2065
2066 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2067 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2068
2069 // This occludes the surface, but not the entire surface's replica.
2070 occlusion.enterTargetRenderSurface(parent->renderSurface());
2071 occlusion.markOccludedBehindLayer(overReplica);
2072 occlusion.markOccludedBehindLayer(overSurface);
2073
2074 EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds());
2075 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2076 EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds());
2077 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2078
2079 occlusion.enterTargetRenderSurface(surface->renderSurface());
2080 occlusion.markOccludedBehindLayer(surface);
2081
2082 EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
2083 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2084 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2085 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2086
2087 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
2088
2089 // Surface is occluded less than replica, so it should dominate what is determined to be unoccluded.
2090 EXPECT_EQ_RECT(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
2091 }
2092};
2093
2094ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore);
2095
2096template<class Types, bool opaqueLayers>
2097class CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2098protected:
2099 void runMyTest()
2100 {
2101 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2102 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2103 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
2104 typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(50, 100), true);
2105 typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(40, 100), true);
2106 this->calcDrawEtc(parent);
2107
2108 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2109 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2110
2111 // This occludes the surface, but not the entire surface's replica.
2112 occlusion.enterTargetRenderSurface(parent->renderSurface());
2113 occlusion.markOccludedBehindLayer(overReplica);
2114 occlusion.markOccludedBehindLayer(overSurface);
2115
2116 EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds());
2117 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2118 EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds());
2119 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
2120
2121 occlusion.enterTargetRenderSurface(surface->renderSurface());
2122 occlusion.markOccludedBehindLayer(surface);
2123
2124 EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
2125 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
2126 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
2127 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2128
2129 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
2130
2131 // Replica is occluded less than the surface, so it should dominate what is determined to be unoccluded.
2132 EXPECT_EQ_RECT(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
2133 }
2134};
2135
2136ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore);
2137
2138template<class Types, bool opaqueLayers>
2139class CCOcclusionTrackerTestSurfaceChildOfSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
2140protected:
2141 void runMyTest()
2142 {
2143 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
2144
2145 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
2146 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
2147 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), false);
2148 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
2149 this->calcDrawEtc(parent);
2150
2151 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
2152 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
2153
2154 // This occludes everything partially so we know occlusion is happening at all.
2155 occlusion.enterTargetRenderSurface(parent->renderSurface());
2156 occlusion.markOccludedBehindLayer(topmost);
2157
2158 EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds());
2159 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2160 EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
2161 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
2162
2163 occlusion.enterTargetRenderSurface(surfaceChild->renderSurface());
2164 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
2165 occlusion.markOccludedBehindLayer(surfaceChild);
2166
2167 EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds());
2168 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
2169 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
2170 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
2171
2172 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
2173 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
2174 // as its parent does not have a clipRect.
2175
2176 occlusion.finishedTargetRenderSurface(surfaceChild, surfaceChild->renderSurface());
2177 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
2178 EXPECT_EQ_RECT(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, IntRect(0, 0, 100, 100)));
2179
2180 occlusion.leaveToTargetRenderSurface(surface->renderSurface());
2181 occlusion.markOccludedBehindLayer(surface);
2182
2183 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
2184 // The surface's parent does have a clipRect as it is the root layer.
2185 EXPECT_EQ_RECT(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
2186 }
2187};
2188
2189ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfSurface);
2190