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

Unified Diff: cc/resources/picture_layer_tiling.cc

Issue 12865017: Makes tile-creation lazy (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months 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 5f74b704d19fbf9ebb1eca67e5797633ab7d40b9..1bab2b3e7680d9b0a1c984611faa02932290617f 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -21,7 +21,7 @@ scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
}
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const {
- return make_scoped_ptr(new PictureLayerTiling(*this));
+ return make_scoped_ptr(new PictureLayerTiling(*this, 0));
}
PictureLayerTiling::PictureLayerTiling(float contents_scale)
@@ -33,6 +33,19 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale)
last_impl_frame_time_(0) {
}
+PictureLayerTiling::PictureLayerTiling(const PictureLayerTiling& other, int)
enne (OOO) 2013/03/27 16:16:27 I'm assuming this "int" here is a way to have an o
whunt 2013/03/27 17:42:02 I agree, that's reasonable.
+ : contents_scale_(other.contents_scale_),
+ layer_bounds_(other.layer_bounds_),
+ resolution_(other.resolution_),
+ client_(other.client_),
+ tiling_data_(other.tiling_data_),
+ tiles_(),
+ interest_rect_(),
+ last_interest_rect_(other.last_interest_rect_),
+ last_source_frame_number_(other.last_source_frame_number_),
+ last_impl_frame_time_(other.last_impl_frame_time_) {
+}
+
PictureLayerTiling::~PictureLayerTiling() {
}
@@ -56,11 +69,33 @@ Tile* PictureLayerTiling::TileAt(int i, int j) const {
}
void PictureLayerTiling::CreateTile(int i, int j) {
- gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j);
- tile_rect.set_size(tiling_data_.max_texture_size());
TileMapKey key(i, j);
DCHECK(tiles_.find(key) == tiles_.end());
- scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
+
+ gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j);
enne (OOO) 2013/03/27 16:16:27 I don't understand this paint_rect code at all. W
whunt 2013/03/27 17:42:02 The paint rect has to do with layers that change s
enne (OOO) 2013/03/27 18:03:20 Ah, I see. Storing a paint rect on every tile sti
+ gfx::Rect tile_rect = paint_rect;
+ tile_rect.set_size(tiling_data_.max_texture_size());
+
+ TileMap::iterator found = tiles_.find(key);
+ if (found != tiles_.end()) {
+ if (found->second->paint_rect().Contains(paint_rect))
+ return;
+ tiles_.erase(found);
+ }
+
+ const PictureLayerTiling* sibling = client_->GetSibling(this);
+ if (sibling) {
+ Tile* candidate_tile = sibling->TileAt(i, j);
+ if (candidate_tile &&
+ candidate_tile->paint_rect().Contains(paint_rect) &&
+ !client_->GetInvalidation()->Intersects(paint_rect)) {
+ tiles_[key] = candidate_tile;
+ return;
+ }
+ }
+
+ scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect,
+ paint_rect);
if (tile)
tiles_[key] = tile;
}
@@ -78,80 +113,31 @@ void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) {
gfx::Size old_layer_bounds = layer_bounds_;
layer_bounds_ = layer_bounds;
- gfx::Size old_content_bounds = tiling_data_.total_size();
- gfx::Size content_bounds =
- gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds_, contents_scale_));
- tiling_data_.SetTotalSize(content_bounds);
+ // Handle the case where the new bounds are empty.
if (layer_bounds_.IsEmpty()) {
enne (OOO) 2013/03/27 16:16:27 I don't think you need to special case this. The
whunt 2013/03/27 17:42:02 I agree, it's not entirely necessary. The check w
tiles_.clear();
+ interest_rect_ = gfx::Rect();
+ tiling_data_.SetTotalSize(gfx::Size());
return;
}
+ // Calculate new content bounds.
+ gfx::Size old_content_bounds = tiling_data_.total_size();
+ gfx::Size content_bounds =
+ gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds_, contents_scale_));
+ tiling_data_.SetTotalSize(content_bounds);
gfx::Size tile_size = client_->CalculateTileSize(
tiling_data_.max_texture_size(),
content_bounds);
+
+ // Handle the case where the size of our tiling has changed.
if (tile_size != tiling_data_.max_texture_size()) {
tiling_data_.SetMaxTextureSize(tile_size);
tiles_.clear();
+ interest_rect_ = gfx::Rect();
enne (OOO) 2013/03/27 16:16:27 Why does this need to happen?
whunt 2013/03/27 17:42:02 It shouldn't happen. This line was left over from
CreateTilesFromLayerRect(gfx::Rect(layer_bounds_));
- return;
}
-
- // Any tiles outside our new bounds are invalid and should be dropped.
enne (OOO) 2013/03/27 16:16:27 I think you still need this block in the SetLayerB
whunt 2013/03/27 17:42:02 The old interest rect still contains those tiles.
enne (OOO) 2013/03/27 18:03:20 It does, but when you change TilingData's total si
- if (old_content_bounds.width() > content_bounds.width() ||
- old_content_bounds.height() > content_bounds.height()) {
- int right =
- tiling_data_.TileXIndexFromSrcCoord(content_bounds.width() - 1);
- int bottom =
- tiling_data_.TileYIndexFromSrcCoord(content_bounds.height() - 1);
-
- std::vector<TileMapKey> invalid_tile_keys;
- for (TileMap::const_iterator it = tiles_.begin();
- it != tiles_.end(); ++it) {
- if (it->first.first > right || it->first.second > bottom)
- invalid_tile_keys.push_back(it->first);
- }
- for (size_t i = 0; i < invalid_tile_keys.size(); ++i)
- tiles_.erase(invalid_tile_keys[i]);
- }
-
- // Create tiles for newly exposed areas.
- Region layer_region((gfx::Rect(layer_bounds_)));
- layer_region.Subtract(gfx::Rect(old_layer_bounds));
- for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) {
- Invalidate(iter.rect());
- CreateTilesFromLayerRect(iter.rect());
- }
-}
-
-void PictureLayerTiling::Invalidate(const Region& layer_invalidation) {
- std::vector<TileMapKey> new_tiles;
-
- for (Region::Iterator region_iter(layer_invalidation);
- region_iter.has_rect();
- region_iter.next()) {
-
- gfx::Rect layer_invalidation = region_iter.rect();
- layer_invalidation.Intersect(gfx::Rect(layer_bounds_));
- gfx::Rect rect =
- gfx::ToEnclosingRect(ScaleRect(layer_invalidation, contents_scale_));
-
- for (PictureLayerTiling::Iterator tile_iter(this, contents_scale_, rect);
- tile_iter;
- ++tile_iter) {
- TileMapKey key(tile_iter.tile_i_, tile_iter.tile_j_);
- TileMap::iterator found = tiles_.find(key);
- if (found == tiles_.end())
- continue;
-
- tiles_.erase(found);
- new_tiles.push_back(key);
- }
- }
-
- for (size_t i = 0; i < new_tiles.size(); ++i)
- CreateTile(new_tiles[i].first, new_tiles[i].second);
}
void PictureLayerTiling::CreateTilesFromLayerRect(gfx::Rect layer_rect) {
@@ -171,6 +157,34 @@ void PictureLayerTiling::CreateTilesFromContentRect(gfx::Rect content_rect) {
}
}
+PictureLayerTiling::SimpleIterator::SimpleIterator(
+ const PictureLayerTiling* tiling,
+ const gfx::Rect& rect)
+ : key_(0, 0),
+ left_(0),
+ right_(0),
+ bottom_(0) {
+ DCHECK(tiling);
+ if (rect.IsEmpty())
+ return;
+
+ const TilingData& tiling_data = tiling->tiling_data_;
+ key_.first = tiling_data.TileXIndexFromSrcCoord(rect.x());
+ key_.second = tiling_data.TileYIndexFromSrcCoord(rect.y());
+ right_ = tiling_data.TileXIndexFromSrcCoord(rect.right() - 1) + 1;
+ bottom_ = tiling_data.TileYIndexFromSrcCoord(rect.bottom() - 1) + 1;
+ left_ = key_.first;
+}
+
+PictureLayerTiling::SimpleIterator& PictureLayerTiling::SimpleIterator::operator++() {
+ ++key_.first;
+ if (key_.first == right_) {
+ key_.first = left_;
+ ++key_.second;
+ }
+ return *this;
+}
+
PictureLayerTiling::Iterator::Iterator()
: tiling_(NULL),
current_tile_(NULL),
@@ -336,6 +350,26 @@ void PictureLayerTiling::UpdateTilePriorities(
if (ContentRect().IsEmpty())
return;
+ gfx::Rect viewport_in_content_space =
+ gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space,
+ contents_scale_));
+
+ gfx::Size tile_size = tiling_data_.max_texture_size();
+ int64 interest_rect_area =
+ TilePriority::kNumTilesToCoverWithInflatedViewportRectForPrioritization *
+ tile_size.width() * tile_size.height();
+
+ gfx::Rect interest_rect = ExpandRectEquallyToAreaBoundedBy(
+ viewport_in_content_space,
+ interest_rect_area,
+ ContentRect());
+ DCHECK(ContentRect().Contains(interest_rect));
+
+ ManageTiles(interest_rect_, interest_rect);
+// ManageTiles(gfx::Rect(), interest_rect);
enne (OOO) 2013/03/27 16:16:27 ?
whunt 2013/03/27 17:42:02 Old debugging code, will be deleted.
+// ManageTiles(gfx::Rect(), viewport_in_content_space);
+ interest_rect_ = interest_rect;
enne (OOO) 2013/03/27 16:16:27 I don't think you need to store this. Is last_int
whunt 2013/03/27 17:42:02 Not sure yet.
+
bool first_update_in_new_source_frame =
current_source_frame_number != last_source_frame_number_;
@@ -352,30 +386,16 @@ void PictureLayerTiling::UpdateTilePriorities(
if (!first_update_in_new_impl_frame && !first_update_in_new_source_frame)
return;
- double time_delta = 0;
- if (last_impl_frame_time_ != 0 && last_layer_bounds == current_layer_bounds)
+ double time_delta = 0.0;
+ if (last_impl_frame_time_ != 0.0 &&
+ last_layer_bounds == current_layer_bounds)
time_delta = current_frame_time - last_impl_frame_time_;
- gfx::Rect viewport_in_content_space =
- gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space,
- contents_scale_));
-
- gfx::Size tile_size = tiling_data_.max_texture_size();
- int64 prioritized_rect_area =
- TilePriority::kNumTilesToCoverWithInflatedViewportRectForPrioritization *
- tile_size.width() * tile_size.height();
-
- gfx::Rect prioritized_rect = ExpandRectEquallyToAreaBoundedBy(
- viewport_in_content_space,
- prioritized_rect_area,
- ContentRect());
- DCHECK(ContentRect().Contains(prioritized_rect));
-
// Iterate through all of the tiles that were live last frame but will
// not be live this frame, and mark them as being dead.
for (TilingData::DifferenceIterator iter(&tiling_data_,
- last_prioritized_rect_,
- prioritized_rect);
+ last_interest_rect_,
+ interest_rect);
iter;
++iter) {
TileMap::iterator find = tiles_.find(iter.index());
@@ -387,7 +407,7 @@ void PictureLayerTiling::UpdateTilePriorities(
Tile* tile = find->second.get();
tile->SetPriority(tree, priority);
}
- last_prioritized_rect_ = prioritized_rect;
+ last_interest_rect_ = interest_rect;
gfx::Rect view_rect(device_viewport);
float current_scale = current_layer_contents_scale / contents_scale_;
@@ -404,7 +424,7 @@ void PictureLayerTiling::UpdateTilePriorities(
last_screen_transform.matrix().get(0, 3),
last_screen_transform.matrix().get(1, 3));
- for (TilingData::Iterator iter(&tiling_data_, prioritized_rect);
+ for (TilingData::Iterator iter(&tiling_data_, interest_rect);
iter; ++iter) {
TileMap::iterator find = tiles_.find(iter.index());
if (find == tiles_.end())
@@ -437,7 +457,7 @@ void PictureLayerTiling::UpdateTilePriorities(
tile->SetPriority(tree, priority);
}
} else {
- for (TilingData::Iterator iter(&tiling_data_, prioritized_rect);
+ for (TilingData::Iterator iter(&tiling_data_, interest_rect);
iter; ++iter) {
TileMap::iterator find = tiles_.find(iter.index());
if (find == tiles_.end())
@@ -485,6 +505,38 @@ void PictureLayerTiling::UpdateTilePriorities(
last_impl_frame_time_ = current_frame_time;
}
+void PictureLayerTiling::ManageTiles(const gfx::Rect& old_interest_rect,
+ const gfx::Rect& new_interest_rect) {
+ if (old_interest_rect == new_interest_rect)
+ return;
+
+ Region free_region(old_interest_rect);
+ free_region.Subtract(new_interest_rect);
+
+ // Iterate to delete all tiles outside of our new interest rect.
+ for (Region::Iterator iter(free_region); iter.has_rect(); iter.next()) {
enne (OOO) 2013/03/27 16:16:27 Both of these loops look like a job for TilingData
whunt 2013/03/27 17:42:02 I'll give that a look.
+ for (SimpleIterator tile_iter(this, iter.rect()); tile_iter; ++tile_iter) {
+ TileMapKey key = *tile_iter;
+ TileMap::iterator found = tiles_.find(key);
+ if (found != tiles_.end() &&
enne (OOO) 2013/03/27 16:16:27 Did you mean || here? I think this intersects con
whunt 2013/03/27 17:42:02 No, I don't mean ||. In this case we're looking f
+ !new_interest_rect.Intersects(found->second->content_rect()))
+ tiles_.erase(found);
+ }
+ }
+
+ Region alloc_region(new_interest_rect);
+ alloc_region.Subtract(old_interest_rect);
+
+ // Iterate to allocate new tiles for all regions with newly exposed area.
+ for (Region::Iterator iter(alloc_region); iter.has_rect(); iter.next()) {
+ for (SimpleIterator tile_iter(this, iter.rect()); tile_iter; ++tile_iter) {
+ TileMapKey key = *tile_iter;
+ TileMap::iterator found = tiles_.find(key);
+ CreateTile(key.first, key.second);
+ }
+ }
+}
+
void PictureLayerTiling::DidBecomeActive() {
for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE));

Powered by Google App Engine
This is Rietveld 408576698