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/layers/tiled_layer_impl.h"
7 #include "cc/layers/append_quads_data.h"
8 #include "cc/quads/tile_draw_quad.h"
9 #include "cc/resources/layer_tiling_data.h"
10 #include "cc/test/fake_impl_proxy.h"
11 #include "cc/test/fake_layer_tree_host_impl.h"
12 #include "cc/test/layer_test_common.h"
13 #include "cc/trees/single_thread_proxy.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
20 class TiledLayerImplTest
: public testing::Test
{
22 TiledLayerImplTest() : host_impl_(&proxy_
, &shared_bitmap_manager_
) {}
24 scoped_ptr
<TiledLayerImpl
> CreateLayerNoTiles(
25 const gfx::Size
& tile_size
,
26 const gfx::Size
& layer_size
,
27 LayerTilingData::BorderTexelOption border_texels
) {
28 scoped_ptr
<TiledLayerImpl
> layer
=
29 TiledLayerImpl::Create(host_impl_
.active_tree(), 1);
30 scoped_ptr
<LayerTilingData
> tiler
=
31 LayerTilingData::Create(tile_size
, border_texels
);
32 tiler
->SetTilingSize(layer_size
);
33 layer
->SetTilingData(*tiler
);
34 layer
->set_skips_draw(false);
35 layer
->draw_properties().visible_content_rect
=
36 gfx::Rect(layer_size
);
37 layer
->draw_properties().opacity
= 1;
38 layer
->SetBounds(layer_size
);
39 layer
->SetContentBounds(layer_size
);
40 layer
->CreateRenderSurface();
41 layer
->draw_properties().render_target
= layer
.get();
45 // Create a default tiled layer with textures for all tiles and a default
46 // visibility of the entire layer size.
47 scoped_ptr
<TiledLayerImpl
> CreateLayer(
48 const gfx::Size
& tile_size
,
49 const gfx::Size
& layer_size
,
50 LayerTilingData::BorderTexelOption border_texels
) {
51 scoped_ptr
<TiledLayerImpl
> layer
=
52 CreateLayerNoTiles(tile_size
, layer_size
, border_texels
);
54 ResourceProvider::ResourceId resource_id
= 1;
55 for (int i
= 0; i
< layer
->TilingForTesting()->num_tiles_x(); ++i
) {
56 for (int j
= 0; j
< layer
->TilingForTesting()->num_tiles_y(); ++j
)
57 layer
->PushTileProperties(i
, j
, resource_id
++, false);
63 void GetQuads(RenderPass
* render_pass
,
64 const gfx::Size
& tile_size
,
65 const gfx::Size
& layer_size
,
66 LayerTilingData::BorderTexelOption border_texel_option
,
67 const gfx::Rect
& visible_content_rect
) {
68 scoped_ptr
<TiledLayerImpl
> layer
=
69 CreateLayer(tile_size
, layer_size
, border_texel_option
);
70 layer
->draw_properties().visible_content_rect
= visible_content_rect
;
71 layer
->SetBounds(layer_size
);
73 MockOcclusionTracker
<LayerImpl
> occlusion_tracker
;
75 layer
->AppendQuads(render_pass
, occlusion_tracker
, &data
);
80 TestSharedBitmapManager shared_bitmap_manager_
;
81 FakeLayerTreeHostImpl host_impl_
;
84 TEST_F(TiledLayerImplTest
, EmptyQuadList
) {
85 gfx::Size
tile_size(90, 90);
88 gfx::Size
layer_size(tile_size
.width() * num_tiles_x
,
89 tile_size
.height() * num_tiles_y
);
91 // Verify default layer does creates quads
93 scoped_ptr
<TiledLayerImpl
> layer
=
94 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
95 MockOcclusionTracker
<LayerImpl
> occlusion_tracker
;
96 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
99 EXPECT_TRUE(layer
->WillDraw(DRAW_MODE_HARDWARE
, NULL
));
100 layer
->AppendQuads(render_pass
.get(), occlusion_tracker
, &data
);
101 layer
->DidDraw(NULL
);
102 unsigned num_tiles
= num_tiles_x
* num_tiles_y
;
103 EXPECT_EQ(render_pass
->quad_list
.size(), num_tiles
);
106 // Layer with empty visible layer rect produces no quads
108 scoped_ptr
<TiledLayerImpl
> layer
=
109 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
110 layer
->draw_properties().visible_content_rect
= gfx::Rect();
112 MockOcclusionTracker
<LayerImpl
> occlusion_tracker
;
113 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
115 EXPECT_FALSE(layer
->WillDraw(DRAW_MODE_HARDWARE
, NULL
));
118 // Layer with non-intersecting visible layer rect produces no quads
120 scoped_ptr
<TiledLayerImpl
> layer
=
121 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
123 gfx::Rect
outside_bounds(-100, -100, 50, 50);
124 layer
->draw_properties().visible_content_rect
= outside_bounds
;
126 MockOcclusionTracker
<LayerImpl
> occlusion_tracker
;
127 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
129 AppendQuadsData data
;
130 EXPECT_TRUE(layer
->WillDraw(DRAW_MODE_HARDWARE
, NULL
));
131 layer
->AppendQuads(render_pass
.get(), occlusion_tracker
, &data
);
132 layer
->DidDraw(NULL
);
133 EXPECT_EQ(render_pass
->quad_list
.size(), 0u);
136 // Layer with skips draw produces no quads
138 scoped_ptr
<TiledLayerImpl
> layer
=
139 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
140 layer
->set_skips_draw(true);
142 MockOcclusionTracker
<LayerImpl
> occlusion_tracker
;
143 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
145 AppendQuadsData data
;
146 layer
->AppendQuads(render_pass
.get(), occlusion_tracker
, &data
);
147 EXPECT_EQ(render_pass
->quad_list
.size(), 0u);
151 TEST_F(TiledLayerImplTest
, Checkerboarding
) {
152 gfx::Size
tile_size(10, 10);
155 gfx::Size
layer_size(tile_size
.width() * num_tiles_x
,
156 tile_size
.height() * num_tiles_y
);
158 scoped_ptr
<TiledLayerImpl
> layer
=
159 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
161 // No checkerboarding
163 MockOcclusionTracker
<LayerImpl
> occlusion_tracker
;
164 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
166 AppendQuadsData data
;
167 layer
->AppendQuads(render_pass
.get(), occlusion_tracker
, &data
);
168 EXPECT_EQ(render_pass
->quad_list
.size(), 4u);
169 EXPECT_EQ(0u, data
.num_missing_tiles
);
171 for (size_t i
= 0; i
< render_pass
->quad_list
.size(); ++i
)
172 EXPECT_EQ(render_pass
->quad_list
[i
]->material
, DrawQuad::TILED_CONTENT
);
175 for (int i
= 0; i
< num_tiles_x
; ++i
)
176 for (int j
= 0; j
< num_tiles_y
; ++j
)
177 layer
->PushTileProperties(i
, j
, 0, false);
179 // All checkerboarding
181 MockOcclusionTracker
<LayerImpl
> occlusion_tracker
;
182 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
184 AppendQuadsData data
;
185 layer
->AppendQuads(render_pass
.get(), occlusion_tracker
, &data
);
186 EXPECT_LT(0u, data
.num_missing_tiles
);
187 EXPECT_EQ(render_pass
->quad_list
.size(), 4u);
188 for (size_t i
= 0; i
< render_pass
->quad_list
.size(); ++i
)
189 EXPECT_NE(render_pass
->quad_list
[i
]->material
, DrawQuad::TILED_CONTENT
);
193 // Test with both border texels and without.
194 #define WITH_AND_WITHOUT_BORDER_TEST(text_fixture_name) \
195 TEST_F(TiledLayerImplBorderTest, text_fixture_name##NoBorders) { \
196 text_fixture_name(LayerTilingData::NO_BORDER_TEXELS); \
198 TEST_F(TiledLayerImplBorderTest, text_fixture_name##HasBorders) { \
199 text_fixture_name(LayerTilingData::HAS_BORDER_TEXELS); \
202 class TiledLayerImplBorderTest
: public TiledLayerImplTest
{
204 void CoverageVisibleRectOnTileBoundaries(
205 LayerTilingData::BorderTexelOption borders
) {
206 gfx::Size
layer_size(1000, 1000);
207 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
208 GetQuads(render_pass
.get(),
212 gfx::Rect(layer_size
));
213 LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass
->quad_list
,
214 gfx::Rect(layer_size
));
217 void CoverageVisibleRectIntersectsTiles(
218 LayerTilingData::BorderTexelOption borders
) {
219 // This rect intersects the middle 3x3 of the 5x5 tiles.
220 gfx::Point
top_left(65, 73);
221 gfx::Point
bottom_right(182, 198);
222 gfx::Rect visible_content_rect
= gfx::BoundingRect(top_left
, bottom_right
);
224 gfx::Size
layer_size(250, 250);
225 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
226 GetQuads(render_pass
.get(),
229 LayerTilingData::NO_BORDER_TEXELS
,
230 visible_content_rect
);
231 LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass
->quad_list
,
232 visible_content_rect
);
235 void CoverageVisibleRectIntersectsBounds(
236 LayerTilingData::BorderTexelOption borders
) {
237 gfx::Size
layer_size(220, 210);
238 gfx::Rect
visible_content_rect(layer_size
);
239 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
240 GetQuads(render_pass
.get(),
243 LayerTilingData::NO_BORDER_TEXELS
,
244 visible_content_rect
);
245 LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass
->quad_list
,
246 visible_content_rect
);
249 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries
);
251 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles
);
253 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds
);
255 TEST_F(TiledLayerImplTest
, TextureInfoForLayerNoBorders
) {
256 gfx::Size
tile_size(50, 50);
257 gfx::Size
layer_size(250, 250);
258 scoped_ptr
<RenderPass
> render_pass
= RenderPass::Create();
259 GetQuads(render_pass
.get(),
262 LayerTilingData::NO_BORDER_TEXELS
,
263 gfx::Rect(layer_size
));
265 for (size_t i
= 0; i
< render_pass
->quad_list
.size(); ++i
) {
266 const TileDrawQuad
* quad
=
267 TileDrawQuad::MaterialCast(render_pass
->quad_list
[i
]);
269 EXPECT_NE(0u, quad
->resource_id
) << LayerTestCommon::quad_string
<< i
;
270 EXPECT_EQ(gfx::RectF(gfx::PointF(), tile_size
), quad
->tex_coord_rect
)
271 << LayerTestCommon::quad_string
<< i
;
272 EXPECT_EQ(tile_size
, quad
->texture_size
) << LayerTestCommon::quad_string
277 TEST_F(TiledLayerImplTest
, GPUMemoryUsage
) {
278 gfx::Size
tile_size(20, 30);
279 int num_tiles_x
= 12;
280 int num_tiles_y
= 32;
281 gfx::Size
layer_size(tile_size
.width() * num_tiles_x
,
282 tile_size
.height() * num_tiles_y
);
284 scoped_ptr
<TiledLayerImpl
> layer
= CreateLayerNoTiles(
285 tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
287 EXPECT_EQ(layer
->GPUMemoryUsageInBytes(), 0u);
289 ResourceProvider::ResourceId resource_id
= 1;
290 layer
->PushTileProperties(0, 1, resource_id
++, false);
291 layer
->PushTileProperties(2, 3, resource_id
++, false);
292 layer
->PushTileProperties(2, 0, resource_id
++, false);
295 layer
->GPUMemoryUsageInBytes(),
296 static_cast<size_t>(3 * 4 * tile_size
.width() * tile_size
.height()));
298 ResourceProvider::ResourceId
empty_resource(0);
299 layer
->PushTileProperties(0, 1, empty_resource
, false);
300 layer
->PushTileProperties(2, 3, empty_resource
, false);
301 layer
->PushTileProperties(2, 0, empty_resource
, false);
303 EXPECT_EQ(layer
->GPUMemoryUsageInBytes(), 0u);
306 TEST_F(TiledLayerImplTest
, EmptyMask
) {
307 gfx::Size
tile_size(20, 20);
308 gfx::Size
layer_size(0, 0);
309 scoped_ptr
<TiledLayerImpl
> layer
=
310 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
312 EXPECT_EQ(0u, layer
->ContentsResourceId());
313 EXPECT_EQ(0, layer
->TilingForTesting()->num_tiles_x());
314 EXPECT_EQ(0, layer
->TilingForTesting()->num_tiles_y());
317 TEST_F(TiledLayerImplTest
, Occlusion
) {
318 gfx::Size
tile_size(100, 100);
319 gfx::Size
layer_bounds(1000, 1000);
320 gfx::Size
viewport_size(1000, 1000);
322 LayerTestCommon::LayerImplTest impl
;
324 TiledLayerImpl
* tiled_layer
= impl
.AddChildToRoot
<TiledLayerImpl
>();
325 tiled_layer
->SetBounds(layer_bounds
);
326 tiled_layer
->SetContentBounds(layer_bounds
);
327 tiled_layer
->SetDrawsContent(true);
328 tiled_layer
->set_skips_draw(false);
330 scoped_ptr
<LayerTilingData
> tiler
=
331 LayerTilingData::Create(tile_size
, LayerTilingData::NO_BORDER_TEXELS
);
332 tiler
->SetTilingSize(layer_bounds
);
333 tiled_layer
->SetTilingData(*tiler
);
335 ResourceProvider::ResourceId resource_id
= 1;
336 for (int i
= 0; i
< tiled_layer
->TilingForTesting()->num_tiles_x(); ++i
) {
337 for (int j
= 0; j
< tiled_layer
->TilingForTesting()->num_tiles_y(); ++j
)
338 tiled_layer
->PushTileProperties(i
, j
, resource_id
++, false);
341 impl
.CalcDrawProps(viewport_size
);
344 SCOPED_TRACE("No occlusion");
346 impl
.AppendQuadsWithOcclusion(tiled_layer
, occluded
);
348 LayerTestCommon::VerifyQuadsExactlyCoverRect(impl
.quad_list(),
349 gfx::Rect(layer_bounds
));
350 EXPECT_EQ(100u, impl
.quad_list().size());
354 SCOPED_TRACE("Full occlusion");
355 gfx::Rect
occluded(tiled_layer
->visible_content_rect());
356 impl
.AppendQuadsWithOcclusion(tiled_layer
, occluded
);
358 LayerTestCommon::VerifyQuadsExactlyCoverRect(impl
.quad_list(), gfx::Rect());
359 EXPECT_EQ(impl
.quad_list().size(), 0u);
363 SCOPED_TRACE("Partial occlusion");
364 gfx::Rect
occluded(150, 0, 200, 1000);
365 impl
.AppendQuadsWithOcclusion(tiled_layer
, occluded
);
367 size_t partially_occluded_count
= 0;
368 LayerTestCommon::VerifyQuadsAreOccluded(
369 impl
.quad_list(), occluded
, &partially_occluded_count
);
370 // The layer outputs one quad, which is partially occluded.
371 EXPECT_EQ(100u - 10u, impl
.quad_list().size());
372 EXPECT_EQ(10u + 10u, partially_occluded_count
);