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/test/mock_quad_culler.h"
14 #include "cc/trees/single_thread_proxy.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
21 class TiledLayerImplTest
: public testing::Test
{
23 TiledLayerImplTest() : host_impl_(&proxy_
) {}
25 scoped_ptr
<TiledLayerImpl
> CreateLayerNoTiles(
26 const gfx::Size
& tile_size
,
27 const gfx::Size
& layer_size
,
28 LayerTilingData::BorderTexelOption border_texels
) {
29 scoped_ptr
<TiledLayerImpl
> layer
=
30 TiledLayerImpl::Create(host_impl_
.active_tree(), 1);
31 scoped_ptr
<LayerTilingData
> tiler
=
32 LayerTilingData::Create(tile_size
, border_texels
);
33 tiler
->SetBounds(layer_size
);
34 layer
->SetTilingData(*tiler
);
35 layer
->set_skips_draw(false);
36 layer
->draw_properties().visible_content_rect
=
37 gfx::Rect(layer_size
);
38 layer
->draw_properties().opacity
= 1;
39 layer
->SetBounds(layer_size
);
40 layer
->SetContentBounds(layer_size
);
41 layer
->CreateRenderSurface();
42 layer
->draw_properties().render_target
= layer
.get();
46 // Create a default tiled layer with textures for all tiles and a default
47 // visibility of the entire layer size.
48 scoped_ptr
<TiledLayerImpl
> CreateLayer(
49 const gfx::Size
& tile_size
,
50 const gfx::Size
& layer_size
,
51 LayerTilingData::BorderTexelOption border_texels
) {
52 scoped_ptr
<TiledLayerImpl
> layer
=
53 CreateLayerNoTiles(tile_size
, layer_size
, border_texels
);
55 layer
->SetDrawsContent(true);
57 ResourceProvider::ResourceId resource_id
= 1;
58 for (int i
= 0; i
< layer
->TilingForTesting()->num_tiles_x(); ++i
) {
59 for (int j
= 0; j
< layer
->TilingForTesting()->num_tiles_y(); ++j
) {
60 gfx::Rect
opaque_rect(
61 layer
->TilingForTesting()->tile_bounds(i
, j
).origin(),
63 layer
->PushTileProperties(i
, j
, resource_id
++, opaque_rect
, false);
70 void GetQuads(QuadList
* quads
,
71 SharedQuadStateList
* shared_states
,
72 const gfx::Size
& tile_size
,
73 const gfx::Size
& layer_size
,
74 LayerTilingData::BorderTexelOption border_texel_option
,
75 const gfx::Rect
& visible_content_rect
) {
76 scoped_ptr
<TiledLayerImpl
> layer
=
77 CreateLayer(tile_size
, layer_size
, border_texel_option
);
78 layer
->draw_properties().visible_content_rect
= visible_content_rect
;
79 layer
->SetBounds(layer_size
);
81 MockQuadCuller
quad_culler(quads
, shared_states
);
83 layer
->AppendQuads(&quad_culler
, &data
);
88 FakeLayerTreeHostImpl host_impl_
;
91 TEST_F(TiledLayerImplTest
, EmptyQuadList
) {
92 gfx::Size
tile_size(90, 90);
95 gfx::Size
layer_size(tile_size
.width() * num_tiles_x
,
96 tile_size
.height() * num_tiles_y
);
98 // Verify default layer does creates quads
100 scoped_ptr
<TiledLayerImpl
> layer
=
101 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
102 MockQuadCuller quad_culler
;
103 AppendQuadsData data
;
104 EXPECT_TRUE(layer
->WillDraw(DRAW_MODE_HARDWARE
, NULL
));
105 layer
->AppendQuads(&quad_culler
, &data
);
106 layer
->DidDraw(NULL
);
107 unsigned num_tiles
= num_tiles_x
* num_tiles_y
;
108 EXPECT_EQ(quad_culler
.quad_list().size(), num_tiles
);
111 // Layer with empty visible layer rect produces no quads
113 scoped_ptr
<TiledLayerImpl
> layer
=
114 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
115 layer
->draw_properties().visible_content_rect
= gfx::Rect();
117 MockQuadCuller quad_culler
;
118 EXPECT_FALSE(layer
->WillDraw(DRAW_MODE_HARDWARE
, NULL
));
121 // Layer with non-intersecting visible layer rect produces no quads
123 scoped_ptr
<TiledLayerImpl
> layer
=
124 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
126 gfx::Rect
outside_bounds(-100, -100, 50, 50);
127 layer
->draw_properties().visible_content_rect
= outside_bounds
;
129 MockQuadCuller quad_culler
;
130 AppendQuadsData data
;
131 EXPECT_TRUE(layer
->WillDraw(DRAW_MODE_HARDWARE
, NULL
));
132 layer
->AppendQuads(&quad_culler
, &data
);
133 layer
->DidDraw(NULL
);
134 EXPECT_EQ(quad_culler
.quad_list().size(), 0u);
137 // Layer with skips draw produces no quads
139 scoped_ptr
<TiledLayerImpl
> layer
=
140 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
141 layer
->set_skips_draw(true);
143 MockQuadCuller quad_culler
;
144 AppendQuadsData data
;
145 layer
->AppendQuads(&quad_culler
, &data
);
146 EXPECT_EQ(quad_culler
.quad_list().size(), 0u);
150 TEST_F(TiledLayerImplTest
, Checkerboarding
) {
151 gfx::Size
tile_size(10, 10);
154 gfx::Size
layer_size(tile_size
.width() * num_tiles_x
,
155 tile_size
.height() * num_tiles_y
);
157 scoped_ptr
<TiledLayerImpl
> layer
=
158 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
160 // No checkerboarding
162 MockQuadCuller quad_culler
;
163 AppendQuadsData data
;
164 layer
->AppendQuads(&quad_culler
, &data
);
165 EXPECT_EQ(quad_culler
.quad_list().size(), 4u);
166 EXPECT_EQ(0u, data
.num_missing_tiles
);
168 for (size_t i
= 0; i
< quad_culler
.quad_list().size(); ++i
)
169 EXPECT_EQ(quad_culler
.quad_list()[i
]->material
, DrawQuad::TILED_CONTENT
);
172 for (int i
= 0; i
< num_tiles_x
; ++i
)
173 for (int j
= 0; j
< num_tiles_y
; ++j
)
174 layer
->PushTileProperties(i
, j
, 0, gfx::Rect(), false);
176 // All checkerboarding
178 MockQuadCuller quad_culler
;
179 AppendQuadsData data
;
180 layer
->AppendQuads(&quad_culler
, &data
);
181 EXPECT_LT(0u, data
.num_missing_tiles
);
182 EXPECT_EQ(quad_culler
.quad_list().size(), 4u);
183 for (size_t i
= 0; i
< quad_culler
.quad_list().size(); ++i
)
184 EXPECT_NE(quad_culler
.quad_list()[i
]->material
, DrawQuad::TILED_CONTENT
);
188 // Test with both border texels and without.
189 #define WITH_AND_WITHOUT_BORDER_TEST(text_fixture_name) \
190 TEST_F(TiledLayerImplBorderTest, text_fixture_name##NoBorders) { \
191 text_fixture_name(LayerTilingData::NO_BORDER_TEXELS); \
193 TEST_F(TiledLayerImplBorderTest, text_fixture_name##HasBorders) { \
194 text_fixture_name(LayerTilingData::HAS_BORDER_TEXELS); \
197 class TiledLayerImplBorderTest
: public TiledLayerImplTest
{
199 void CoverageVisibleRectOnTileBoundaries(
200 LayerTilingData::BorderTexelOption borders
) {
201 gfx::Size
layer_size(1000, 1000);
203 SharedQuadStateList shared_states
;
209 gfx::Rect(layer_size
));
210 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads
, gfx::Rect(layer_size
));
213 void CoverageVisibleRectIntersectsTiles(
214 LayerTilingData::BorderTexelOption borders
) {
215 // This rect intersects the middle 3x3 of the 5x5 tiles.
216 gfx::Point
top_left(65, 73);
217 gfx::Point
bottom_right(182, 198);
218 gfx::Rect visible_content_rect
= gfx::BoundingRect(top_left
, bottom_right
);
220 gfx::Size
layer_size(250, 250);
222 SharedQuadStateList shared_states
;
227 LayerTilingData::NO_BORDER_TEXELS
,
228 visible_content_rect
);
229 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads
, visible_content_rect
);
232 void CoverageVisibleRectIntersectsBounds(
233 LayerTilingData::BorderTexelOption borders
) {
234 gfx::Size
layer_size(220, 210);
235 gfx::Rect
visible_content_rect(layer_size
);
237 SharedQuadStateList shared_states
;
242 LayerTilingData::NO_BORDER_TEXELS
,
243 visible_content_rect
);
244 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads
, visible_content_rect
);
247 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries
);
249 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles
);
251 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds
);
253 TEST_F(TiledLayerImplTest
, TextureInfoForLayerNoBorders
) {
254 gfx::Size
tile_size(50, 50);
255 gfx::Size
layer_size(250, 250);
257 SharedQuadStateList shared_states
;
262 LayerTilingData::NO_BORDER_TEXELS
,
263 gfx::Rect(layer_size
));
265 for (size_t i
= 0; i
< quads
.size(); ++i
) {
266 const TileDrawQuad
* quad
= TileDrawQuad::MaterialCast(quads
[i
]);
268 EXPECT_NE(0u, quad
->resource_id
) << LayerTestCommon::quad_string
<< i
;
269 EXPECT_EQ(gfx::RectF(gfx::PointF(), tile_size
), quad
->tex_coord_rect
)
270 << LayerTestCommon::quad_string
<< i
;
271 EXPECT_EQ(tile_size
, quad
->texture_size
) << LayerTestCommon::quad_string
273 EXPECT_EQ(gfx::Size(1, 1).ToString(), quad
->opaque_rect
.size().ToString())
274 << LayerTestCommon::quad_string
<< i
;
278 TEST_F(TiledLayerImplTest
, GPUMemoryUsage
) {
279 gfx::Size
tile_size(20, 30);
280 int num_tiles_x
= 12;
281 int num_tiles_y
= 32;
282 gfx::Size
layer_size(tile_size
.width() * num_tiles_x
,
283 tile_size
.height() * num_tiles_y
);
285 scoped_ptr
<TiledLayerImpl
> layer
= CreateLayerNoTiles(
286 tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
288 EXPECT_EQ(layer
->GPUMemoryUsageInBytes(), 0u);
290 ResourceProvider::ResourceId resource_id
= 1;
291 layer
->PushTileProperties(0, 1, resource_id
++, gfx::Rect(0, 0, 1, 1), false);
292 layer
->PushTileProperties(2, 3, resource_id
++, gfx::Rect(0, 0, 1, 1), false);
293 layer
->PushTileProperties(2, 0, resource_id
++, gfx::Rect(0, 0, 1, 1), false);
296 layer
->GPUMemoryUsageInBytes(),
297 static_cast<size_t>(3 * 4 * tile_size
.width() * tile_size
.height()));
299 ResourceProvider::ResourceId
empty_resource(0);
300 layer
->PushTileProperties(0, 1, empty_resource
, gfx::Rect(0, 0, 1, 1), false);
301 layer
->PushTileProperties(2, 3, empty_resource
, gfx::Rect(0, 0, 1, 1), false);
302 layer
->PushTileProperties(2, 0, empty_resource
, gfx::Rect(0, 0, 1, 1), false);
304 EXPECT_EQ(layer
->GPUMemoryUsageInBytes(), 0u);
307 TEST_F(TiledLayerImplTest
, EmptyMask
) {
308 gfx::Size
tile_size(20, 20);
309 gfx::Size
layer_size(0, 0);
310 scoped_ptr
<TiledLayerImpl
> layer
=
311 CreateLayer(tile_size
, layer_size
, LayerTilingData::NO_BORDER_TEXELS
);
313 EXPECT_EQ(0u, layer
->ContentsResourceId());
314 EXPECT_EQ(0, layer
->TilingForTesting()->num_tiles_x());
315 EXPECT_EQ(0, layer
->TilingForTesting()->num_tiles_y());