Home | History | Annotate | Download | only in layers
      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 
     18 namespace cc {
     19 namespace {
     20 
     21 class 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 
     87 TEST_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 
    146 TEST_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 
    193 class 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 };
    243 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries);
    244 
    245 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles);
    246 
    247 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds);
    248 
    249 TEST_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 
    274 TEST_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