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_) {} 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 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 gfx::Size tile_size, 73 gfx::Size layer_size, 74 LayerTilingData::BorderTexelOption border_texel_option, 75 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 FakeLayerTreeHostImpl host_impl_; 89}; 90 91TEST_F(TiledLayerImplTest, EmptyQuadList) { 92 gfx::Size tile_size(90, 90); 93 int num_tiles_x = 8; 94 int num_tiles_y = 4; 95 gfx::Size layer_size(tile_size.width() * num_tiles_x, 96 tile_size.height() * num_tiles_y); 97 98 // Verify default layer does creates quads 99 { 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); 109 } 110 111 // Layer with empty visible layer rect produces no quads 112 { 113 scoped_ptr<TiledLayerImpl> layer = 114 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 115 layer->draw_properties().visible_content_rect = gfx::Rect(); 116 117 MockQuadCuller quad_culler; 118 EXPECT_FALSE(layer->WillDraw(DRAW_MODE_HARDWARE, NULL)); 119 } 120 121 // Layer with non-intersecting visible layer rect produces no quads 122 { 123 scoped_ptr<TiledLayerImpl> layer = 124 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 125 126 gfx::Rect outside_bounds(-100, -100, 50, 50); 127 layer->draw_properties().visible_content_rect = outside_bounds; 128 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); 135 } 136 137 // Layer with skips draw produces no quads 138 { 139 scoped_ptr<TiledLayerImpl> layer = 140 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 141 layer->set_skips_draw(true); 142 143 MockQuadCuller quad_culler; 144 AppendQuadsData data; 145 layer->AppendQuads(&quad_culler, &data); 146 EXPECT_EQ(quad_culler.quad_list().size(), 0u); 147 } 148} 149 150TEST_F(TiledLayerImplTest, Checkerboarding) { 151 gfx::Size tile_size(10, 10); 152 int num_tiles_x = 2; 153 int num_tiles_y = 2; 154 gfx::Size layer_size(tile_size.width() * num_tiles_x, 155 tile_size.height() * num_tiles_y); 156 157 scoped_ptr<TiledLayerImpl> layer = 158 CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 159 160 // No checkerboarding 161 { 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); 167 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); 170 } 171 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); 175 176 // All checkerboarding 177 { 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); 185 } 186} 187 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); \ 192 } \ 193 TEST_F(TiledLayerImplBorderTest, text_fixture_name##HasBorders) { \ 194 text_fixture_name(LayerTilingData::HAS_BORDER_TEXELS); \ 195 } 196 197class TiledLayerImplBorderTest : public TiledLayerImplTest { 198 public: 199 void CoverageVisibleRectOnTileBoundaries( 200 LayerTilingData::BorderTexelOption borders) { 201 gfx::Size layer_size(1000, 1000); 202 QuadList quads; 203 SharedQuadStateList shared_states; 204 GetQuads(&quads, 205 &shared_states, 206 gfx::Size(100, 100), 207 layer_size, 208 borders, 209 gfx::Rect(layer_size)); 210 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, gfx::Rect(layer_size)); 211 } 212 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); 219 220 gfx::Size layer_size(250, 250); 221 QuadList quads; 222 SharedQuadStateList shared_states; 223 GetQuads(&quads, 224 &shared_states, 225 gfx::Size(50, 50), 226 gfx::Size(250, 250), 227 LayerTilingData::NO_BORDER_TEXELS, 228 visible_content_rect); 229 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, visible_content_rect); 230 } 231 232 void CoverageVisibleRectIntersectsBounds( 233 LayerTilingData::BorderTexelOption borders) { 234 gfx::Size layer_size(220, 210); 235 gfx::Rect visible_content_rect(layer_size); 236 QuadList quads; 237 SharedQuadStateList shared_states; 238 GetQuads(&quads, 239 &shared_states, 240 gfx::Size(100, 100), 241 layer_size, 242 LayerTilingData::NO_BORDER_TEXELS, 243 visible_content_rect); 244 LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, visible_content_rect); 245 } 246}; 247WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries); 248 249WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles); 250 251WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds); 252 253TEST_F(TiledLayerImplTest, TextureInfoForLayerNoBorders) { 254 gfx::Size tile_size(50, 50); 255 gfx::Size layer_size(250, 250); 256 QuadList quads; 257 SharedQuadStateList shared_states; 258 GetQuads(&quads, 259 &shared_states, 260 tile_size, 261 layer_size, 262 LayerTilingData::NO_BORDER_TEXELS, 263 gfx::Rect(layer_size)); 264 265 for (size_t i = 0; i < quads.size(); ++i) { 266 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(quads[i]); 267 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 272 << i; 273 EXPECT_EQ(gfx::Size(1, 1).ToString(), quad->opaque_rect.size().ToString()) 274 << LayerTestCommon::quad_string << i; 275 } 276} 277 278TEST_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); 284 285 scoped_ptr<TiledLayerImpl> layer = CreateLayerNoTiles( 286 tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS); 287 288 EXPECT_EQ(layer->GPUMemoryUsageInBytes(), 0u); 289 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); 294 295 EXPECT_EQ( 296 layer->GPUMemoryUsageInBytes(), 297 static_cast<size_t>(3 * 4 * tile_size.width() * tile_size.height())); 298 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); 303 304 EXPECT_EQ(layer->GPUMemoryUsageInBytes(), 0u); 305} 306 307} // namespace 308} // namespace cc 309