tiled_layer_impl_unittest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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    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
87TEST_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
146TEST_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
193class 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};
243WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries);
244
245WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles);
246
247WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds);
248
249TEST_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
274TEST_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