Chromium Code Reviews| 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)); |