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