Index: cc/resources/picture_pile.cc |
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc |
index ae67cd482163bb5839f2a17961779246dd23e15d..8b933273a0245a8a9f03a7e4221cfb4d7c4422ea 100644 |
--- a/cc/resources/picture_pile.cc |
+++ b/cc/resources/picture_pile.cc |
@@ -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 interst rect has been expanded to the |
enne (OOO)
2014/08/25 20:06:16
typo
|
+ // 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); |
} |
} |