1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/quad_culler.h"
7 #include "cc/append_quads_data.h"
8 #include "cc/layer_tiling_data.h"
9 #include "cc/math_util.h"
10 #include "cc/occlusion_tracker.h"
11 #include "cc/overdraw_metrics.h"
12 #include "cc/single_thread_proxy.h"
13 #include "cc/test/fake_impl_proxy.h"
14 #include "cc/test/fake_layer_tree_host_impl.h"
15 #include "cc/tile_draw_quad.h"
16 #include "cc/tiled_layer_impl.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/gfx/transform.h"
24 class TestOcclusionTrackerImpl
: public OcclusionTrackerImpl
{
26 TestOcclusionTrackerImpl(const gfx::Rect
& scissorRectInScreen
, bool recordMetricsForFrame
= true)
27 : OcclusionTrackerImpl(scissorRectInScreen
, recordMetricsForFrame
)
28 , m_scissorRectInScreen(scissorRectInScreen
)
33 virtual gfx::Rect
layerScissorRectInTargetSurface(const LayerImpl
* layer
) const { return m_scissorRectInScreen
; }
36 gfx::Rect m_scissorRectInScreen
;
39 typedef LayerIterator
<LayerImpl
, std::vector
<LayerImpl
*>, RenderSurfaceImpl
, LayerIteratorActions::FrontToBack
> LayerIteratorType
;
41 class QuadCullerTest
: public testing::Test
45 : m_hostImpl(&m_proxy
)
50 scoped_ptr
<TiledLayerImpl
> makeLayer(TiledLayerImpl
* parent
, const gfx::Transform
& drawTransform
, const gfx::Rect
& layerRect
, float opacity
, bool opaque
, const gfx::Rect
& layerOpaqueRect
, std::vector
<LayerImpl
*>& surfaceLayerList
)
52 scoped_ptr
<TiledLayerImpl
> layer
= TiledLayerImpl::create(m_hostImpl
.activeTree(), m_layerId
++);
53 scoped_ptr
<LayerTilingData
> tiler
= LayerTilingData::create(gfx::Size(100, 100), LayerTilingData::NoBorderTexels
);
54 tiler
->setBounds(layerRect
.size());
55 layer
->setTilingData(*tiler
);
56 layer
->setSkipsDraw(false);
57 layer
->drawProperties().target_space_transform
= drawTransform
;
58 layer
->drawProperties().screen_space_transform
= drawTransform
;
59 layer
->drawProperties().visible_content_rect
= layerRect
;
60 layer
->drawProperties().opacity
= opacity
;
61 layer
->setContentsOpaque(opaque
);
62 layer
->setBounds(layerRect
.size());
63 layer
->setContentBounds(layerRect
.size());
65 ResourceProvider::ResourceId resourceId
= 1;
66 for (int i
= 0; i
< tiler
->numTilesX(); ++i
)
67 for (int j
= 0; j
< tiler
->numTilesY(); ++j
) {
68 gfx::Rect tileOpaqueRect
= opaque
? tiler
->tileBounds(i
, j
) : gfx::IntersectRects(tiler
->tileBounds(i
, j
), layerOpaqueRect
);
69 layer
->pushTileProperties(i
, j
, resourceId
++, tileOpaqueRect
, false);
72 gfx::Rect rectInTarget
= MathUtil::mapClippedRect(layer
->drawTransform(), layer
->visibleContentRect());
74 layer
->createRenderSurface();
75 layer
->renderSurface()->setContentRect(rectInTarget
);
76 surfaceLayerList
.push_back(layer
.get());
77 layer
->renderSurface()->layerList().push_back(layer
.get());
79 layer
->drawProperties().render_target
= parent
->renderTarget();
80 parent
->renderSurface()->layerList().push_back(layer
.get());
81 rectInTarget
.Union(MathUtil::mapClippedRect(parent
->drawTransform(), parent
->visibleContentRect()));
82 parent
->renderSurface()->setContentRect(rectInTarget
);
84 layer
->drawProperties().drawable_content_rect
= rectInTarget
;
89 void appendQuads(QuadList
& quadList
, SharedQuadStateList
& sharedStateList
, TiledLayerImpl
* layer
, LayerIteratorType
& it
, OcclusionTrackerImpl
& occlusionTracker
)
91 occlusionTracker
.enterLayer(it
);
92 QuadCuller
quadCuller(quadList
, sharedStateList
, layer
, occlusionTracker
, false, false);
94 layer
->appendQuads(quadCuller
, data
);
95 occlusionTracker
.leaveLayer(it
);
100 FakeImplProxy m_proxy
;
101 FakeLayerTreeHostImpl m_hostImpl
;
105 #define DECLARE_AND_INITIALIZE_TEST_QUADS \
107 SharedQuadStateList sharedStateList; \
108 std::vector<LayerImpl*> renderSurfaceLayerList; \
109 gfx::Transform childTransform; \
110 gfx::Size rootSize = gfx::Size(300, 300); \
111 gfx::Rect rootRect = gfx::Rect(rootSize); \
112 gfx::Size childSize = gfx::Size(200, 200); \
113 gfx::Rect childRect = gfx::Rect(childSize);
115 TEST_F(QuadCullerTest
, verifyNoCulling
)
117 DECLARE_AND_INITIALIZE_TEST_QUADS
119 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
120 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), gfx::Transform(), childRect
, 1, false, gfx::Rect(), renderSurfaceLayerList
);
121 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
122 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
124 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
125 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
126 EXPECT_EQ(quadList
.size(), 13u);
127 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 90000, 1);
128 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 40000, 1);
129 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 0, 1);
132 TEST_F(QuadCullerTest
, verifyCullChildLinesUpTopLeft
)
134 DECLARE_AND_INITIALIZE_TEST_QUADS
136 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
137 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), gfx::Transform(), childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
138 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
139 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
141 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
142 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
143 EXPECT_EQ(quadList
.size(), 9u);
144 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 90000, 1);
145 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
146 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 40000, 1);
149 TEST_F(QuadCullerTest
, verifyCullWhenChildOpacityNotOne
)
151 DECLARE_AND_INITIALIZE_TEST_QUADS
153 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
154 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 0.9f
, true, gfx::Rect(), renderSurfaceLayerList
);
155 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
156 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
158 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
159 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
160 EXPECT_EQ(quadList
.size(), 13u);
161 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 90000, 1);
162 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 40000, 1);
163 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 0, 1);
166 TEST_F(QuadCullerTest
, verifyCullWhenChildOpaqueFlagFalse
)
168 DECLARE_AND_INITIALIZE_TEST_QUADS
170 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
171 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, false, gfx::Rect(), renderSurfaceLayerList
);
172 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
173 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
175 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
176 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
177 EXPECT_EQ(quadList
.size(), 13u);
178 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 90000, 1);
179 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 40000, 1);
180 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 0, 1);
183 TEST_F(QuadCullerTest
, verifyCullCenterTileOnly
)
185 DECLARE_AND_INITIALIZE_TEST_QUADS
187 childTransform
.Translate(50, 50);
189 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
190 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
191 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
192 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
194 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
195 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
196 ASSERT_EQ(quadList
.size(), 12u);
198 gfx::Rect quadVisibleRect1
= quadList
[5]->visible_rect
;
199 EXPECT_EQ(quadVisibleRect1
.height(), 50);
201 gfx::Rect quadVisibleRect3
= quadList
[7]->visible_rect
;
202 EXPECT_EQ(quadVisibleRect3
.width(), 50);
204 // Next index is 8, not 9, since centre quad culled.
205 gfx::Rect quadVisibleRect4
= quadList
[8]->visible_rect
;
206 EXPECT_EQ(quadVisibleRect4
.width(), 50);
207 EXPECT_EQ(quadVisibleRect4
.x(), 250);
209 gfx::Rect quadVisibleRect6
= quadList
[10]->visible_rect
;
210 EXPECT_EQ(quadVisibleRect6
.height(), 50);
211 EXPECT_EQ(quadVisibleRect6
.y(), 250);
213 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 100000, 1);
214 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
215 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 30000, 1);
218 TEST_F(QuadCullerTest
, verifyCullCenterTileNonIntegralSize1
)
220 DECLARE_AND_INITIALIZE_TEST_QUADS
222 childTransform
.Translate(100, 100);
224 // Make the root layer's quad have extent (99.1, 99.1) -> (200.9, 200.9) to make
225 // sure it doesn't get culled due to transform rounding.
226 gfx::Transform rootTransform
;
227 rootTransform
.Translate(99.1, 99.1);
228 rootTransform
.Scale(1.018, 1.018);
230 rootRect
= childRect
= gfx::Rect(0, 0, 100, 100);
232 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, rootTransform
, rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
233 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
234 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
235 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
237 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
238 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
239 EXPECT_EQ(quadList
.size(), 2u);
241 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 20363, 1);
242 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
243 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 0, 1);
246 TEST_F(QuadCullerTest
, verifyCullCenterTileNonIntegralSize2
)
248 DECLARE_AND_INITIALIZE_TEST_QUADS
250 // Make the child's quad slightly smaller than, and centred over, the root layer tile.
251 // Verify the child does not cause the quad below to be culled due to rounding.
252 childTransform
.Translate(100.1, 100.1);
253 childTransform
.Scale(0.982, 0.982);
255 gfx::Transform rootTransform
;
256 rootTransform
.Translate(100, 100);
258 rootRect
= childRect
= gfx::Rect(0, 0, 100, 100);
260 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, rootTransform
, rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
261 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
262 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
263 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
265 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
266 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
267 EXPECT_EQ(quadList
.size(), 2u);
269 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 19643, 1);
270 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
271 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 0, 1);
274 TEST_F(QuadCullerTest
, verifyCullChildLinesUpBottomRight
)
276 DECLARE_AND_INITIALIZE_TEST_QUADS
278 childTransform
.Translate(100, 100);
280 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
281 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
282 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
283 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
285 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
286 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
287 EXPECT_EQ(quadList
.size(), 9u);
288 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 90000, 1);
289 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
290 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 40000, 1);
293 TEST_F(QuadCullerTest
, verifyCullSubRegion
)
295 DECLARE_AND_INITIALIZE_TEST_QUADS
297 childTransform
.Translate(50, 50);
299 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
300 gfx::Rect
childOpaqueRect(childRect
.x() + childRect
.width() / 4, childRect
.y() + childRect
.height() / 4, childRect
.width() / 2, childRect
.height() / 2);
301 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, false, childOpaqueRect
, renderSurfaceLayerList
);
302 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
303 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
305 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
306 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
307 EXPECT_EQ(quadList
.size(), 12u);
308 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 90000, 1);
309 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 30000, 1);
310 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 10000, 1);
313 TEST_F(QuadCullerTest
, verifyCullSubRegion2
)
315 DECLARE_AND_INITIALIZE_TEST_QUADS
317 childTransform
.Translate(50, 10);
319 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
320 gfx::Rect
childOpaqueRect(childRect
.x() + childRect
.width() / 4, childRect
.y() + childRect
.height() / 4, childRect
.width() / 2, childRect
.height() * 3 / 4);
321 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, false, childOpaqueRect
, renderSurfaceLayerList
);
322 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
323 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
325 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
326 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
327 EXPECT_EQ(quadList
.size(), 12u);
328 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 90000, 1);
329 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 25000, 1);
330 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 15000, 1);
333 TEST_F(QuadCullerTest
, verifyCullSubRegionCheckOvercull
)
335 DECLARE_AND_INITIALIZE_TEST_QUADS
337 childTransform
.Translate(50, 49);
339 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
340 gfx::Rect
childOpaqueRect(childRect
.x() + childRect
.width() / 4, childRect
.y() + childRect
.height() / 4, childRect
.width() / 2, childRect
.height() / 2);
341 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, false, childOpaqueRect
, renderSurfaceLayerList
);
342 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
343 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
345 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
346 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
347 EXPECT_EQ(quadList
.size(), 13u);
348 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 90000, 1);
349 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 30000, 1);
350 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 10000, 1);
353 TEST_F(QuadCullerTest
, verifyNonAxisAlignedQuadsDontOcclude
)
355 DECLARE_AND_INITIALIZE_TEST_QUADS
357 // Use a small rotation so as to not disturb the geometry significantly.
358 childTransform
.Rotate(1);
360 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
361 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), childTransform
, childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
362 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
363 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
365 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
366 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
367 EXPECT_EQ(quadList
.size(), 13u);
368 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 130000, 1);
369 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
370 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 0, 1);
373 // This test requires some explanation: here we are rotating the quads to be culled.
374 // The 2x2 tile child layer remains in the top-left corner, unrotated, but the 3x3
375 // tile parent layer is rotated by 1 degree. Of the four tiles the child would
376 // normally occlude, three will move (slightly) out from under the child layer, and
377 // one moves further under the child. Only this last tile should be culled.
378 TEST_F(QuadCullerTest
, verifyNonAxisAlignedQuadsSafelyCulled
)
380 DECLARE_AND_INITIALIZE_TEST_QUADS
382 // Use a small rotation so as to not disturb the geometry significantly.
383 gfx::Transform parentTransform
;
384 parentTransform
.Rotate(1);
386 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, parentTransform
, rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
387 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), gfx::Transform(), childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
388 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(-100, -100, 1000, 1000));
389 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
391 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
392 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
393 EXPECT_EQ(quadList
.size(), 12u);
394 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 100600, 1);
395 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
396 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 29400, 1);
399 TEST_F(QuadCullerTest
, verifyCullOutsideScissorOverTile
)
401 DECLARE_AND_INITIALIZE_TEST_QUADS
403 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
404 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), gfx::Transform(), childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
405 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(200, 100, 100, 100));
406 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
408 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
409 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
410 EXPECT_EQ(quadList
.size(), 1u);
411 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 10000, 1);
412 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
413 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 120000, 1);
416 TEST_F(QuadCullerTest
, verifyCullOutsideScissorOverCulledTile
)
418 DECLARE_AND_INITIALIZE_TEST_QUADS
420 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
421 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), gfx::Transform(), childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
422 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(100, 100, 100, 100));
423 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
425 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
426 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
427 EXPECT_EQ(quadList
.size(), 1u);
428 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 10000, 1);
429 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
430 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 120000, 1);
433 TEST_F(QuadCullerTest
, verifyCullOutsideScissorOverPartialTiles
)
435 DECLARE_AND_INITIALIZE_TEST_QUADS
437 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
438 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), gfx::Transform(), childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
439 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(50, 50, 200, 200));
440 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
442 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
443 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
444 EXPECT_EQ(quadList
.size(), 9u);
445 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 40000, 1);
446 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
447 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 90000, 1);
450 TEST_F(QuadCullerTest
, verifyCullOutsideScissorOverNoTiles
)
452 DECLARE_AND_INITIALIZE_TEST_QUADS
454 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
455 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), gfx::Transform(), childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
456 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(500, 500, 100, 100));
457 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
459 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
460 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
461 EXPECT_EQ(quadList
.size(), 0u);
462 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
463 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
464 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 130000, 1);
467 TEST_F(QuadCullerTest
, verifyWithoutMetrics
)
469 DECLARE_AND_INITIALIZE_TEST_QUADS
471 scoped_ptr
<TiledLayerImpl
> rootLayer
= makeLayer(0, gfx::Transform(), rootRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
472 scoped_ptr
<TiledLayerImpl
> childLayer
= makeLayer(rootLayer
.get(), gfx::Transform(), childRect
, 1, true, gfx::Rect(), renderSurfaceLayerList
);
473 TestOcclusionTrackerImpl
occlusionTracker(gfx::Rect(50, 50, 200, 200), false);
474 LayerIteratorType it
= LayerIteratorType::begin(&renderSurfaceLayerList
);
476 appendQuads(quadList
, sharedStateList
, childLayer
.get(), it
, occlusionTracker
);
477 appendQuads(quadList
, sharedStateList
, rootLayer
.get(), it
, occlusionTracker
);
478 EXPECT_EQ(quadList
.size(), 9u);
479 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
480 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsDrawnTranslucent(), 0, 1);
481 EXPECT_NEAR(occlusionTracker
.overdrawMetrics().pixelsCulledForDrawing(), 0, 1);