summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-31 01:54:14 +0000
committerenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-31 01:54:14 +0000
commitc5c70cb2a575c1ada87b452376e8f4bdb264cf57 (patch)
tree1a38eb28c79a0485159fe491858574790b530192
parent9190109795bc1f9360bc15236cc6f0a2debc97c9 (diff)
downloadchromium_src-c5c70cb2a575c1ada87b452376e8f4bdb264cf57.zip
chromium_src-c5c70cb2a575c1ada87b452376e8f4bdb264cf57.tar.gz
chromium_src-c5c70cb2a575c1ada87b452376e8f4bdb264cf57.tar.bz2
cc: Let impl-side painting use smaller tiles
To avoid wasting memory when there are lots of small layers (e.g. mobile gmail), allow small layers to create smaller tiles. The heuristic is similar to TiledLayer. If a layer is smaller than the max untiled size, then just use that content bounds as the size. If a layer has one larger dimension larger than the max untiled size then tile that dimension at the max untiled size and clamp the other dimension at the content size. If a layer is neither of these, then tile using the default tile size. NOTRY=true R=danakj@chromium.org BUG=172966 Review URL: https://chromiumcodereview.appspot.com/12087068 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@179764 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/picture_layer_impl.cc51
-rw-r--r--cc/picture_layer_impl.h4
-rw-r--r--cc/picture_layer_impl_unittest.cc6
-rw-r--r--cc/picture_layer_tiling.cc18
-rw-r--r--cc/picture_layer_tiling.h22
-rw-r--r--cc/picture_layer_tiling_set.cc6
-rw-r--r--cc/picture_layer_tiling_set.h4
-rw-r--r--cc/picture_layer_tiling_set_unittest.cc12
-rw-r--r--cc/picture_layer_tiling_unittest.cc2
-rw-r--r--cc/test/fake_picture_layer_tiling_client.cc8
-rw-r--r--cc/test/fake_picture_layer_tiling_client.h3
11 files changed, 90 insertions, 46 deletions
diff --git a/cc/picture_layer_impl.cc b/cc/picture_layer_impl.cc
index a7cd43c8..826fb76 100644
--- a/cc/picture_layer_impl.cc
+++ b/cc/picture_layer_impl.cc
@@ -329,6 +329,42 @@ void PictureLayerImpl::UpdatePile(Tile* tile) {
tile->set_picture_pile(pile_);
}
+gfx::Size PictureLayerImpl::CalculateTileSize(
+ gfx::Size /* current_tile_size */,
+ gfx::Size content_bounds) {
+ if (is_mask_) {
+ int max_size = layerTreeImpl()->MaxTextureSize();
+ return gfx::Size(
+ std::min(max_size, content_bounds.width()),
+ std::min(max_size, content_bounds.height()));
+ }
+
+ gfx::Size default_tile_size = layerTreeImpl()->settings().defaultTileSize;
+ gfx::Size max_untiled_content_size =
+ layerTreeImpl()->settings().maxUntiledLayerSize;
+
+ 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) {
+ gfx::Size tile_size(
+ std::min(max_untiled_content_size.width(), content_bounds.width()),
+ std::min(max_untiled_content_size.height(), content_bounds.height()));
+ return tile_size;
+ }
+
+ return default_tile_size;
+}
+
void PictureLayerImpl::SyncFromActiveLayer() {
DCHECK(layerTreeImpl()->IsPendingTree());
if (!drawsContent())
@@ -432,9 +468,7 @@ PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
if (recorded.IsEmpty())
return NULL;
- PictureLayerTiling* tiling = tilings_->AddTiling(
- contents_scale,
- TileSize());
+ PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
for (Region::Iterator iter(recorded); iter.has_rect(); iter.next())
tiling->CreateTilesFromLayerRect(iter.rect());
@@ -458,17 +492,6 @@ PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
return tiling;
}
-gfx::Size PictureLayerImpl::TileSize() const {
- if (is_mask_) {
- int max_size = layerTreeImpl()->MaxTextureSize();
- return gfx::Size(
- std::min(max_size, contentBounds().width()),
- std::min(max_size, contentBounds().height()));
- }
-
- return layerTreeImpl()->settings().defaultTileSize;
-}
-
namespace {
inline float PositiveRatio(float float1, float float2) {
diff --git a/cc/picture_layer_impl.h b/cc/picture_layer_impl.h
index bc2af67..6d29e47 100644
--- a/cc/picture_layer_impl.h
+++ b/cc/picture_layer_impl.h
@@ -48,6 +48,9 @@ public:
virtual scoped_refptr<Tile> CreateTile(PictureLayerTiling* tiling,
gfx::Rect content_rect) OVERRIDE;
virtual void UpdatePile(Tile* tile) OVERRIDE;
+ virtual gfx::Size CalculateTileSize(
+ gfx::Size current_tile_size,
+ gfx::Size content_bounds) OVERRIDE;
// PushPropertiesTo active tree => pending tree
void SyncFromActiveLayer();
@@ -68,7 +71,6 @@ protected:
PictureLayerImpl(LayerTreeImpl* treeImpl, int id);
PictureLayerTiling* AddTiling(float contents_scale);
void SyncFromActiveLayer(const PictureLayerImpl* other);
- gfx::Size TileSize() const;
void ManageTilings(float ideal_contents_scale);
void CleanUpUnusedTilings(std::vector<PictureLayerTiling*> used_tilings);
diff --git a/cc/picture_layer_impl_unittest.cc b/cc/picture_layer_impl_unittest.cc
index 56fc0e8..e69ca81 100644
--- a/cc/picture_layer_impl_unittest.cc
+++ b/cc/picture_layer_impl_unittest.cc
@@ -28,6 +28,12 @@ class TestablePictureLayerImpl : public PictureLayerImpl {
PictureLayerTilingSet& tilings() { return *tilings_; }
Region& invalidation() { return invalidation_; }
+ virtual gfx::Size CalculateTileSize(
+ gfx::Size current_tile_size,
+ gfx::Size /* content_bounds */) OVERRIDE {
+ return current_tile_size;
+ }
+
using PictureLayerImpl::AddTiling;
private:
diff --git a/cc/picture_layer_tiling.cc b/cc/picture_layer_tiling.cc
index a8000ec..6e8e883 100644
--- a/cc/picture_layer_tiling.cc
+++ b/cc/picture_layer_tiling.cc
@@ -13,20 +13,18 @@
namespace cc {
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
- float contents_scale,
- gfx::Size tile_size) {
- return make_scoped_ptr(new PictureLayerTiling(contents_scale, tile_size));
+ float contents_scale) {
+ return make_scoped_ptr(new PictureLayerTiling(contents_scale));
}
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const {
return make_scoped_ptr(new PictureLayerTiling(*this));
}
-PictureLayerTiling::PictureLayerTiling(float contents_scale,
- gfx::Size tile_size)
+PictureLayerTiling::PictureLayerTiling(float contents_scale)
: client_(NULL),
contents_scale_(contents_scale),
- tiling_data_(tile_size, gfx::Size(), true),
+ tiling_data_(gfx::Size(), gfx::Size(), true),
resolution_(NON_IDEAL_RESOLUTION) {
}
@@ -87,6 +85,14 @@ void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) {
return;
}
+ gfx::Size tile_size = client_->CalculateTileSize(
+ tiling_data_.max_texture_size(),
+ content_bounds);
+ if (tile_size != tiling_data_.max_texture_size()) {
+ tiling_data_.SetMaxTextureSize(tile_size);
+ tiles_.clear();
+ }
+
// Any tiles outside our new bounds are invalid and should be dropped.
if (old_content_bounds.width() > content_bounds.width() ||
old_content_bounds.height() > content_bounds.height()) {
diff --git a/cc/picture_layer_tiling.h b/cc/picture_layer_tiling.h
index cdc991c..60505f3 100644
--- a/cc/picture_layer_tiling.h
+++ b/cc/picture_layer_tiling.h
@@ -21,13 +21,16 @@ namespace cc {
class PictureLayerTiling;
class PictureLayerTilingClient {
- public:
- // Create a tile at the given content_rect (in the contents scale of the
- // tiling) This might return null if the client cannot create such a tile.
- virtual scoped_refptr<Tile> CreateTile(
- PictureLayerTiling* tiling,
- gfx::Rect content_rect) = 0;
- virtual void UpdatePile(Tile* tile) = 0;
+ public:
+ // Create a tile at the given content_rect (in the contents scale of the
+ // tiling) This might return null if the client cannot create such a tile.
+ virtual scoped_refptr<Tile> CreateTile(
+ PictureLayerTiling* tiling,
+ gfx::Rect content_rect) = 0;
+ virtual void UpdatePile(Tile* tile) = 0;
+ virtual gfx::Size CalculateTileSize(
+ gfx::Size current_tile_size,
+ gfx::Size content_bounds) = 0;
};
class CC_EXPORT PictureLayerTiling {
@@ -35,8 +38,7 @@ class CC_EXPORT PictureLayerTiling {
~PictureLayerTiling();
// Create a tiling with no tiles. CreateTiles must be called to add some.
- static scoped_ptr<PictureLayerTiling> Create(float contents_scale,
- gfx::Size tile_size);
+ static scoped_ptr<PictureLayerTiling> Create(float contents_scale);
scoped_ptr<PictureLayerTiling> Clone() const;
gfx::Size layer_bounds() const { return layer_bounds_; }
@@ -130,7 +132,7 @@ class CC_EXPORT PictureLayerTiling {
typedef std::pair<int, int> TileMapKey;
typedef base::hash_map<TileMapKey, scoped_refptr<Tile> > TileMap;
- PictureLayerTiling(float contents_scale, gfx::Size tileSize);
+ PictureLayerTiling(float contents_scale);
Tile* TileAt(int, int) const;
void CreateTilesFromContentRect(gfx::Rect layer_rect);
void CreateTile(int i, int j);
diff --git a/cc/picture_layer_tiling_set.cc b/cc/picture_layer_tiling_set.cc
index fe5b95e..5472bde 100644
--- a/cc/picture_layer_tiling_set.cc
+++ b/cc/picture_layer_tiling_set.cc
@@ -70,10 +70,8 @@ gfx::Size PictureLayerTilingSet::LayerBounds() const {
return layer_bounds_;
}
-PictureLayerTiling* PictureLayerTilingSet::AddTiling(
- float contents_scale,
- gfx::Size tile_size) {
- tilings_.push_back(PictureLayerTiling::Create(contents_scale, tile_size));
+PictureLayerTiling* PictureLayerTilingSet::AddTiling(float contents_scale) {
+ tilings_.push_back(PictureLayerTiling::Create(contents_scale));
PictureLayerTiling* appended = tilings_.back();
appended->SetClient(client_);
appended->SetLayerBounds(layer_bounds_);
diff --git a/cc/picture_layer_tiling_set.h b/cc/picture_layer_tiling_set.h
index d6a8950..197ea42 100644
--- a/cc/picture_layer_tiling_set.h
+++ b/cc/picture_layer_tiling_set.h
@@ -28,9 +28,7 @@ class CC_EXPORT PictureLayerTilingSet {
void SetLayerBounds(gfx::Size layer_bounds);
gfx::Size LayerBounds() const;
- PictureLayerTiling* AddTiling(
- float contents_scale,
- gfx::Size tile_size);
+ PictureLayerTiling* AddTiling(float contents_scale);
size_t num_tilings() const { return tilings_.size(); }
PictureLayerTiling* tiling_at(size_t idx) { return tilings_[idx]; }
const PictureLayerTiling* tiling_at(size_t idx) const {
diff --git a/cc/picture_layer_tiling_set_unittest.cc b/cc/picture_layer_tiling_set_unittest.cc
index 707180c..17affd7 100644
--- a/cc/picture_layer_tiling_set_unittest.cc
+++ b/cc/picture_layer_tiling_set_unittest.cc
@@ -18,14 +18,14 @@ namespace {
TEST(PictureLayerTilingSetTest, NoResources) {
FakePictureLayerTilingClient client;
PictureLayerTilingSet set(&client);
- gfx::Size default_tile_size(256, 256);
+ client.SetTileSize(gfx::Size(256, 256));
gfx::Size layer_bounds(1000, 800);
set.SetLayerBounds(layer_bounds);
- set.AddTiling(1.0, default_tile_size);
- set.AddTiling(1.5, default_tile_size);
- set.AddTiling(2.0, default_tile_size);
+ set.AddTiling(1.0);
+ set.AddTiling(1.5);
+ set.AddTiling(2.0);
float contents_scale = 2.0;
gfx::Size content_bounds(
@@ -64,15 +64,15 @@ class PictureLayerTilingSetTestWithResources : public testing::Test {
ResourceProvider::create(output_surface.get());
FakePictureLayerTilingClient client;
+ client.SetTileSize(gfx::Size(256, 256));
PictureLayerTilingSet set(&client);
- gfx::Size default_tile_size(256, 256);
gfx::Size layer_bounds(1000, 800);
set.SetLayerBounds(layer_bounds);
float scale = min_scale;
for (int i = 0; i < num_tilings; ++i, scale += scale_increment) {
- PictureLayerTiling* tiling = set.AddTiling(scale, default_tile_size);
+ PictureLayerTiling* tiling = set.AddTiling(scale);
std::vector<Tile*> tiles = tiling->AllTilesForTesting();
for (size_t i = 0; i < tiles.size(); ++i) {
EXPECT_FALSE(tiles[i]->ManagedStateForTesting().resource);
diff --git a/cc/picture_layer_tiling_unittest.cc b/cc/picture_layer_tiling_unittest.cc
index f9628bbf..74d7b477 100644
--- a/cc/picture_layer_tiling_unittest.cc
+++ b/cc/picture_layer_tiling_unittest.cc
@@ -20,7 +20,7 @@ class PictureLayerTilingIteratorTest : public testing::Test {
float contents_scale,
gfx::Size layer_bounds) {
client_.SetTileSize(tile_size);
- tiling_ = PictureLayerTiling::Create(contents_scale, tile_size);
+ tiling_ = PictureLayerTiling::Create(contents_scale);
tiling_->SetClient(&client_);
tiling_->SetLayerBounds(layer_bounds);
}
diff --git a/cc/test/fake_picture_layer_tiling_client.cc b/cc/test/fake_picture_layer_tiling_client.cc
index 4e2ee00..857eb8d 100644
--- a/cc/test/fake_picture_layer_tiling_client.cc
+++ b/cc/test/fake_picture_layer_tiling_client.cc
@@ -26,7 +26,13 @@ scoped_refptr<Tile> FakePictureLayerTilingClient::CreateTile(
}
void FakePictureLayerTilingClient::SetTileSize(gfx::Size tile_size) {
- tile_size_ = tile_size;
+ tile_size_ = tile_size;
+}
+
+gfx::Size FakePictureLayerTilingClient::CalculateTileSize(
+ gfx::Size /* current_tile_size */,
+ gfx::Size /* content_bounds */) {
+ return tile_size_;
}
} // namespace cc
diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h
index 78603cc..5935ae3 100644
--- a/cc/test/fake_picture_layer_tiling_client.h
+++ b/cc/test/fake_picture_layer_tiling_client.h
@@ -23,6 +23,9 @@ class FakePictureLayerTilingClient : public PictureLayerTilingClient {
virtual scoped_refptr<Tile> CreateTile(
PictureLayerTiling* tiling, gfx::Rect rect) OVERRIDE;
virtual void UpdatePile(Tile* tile) OVERRIDE {}
+ virtual gfx::Size CalculateTileSize(
+ gfx::Size current_tile_size,
+ gfx::Size content_bounds) OVERRIDE;
void SetTileSize(gfx::Size tile_size);
gfx::Size TileSize() const { return tile_size_; }