Index: cc/picture_layer_tiling.cc |
diff --git a/cc/picture_layer_tiling.cc b/cc/picture_layer_tiling.cc |
index 5dd2dfef0099d9b51829b8b52522638a87881491..202e74ac73f71fe4c13ae2d7a889730197970a8d 100644 |
--- a/cc/picture_layer_tiling.cc |
+++ b/cc/picture_layer_tiling.cc |
@@ -19,7 +19,20 @@ scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
} |
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const { |
- return make_scoped_ptr(new PictureLayerTiling(*this)); |
+ PictureLayerTiling* new_tiling = new PictureLayerTiling(*this); |
+ |
+ // The live_tiles_ list was shallow-copied, restore it explicitly. |
+ new_tiling->live_tiles_.clear(); |
+ for (TileList::const_iterator it = live_tiles_.begin(); |
+ it != live_tiles_.end(); ++it) { |
+ const TileHandle* tile_handle = *it; |
+ TileMap::iterator find = new_tiling->tiles_.find(tile_handle->key()); |
+ DCHECK(find != new_tiling->tiles_.end()); |
+ TileHandle* new_tile_handle = &find->second; |
+ new_tile_handle->AddToLiveTileList(new_tiling); |
+ } |
+ |
+ return make_scoped_ptr(new_tiling); |
} |
PictureLayerTiling::PictureLayerTiling(float contents_scale) |
@@ -32,6 +45,8 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale) |
} |
PictureLayerTiling::~PictureLayerTiling() { |
+ tiles_.clear(); |
+ DCHECK(live_tiles_.empty()); |
} |
void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { |
@@ -60,7 +75,7 @@ void PictureLayerTiling::CreateTile(int i, int j) { |
DCHECK(tiles_.find(key) == tiles_.end()); |
scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
if (tile) |
- tiles_.insert(make_pair(key, TileHandle(tile))); |
+ tiles_.insert(make_pair(key, TileHandle(key, tile))); |
} |
Region PictureLayerTiling::OpaqueRegionInContentRect( |
@@ -401,24 +416,40 @@ void PictureLayerTiling::UpdateTilePriorities( |
-adjusted_inset); |
inflated_rect.Intersect(ContentRect()); |
- // 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_, |
- inflated_rect); |
- iter; |
- ++iter) { |
+ // Mark all tiles in the inflated rect as live. |
+ for (TilingData::Iterator iter(&tiling_data_, inflated_rect); |
+ iter; ++iter) { |
TileMap::iterator find = tiles_.find(iter.index()); |
if (find == tiles_.end()) |
continue; |
- |
- TilePriority priority; |
- DCHECK(!priority.is_live); |
TileHandle* tile_handle = &find->second; |
- Tile* tile = tile_handle->tile(); |
- tile->set_priority(tree, priority); |
- tile_handle->UnregisterFromTileManager(); |
+ tile_handle->set_should_be_live(true); |
+ tile_handle->AddToLiveTileList(this); |
+ } |
+ |
+ // Iterate through all of the tiles that were live last frame but will |
+ // not be live this frame, and mark them as being dead. |
+ // TODO(ccameron): merge this loop with the loops below. |
+ for (TileList::iterator it = live_tiles_.begin(); |
+ it != live_tiles_.end(); ) { |
+ TileHandle* tile_handle = *it; |
+ TileList::iterator it_next = it; |
+ it_next++; |
+ if (!tile_handle->should_be_live() && |
+ !tile_handle->tile()->GetResourceId()) { |
+ TilePriority priority; |
+ DCHECK(!priority.is_live); |
+ tile_handle->tile()->set_priority(tree, priority); |
+ tile_handle->RemoveFromLiveTileList(); |
+ tile_handle->UnregisterFromTileManager(); |
+ } else { |
+ tile_handle->RegisterWithTileManager(); |
+ // Mark the tile as not live for the next time through. |
+ tile_handle->set_should_be_live(false); |
+ } |
+ it = it_next; |
} |
+ |
last_prioritized_rect_ = inflated_rect; |
gfx::Rect view_rect(device_viewport); |
@@ -436,17 +467,14 @@ void PictureLayerTiling::UpdateTilePriorities( |
last_screen_transform.matrix().get(0, 3), |
last_screen_transform.matrix().get(1, 3)); |
- for (TilingData::Iterator iter(&tiling_data_, inflated_rect); |
- iter; ++iter) { |
- TileMap::iterator find = tiles_.find(iter.index()); |
- if (find == tiles_.end()) |
- continue; |
- TileHandle* tile_handle = &find->second; |
+ for (TileList::iterator it = live_tiles_.begin(); |
+ it != live_tiles_.end(); ++it) { |
+ TileHandle* tile_handle = *it; |
Tile* tile = tile_handle->tile(); |
- tile_handle->RegisterWithTileManager(); |
gfx::Rect tile_bounds = |
- tiling_data_.TileBounds(iter.index_x(), iter.index_y()); |
+ tiling_data_.TileBounds(tile_handle->key().first, |
+ tile_handle->key().second); |
gfx::RectF current_screen_rect = gfx::ScaleRect( |
tile_bounds, |
current_scale, |
@@ -471,17 +499,14 @@ void PictureLayerTiling::UpdateTilePriorities( |
tile->set_priority(tree, priority); |
} |
} else { |
- for (TilingData::Iterator iter(&tiling_data_, inflated_rect); |
- iter; ++iter) { |
- TileMap::iterator find = tiles_.find(iter.index()); |
- if (find == tiles_.end()) |
- continue; |
- TileHandle* tile_handle = &find->second; |
+ for (TileList::iterator it = live_tiles_.begin(); |
+ it != live_tiles_.end(); ++it) { |
+ TileHandle* tile_handle = *it; |
Tile* tile = tile_handle->tile(); |
- tile_handle->RegisterWithTileManager(); |
gfx::Rect tile_bounds = |
- tiling_data_.TileBounds(iter.index_x(), iter.index_y()); |
+ tiling_data_.TileBounds(tile_handle->key().first, |
+ tile_handle->key().second); |
gfx::RectF current_layer_content_rect = gfx::ScaleRect( |
tile_bounds, |
current_scale, |
@@ -546,7 +571,23 @@ scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { |
return state.PassAs<base::Value>(); |
} |
-TileHandle::TileHandle(scoped_refptr<Tile> tile) : tile_(tile) { |
+TileHandle::TileHandle(std::pair<int, int> key, scoped_refptr<Tile> tile) |
+ : key_(key), |
+ tile_(tile), |
+ should_be_live_(false), |
+ tiling_(NULL) { |
+} |
+ |
+TileHandle::TileHandle(const TileHandle& tile_handle) |
+ : key_(tile_handle.key_), |
+ tile_(tile_handle.tile_), |
+ managed_tile_state_(tile_handle.managed_tile_state_), |
+ should_be_live_(false), |
+ tiling_(NULL) { |
+} |
+ |
+TileHandle::~TileHandle() { |
+ RemoveFromLiveTileList(); |
} |
void TileHandle::RegisterWithTileManager() { |
@@ -559,4 +600,23 @@ void TileHandle::UnregisterFromTileManager() { |
managed_tile_state_ = NULL; |
} |
+void TileHandle::AddToLiveTileList(PictureLayerTiling* tiling) { |
+ if (tiling_) { |
+ DCHECK(tiling == tiling_); |
+ DCHECK(tiling_live_tile_list_iterator_ != tiling_->live_tiles_.end()); |
+ return; |
+ } |
+ tiling_ = tiling; |
+ tiling_live_tile_list_iterator_ = |
+ tiling_->live_tiles_.insert(tiling_->live_tiles_.begin(), this); |
+} |
+ |
+void TileHandle::RemoveFromLiveTileList() { |
+ if (!tiling_) |
+ return; |
+ tiling_->live_tiles_.erase(tiling_live_tile_list_iterator_); |
+ tiling_live_tile_list_iterator_ = tiling_->live_tiles_.end(); |
+ tiling_ = NULL; |
+} |
+ |
} // namespace cc |