Index: cc/resources/picture_layer_tiling.cc |
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc |
index 7c021049a38a618c5f5a6de0d2d9eb5d9a4fbd46..d4ad254c37b190f33bb0b7baefd670ac03bfcc2c 100644 |
--- a/cc/resources/picture_layer_tiling.cc |
+++ b/cc/resources/picture_layer_tiling.cc |
@@ -53,12 +53,6 @@ class TileEvictionOrder { |
TreePriority tree_priority_; |
}; |
-void ReleaseTile(Tile* tile, WhichTree tree) { |
- // Reset priority as tile is ref-counted and might still be used |
- // even though we no longer hold a reference to it here anymore. |
- tile->SetPriority(tree, TilePriority()); |
-} |
- |
} // namespace |
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
@@ -79,6 +73,7 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale, |
client_(client), |
tiling_data_(gfx::Size(), gfx::Size(), true), |
last_impl_frame_time_in_seconds_(0.0), |
+ content_to_screen_scale_(1.0f), |
has_visible_rect_tiles_(false), |
has_skewport_rect_tiles_(false), |
has_soon_border_rect_tiles_(false), |
@@ -100,8 +95,6 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale, |
} |
PictureLayerTiling::~PictureLayerTiling() { |
- for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
- ReleaseTile(it->second.get(), client_->GetTree()); |
} |
void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { |
@@ -126,6 +119,8 @@ Tile* PictureLayerTiling::CreateTile(int i, |
gfx::Rect rect = |
gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); |
if (!client_->GetInvalidation()->Intersects(rect)) { |
+ DCHECK_EQ(i, candidate_tile->tiling_i_index()); |
+ DCHECK_EQ(j, candidate_tile->tiling_j_index()); |
tiles_[key] = candidate_tile; |
return candidate_tile; |
} |
@@ -134,8 +129,10 @@ Tile* 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()) |
+ if (tile.get()) { |
+ tile->set_tiling_index(i, j); |
tiles_[key] = tile; |
+ } |
return tile.get(); |
} |
@@ -223,8 +220,6 @@ void PictureLayerTiling::DoInvalidate(const Region& layer_region, |
if (find == tiles_.end()) |
continue; |
- ReleaseTile(find->second.get(), client_->GetTree()); |
- |
tiles_.erase(find); |
new_tile_keys.push_back(key); |
} |
@@ -392,8 +387,6 @@ gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { |
void PictureLayerTiling::Reset() { |
live_tiles_rect_ = gfx::Rect(); |
- for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
- ReleaseTile(it->second.get(), client_->GetTree()); |
tiles_.clear(); |
} |
@@ -468,16 +461,18 @@ void PictureLayerTiling::UpdateTilePriorities( |
return; |
} |
+ // Calculate the skewport. |
+ gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, |
+ visible_rect_in_content_space); |
+ DCHECK(skewport.Contains(visible_rect_in_content_space)); |
+ |
+ // Calculate the eventually/live tiles rect. |
size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); |
gfx::Size tile_size = tiling_data_.max_texture_size(); |
int64 eventually_rect_area = |
max_tiles_for_interest_area * tile_size.width() * tile_size.height(); |
- gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, |
- visible_rect_in_content_space); |
- DCHECK(skewport.Contains(visible_rect_in_content_space)); |
- |
gfx::Rect eventually_rect = |
ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, |
eventually_rect_area, |
@@ -489,6 +484,13 @@ void PictureLayerTiling::UpdateTilePriorities( |
<< "tiling_size: " << tiling_size().ToString() |
<< " eventually_rect: " << eventually_rect.ToString(); |
+ // Calculate the soon border rect. |
+ content_to_screen_scale_ = 1.0f / (contents_scale_ * ideal_contents_scale); |
USE eero AT chromium.org
2014/08/19 08:40:20
This should be
content_to_screen_scale_ = ideal_
vmpstr
2014/08/19 18:04:33
Good point, I'll rebase.
|
+ gfx::Rect soon_border_rect = visible_rect_in_content_space; |
+ float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; |
+ soon_border_rect.Inset(-border, -border, -border, -border); |
+ |
+ // Update the tiling state. |
SetLiveTilesRect(eventually_rect); |
last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
@@ -496,111 +498,43 @@ void PictureLayerTiling::UpdateTilePriorities( |
eviction_tiles_cache_valid_ = false; |
- TilePriority now_priority(resolution_, TilePriority::NOW, 0); |
- float content_to_screen_scale = |
- 1.0f / (contents_scale_ * ideal_contents_scale); |
+ // Update iteration rects. |
+ current_visible_rect_ = visible_rect_in_content_space; |
+ current_skewport_rect_ = skewport; |
+ current_soon_border_rect_ = soon_border_rect; |
+ current_eventually_rect_ = eventually_rect; |
- // Assign now priority to all visible tiles. |
- bool include_borders = true; |
- has_visible_rect_tiles_ = false; |
- for (TilingData::Iterator iter( |
- &tiling_data_, visible_rect_in_content_space, include_borders); |
- iter; |
- ++iter) { |
- TileMap::iterator find = tiles_.find(iter.index()); |
- if (find == tiles_.end()) |
- continue; |
- has_visible_rect_tiles_ = true; |
- Tile* tile = find->second.get(); |
+ // Update has_*_tiles state. |
+ const gfx::Rect& tiling_rect = gfx::Rect(tiling_size()); |
- tile->SetPriority(tree, now_priority); |
+ has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); |
+ has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_); |
+ has_soon_border_rect_tiles_ = |
+ tiling_rect.Intersects(current_soon_border_rect_); |
+ has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_); |
- // Set whether tile is occluded or not. |
- bool is_occluded = false; |
- if (occlusion_tracker) { |
+ // Update occlusion. |
+ occlusion_set_.clear(); |
+ if (occlusion_tracker) { |
+ bool include_borders = true; |
+ for (TilingData::Iterator iter( |
+ &tiling_data_, visible_rect_in_content_space, include_borders); |
+ iter; |
+ ++iter) { |
+ gfx::Rect paint_rect = |
+ tiling_data_.TileBoundsWithBorder(iter.index_x(), iter.index_y()); |
+ gfx::Rect tile_rect = paint_rect; |
+ tile_rect.set_size(tiling_data_.max_texture_size()); |
gfx::Rect tile_query_rect = ScaleToEnclosingRect( |
- IntersectRects(tile->content_rect(), visible_rect_in_content_space), |
+ IntersectRects(tile_rect, visible_rect_in_content_space), |
1.0f / contents_scale_); |
- // TODO(vmpstr): Remove render_target and draw_transform from the |
- // parameters so they can be hidden from the tiling. |
- is_occluded = occlusion_tracker->Occluded( |
+ bool is_occluded = occlusion_tracker->Occluded( |
render_target, tile_query_rect, draw_transform); |
+ if (!is_occluded) |
+ continue; |
+ occlusion_set_.insert(iter.index()); |
} |
- tile->set_is_occluded(tree, is_occluded); |
} |
- |
- // Assign soon priority to skewport tiles. |
- has_skewport_rect_tiles_ = false; |
- for (TilingData::DifferenceIterator iter( |
- &tiling_data_, skewport, visible_rect_in_content_space); |
- iter; |
- ++iter) { |
- TileMap::iterator find = tiles_.find(iter.index()); |
- if (find == tiles_.end()) |
- continue; |
- has_skewport_rect_tiles_ = true; |
- Tile* tile = find->second.get(); |
- |
- gfx::Rect tile_bounds = |
- tiling_data_.TileBounds(iter.index_x(), iter.index_y()); |
- |
- float distance_to_visible = |
- visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * |
- content_to_screen_scale; |
- |
- TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible); |
- tile->SetPriority(tree, priority); |
- } |
- |
- // Assign eventually priority to interest rect tiles. |
- has_eventually_rect_tiles_ = false; |
- for (TilingData::DifferenceIterator iter( |
- &tiling_data_, eventually_rect, skewport); |
- iter; |
- ++iter) { |
- TileMap::iterator find = tiles_.find(iter.index()); |
- if (find == tiles_.end()) |
- continue; |
- has_eventually_rect_tiles_ = true; |
- Tile* tile = find->second.get(); |
- |
- gfx::Rect tile_bounds = |
- tiling_data_.TileBounds(iter.index_x(), iter.index_y()); |
- |
- float distance_to_visible = |
- visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * |
- content_to_screen_scale; |
- TilePriority priority( |
- resolution_, TilePriority::EVENTUALLY, distance_to_visible); |
- tile->SetPriority(tree, priority); |
- } |
- |
- // Upgrade the priority on border tiles to be SOON. |
- gfx::Rect soon_border_rect = visible_rect_in_content_space; |
- float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale; |
- soon_border_rect.Inset(-border, -border, -border, -border); |
- has_soon_border_rect_tiles_ = false; |
- for (TilingData::DifferenceIterator iter( |
- &tiling_data_, soon_border_rect, skewport); |
- iter; |
- ++iter) { |
- TileMap::iterator find = tiles_.find(iter.index()); |
- if (find == tiles_.end()) |
- continue; |
- has_soon_border_rect_tiles_ = true; |
- Tile* tile = find->second.get(); |
- |
- TilePriority priority(resolution_, |
- TilePriority::SOON, |
- tile->priority(tree).distance_to_visible); |
- tile->SetPriority(tree, priority); |
- } |
- |
- // Update iteration rects. |
- current_visible_rect_ = visible_rect_in_content_space; |
- current_skewport_rect_ = skewport; |
- current_soon_border_rect_ = soon_border_rect; |
- current_eventually_rect_ = eventually_rect; |
} |
void PictureLayerTiling::SetLiveTilesRect( |
@@ -622,10 +556,8 @@ void PictureLayerTiling::SetLiveTilesRect( |
TileMap::iterator found = tiles_.find(key); |
// 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()) { |
- ReleaseTile(found->second.get(), client_->GetTree()); |
+ if (found != tiles_.end()) |
tiles_.erase(found); |
- } |
} |
const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |
@@ -643,30 +575,90 @@ void PictureLayerTiling::SetLiveTilesRect( |
live_tiles_rect_ = new_live_tiles_rect; |
} |
-void PictureLayerTiling::DidBecomeRecycled() { |
- // DidBecomeActive below will set the active priority for tiles that are |
- // 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()); |
- } |
+bool PictureLayerTiling::IsTileOccluded(const Tile* tile) const { |
+ DCHECK(tile); |
+ bool is_occluded = occlusion_set_.count(std::make_pair( |
+ tile->tiling_i_index(), tile->tiling_j_index())) != 0; |
+ return is_occluded; |
} |
-void PictureLayerTiling::DidBecomeActive() { |
- PicturePileImpl* active_pile = client_->GetPile(); |
- 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. |
- it->second->set_picture_pile(active_pile); |
+bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const { |
+ if (resolution_ != HIGH_RESOLUTION) |
+ return false; |
+ |
+ WhichTree tree = client_->GetTree(); |
+ if (tree != PENDING_TREE) |
+ return false; |
+ |
+ if (IsTileOccluded(tile)) |
+ return false; |
+ |
+ if (client_->RequiresHighResToDraw()) |
+ return true; |
+ |
+ const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |
+ if (!twin_tiling) |
+ return true; |
+ |
+ if (twin_tiling->layer_bounds() != layer_bounds()) |
+ return true; |
+ |
+ if (twin_tiling->current_visible_rect_ != current_visible_rect_) |
+ return true; |
+ |
+ Tile* twin_tile = |
+ twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()); |
danakj
2014/08/18 19:29:13
:( We do this every time we want to see if we can
vmpstr
2014/08/18 19:49:52
I'll do this in a separate patch.
|
+ if (!twin_tile || twin_tile == tile) |
+ return false; |
+ |
+ return true; |
+} |
+ |
+void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const { |
+ const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |
+ if (twin_tiling) |
+ twin_tiling->UpdateTilePriority(tile); |
+ UpdateTilePriority(tile); |
+} |
+ |
+void PictureLayerTiling::UpdateTilePriority(Tile* tile) const { |
+ WhichTree tree = client_->GetTree(); |
+ |
+ if (tree == PENDING_TREE) |
+ tile->set_required_for_activation(false); |
+ tile->set_is_occluded(tree, false); |
+ |
+ if (TileAt(tile->tiling_i_index(), tile->tiling_j_index()) != tile) { |
+ tile->SetPriority(tree, TilePriority()); |
+ return; |
} |
+ |
+ gfx::Rect tile_bounds = tiling_data_.TileBoundsWithBorder( |
+ tile->tiling_i_index(), tile->tiling_j_index()); |
+ |
+ if (current_visible_rect_.Intersects(tile_bounds)) { |
+ tile->SetPriority(tree, TilePriority(resolution_, TilePriority::NOW, 0)); |
+ if (tree == PENDING_TREE) |
+ tile->set_required_for_activation(IsTileRequiredForActivation(tile)); |
+ tile->set_is_occluded(tree, IsTileOccluded(tile)); |
+ return; |
+ } |
+ |
+ float distance_to_visible = |
+ current_visible_rect_.ManhattanInternalDistance(tile_bounds) * |
+ content_to_screen_scale_; |
+ |
+ if (current_soon_border_rect_.Intersects(tile_bounds) || |
+ current_skewport_rect_.Intersects(tile_bounds)) { |
+ tile->SetPriority( |
+ tree, |
+ TilePriority(resolution_, TilePriority::SOON, distance_to_visible)); |
+ return; |
+ } |
+ |
+ tile->SetPriority( |
+ tree, |
+ TilePriority(resolution_, TilePriority::EVENTUALLY, distance_to_visible)); |
} |
void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { |
@@ -849,9 +841,8 @@ void PictureLayerTiling::UpdateEvictionCacheIfNeeded( |
eviction_tiles_eventually_and_rfa_.clear(); |
for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
- // TODO(vmpstr): This should update the priority if UpdateTilePriorities |
- // changes not to do this. |
Tile* tile = it->second; |
+ UpdateTileAndTwinPriority(tile); |
const TilePriority& priority = |
tile->priority_for_tree_priority(tree_priority); |
switch (priority.priority_bin) { |
@@ -943,8 +934,11 @@ PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( |
current_tile_ = |
tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); |
- if (!current_tile_ || !TileNeedsRaster(current_tile_)) |
+ if (!current_tile_ || !TileNeedsRaster(current_tile_)) { |
++(*this); |
+ return; |
+ } |
+ tiling_->UpdateTileAndTwinPriority(current_tile_); |
} |
PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} |
@@ -1005,6 +999,9 @@ void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { |
break; |
} |
} while (!spiral_iterator_); |
+ |
+ if (current_tile_) |
+ tiling_->UpdateTileAndTwinPriority(current_tile_); |
} |
PictureLayerTiling::TilingRasterTileIterator& |
@@ -1042,6 +1039,9 @@ operator++() { |
} |
current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
} |
+ |
+ if (current_tile_) |
+ tiling_->UpdateTileAndTwinPriority(current_tile_); |
return *this; |
} |