Index: cc/resources/picture_pile.cc |
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc |
index 6341e88b3688889df468543cecf2c652136f20c9..7bdfc5d5afaf29cee83e2cb7d12961f3770b0b5a 100644 |
--- a/cc/resources/picture_pile.cc |
+++ b/cc/resources/picture_pile.cc |
@@ -152,6 +152,7 @@ bool PicturePile::UpdateAndExpandInvalidation( |
SkColor background_color, |
bool contents_opaque, |
bool contents_fill_bounds_completely, |
+ const gfx::Rect& layer_bounds_rect, |
const gfx::Rect& visible_layer_rect, |
int frame_number, |
Picture::RecordingMode recording_mode, |
@@ -160,6 +161,15 @@ bool PicturePile::UpdateAndExpandInvalidation( |
contents_opaque_ = contents_opaque; |
contents_fill_bounds_completely_ = contents_fill_bounds_completely; |
+ bool updated = false; |
+ |
+ Region resize_invalidation; |
+ gfx::Rect old_tiling_rect = tiling_rect(); |
+ if (old_tiling_rect != layer_bounds_rect) { |
+ tiling_.SetTilingRect(layer_bounds_rect); |
+ updated = true; |
+ } |
+ |
gfx::Rect interest_rect = visible_layer_rect; |
interest_rect.Inset( |
-kPixelDistanceToRecord, |
@@ -172,11 +182,83 @@ bool PicturePile::UpdateAndExpandInvalidation( |
gfx::Rect interest_rect_over_tiles = |
tiling_.ExpandRectToTileBounds(interest_rect); |
- Region invalidation_expanded_to_full_tiles; |
+ if (old_tiling_rect != layer_bounds_rect) { |
+ has_any_recordings_ = false; |
- bool invalidated = false; |
+ if (tiling_rect().origin() != old_tiling_rect.origin()) { |
+ // If the origin changes we just do something simple. |
+ picture_map_.clear(); |
+ invalidation->Union(old_tiling_rect); |
+ invalidation->Union(tiling_rect()); |
+ } else { |
+ // Drop recordings that are outside the new layer bounds or that changed |
+ // size. |
+ std::vector<PictureMapKey> to_erase; |
+ int min_toss_x = tiling_.num_tiles_x(); |
+ if (tiling_rect().right() > old_tiling_rect.right()) { |
+ min_toss_x = |
+ tiling_.FirstBorderTileXIndexFromSrcCoord(old_tiling_rect.right()); |
+ } |
+ int min_toss_y = tiling_.num_tiles_y(); |
+ if (tiling_rect().bottom() > old_tiling_rect.bottom()) { |
+ min_toss_y = |
+ tiling_.FirstBorderTileYIndexFromSrcCoord(old_tiling_rect.bottom()); |
+ } |
+ for (PictureMap::const_iterator it = picture_map_.begin(); |
+ it != picture_map_.end(); |
+ ++it) { |
+ const PictureMapKey& key = it->first; |
+ if (key.first < min_toss_x && key.second < min_toss_y) { |
+ has_any_recordings_ |= !!it->second.GetPicture(); |
+ continue; |
+ } |
+ to_erase.push_back(key); |
+ } |
+ |
+ for (size_t i = 0; i < to_erase.size(); ++i) |
+ picture_map_.erase(to_erase[i]); |
+ |
+ // Invalidate dropped recordings that changed size that are outside the |
+ // interest rect. These tiles will not be re-recorded below, so any raster |
enne (OOO)
2014/07/11 18:21:54
Sure, but isn't the subtraction there so that you
|
+ // tiles that depend on these recording tiles must be dropped, which the |
+ // invalidation ensures will happen. |
+ gfx::Rect old_tiling_rect_over_tiles = |
+ tiling_.ExpandRectToTileBounds(old_tiling_rect); |
+ if (min_toss_x < tiling_.num_tiles_x()) { |
+ gfx::Rect right_side(tiling_.TilePositionX(min_toss_x), |
+ old_tiling_rect_over_tiles.y(), |
+ tiling_.TileSizeX(min_toss_x), |
+ old_tiling_rect_over_tiles.height()); |
+ right_side.Subtract(interest_rect_over_tiles); |
+ resize_invalidation.Union(right_side); |
+ } |
+ if (min_toss_y < tiling_.num_tiles_y()) { |
+ gfx::Rect bottom_side(old_tiling_rect_over_tiles.x(), |
+ tiling_.TilePositionY(min_toss_y), |
+ old_tiling_rect_over_tiles.width(), |
+ tiling_.TileSizeY(min_toss_y)); |
+ bottom_side.Subtract(interest_rect_over_tiles); |
+ resize_invalidation.Union(bottom_side); |
+ } |
+ } |
+ } |
+ |
+ Region invalidation_expanded_to_full_tiles; |
for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) { |
gfx::Rect invalid_rect = i.rect(); |
+ |
+ // Expand invalidation that is outside tiles that intersect the interest |
+ // rect. These tiles are no longer valid and should be considerered fully |
+ // invalid, so we can know to not keep around raster tiles that intersect |
+ // with these recording tiles. |
+ gfx::Rect invalid_rect_outside_interest_rect_tiles = invalid_rect; |
+ // TODO(danakj): We should have a Rect-subtract-Rect-to-2-rects operator |
+ // instead of using Rect::Subtract which gives you the bounding box of the |
+ // subtraction. |
+ invalid_rect_outside_interest_rect_tiles.Subtract(interest_rect_over_tiles); |
+ invalidation_expanded_to_full_tiles.Union(tiling_.ExpandRectToTileBounds( |
+ invalid_rect_outside_interest_rect_tiles)); |
+ |
// Split this inflated invalidation across tile boundaries and apply it |
// to all tiles that it touches. |
bool include_borders = true; |
@@ -190,23 +272,18 @@ bool PicturePile::UpdateAndExpandInvalidation( |
continue; |
// Inform the grid cell that it has been invalidated in this frame. |
- invalidated = picture_it->second.Invalidate(frame_number) || invalidated; |
+ updated = picture_it->second.Invalidate(frame_number) || updated; |
+ // Invalidate drops the picture so the whole tile better be invalidated if |
+ // it won't be re-recorded below. |
+ DCHECK( |
+ tiling_.TileBounds(key.first, key.second).Intersects(interest_rect) || |
+ invalidation_expanded_to_full_tiles.Contains( |
+ tiling_.TileBounds(key.first, key.second))); |
} |
- |
- // Expand invalidation that is outside tiles that intersect the interest |
- // rect. These tiles are no longer valid and should be considerered fully |
- // invalid, so we can know to not keep around raster tiles that intersect |
- // with these recording tiles. |
- gfx::Rect invalid_rect_outside_interest_rect_tiles = invalid_rect; |
- // TODO(danakj): We should have a Rect-subtract-Rect-to-2-rects operator |
- // instead of using Rect::Subtract which gives you the bounding box of the |
- // subtraction. |
- invalid_rect_outside_interest_rect_tiles.Subtract(interest_rect_over_tiles); |
- invalidation_expanded_to_full_tiles.Union(tiling_.ExpandRectToTileBounds( |
- invalid_rect_outside_interest_rect_tiles)); |
} |
invalidation->Union(invalidation_expanded_to_full_tiles); |
+ invalidation->Union(resize_invalidation); |
// Make a list of all invalid tiles; we will attempt to |
// cluster these into multiple invalidation regions. |
@@ -244,7 +321,7 @@ bool PicturePile::UpdateAndExpandInvalidation( |
ClusterTiles(invalid_tiles, &record_rects); |
if (record_rects.empty()) |
- return invalidated; |
+ return updated; |
for (std::vector<gfx::Rect>::iterator it = record_rects.begin(); |
it != record_rects.end(); |
@@ -310,4 +387,11 @@ bool PicturePile::UpdateAndExpandInvalidation( |
return true; |
} |
+void PicturePile::SetEmptyBounds() { |
+ tiling_.SetTilingRect(gfx::Rect()); |
+ picture_map_.clear(); |
+ has_any_recordings_ = false; |
+ recorded_viewport_ = gfx::Rect(); |
+} |
+ |
} // namespace cc |