Commit d27cb086 authored by danakj's avatar danakj Committed by Commit bot

cc: Fix CanRaster dcheck failures ONCE AND FOR ALL.

When a PicturePile grows along either axis, the tiles on the edge where
it grew are dropped if any new pixels are added to their recordings.
This means that we need to invalidate them to inform the impl side
about the recording being dropped.

However, if we're going to re-record the tile (it intersects the
interest_rect), then there's no need to invalidate it as the old
recorded pixels remain valid.

Previously we made the assumption that when a PicturePile resized, the
interest rect's center would be to the left and above the old edge of
the pile. However, the interest rect can move at the same time as the
pile is resized, and it can live anywhere with respect to the recording
tiles being dropped.

So we invalidate everything inside the row/column of tiles that were
dropped that is outside of the interest rect by invalidating on all
four sides of the interest rect, but clamping the resulting invalidation
rects to within the dropped tiles row/column.

R=enne
BUG=386998

Review URL: https://codereview.chromium.org/504513002

Cr-Commit-Position: refs/heads/master@{#291762}
parent 7aad4986
......@@ -226,34 +226,143 @@ bool PicturePile::UpdateAndExpandInvalidation(
gfx::Rect old_tiling_rect_over_tiles =
tiling_.ExpandRectToTileBounds(gfx::Rect(old_tiling_size));
if (min_toss_x < tiling_.num_tiles_x()) {
int unrecorded_left = std::max(tiling_.TilePositionX(min_toss_x),
interest_rect_over_tiles.right());
// The bounds which we want to invalidate are the tiles along the old
// edge of the pile. We'll call this bounding box the OLD EDGE RECT.
//
// In the picture below, the old edge rect would be the bounding box
// of tiles {h,i,j}. |min_toss_x| would be equal to the horizontal index
// of the same tiles.
//
// old pile edge-v new pile edge-v
// ---------------+ - - - - - - - -+
// mmppssvvyybbeeh|h .
// mmppssvvyybbeeh|h .
// nnqqttwwzzccffi|i .
// nnqqttwwzzccffi|i .
// oorruuxxaaddggj|j .
// oorruuxxaaddggj|j .
// ---------------+ - - - - - - - -+ <- old pile edge
// .
// - - - - - - - - - - - - - - - -+ <- new pile edge
//
// If you were to slide a vertical beam from the left edge of the
// old edge rect toward the right, it would either hit the right edge
// of the old edge rect, or the interest rect (expanded to the bounds
// of the tiles it touches). The same is true for a beam parallel to
// any of the four edges, sliding accross the old edge rect. We use
// the union of these four rectangles generated by these beams to
// determine which part of the old edge rect is outside of the expanded
// interest rect.
//
// Case 1: Intersect rect is outside the old edge rect. It can be
// either on the left or the right. The |left_rect| and |right_rect|,
// cover this case, one will be empty and one will cover the full
// old edge rect. In the picture below, |left_rect| would cover the
// old edge rect, and |right_rect| would be empty.
// +----------------------+ |^^^^^^^^^^^^^^^|
// |===> OLD EDGE RECT | | |
// |===> | | INTEREST RECT |
// |===> | | |
// |===> | | |
// +----------------------+ |vvvvvvvvvvvvvvv|
//
// Case 2: Interest rect is inside the old edge rect. It will always
// fill the entire old edge rect horizontally since the old edge rect
// is a single tile wide, and the interest rect has been expanded to the
// bounds of the tiles it touches. In this case the |left_rect| and
// |right_rect| will be empty, but the case is handled by the |top_rect|
// and |bottom_rect|. In the picture below, neither the |top_rect| nor
// |bottom_rect| would empty, they would each cover the area of the old
// edge rect outside the expanded interest rect.
// +-----------------+
// |:::::::::::::::::|
// |:::::::::::::::::|
// |vvvvvvvvvvvvvvvvv|
// | |
// +-----------------+
// | INTEREST RECT |
// | |
// +-----------------+
// | |
// | OLD EDGE RECT |
// +-----------------+
//
// Lastly, we need to consider tiles inside the expanded interest rect.
// For those tiles, we want to invalidate exactly the newly exposed
// pixels. In the picture below the tiles in the old edge rect have been
// resized and the area covered by periods must be invalidated. The
// |exposed_rect| will cover exactly that area.
// v-old pile edge
// +---------+-------+
// | ........|
// | ........|
// | OLD EDGE.RECT..|
// | ........|
// | ........|
// | ........|
// | ........|
// | ........|
// | ........|
// +---------+-------+
int left = tiling_.TilePositionX(min_toss_x);
int right = left + tiling_.TileSizeX(min_toss_x);
int top = old_tiling_rect_over_tiles.y();
int bottom = old_tiling_rect_over_tiles.bottom();
int left_until = std::min(interest_rect_over_tiles.x(), right);
int right_until = std::max(interest_rect_over_tiles.right(), left);
int top_until = std::min(interest_rect_over_tiles.y(), bottom);
int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
int exposed_left = old_tiling_size.width();
int left = std::min(unrecorded_left, exposed_left);
int tile_right =
tiling_.TilePositionX(min_toss_x) + tiling_.TileSizeX(min_toss_x);
int exposed_right = tiling_size().width();
int right = std::min(tile_right, exposed_right);
gfx::Rect right_side(left,
old_tiling_rect_over_tiles.y(),
right - left,
old_tiling_rect_over_tiles.height());
resize_invalidation.Union(right_side);
int exposed_left_until = right;
DCHECK_GE(exposed_left, left);
gfx::Rect left_rect(left, top, left_until - left, bottom - top);
gfx::Rect right_rect(right_until, top, right - right_until, bottom - top);
gfx::Rect top_rect(left, top, right - left, top_until - top);
gfx::Rect bottom_rect(
left, bottom_until, right - left, bottom - bottom_until);
gfx::Rect exposed_rect(
exposed_left, top, exposed_left_until - exposed_left, bottom - top);
resize_invalidation.Union(left_rect);
resize_invalidation.Union(right_rect);
resize_invalidation.Union(top_rect);
resize_invalidation.Union(bottom_rect);
resize_invalidation.Union(exposed_rect);
}
if (min_toss_y < tiling_.num_tiles_y()) {
int unrecorded_top = std::max(tiling_.TilePositionY(min_toss_y),
interest_rect_over_tiles.bottom());
// The same thing occurs here as in the case above, but the invalidation
// rect is the bounding box around the bottom row of tiles in the old
// pile. This would be tiles {o,r,u,x,a,d,g,j} in the above picture.
int top = tiling_.TilePositionY(min_toss_y);
int bottom = top + tiling_.TileSizeY(min_toss_y);
int left = old_tiling_rect_over_tiles.x();
int right = old_tiling_rect_over_tiles.right();
int top_until = std::min(interest_rect_over_tiles.y(), bottom);
int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
int left_until = std::min(interest_rect_over_tiles.x(), right);
int right_until = std::max(interest_rect_over_tiles.right(), left);
int exposed_top = old_tiling_size.height();
int top = std::min(unrecorded_top, exposed_top);
int tile_bottom =
tiling_.TilePositionY(min_toss_y) + tiling_.TileSizeY(min_toss_y);
int exposed_bottom = tiling_size().height();
int bottom = std::min(tile_bottom, exposed_bottom);
gfx::Rect bottom_side(old_tiling_rect_over_tiles.x(),
top,
old_tiling_rect_over_tiles.width(),
bottom - top);
resize_invalidation.Union(bottom_side);
int exposed_top_until = bottom;
DCHECK_GE(exposed_top, top);
gfx::Rect left_rect(left, top, left_until - left, bottom - top);
gfx::Rect right_rect(right_until, top, right - right_until, bottom - top);
gfx::Rect top_rect(left, top, right - left, top_until - top);
gfx::Rect bottom_rect(
left, bottom_until, right - left, bottom - bottom_until);
gfx::Rect exposed_rect(
left, exposed_top, right - left, exposed_top_until - exposed_top);
resize_invalidation.Union(left_rect);
resize_invalidation.Union(right_rect);
resize_invalidation.Union(top_rect);
resize_invalidation.Union(bottom_rect);
resize_invalidation.Union(exposed_rect);
}
}
......
This diff is collapsed.
......@@ -134,6 +134,7 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> {
void set_picture_pile(scoped_refptr<PicturePileImpl> pile) {
DCHECK(pile->CanRaster(contents_scale_, content_rect_))
<< "Recording rect: "
<< gfx::ScaleToEnclosingRect(content_rect_, 1.f / contents_scale_)
.ToString();
picture_pile_ = pile;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment