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. 4 5 #include "cc/layers/tiled_layer_impl.h" 6 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" 17 18 namespace cc { 19 namespace { 20 21 class TiledLayerImplTest : public testing::Test { 22 public: 23 TiledLayerImplTest() : host_impl_(&proxy_) {} 24 25 scoped_ptr<TiledLayerImpl> CreateLayerNoTiles( 26 gfx::Size tile_size, 27 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(); 43 return layer.Pass(); 44 } 45 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 gfx::Size tile_size, 50 gfx::Size layer_size, 51 LayerTilingData::BorderTexelOption border_texels) { 52 scoped_ptr<TiledLayerImpl> layer = 53 CreateLayerNoTiles(tile_size, layer_size, border_texels); 54 55 ResourceProvider::ResourceId resource_id = 1; 56 for (int i = 0; i < layer->TilingForTesting()->num_tiles_x(); ++i) { 57 for (int j = 0; j < layer->TilingForTesting()->num_tiles_y(); ++j) { 58 layer->PushTileProperties( 59 i, j, resource_id++, gfx::Rect(0, 0, 1, 1), false); 60 } 61 } 62 63 return layer.Pass(); 64 } 65 66 void GetQuads(QuadList* quads, 67 SharedQuadStateList* shared_states, 68 gfx::Size tile_size, 69 gfx::Size layer_size, 70 LayerTilingData::BorderTexelOption border_texel_option, 71 gfx::Rect visible_content_rect) { 72 scoped_ptr<TiledLayerImpl> layer = 73 CreateLayer(tile_size, layer_size, border_texel_option); 74 layer->draw_properties().visible_content_rect = visible_content_rect; 75 layer->SetBounds(layer_size); 76 77 MockQuadCuller quad_culler(quads, shared_states); 78 AppendQuadsData data; 79 layer->AppendQuads(&quad_culler, &data); 80 } 81 82 protected: 83 FakeImplProxy proxy_; 84 FakeLayerTreeHostImpl host_impl_; 85 }; 86 87 TEST_F(TiledLayerImplTest, EmptyQuadList) { 88 gfx::Size tile_size(90, 90); 89 int num_tiles_x = 8; 90 int num_tiles_y = 4; 91 gfx::Size layer_size(tile_size.width() * num_tiles_x, 92 tile_size.height() * num_tiles_y); 93 94 // Verify default layer does creates quads 95 { 96 scoped_ptr<TiledLayerImpl> layer = 97 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 98 MockQuadCuller quad_culler; 99 AppendQuadsData data; 100 EXPECT_TRUE(layer->WillDraw(DRAW_MODE_HARDWARE, NULL)); 101 layer->AppendQuads(&quad_culler, &data); 102 layer->DidDraw(NULL); 103 unsigned num_tiles = num_tiles_x * num_tiles_y; 104 EXPECT_EQ(quad_culler.quad_list().size(), num_tiles); 105 } 106 107 // Layer with empty visible layer rect produces no quads 108 { 109 scoped_ptr<TiledLayerImpl> layer = 110 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 111 layer->draw_properties().visible_content_rect = gfx::Rect(); 112 113 MockQuadCuller quad_culler; 114 EXPECT_FALSE(layer->WillDraw(DRAW_MODE_HARDWARE, NULL)); 115 } 116 117 // Layer with non-intersecting visible layer rect produces no quads 118 { 119 scoped_ptr<TiledLayerImpl> layer = 120 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 121 122 gfx::Rect outside_bounds(-100, -100, 50, 50); 123 layer->draw_properties().visible_content_rect = outside_bounds; 124 125 MockQuadCuller quad_culler; 126 AppendQuadsData data; 127 EXPECT_TRUE(layer->WillDraw(DRAW_MODE_HARDWARE, NULL)); 128 layer->AppendQuads(&quad_culler, &data); 129 layer->DidDraw(NULL); 130 EXPECT_EQ(quad_culler.quad_list().size(), 0u); 131 } 132 133 // Layer with skips draw produces no quads 134 { 135 scoped_ptr<TiledLayerImpl> layer = 136 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 137 layer->set_skips_draw(true); 138 139 MockQuadCuller quad_culler; 140 AppendQuadsData data; 141 layer->AppendQuads(&quad_culler, &data); 142 EXPECT_EQ(quad_culler.quad_list().size(), 0u); 143 } 144 } 145 146 TEST_F(TiledLayerImplTest, Checkerboarding) { 147 gfx::Size tile_size(10, 10); 148 int num_tiles_x = 2; 149 int num_tiles_y = 2; 150 gfx::Size layer_size(tile_size.width() * num_tiles_x, 151 tile_size.height() * num_tiles_y); 152 153 scoped_ptr<TiledLayerImpl> layer = 154 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 155 156 // No checkerboarding 157 { 158 MockQuadCuller quad_culler; 159 AppendQuadsData data; 160 layer->AppendQuads(&quad_culler, &data); 161 EXPECT_EQ(quad_culler.quad_list().size(), 4u); 162 EXPECT_EQ(0u, data.num_missing_tiles); 163 164 for (size_t i = 0; i < quad_culler.quad_list().size(); ++i) 165 EXPECT_EQ(quad_culler.quad_list()[i]->material, DrawQuad::TILED_CONTENT); 166 } 167 168 for (int i = 0; i < num_tiles_x; ++i) 169 for (int j = 0; j < num_tiles_y; ++j) 170 layer->PushTileProperties(i, j, 0, gfx::Rect(), false); 171 172 // All checkerboarding 173 { 174 MockQuadCuller quad_culler; 175 AppendQuadsData data; 176 layer->AppendQuads(&quad_culler, &data); 177 EXPECT_LT(0u, data.num_missing_tiles); 178 EXPECT_EQ(quad_culler.quad_list().size(), 4u); 179 for (size_t i = 0; i < quad_culler.quad_list().size(); ++i) 180 EXPECT_NE(quad_culler.quad_list()[i]->material, DrawQuad::TILED_CONTENT); 181 } 182 } 183 184 // Test with both border texels and without. 185 #define WITH_AND_WITHOUT_BORDER_TEST(text_fixture_name) \ 186 TEST_F(TiledLayerImplBorderTest, text_fixture_name##NoBorders) { \ 187 text_fixture_name(LayerTilingData::NO_BORDER_TEXELS); \ 188 } \ 189 TEST_F(TiledLayerImplBorderTest, text_fixture_name##HasBorders) { \ 190 text_fixture_name(LayerTilingData::HAS_BORDER_TEXELS); \ 191 } 192 193 class TiledLayerImplBorderTest : public TiledLayerImplTest { 194 public: 195 void CoverageVisibleRectOnTileBoundaries( 196 LayerTilingData::BorderTexelOption borders) { 197 gfx::Size layer_size(1000, 1000); 198 QuadList quads; 199 SharedQuadStateList shared_states; 200 GetQuads(&quads, 201 &shared_states, 202 gfx::Size(100, 100), 203 layer_size, 204 borders, 205 gfx::Rect(layer_size)); 206 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, gfx::Rect(layer_size)); 207 } 208 209 void CoverageVisibleRectIntersectsTiles( 210 LayerTilingData::BorderTexelOption borders) { 211 // This rect intersects the middle 3x3 of the 5x5 tiles. 212 gfx::Point top_left(65, 73); 213 gfx::Point bottom_right(182, 198); 214 gfx::Rect visible_content_rect = gfx::BoundingRect(top_left, bottom_right); 215 216 gfx::Size layer_size(250, 250); 217 QuadList quads; 218 SharedQuadStateList shared_states; 219 GetQuads(&quads, 220 &shared_states, 221 gfx::Size(50, 50), 222 gfx::Size(250, 250), 223 LayerTilingData::NO_BORDER_TEXELS, 224 visible_content_rect); 225 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, visible_content_rect); 226 } 227 228 void CoverageVisibleRectIntersectsBounds( 229 LayerTilingData::BorderTexelOption borders) { 230 gfx::Size layer_size(220, 210); 231 gfx::Rect visible_content_rect(layer_size); 232 QuadList quads; 233 SharedQuadStateList shared_states; 234 GetQuads(&quads, 235 &shared_states, 236 gfx::Size(100, 100), 237 layer_size, 238 LayerTilingData::NO_BORDER_TEXELS, 239 visible_content_rect); 240 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, visible_content_rect); 241 } 242 }; 243 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries); 244 245 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles); 246 247 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds); 248 249 TEST_F(TiledLayerImplTest, TextureInfoForLayerNoBorders) { 250 gfx::Size tile_size(50, 50); 251 gfx::Size layer_size(250, 250); 252 QuadList quads; 253 SharedQuadStateList shared_states; 254 GetQuads(&quads, 255 &shared_states, 256 tile_size, 257 layer_size, 258 LayerTilingData::NO_BORDER_TEXELS, 259 gfx::Rect(layer_size)); 260 261 for (size_t i = 0; i < quads.size(); ++i) { 262 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(quads[i]); 263 264 EXPECT_NE(0u, quad->resource_id) << LayerTestCommon::quad_string << i; 265 EXPECT_EQ(gfx::RectF(gfx::PointF(), tile_size), quad->tex_coord_rect) 266 << LayerTestCommon::quad_string << i; 267 EXPECT_EQ(tile_size, quad->texture_size) << LayerTestCommon::quad_string 268 << i; 269 EXPECT_EQ(gfx::Rect(0, 0, 1, 1), quad->opaque_rect) 270 << LayerTestCommon::quad_string << i; 271 } 272 } 273 274 TEST_F(TiledLayerImplTest, GPUMemoryUsage) { 275 gfx::Size tile_size(20, 30); 276 int num_tiles_x = 12; 277 int num_tiles_y = 32; 278 gfx::Size layer_size(tile_size.width() * num_tiles_x, 279 tile_size.height() * num_tiles_y); 280 281 scoped_ptr<TiledLayerImpl> layer = CreateLayerNoTiles( 282 tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 283 284 EXPECT_EQ(layer->GPUMemoryUsageInBytes(), 0u); 285 286 ResourceProvider::ResourceId resource_id = 1; 287 layer->PushTileProperties(0, 1, resource_id++, gfx::Rect(0, 0, 1, 1), false); 288 layer->PushTileProperties(2, 3, resource_id++, gfx::Rect(0, 0, 1, 1), false); 289 layer->PushTileProperties(2, 0, resource_id++, gfx::Rect(0, 0, 1, 1), false); 290 291 EXPECT_EQ( 292 layer->GPUMemoryUsageInBytes(), 293 static_cast<size_t>(3 * 4 * tile_size.width() * tile_size.height())); 294 295 ResourceProvider::ResourceId empty_resource(0); 296 layer->PushTileProperties(0, 1, empty_resource, gfx::Rect(0, 0, 1, 1), false); 297 layer->PushTileProperties(2, 3, empty_resource, gfx::Rect(0, 0, 1, 1), false); 298 layer->PushTileProperties(2, 0, empty_resource, gfx::Rect(0, 0, 1, 1), false); 299 300 EXPECT_EQ(layer->GPUMemoryUsageInBytes(), 0u); 301 } 302 303 } // namespace 304 } // namespace cc 305