Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3637)

Unified Diff: cc/resources/picture_layer_tiling.cc

Issue 62283012: cc: Added tile bundles (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/resources/picture_layer_tiling.cc
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index 497b75c23016de5462450a43ae3dc3e467c5a450..de84d57ce9f2d901690d01fa69f343844a04a0ba 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -17,6 +17,17 @@
namespace cc {
+namespace {
+
+const int kTileBundleWidth = 2;
+const int kTileBundleHeight = 2;
+
+std::pair<int, int> ComputeTileBundleIndex(int i, int j) {
+ return std::make_pair(i / kTileBundleWidth, j / kTileBundleHeight);
+}
+
+}
+
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
float contents_scale,
gfx::Size layer_bounds,
@@ -34,6 +45,7 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale,
resolution_(NON_IDEAL_RESOLUTION),
client_(client),
tiling_data_(gfx::Size(), gfx::Size(), true),
+ bundle_tiling_data_(gfx::Size(), gfx::Size(), true),
last_impl_frame_time_in_seconds_(0.0) {
gfx::Size content_bounds =
gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale));
@@ -47,6 +59,10 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale,
tiling_data_.SetTotalSize(content_bounds);
tiling_data_.SetMaxTextureSize(tile_size);
+ bundle_tiling_data_.SetTotalSize(content_bounds);
+ bundle_tiling_data_.SetMaxTextureSize(
+ gfx::Size(tile_size.width() * kTileBundleWidth,
+ tile_size.height() * kTileBundleHeight));
}
PictureLayerTiling::~PictureLayerTiling() {
@@ -54,6 +70,11 @@ PictureLayerTiling::~PictureLayerTiling() {
void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) {
client_ = client;
+ for (TileBundleMap::iterator it = tile_bundles_.begin();
+ it != tile_bundles_.end();
+ ++it) {
+ it->second->SetClient(client_);
+ }
}
gfx::Rect PictureLayerTiling::ContentRect() const {
@@ -64,18 +85,46 @@ gfx::SizeF PictureLayerTiling::ContentSizeF() const {
return gfx::ScaleSize(layer_bounds_, contents_scale_);
}
+TileBundle* PictureLayerTiling::CreateBundleForTileAt(int i, int j) {
+ TileBundleMapKey key = ComputeTileBundleIndex(i, j);
+ DCHECK(tile_bundles_.find(key) == tile_bundles_.end());
+
+ scoped_refptr<TileBundle> bundle =
+ client_->CreateTileBundle(kTileBundleWidth,
+ kTileBundleHeight,
+ key.first * kTileBundleWidth,
+ key.second * kTileBundleHeight);
+ bundle->SetTiling(this);
+ tile_bundles_[key] = bundle;
+ return bundle.get();
+}
+
+TileBundle* PictureLayerTiling::TileBundleContainingTileAt(int i, int j) const {
+ TileBundleMapKey key = ComputeTileBundleIndex(i, j);
+ return TileBundleAt(key.first, key.second);
+}
+
+TileBundle* PictureLayerTiling::TileBundleAt(int i, int j) const {
+ TileBundleMapKey key(i, j);
+ TileBundleMap::const_iterator it = tile_bundles_.find(key);
+ if (it == tile_bundles_.end())
+ return NULL;
+ return it->second.get();
+}
+
Tile* PictureLayerTiling::TileAt(int i, int j) const {
- TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j));
- if (iter == tiles_.end())
+ TileBundle* bundle = TileBundleContainingTileAt(i, j);
+ if (!bundle)
return NULL;
- return iter->second.get();
+ return bundle->TileAt(i, j);
}
void PictureLayerTiling::CreateTile(int i,
int j,
const PictureLayerTiling* twin_tiling) {
- TileMapKey key(i, j);
- DCHECK(tiles_.find(key) == tiles_.end());
+ TileBundle* bundle = TileBundleContainingTileAt(i, j);
+ if (!bundle)
+ bundle = CreateBundleForTileAt(i, j);
gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j);
gfx::Rect tile_rect = paint_rect;
@@ -89,7 +138,7 @@ void PictureLayerTiling::CreateTile(int i,
gfx::Rect rect =
gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_);
if (!client_->GetInvalidation()->Intersects(rect)) {
- tiles_[key] = candidate_tile;
+ bundle->AddTileAt(i, j, candidate_tile);
return;
}
}
@@ -98,7 +147,19 @@ void PictureLayerTiling::CreateTile(int i,
// Create a new tile because our twin didn't have a valid one.
scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
if (tile.get())
- tiles_[key] = tile;
+ bundle->AddTileAt(i, j, tile);
+}
+
+bool PictureLayerTiling::RemoveTile(int i, int j) {
+ TileBundleMapKey key = ComputeTileBundleIndex(i, j);
+ TileBundleMap::iterator it = tile_bundles_.find(key);
+ if (it == tile_bundles_.end())
+ return false;
+
+ bool did_delete = it->second->RemoveTileAt(i, j);
+ if (it->second->TileCount() == 0)
+ tile_bundles_.erase(it);
+ return did_delete;
}
Region PictureLayerTiling::OpaqueRegionInContentRect(
@@ -109,19 +170,24 @@ Region PictureLayerTiling::OpaqueRegionInContentRect(
}
void PictureLayerTiling::SetCanUseLCDText(bool can_use_lcd_text) {
- for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it)
- it->second->set_can_use_lcd_text(can_use_lcd_text);
+ for (TileBundleMap::iterator it = tile_bundles_.begin();
+ it != tile_bundles_.end();
+ ++it) {
+ for (TileBundle::Iterator tile_it(it->second); tile_it; ++tile_it)
+ tile_it->set_can_use_lcd_text(can_use_lcd_text);
+ }
}
void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
for (TilingData::Iterator iter(&tiling_data_, live_tiles_rect_); iter;
++iter) {
- TileMapKey key = iter.index();
- TileMap::iterator find = tiles_.find(key);
- if (find != tiles_.end())
+ int tile_x = iter.index_x();
+ int tile_y = iter.index_y();
+ Tile* tile = TileAt(tile_x, tile_y);
+ if (tile)
continue;
- CreateTile(key.first, key.second, twin_tiling);
+ CreateTile(tile_x, tile_y, twin_tiling);
}
}
@@ -141,6 +207,10 @@ void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) {
if (tile_size != tiling_data_.max_texture_size()) {
tiling_data_.SetTotalSize(content_bounds);
tiling_data_.SetMaxTextureSize(tile_size);
+ bundle_tiling_data_.SetTotalSize(content_bounds);
+ bundle_tiling_data_.SetMaxTextureSize(
+ gfx::Size(tile_size.width() * kTileBundleWidth,
+ tile_size.height() * kTileBundleHeight));
Reset();
return;
}
@@ -150,6 +220,7 @@ void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) {
bounded_live_tiles_rect.Intersect(gfx::Rect(content_bounds));
SetLiveTilesRect(bounded_live_tiles_rect);
tiling_data_.SetTotalSize(content_bounds);
+ bundle_tiling_data_.SetTotalSize(content_bounds);
// Create tiles for newly exposed areas.
Region layer_region((gfx::Rect(layer_bounds_)));
@@ -158,7 +229,7 @@ void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) {
}
void PictureLayerTiling::Invalidate(const Region& layer_region) {
- std::vector<TileMapKey> new_tile_keys;
+ std::vector<std::pair<int, int> > new_tile_keys;
for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) {
gfx::Rect layer_rect = iter.rect();
gfx::Rect content_rect =
@@ -167,12 +238,13 @@ void PictureLayerTiling::Invalidate(const Region& layer_region) {
if (content_rect.IsEmpty())
continue;
for (TilingData::Iterator iter(&tiling_data_, content_rect); iter; ++iter) {
- TileMapKey key(iter.index());
- TileMap::iterator find = tiles_.find(key);
- if (find == tiles_.end())
- continue;
- tiles_.erase(find);
- new_tile_keys.push_back(key);
+ int tile_x = iter.index_x();
+ int tile_y = iter.index_y();
+
+ // If there is no bundle for the given tile, we can skip.
+ bool deleted = RemoveTile(tile_x, tile_y);
+ if (deleted)
+ new_tile_keys.push_back(std::make_pair(tile_x, tile_y));
}
}
@@ -316,6 +388,19 @@ PictureLayerTiling::CoverageIterator::full_tile_geometry_rect() const {
return rect;
}
+TilePriority PictureLayerTiling::CoverageIterator::priority() {
+ TileBundle* bundle = tiling_->TileBundleContainingTileAt(tile_i_, tile_j_);
+ if (bundle)
+ return bundle->GetPriority();
+ return TilePriority();
+}
+
+void PictureLayerTiling::CoverageIterator::SetPriorityForTesting(
+ const TilePriority& priority) {
+ TileBundle* bundle = tiling_->TileBundleContainingTileAt(tile_i_, tile_j_);
+ bundle->SetPriority(priority);
+}
+
gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const {
gfx::PointF tex_origin =
tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin();
@@ -336,7 +421,7 @@ gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const {
void PictureLayerTiling::Reset() {
live_tiles_rect_ = gfx::Rect();
- tiles_.clear();
+ tile_bundles_.clear();
}
void PictureLayerTiling::UpdateTilePriorities(
@@ -407,23 +492,22 @@ void PictureLayerTiling::UpdateTilePriorities(
last_screen_transform.matrix().get(0, 3),
last_screen_transform.matrix().get(1, 3));
- for (TilingData::Iterator iter(&tiling_data_, interest_rect);
+ for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect);
iter; ++iter) {
- TileMap::iterator find = tiles_.find(iter.index());
- if (find == tiles_.end())
+ int bundle_x = iter.index_x();
+ int bundle_y = iter.index_y();
+ TileBundle* bundle = TileBundleAt(bundle_x, bundle_y);
+ if (!bundle)
continue;
- Tile* tile = find->second.get();
- gfx::Rect tile_bounds =
- tiling_data_.TileBounds(iter.index_x(), iter.index_y());
- gfx::RectF current_screen_rect = gfx::ScaleRect(
- tile_bounds,
- current_scale,
- current_scale) + current_offset;
- gfx::RectF last_screen_rect = gfx::ScaleRect(
- tile_bounds,
- last_scale,
- last_scale) + last_offset;
+ gfx::Rect bundle_bounds =
+ bundle_tiling_data_.TileBounds(bundle_x, bundle_y);
+ gfx::RectF current_screen_rect =
+ gfx::ScaleRect(bundle_bounds, current_scale, current_scale) +
+ current_offset;
+ gfx::RectF last_screen_rect =
+ gfx::ScaleRect(bundle_bounds, last_scale, last_scale) +
+ last_offset;
float distance_to_visible_in_pixels =
TilePriority::manhattanDistance(current_screen_rect, view_rect);
@@ -435,7 +519,8 @@ void PictureLayerTiling::UpdateTilePriorities(
resolution_,
time_to_visible_in_seconds,
distance_to_visible_in_pixels);
- tile->SetPriority(tree, priority);
+
+ bundle->SetPriority(priority);
}
} else if (!last_screen_transform.HasPerspective() &&
!current_screen_transform.HasPerspective()) {
@@ -455,55 +540,57 @@ void PictureLayerTiling::UpdateTilePriorities(
last_screen_transform.matrix().get(0, 3),
last_screen_transform.matrix().get(1, 3));
- float current_tile_width = tiling_data_.TileSizeX(0) * current_scale;
- float last_tile_width = tiling_data_.TileSizeX(0) * last_scale;
- float current_tile_height = tiling_data_.TileSizeY(0) * current_scale;
- float last_tile_height = tiling_data_.TileSizeY(0) * last_scale;
+ float current_bundle_width =
+ bundle_tiling_data_.TileSizeX(0) * current_scale;
+ float last_bundle_width =
+ bundle_tiling_data_.TileSizeX(0) * last_scale;
+ float current_bundle_height =
+ bundle_tiling_data_.TileSizeY(0) * current_scale;
+ float last_bundle_height =
+ bundle_tiling_data_.TileSizeY(0) * last_scale;
// Apply screen space transform to local basis vectors (tile_width, 0) and
// (0, tile_height); the math simplifies and can be initialized directly.
gfx::Vector2dF current_horizontal(
- current_screen_transform.matrix().get(0, 0) * current_tile_width,
- current_screen_transform.matrix().get(1, 0) * current_tile_width);
+ current_screen_transform.matrix().get(0, 0) * current_bundle_width,
+ current_screen_transform.matrix().get(1, 0) * current_bundle_width);
gfx::Vector2dF current_vertical(
- current_screen_transform.matrix().get(0, 1) * current_tile_height,
- current_screen_transform.matrix().get(1, 1) * current_tile_height);
+ current_screen_transform.matrix().get(0, 1) * current_bundle_height,
+ current_screen_transform.matrix().get(1, 1) * current_bundle_height);
gfx::Vector2dF last_horizontal(
- last_screen_transform.matrix().get(0, 0) * last_tile_width,
- last_screen_transform.matrix().get(1, 0) * last_tile_width);
+ last_screen_transform.matrix().get(0, 0) * last_bundle_width,
+ last_screen_transform.matrix().get(1, 0) * last_bundle_width);
gfx::Vector2dF last_vertical(
- last_screen_transform.matrix().get(0, 1) * last_tile_height,
- last_screen_transform.matrix().get(1, 1) * last_tile_height);
+ last_screen_transform.matrix().get(0, 1) * last_bundle_height,
+ last_screen_transform.matrix().get(1, 1) * last_bundle_height);
- for (TilingData::Iterator iter(&tiling_data_, interest_rect);
+ for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect);
iter; ++iter) {
- TileMap::iterator find = tiles_.find(iter.index());
- if (find == tiles_.end())
+ int bundle_x = iter.index_x();
+ int bundle_y = iter.index_y();
+ TileBundle* bundle = TileBundleAt(bundle_x, bundle_y);
+ if (!bundle)
continue;
- Tile* tile = find->second.get();
-
- int i = iter.index_x();
- int j = iter.index_y();
- gfx::PointF current_tile_origin = current_screen_space_origin +
- ScaleVector2d(current_horizontal, i) +
- ScaleVector2d(current_vertical, j);
- gfx::PointF last_tile_origin = last_screen_space_origin +
- ScaleVector2d(last_horizontal, i) +
- ScaleVector2d(last_vertical, j);
+ gfx::PointF current_bundle_origin = current_screen_space_origin +
+ ScaleVector2d(current_horizontal, bundle_x) +
+ ScaleVector2d(current_vertical, bundle_y);
+ gfx::PointF last_bundle_origin = last_screen_space_origin +
+ ScaleVector2d(last_horizontal, bundle_x) +
+ ScaleVector2d(last_vertical, bundle_y);
gfx::RectF current_screen_rect = gfx::QuadF(
- current_tile_origin,
- current_tile_origin + current_horizontal,
- current_tile_origin + current_horizontal + current_vertical,
- current_tile_origin + current_vertical).BoundingBox();
+ current_bundle_origin,
+ current_bundle_origin + current_horizontal,
+ current_bundle_origin + current_horizontal + current_vertical,
+ current_bundle_origin + current_vertical).BoundingBox();
gfx::RectF last_screen_rect = gfx::QuadF(
- last_tile_origin,
- last_tile_origin + last_horizontal,
- last_tile_origin + last_horizontal + last_vertical,
- last_tile_origin + last_vertical).BoundingBox();
+ last_bundle_origin,
+ last_bundle_origin + last_horizontal,
+ last_bundle_origin + last_horizontal + last_vertical,
+ last_bundle_origin + last_vertical).BoundingBox();
float distance_to_visible_in_pixels =
TilePriority::manhattanDistance(current_screen_rect, view_rect);
@@ -515,26 +602,28 @@ void PictureLayerTiling::UpdateTilePriorities(
resolution_,
time_to_visible_in_seconds,
distance_to_visible_in_pixels);
- tile->SetPriority(tree, priority);
+
+ bundle->SetPriority(priority);
}
} else {
- for (TilingData::Iterator iter(&tiling_data_, interest_rect);
+ for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect);
iter; ++iter) {
- TileMap::iterator find = tiles_.find(iter.index());
- if (find == tiles_.end())
+ int bundle_x = iter.index_x();
+ int bundle_y = iter.index_y();
+ TileBundle* bundle = TileBundleAt(bundle_x, bundle_y);
+ if (!bundle)
continue;
- Tile* tile = find->second.get();
- gfx::Rect tile_bounds =
- tiling_data_.TileBounds(iter.index_x(), iter.index_y());
+ gfx::Rect bundle_bounds =
+ bundle_tiling_data_.TileBounds(bundle_x, bundle_y);
gfx::RectF current_layer_content_rect = gfx::ScaleRect(
- tile_bounds,
+ bundle_bounds,
current_scale,
current_scale);
gfx::RectF current_screen_rect = MathUtil::MapClippedRect(
current_screen_transform, current_layer_content_rect);
gfx::RectF last_layer_content_rect = gfx::ScaleRect(
- tile_bounds,
+ bundle_bounds,
last_scale,
last_scale);
gfx::RectF last_screen_rect = MathUtil::MapClippedRect(
@@ -551,7 +640,8 @@ void PictureLayerTiling::UpdateTilePriorities(
resolution_,
time_to_visible_in_seconds,
distance_to_visible_in_pixels);
- tile->SetPriority(tree, priority);
+
+ bundle->SetPriority(priority);
}
}
@@ -571,12 +661,12 @@ void PictureLayerTiling::SetLiveTilesRect(
new_live_tiles_rect);
iter;
++iter) {
- TileMapKey key(iter.index());
- TileMap::iterator found = tiles_.find(key);
+ int tile_x = iter.index_x();
+ int tile_y = iter.index_y();
+
// If the tile was outside of the recorded region, it won't exist even
// though it was in the live rect.
- if (found != tiles_.end())
- tiles_.erase(found);
+ RemoveTile(tile_x, tile_y);
}
const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
@@ -587,8 +677,7 @@ void PictureLayerTiling::SetLiveTilesRect(
live_tiles_rect_);
iter;
++iter) {
- TileMapKey key(iter.index());
- CreateTile(key.first, key.second, twin_tiling);
+ CreateTile(iter.index_x(), iter.index_y(), twin_tiling);
}
live_tiles_rect_ = new_live_tiles_rect;
@@ -599,35 +688,42 @@ void PictureLayerTiling::DidBecomeRecycled() {
// still in the tree. Calling this first on an active tiling that is becoming
// recycled takes care of tiles that are no longer in the active tree (eg.
// due to a pending invalidation).
- for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
- it->second->SetPriority(ACTIVE_TREE, TilePriority());
+ for (TileBundleMap::const_iterator it = tile_bundles_.begin();
+ it != tile_bundles_.end();
+ ++it) {
+ it->second->DidBecomeRecycled();
}
}
void PictureLayerTiling::DidBecomeActive() {
- for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
- it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE));
- it->second->SetPriority(PENDING_TREE, TilePriority());
-
- // Tile holds a ref onto a picture pile. If the tile never gets invalidated
- // and recreated, then that picture pile ref could exist indefinitely. To
- // prevent this, ask the client to update the pile to its own ref. This
- // will cause PicturePileImpls and their clones to get deleted once the
- // corresponding PictureLayerImpl and any in flight raster jobs go out of
- // scope.
- client_->UpdatePile(it->second.get());
+ for (TileBundleMap::const_iterator it = tile_bundles_.begin();
+ it != tile_bundles_.end();
+ ++it) {
+ it->second->DidBecomeActive();
+ for (TileBundle::Iterator tile_it(it->second.get()); tile_it; ++tile_it) {
+ // Tile holds a ref onto a picture pile. If the tile never gets
+ // invalidated and recreated, then that picture pile ref could exist
+ // indefinitely. To prevent this, ask the client to update the pile to
+ // its own ref. This will cause PicturePileImpls and their clones to get
+ // deleted once the corresponding PictureLayerImpl and any in flight
+ // raster jobs go out of scope.
+ client_->UpdatePile(*tile_it);
+ }
}
}
void PictureLayerTiling::UpdateTilesToCurrentPile() {
- for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
- client_->UpdatePile(it->second.get());
+ for (TileBundleMap::const_iterator it = tile_bundles_.begin();
+ it != tile_bundles_.end();
+ ++it) {
+ for (TileBundle::Iterator tile_it(it->second.get()); tile_it; ++tile_it)
+ client_->UpdatePile(*tile_it);
}
}
scoped_ptr<base::Value> PictureLayerTiling::AsValue() const {
scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
- state->SetInteger("num_tiles", tiles_.size());
+ state->SetInteger("num_tile_bundles", tile_bundles_.size());
state->SetDouble("content_scale", contents_scale_);
state->Set("content_bounds",
MathUtil::AsValue(ContentRect().size()).release());
@@ -636,9 +732,11 @@ scoped_ptr<base::Value> PictureLayerTiling::AsValue() const {
size_t PictureLayerTiling::GPUMemoryUsageInBytes() const {
size_t amount = 0;
- for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
- const Tile* tile = it->second.get();
- amount += tile->GPUMemoryUsageInBytes();
+ for (TileBundleMap::const_iterator it = tile_bundles_.begin();
+ it != tile_bundles_.end();
+ ++it) {
+ for (TileBundle::Iterator tile_it(it->second.get()); tile_it; ++tile_it)
+ amount += tile_it->GPUMemoryUsageInBytes();
}
return amount;
}

Powered by Google App Engine
This is Rietveld 408576698