Index: cc/resources/picture_pile.cc |
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc |
index 97cd127c62d4e4fc8e3a00cc83112933fac72f20..d94ce7cf2187b535237031aec82d8c78e2f8081b 100644 |
--- a/cc/resources/picture_pile.cc |
+++ b/cc/resources/picture_pile.cc |
@@ -106,18 +106,17 @@ float PerformClustering(const std::vector<gfx::Rect>& tiles, |
static_cast<float>(total_record_area); |
} |
-float ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles, |
- std::vector<gfx::Rect>* record_rects) { |
+void ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles, |
+ std::vector<gfx::Rect>* record_rects) { |
TRACE_EVENT1("cc", "ClusterTiles", |
"count", |
invalid_tiles.size()); |
- |
if (invalid_tiles.size() <= 1) { |
// Quickly handle the special case for common |
// single-invalidation update, and also the less common |
// case of no tiles passed in. |
*record_rects = invalid_tiles; |
- return 1; |
+ return; |
} |
// Sort the invalid tiles by y coordinate. |
@@ -126,15 +125,14 @@ float ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles, |
invalid_tiles_vertical.end(), |
rect_sort_y); |
- float vertical_density; |
std::vector<gfx::Rect> vertical_clustering; |
- vertical_density = PerformClustering(invalid_tiles_vertical, |
- &vertical_clustering); |
+ float vertical_density = |
+ PerformClustering(invalid_tiles_vertical, &vertical_clustering); |
// If vertical density is optimal, then we can return early. |
if (vertical_density == 1.f) { |
*record_rects = vertical_clustering; |
- return vertical_density; |
+ return; |
} |
// Now try again with a horizontal sort, see which one is best |
@@ -143,18 +141,16 @@ float ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles, |
invalid_tiles_horizontal.end(), |
rect_sort_x); |
- float horizontal_density; |
std::vector<gfx::Rect> horizontal_clustering; |
- horizontal_density = PerformClustering(invalid_tiles_horizontal, |
- &horizontal_clustering); |
+ float horizontal_density = |
+ PerformClustering(invalid_tiles_horizontal, &horizontal_clustering); |
if (vertical_density < horizontal_density) { |
*record_rects = horizontal_clustering; |
- return horizontal_density; |
+ return; |
} |
*record_rects = vertical_clustering; |
- return vertical_density; |
} |
} // namespace |
@@ -190,6 +186,37 @@ bool PicturePile::UpdateAndExpandInvalidation( |
bool can_use_lcd_text_changed = can_use_lcd_text_ != can_use_lcd_text; |
can_use_lcd_text_ = can_use_lcd_text; |
+ gfx::Rect interest_rect = visible_layer_rect; |
+ interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_); |
+ recorded_viewport_ = interest_rect; |
+ recorded_viewport_.Intersect(gfx::Rect(layer_size)); |
+ |
+ bool updated = |
+ ApplyInvalidationAndResize(interest_rect, invalidation, layer_size, |
+ frame_number, can_use_lcd_text_changed); |
+ std::vector<gfx::Rect> invalid_tiles; |
+ GetInvalidTileRects(interest_rect, invalidation, visible_layer_rect, |
+ frame_number, &invalid_tiles); |
+ std::vector<gfx::Rect> record_rects; |
+ ClusterTiles(invalid_tiles, &record_rects); |
+ |
+ if (record_rects.empty()) |
+ return updated; |
+ |
+ CreatePictures(painter, recording_mode, record_rects); |
+ |
+ DetermineIfSolidColor(); |
+ |
+ has_any_recordings_ = true; |
+ DCHECK(CanRasterSlowTileCheck(recorded_viewport_)); |
+ return true; |
+} |
+ |
+bool PicturePile::ApplyInvalidationAndResize(const gfx::Rect& interest_rect, |
+ Region* invalidation, |
+ const gfx::Size& layer_size, |
+ int frame_number, |
+ bool can_use_lcd_text_changed) { |
bool updated = false; |
Region synthetic_invalidation; |
@@ -207,22 +234,17 @@ bool PicturePile::UpdateAndExpandInvalidation( |
updated = true; |
} |
- gfx::Rect interest_rect = visible_layer_rect; |
- interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_); |
- recorded_viewport_ = interest_rect; |
- recorded_viewport_.Intersect(gfx::Rect(GetSize())); |
- |
gfx::Rect interest_rect_over_tiles = |
tiling_.ExpandRectToTileBounds(interest_rect); |
- gfx::Size min_tiling_size( |
- std::min(GetSize().width(), old_tiling_size.width()), |
- std::min(GetSize().height(), old_tiling_size.height())); |
- gfx::Size max_tiling_size( |
- std::max(GetSize().width(), old_tiling_size.width()), |
- std::max(GetSize().height(), old_tiling_size.height())); |
- |
if (old_tiling_size != layer_size) { |
+ gfx::Size min_tiling_size( |
+ std::min(GetSize().width(), old_tiling_size.width()), |
+ std::min(GetSize().height(), old_tiling_size.height())); |
+ gfx::Size max_tiling_size( |
+ std::max(GetSize().width(), old_tiling_size.width()), |
+ std::max(GetSize().height(), old_tiling_size.height())); |
+ |
has_any_recordings_ = false; |
// Drop recordings that are outside the new or old layer bounds or that |
@@ -240,12 +262,10 @@ bool PicturePile::UpdateAndExpandInvalidation( |
min_toss_y = |
tiling_.FirstBorderTileYIndexFromSrcCoord(min_tiling_size.height()); |
} |
- for (PictureMap::const_iterator it = picture_map_.begin(); |
- it != picture_map_.end(); |
- ++it) { |
- const PictureMapKey& key = it->first; |
+ for (const auto& key_picture_pair : picture_map_) { |
+ const PictureMapKey& key = key_picture_pair.first; |
if (key.first < min_toss_x && key.second < min_toss_y) { |
- has_any_recordings_ |= !!it->second.GetPicture(); |
+ has_any_recordings_ |= !!key_picture_pair.second.GetPicture(); |
continue; |
} |
to_erase.push_back(key); |
@@ -472,10 +492,16 @@ bool PicturePile::UpdateAndExpandInvalidation( |
} |
invalidation->Union(synthetic_invalidation); |
+ return updated; |
+} |
+void PicturePile::GetInvalidTileRects(const gfx::Rect& interest_rect, |
+ Region* invalidation, |
+ const gfx::Rect& visible_layer_rect, |
+ int frame_number, |
+ std::vector<gfx::Rect>* invalid_tiles) { |
// Make a list of all invalid tiles; we will attempt to |
// cluster these into multiple invalidation regions. |
- std::vector<gfx::Rect> invalid_tiles; |
bool include_borders = true; |
for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it; |
++it) { |
@@ -488,7 +514,7 @@ bool PicturePile::UpdateAndExpandInvalidation( |
if (info.NeedsRecording(frame_number, distance_to_visible)) { |
gfx::Rect tile = tiling_.TileBounds(key.first, key.second); |
- invalid_tiles.push_back(tile); |
+ invalid_tiles->push_back(tile); |
} else if (!info.GetPicture()) { |
if (recorded_viewport_.Intersects(rect)) { |
// Recorded viewport is just an optimization for a fully recorded |
@@ -504,18 +530,13 @@ bool PicturePile::UpdateAndExpandInvalidation( |
invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y())); |
} |
} |
+} |
- std::vector<gfx::Rect> record_rects; |
- ClusterTiles(invalid_tiles, &record_rects); |
- |
- if (record_rects.empty()) |
- return updated; |
- |
- for (std::vector<gfx::Rect>::iterator it = record_rects.begin(); |
- it != record_rects.end(); |
- it++) { |
- gfx::Rect record_rect = *it; |
- record_rect = PadRect(record_rect); |
+void PicturePile::CreatePictures(ContentLayerClient* painter, |
+ Picture::RecordingMode recording_mode, |
+ const std::vector<gfx::Rect>& record_rects) { |
+ for (const auto& record_rect : record_rects) { |
+ gfx::Rect padded_record_rect = PadRect(record_rect); |
int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); |
scoped_refptr<Picture> picture; |
@@ -526,44 +547,34 @@ bool PicturePile::UpdateAndExpandInvalidation( |
// Picture::Create. |
bool gather_pixel_refs = RasterWorkerPool::GetNumRasterThreads() > 1; |
- { |
- for (int i = 0; i < repeat_count; i++) { |
- picture = Picture::Create(record_rect, |
- painter, |
- tile_grid_info_, |
- gather_pixel_refs, |
- recording_mode); |
- // Note the '&&' with previous is-suitable state. |
- // This means that once a picture-pile becomes unsuitable for gpu |
- // rasterization due to some content, it will continue to be unsuitable |
- // even if that content is replaced by gpu-friendly content. |
- // This is an optimization to avoid iterating though all pictures in |
- // the pile after each invalidation. |
- is_suitable_for_gpu_rasterization_ &= |
- picture->IsSuitableForGpuRasterization(); |
- } |
+ for (int i = 0; i < repeat_count; i++) { |
+ picture = Picture::Create(padded_record_rect, painter, tile_grid_info_, |
+ gather_pixel_refs, recording_mode); |
+ // Note the '&&' with previous is-suitable state. |
+ // This means that once a picture-pile becomes unsuitable for gpu |
+ // rasterization due to some content, it will continue to be unsuitable |
+ // even if that content is replaced by gpu-friendly content. |
+ // This is an optimization to avoid iterating though all pictures in |
+ // the pile after each invalidation. |
+ is_suitable_for_gpu_rasterization_ &= |
+ picture->IsSuitableForGpuRasterization(); |
} |
bool found_tile_for_recorded_picture = false; |
bool include_borders = true; |
- for (TilingData::Iterator it(&tiling_, record_rect, include_borders); it; |
- ++it) { |
+ for (TilingData::Iterator it(&tiling_, padded_record_rect, include_borders); |
+ it; ++it) { |
const PictureMapKey& key = it.index(); |
gfx::Rect tile = PaddedRect(key); |
- if (record_rect.Contains(tile)) { |
+ if (padded_record_rect.Contains(tile)) { |
PictureInfo& info = picture_map_[key]; |
info.SetPicture(picture); |
found_tile_for_recorded_picture = true; |
} |
} |
- DetermineIfSolidColor(); |
DCHECK(found_tile_for_recorded_picture); |
} |
- |
- has_any_recordings_ = true; |
- DCHECK(CanRasterSlowTileCheck(recorded_viewport_)); |
- return true; |
} |
scoped_refptr<RasterSource> PicturePile::CreateRasterSource() const { |