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