summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-01 18:42:02 +0000
committerenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-01 18:42:02 +0000
commit71003cd425276c7abbf81cd9e9f07eeb20fc20f5 (patch)
treeebe4c9a8cf05b9c203122085459338d3c2e24513
parent18e04df8ee64c19857826cd612e127c53230250f (diff)
downloadchromium_src-71003cd425276c7abbf81cd9e9f07eeb20fc20f5.zip
chromium_src-71003cd425276c7abbf81cd9e9f07eeb20fc20f5.tar.gz
chromium_src-71003cd425276c7abbf81cd9e9f07eeb20fc20f5.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 Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=179764 Review URL: https://chromiumcodereview.appspot.com/12087068 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@180162 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/picture_layer_impl.cc57
-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, 96 insertions, 46 deletions
diff --git a/cc/picture_layer_impl.cc b/cc/picture_layer_impl.cc
index 4cba5bd..a5b21f2 100644
--- a/cc/picture_layer_impl.cc
+++ b/cc/picture_layer_impl.cc
@@ -14,6 +14,7 @@
#include "cc/quad_sink.h"
#include "cc/solid_color_draw_quad.h"
#include "cc/tile_draw_quad.h"
+#include "cc/util.h"
#include "ui/gfx/quad_f.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/size_conversions.h"
@@ -305,6 +306,47 @@ 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) {
+ int width =
+ std::min(max_untiled_content_size.width(), content_bounds.width());
+ int height =
+ std::min(max_untiled_content_size.height(), content_bounds.height());
+ // Round width and height up to the closest multiple of 8. This is to
+ // help IMG drivers where facter of 8 texture sizes are faster.
+ width = RoundUp(width, 8);
+ height = RoundUp(height, 8);
+ return gfx::Size(width, height);
+ }
+
+ return default_tile_size;
+}
+
void PictureLayerImpl::SyncFromActiveLayer() {
DCHECK(layerTreeImpl()->IsPendingTree());
if (!drawsContent())
@@ -408,9 +450,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());
@@ -434,17 +474,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 243548a..c94045c 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 d90eb42..df12b6b 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),
last_source_frame_number_(0),
last_impl_frame_time_(0) {
@@ -89,6 +87,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 8725bc1..942dbbb 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_; }
@@ -135,7 +137,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 4025ac0..d181451 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 62c4b9d..14e6722 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_; }