Commit 9ee9c855 authored by epenner's avatar epenner Committed by Commit bot

CC: Tile-size cleanup.

Two tile-size cleanups in this patch:

- Fixes a bug where the minimum tile-height for GPU-raster
  pages is 512 until any amount of zoom is applied (all
  layers we being considered 'long-and-skinny' by the old
  logic).

- Reserves default_tile_size/max_untiled_layer_size for
  software-raster. GPU-raster now computes both of these,
  leaving only tile-grid-size which re-uses the setting.
  That will be removed in my next patch.

BUG=365877

Review URL: https://codereview.chromium.org/605773004

Cr-Commit-Position: refs/heads/master@{#299027}
parent aaa0642e
...@@ -44,6 +44,15 @@ const float kCpuSkewportTargetTimeInFrames = 60.0f; ...@@ -44,6 +44,15 @@ const float kCpuSkewportTargetTimeInFrames = 60.0f;
// TileManager::BinFromTilePriority). // TileManager::BinFromTilePriority).
const float kGpuSkewportTargetTimeInFrames = 0.0f; const float kGpuSkewportTargetTimeInFrames = 0.0f;
// Even for really wide viewports, at some point GPU raster should use
// less than 4 tiles to fill the viewport. This is set to 128 as a
// sane minimum for now, but we might want to increase with tuning.
const int kMinHeightForGpuRasteredTile = 128;
// When making odd-sized tiles, round them up to increase the chances
// of using the same tile size.
const int kTileRoundUp = 64;
} // namespace } // namespace
namespace cc { namespace cc {
...@@ -677,48 +686,64 @@ gfx::Size PictureLayerImpl::CalculateTileSize( ...@@ -677,48 +686,64 @@ gfx::Size PictureLayerImpl::CalculateTileSize(
return content_bounds; return content_bounds;
} }
gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size; int default_tile_width = 0;
int default_tile_height = 0;
if (layer_tree_impl()->use_gpu_rasterization()) { if (layer_tree_impl()->use_gpu_rasterization()) {
// TODO(ernstm) crbug.com/365877: We need a unified way to override the // For GPU rasterization, we pick an ideal tile size using the viewport
// default-tile-size. // so we don't need any settings. The current approach uses 4 tiles
default_tile_size = // to cover the viewport vertically.
gfx::Size(layer_tree_impl()->device_viewport_size().width(), int viewport_width = layer_tree_impl()->device_viewport_size().width();
layer_tree_impl()->device_viewport_size().height() / 4); int viewport_height = layer_tree_impl()->device_viewport_size().height();
default_tile_width = viewport_width;
default_tile_height = viewport_height / 4;
default_tile_height =
std::max(default_tile_height, kMinHeightForGpuRasteredTile);
// Increase the tile-height proportionally when the content width
// drops below half the viewport width.
if (content_bounds.width() <= viewport_width / 2)
default_tile_height *= 2;
} else {
// For CPU rasterization we use tile-size settings.
const LayerTreeSettings& settings = layer_tree_impl()->settings();
int max_untiled_content_width = settings.max_untiled_layer_size.width();
int max_untiled_content_height = settings.max_untiled_layer_size.height();
default_tile_width = settings.default_tile_size.width();
default_tile_height = settings.default_tile_size.height();
// If the content width is small, increase tile size vertically.
// If the content height is small, increase tile size horizontally.
// If both are less than the untiled-size, use a single tile.
if (content_bounds.width() < default_tile_width)
default_tile_height = max_untiled_content_height;
if (content_bounds.height() < default_tile_height)
default_tile_width = max_untiled_content_width;
if (content_bounds.width() < max_untiled_content_width &&
content_bounds.height() < max_untiled_content_height) {
default_tile_height = max_untiled_content_height;
default_tile_width = max_untiled_content_width;
}
}
int tile_width = default_tile_width;
int tile_height = default_tile_height;
// Clamp the tile width/height to the content width/height to save space.
if (content_bounds.width() < default_tile_width) {
tile_width = std::min(tile_width, content_bounds.width());
tile_width = RoundUp(tile_width, kTileRoundUp);
tile_width = std::min(tile_width, default_tile_width);
} }
default_tile_size.SetToMin(gfx::Size(max_texture_size, max_texture_size)); if (content_bounds.height() < default_tile_height) {
tile_height = std::min(tile_height, content_bounds.height());
gfx::Size max_untiled_content_size = tile_height = RoundUp(tile_height, kTileRoundUp);
layer_tree_impl()->settings().max_untiled_layer_size; tile_height = std::min(tile_height, default_tile_height);
max_untiled_content_size.SetToMin(
gfx::Size(max_texture_size, max_texture_size));
bool any_dimension_too_large =
content_bounds.width() > max_untiled_content_size.width() ||
content_bounds.height() > max_untiled_content_size.height();
bool any_dimension_one_tile =
content_bounds.width() <= default_tile_size.width() ||
content_bounds.height() <= default_tile_size.height();
// If long and skinny, tile at the max untiled content size, and clamp
// the smaller dimension to the content size, e.g. 1000x12 layer with
// 500x500 max untiled size would get 500x12 tiles. Also do this
// if the layer is small.
if (any_dimension_one_tile || !any_dimension_too_large) {
int width = std::min(
std::max(max_untiled_content_size.width(), default_tile_size.width()),
content_bounds.width());
int height = std::min(
std::max(max_untiled_content_size.height(), default_tile_size.height()),
content_bounds.height());
// Round up to the closest multiple of 64. This improves recycling and
// avoids odd texture sizes.
width = RoundUp(width, 64);
height = RoundUp(height, 64);
return gfx::Size(width, height);
} }
return default_tile_size; // Under no circumstance should we be larger than the max texture size.
tile_width = std::min(tile_width, max_texture_size);
tile_height = std::min(tile_height, max_texture_size);
return gfx::Size(tile_width, tile_height);
} }
void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) { void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
......
...@@ -4424,5 +4424,73 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { ...@@ -4424,5 +4424,73 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) {
EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
} }
class TileSizeSettings : public ImplSidePaintingSettings {
public:
TileSizeSettings() {
default_tile_size = gfx::Size(100, 100);
max_untiled_layer_size = gfx::Size(200, 200);
}
};
class TileSizeTest : public PictureLayerImplTest {
public:
TileSizeTest() : PictureLayerImplTest(TileSizeSettings()) {}
};
TEST_F(TileSizeTest, TileSizes) {
host_impl_.CreatePendingTree();
LayerTreeImpl* pending_tree = host_impl_.pending_tree();
scoped_ptr<FakePictureLayerImpl> layer =
FakePictureLayerImpl::Create(pending_tree, id_);
gfx::Size viewport_size = gfx::Size(1000, 1000);
host_impl_.SetViewportSize(viewport_size);
gfx::Size result;
host_impl_.SetUseGpuRasterization(false);
// Default tile-size for large layers.
result = layer->CalculateTileSize(gfx::Size(10000, 10000));
EXPECT_EQ(result.width(), 100);
EXPECT_EQ(result.height(), 100);
// Don't tile and round-up, when under max_untiled_layer_size.
result = layer->CalculateTileSize(gfx::Size(42, 42));
EXPECT_EQ(result.width(), 64);
EXPECT_EQ(result.height(), 64);
result = layer->CalculateTileSize(gfx::Size(184, 184));
EXPECT_EQ(result.width(), 192);
EXPECT_EQ(result.height(), 192);
result = layer->CalculateTileSize(gfx::Size(199, 199));
EXPECT_EQ(result.width(), 200);
EXPECT_EQ(result.height(), 200);
host_impl_.SetUseGpuRasterization(true);
// Gpu-rasterization uses 25% viewport-height tiles.
result = layer->CalculateTileSize(gfx::Size(10000, 10000));
EXPECT_EQ(result.width(), 1000);
EXPECT_EQ(result.height(), 250);
// Clamp and round-up, when smaller than viewport.
result = layer->CalculateTileSize(gfx::Size(831, 10000));
EXPECT_EQ(result.width(), 832);
EXPECT_EQ(result.height(), 250);
// Tile-height doubles to 50% when width shrinks to <= 50%.
result = layer->CalculateTileSize(gfx::Size(447, 10000));
EXPECT_EQ(result.width(), 448);
EXPECT_EQ(result.height(), 500);
// Largest layer is 50% of viewport width (rounded up), and
// 50% of viewport in height.
result = layer->CalculateTileSize(gfx::Size(447, 400));
EXPECT_EQ(result.width(), 448);
EXPECT_EQ(result.height(), 448);
result = layer->CalculateTileSize(gfx::Size(500, 499));
EXPECT_EQ(result.width(), 512);
EXPECT_EQ(result.height(), 500);
}
} // namespace } // namespace
} // namespace cc } // namespace cc
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment