tiled_layer_impl_unittest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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  // Create a default tiled layer with textures for all tiles and a default
26  // visibility of the entire layer size.
27  scoped_ptr<TiledLayerImpl> CreateLayer(
28      gfx::Size tile_size,
29      gfx::Size layer_size,
30      LayerTilingData::BorderTexelOption border_texels) {
31    scoped_ptr<TiledLayerImpl> layer =
32        TiledLayerImpl::Create(host_impl_.active_tree(), 1);
33    scoped_ptr<LayerTilingData> tiler =
34        LayerTilingData::Create(tile_size, border_texels);
35    tiler->SetBounds(layer_size);
36    layer->SetTilingData(*tiler);
37    layer->set_skips_draw(false);
38    layer->draw_properties().visible_content_rect =
39        gfx::Rect(layer_size);
40    layer->draw_properties().opacity = 1;
41    layer->SetBounds(layer_size);
42    layer->SetContentBounds(layer_size);
43    layer->CreateRenderSurface();
44    layer->draw_properties().render_target = layer.get();
45
46    ResourceProvider::ResourceId resource_id = 1;
47    for (int i = 0; i < tiler->num_tiles_x(); ++i) {
48      for (int j = 0; j < tiler->num_tiles_y(); ++j) {
49        layer->PushTileProperties(
50            i, j, resource_id++, gfx::Rect(0, 0, 1, 1), false);
51      }
52    }
53
54    return layer.Pass();
55  }
56
57  void GetQuads(QuadList* quads,
58                SharedQuadStateList* shared_states,
59                gfx::Size tile_size,
60                gfx::Size layer_size,
61                LayerTilingData::BorderTexelOption border_texel_option,
62                gfx::Rect visible_content_rect) {
63    scoped_ptr<TiledLayerImpl> layer =
64        CreateLayer(tile_size, layer_size, border_texel_option);
65    layer->draw_properties().visible_content_rect = visible_content_rect;
66    layer->SetBounds(layer_size);
67
68    MockQuadCuller quad_culler(quads, shared_states);
69    AppendQuadsData data;
70    layer->AppendQuads(&quad_culler, &data);
71  }
72
73 protected:
74  FakeImplProxy proxy_;
75  FakeLayerTreeHostImpl host_impl_;
76};
77
78TEST_F(TiledLayerImplTest, EmptyQuadList) {
79  gfx::Size tile_size(90, 90);
80  int num_tiles_x = 8;
81  int num_tiles_y = 4;
82  gfx::Size layer_size(tile_size.width() * num_tiles_x,
83                       tile_size.height() * num_tiles_y);
84
85  // Verify default layer does creates quads
86  {
87    scoped_ptr<TiledLayerImpl> layer =
88        CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
89    MockQuadCuller quad_culler;
90    AppendQuadsData data;
91    layer->AppendQuads(&quad_culler, &data);
92    unsigned num_tiles = num_tiles_x * num_tiles_y;
93    EXPECT_EQ(quad_culler.quad_list().size(), num_tiles);
94  }
95
96  // Layer with empty visible layer rect produces no quads
97  {
98    scoped_ptr<TiledLayerImpl> layer =
99        CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
100    layer->draw_properties().visible_content_rect = gfx::Rect();
101
102    MockQuadCuller quad_culler;
103    AppendQuadsData data;
104    layer->AppendQuads(&quad_culler, &data);
105    EXPECT_EQ(quad_culler.quad_list().size(), 0u);
106  }
107
108  // Layer with non-intersecting visible layer rect produces no quads
109  {
110    scoped_ptr<TiledLayerImpl> layer =
111        CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
112
113    gfx::Rect outside_bounds(-100, -100, 50, 50);
114    layer->draw_properties().visible_content_rect = outside_bounds;
115
116    MockQuadCuller quad_culler;
117    AppendQuadsData data;
118    layer->AppendQuads(&quad_culler, &data);
119    EXPECT_EQ(quad_culler.quad_list().size(), 0u);
120  }
121
122  // Layer with skips draw produces no quads
123  {
124    scoped_ptr<TiledLayerImpl> layer =
125        CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
126    layer->set_skips_draw(true);
127
128    MockQuadCuller quad_culler;
129    AppendQuadsData data;
130    layer->AppendQuads(&quad_culler, &data);
131    EXPECT_EQ(quad_culler.quad_list().size(), 0u);
132  }
133}
134
135TEST_F(TiledLayerImplTest, Checkerboarding) {
136  gfx::Size tile_size(10, 10);
137  int num_tiles_x = 2;
138  int num_tiles_y = 2;
139  gfx::Size layer_size(tile_size.width() * num_tiles_x,
140                       tile_size.height() * num_tiles_y);
141
142  scoped_ptr<TiledLayerImpl> layer =
143      CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
144
145  // No checkerboarding
146  {
147    MockQuadCuller quad_culler;
148    AppendQuadsData data;
149    layer->AppendQuads(&quad_culler, &data);
150    EXPECT_EQ(quad_culler.quad_list().size(), 4u);
151    EXPECT_EQ(0u, data.num_missing_tiles);
152
153    for (size_t i = 0; i < quad_culler.quad_list().size(); ++i)
154      EXPECT_EQ(quad_culler.quad_list()[i]->material, DrawQuad::TILED_CONTENT);
155  }
156
157  for (int i = 0; i < num_tiles_x; ++i)
158    for (int j = 0; j < num_tiles_y; ++j)
159      layer->PushTileProperties(i, j, 0, gfx::Rect(), false);
160
161  // All checkerboarding
162  {
163    MockQuadCuller quad_culler;
164    AppendQuadsData data;
165    layer->AppendQuads(&quad_culler, &data);
166    EXPECT_LT(0u, data.num_missing_tiles);
167    EXPECT_EQ(quad_culler.quad_list().size(), 4u);
168    for (size_t i = 0; i < quad_culler.quad_list().size(); ++i)
169      EXPECT_NE(quad_culler.quad_list()[i]->material, DrawQuad::TILED_CONTENT);
170  }
171}
172
173// Test with both border texels and without.
174#define WITH_AND_WITHOUT_BORDER_TEST(text_fixture_name)                        \
175  TEST_F(TiledLayerImplBorderTest, text_fixture_name##NoBorders) {             \
176    text_fixture_name(LayerTilingData::NO_BORDER_TEXELS);                      \
177  }                                                                            \
178  TEST_F(TiledLayerImplBorderTest, text_fixture_name##HasBorders) {            \
179    text_fixture_name(LayerTilingData::HAS_BORDER_TEXELS);                     \
180  }
181
182class TiledLayerImplBorderTest : public TiledLayerImplTest {
183 public:
184  void CoverageVisibleRectOnTileBoundaries(
185      LayerTilingData::BorderTexelOption borders) {
186    gfx::Size layer_size(1000, 1000);
187    QuadList quads;
188    SharedQuadStateList shared_states;
189    GetQuads(&quads,
190             &shared_states,
191             gfx::Size(100, 100),
192             layer_size,
193             borders,
194             gfx::Rect(layer_size));
195    LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, gfx::Rect(layer_size));
196  }
197
198  void CoverageVisibleRectIntersectsTiles(
199      LayerTilingData::BorderTexelOption borders) {
200    // This rect intersects the middle 3x3 of the 5x5 tiles.
201    gfx::Point top_left(65, 73);
202    gfx::Point bottom_right(182, 198);
203    gfx::Rect visible_content_rect = gfx::BoundingRect(top_left, bottom_right);
204
205    gfx::Size layer_size(250, 250);
206    QuadList quads;
207    SharedQuadStateList shared_states;
208    GetQuads(&quads,
209             &shared_states,
210             gfx::Size(50, 50),
211             gfx::Size(250, 250),
212             LayerTilingData::NO_BORDER_TEXELS,
213             visible_content_rect);
214    LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, visible_content_rect);
215  }
216
217  void CoverageVisibleRectIntersectsBounds(
218      LayerTilingData::BorderTexelOption borders) {
219    gfx::Size layer_size(220, 210);
220    gfx::Rect visible_content_rect(layer_size);
221    QuadList quads;
222    SharedQuadStateList shared_states;
223    GetQuads(&quads,
224             &shared_states,
225             gfx::Size(100, 100),
226             layer_size,
227             LayerTilingData::NO_BORDER_TEXELS,
228             visible_content_rect);
229    LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, visible_content_rect);
230  }
231};
232WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries);
233
234WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles);
235
236WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds);
237
238TEST_F(TiledLayerImplTest, TextureInfoForLayerNoBorders) {
239  gfx::Size tile_size(50, 50);
240  gfx::Size layer_size(250, 250);
241  QuadList quads;
242  SharedQuadStateList shared_states;
243  GetQuads(&quads,
244           &shared_states,
245           tile_size,
246           layer_size,
247           LayerTilingData::NO_BORDER_TEXELS,
248           gfx::Rect(layer_size));
249
250  for (size_t i = 0; i < quads.size(); ++i) {
251    const TileDrawQuad* quad = TileDrawQuad::MaterialCast(quads[i]);
252
253    EXPECT_NE(0u, quad->resource_id) << LayerTestCommon::quad_string << i;
254    EXPECT_EQ(gfx::RectF(gfx::PointF(), tile_size), quad->tex_coord_rect)
255        << LayerTestCommon::quad_string << i;
256    EXPECT_EQ(tile_size, quad->texture_size) << LayerTestCommon::quad_string
257                                             << i;
258    EXPECT_EQ(gfx::Rect(0, 0, 1, 1), quad->opaque_rect)
259        << LayerTestCommon::quad_string << i;
260  }
261}
262
263}  // namespace
264}  // namespace cc
265