diff options
author | Alex Mineer <amineer@chromium.org> | 2014-11-19 10:43:30 -0800 |
---|---|---|
committer | Alex Mineer <amineer@chromium.org> | 2014-11-19 18:44:09 +0000 |
commit | 2ce5f1aa5a959994c6a13ea33b3f850a769ab80c (patch) | |
tree | 407a2d6bc9dbc648a6c718cd20e5241d3c0dea46 | |
parent | de1e82c991ee5b93a5dc87682b141fe6fa5b8306 (diff) | |
download | chromium_src-2ce5f1aa5a959994c6a13ea33b3f850a769ab80c.zip chromium_src-2ce5f1aa5a959994c6a13ea33b3f850a769ab80c.tar.gz chromium_src-2ce5f1aa5a959994c6a13ea33b3f850a769ab80c.tar.bz2 |
Revert "Revert "cc: Add invalidations when shrinking piles""
We can keep this in the M39 branch as it's high impact for WebView.
This reverts commit e606d6333c214baae2a39441701dd115ae8fa266.
Cr-Commit-Position: refs/branch-heads/2171@{#432}
Cr-Branched-From: 267aeeb8d85c8503a7fd12bd14654b8ea78d3974-refs/heads/master@{#297060}
-rw-r--r-- | cc/resources/picture_pile.cc | 99 | ||||
-rw-r--r-- | cc/resources/picture_pile_unittest.cc | 615 |
2 files changed, 418 insertions, 296 deletions
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc index ae2f8af..71a421d 100644 --- a/cc/resources/picture_pile.cc +++ b/cc/resources/picture_pile.cc @@ -189,21 +189,30 @@ bool PicturePile::UpdateAndExpandInvalidation( gfx::Rect interest_rect_over_tiles = tiling_.ExpandRectToTileBounds(interest_rect); + gfx::Size min_tiling_size( + std::min(tiling_size().width(), old_tiling_size.width()), + std::min(tiling_size().height(), old_tiling_size.height())); + gfx::Size max_tiling_size( + std::max(tiling_size().width(), old_tiling_size.width()), + std::max(tiling_size().height(), old_tiling_size.height())); + if (old_tiling_size != layer_size) { has_any_recordings_ = false; - // Drop recordings that are outside the new layer bounds or that changed - // size. + // Drop recordings that are outside the new or old layer bounds or that + // changed size. Newly exposed areas are considered invalidated. + // Previously exposed areas that are now outside of bounds also need to + // be invalidated, as they may become part of raster when scale < 1. std::vector<PictureMapKey> to_erase; int min_toss_x = tiling_.num_tiles_x(); - if (tiling_size().width() > old_tiling_size.width()) { + if (max_tiling_size.width() > min_tiling_size.width()) { min_toss_x = - tiling_.FirstBorderTileXIndexFromSrcCoord(old_tiling_size.width()); + tiling_.FirstBorderTileXIndexFromSrcCoord(min_tiling_size.width()); } int min_toss_y = tiling_.num_tiles_y(); - if (tiling_size().height() > old_tiling_size.height()) { + if (max_tiling_size.height() > min_tiling_size.height()) { min_toss_y = - tiling_.FirstBorderTileYIndexFromSrcCoord(old_tiling_size.height()); + tiling_.FirstBorderTileYIndexFromSrcCoord(min_tiling_size.height()); } for (PictureMap::const_iterator it = picture_map_.begin(); it != picture_map_.end(); @@ -222,20 +231,22 @@ bool PicturePile::UpdateAndExpandInvalidation( // If a recording is dropped and not re-recorded below, invalidate that // full recording to cause any raster tiles that would use it to be // dropped. - // If the recording will be replaced below, just invalidate newly exposed - // areas to force raster tiles that include the old recording to know - // there is new recording to display. - gfx::Rect old_tiling_rect_over_tiles = - tiling_.ExpandRectToTileBounds(gfx::Rect(old_tiling_size)); + // If the recording will be replaced below, invalidate newly exposed + // areas and previously exposed areas to force raster tiles that include the + // old recording to know there is new recording to display. + gfx::Rect min_tiling_rect_over_tiles = + tiling_.ExpandRectToTileBounds(gfx::Rect(min_tiling_size)); if (min_toss_x < tiling_.num_tiles_x()) { // 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. + // edge of the pile when expanding, or the new edge of the pile when + // shrinking. In either case, it's the difference of the two, so we'll + // call this bounding box the DELTA 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. + // In the picture below, the delta 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 + // min pile edge-v max pile edge-v // ---------------+ - - - - - - - -+ // mmppssvvyybbeeh|h . // mmppssvvyybbeeh|h . @@ -243,33 +254,33 @@ bool PicturePile::UpdateAndExpandInvalidation( // nnqqttwwzzccffi|i . // oorruuxxaaddggj|j . // oorruuxxaaddggj|j . - // ---------------+ - - - - - - - -+ <- old pile edge + // ---------------+ - - - - - - - -+ <- min pile edge // . - // - - - - - - - - - - - - - - - -+ <- new pile edge + // - - - - - - - - - - - - - - - -+ <- max 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 + // delta edge rect toward the right, it would either hit the right edge + // of the delta 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 + // any of the four edges, sliding across the delta 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 + // determine which part of the delta edge rect is outside of the expanded // interest rect. // - // Case 1: Intersect rect is outside the old edge rect. It can be + // Case 1: Intersect rect is outside the delta 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. + // delta edge rect. In the picture below, |left_rect| would cover the + // delta edge rect, and |right_rect| would be empty. // +----------------------+ |^^^^^^^^^^^^^^^| - // |===> OLD EDGE RECT | | | + // |===> DELTA 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 + // Case 2: Interest rect is inside the delta edge rect. It will always + // fill the entire delta 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| @@ -286,19 +297,19 @@ bool PicturePile::UpdateAndExpandInvalidation( // | | // +-----------------+ // | | - // | OLD EDGE RECT | + // | DELTA 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 + // pixels. In the picture below the tiles in the delta 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 + // v-min pile edge // +---------+-------+ // | ........| // | ........| - // | OLD EDGE.RECT..| + // | DELTA EDGE.RECT.| // | ........| // | ........| // | ........| @@ -309,18 +320,18 @@ bool PicturePile::UpdateAndExpandInvalidation( 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 top = min_tiling_rect_over_tiles.y(); + int bottom = min_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 exposed_left_until = tiling_size().width(); + int exposed_left = min_tiling_size.width(); + int exposed_left_until = max_tiling_size.width(); int exposed_top = top; - int exposed_bottom = tiling_size().height(); + int exposed_bottom = max_tiling_size.height(); DCHECK_GE(exposed_left, left); gfx::Rect left_rect(left, top, left_until - left, bottom - top); @@ -340,23 +351,23 @@ bool PicturePile::UpdateAndExpandInvalidation( } if (min_toss_y < tiling_.num_tiles_y()) { // 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 + // rect is the bounding box around the bottom row of tiles in the min // 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 left = min_tiling_rect_over_tiles.x(); + int right = min_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 exposed_top_until = tiling_size().height(); + int exposed_top = min_tiling_size.height(); + int exposed_top_until = max_tiling_size.height(); int exposed_left = left; - int exposed_right = tiling_size().width(); + int exposed_right = max_tiling_size.width(); DCHECK_GE(exposed_top, top); gfx::Rect left_rect(left, top, left_until - left, bottom - top); diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc index 5143b44..c9bc063 100644 --- a/cc/resources/picture_pile_unittest.cc +++ b/cc/resources/picture_pile_unittest.cc @@ -614,11 +614,11 @@ TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { } UpdateAndExpandInvalidation( - &invalidation, - grow_down_tiling_size, + &invalidation, grow_down_tiling_size, CornerSinglePixelRect(corner, grow_down_tiling_size)); - // We should have lost the recordings in the bottom row. + // We should have lost all of the recordings in the bottom row as none of them + // are in the current interest rect (which is either the above or below it). EXPECT_EQ(6, pile_->tiling().num_tiles_x()); EXPECT_EQ(8, pile_->tiling().num_tiles_y()); for (int i = 0; i < 6; ++i) { @@ -643,11 +643,11 @@ TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { invalidation.Clear(); UpdateWholePile(); - UpdateAndExpandInvalidation(&invalidation, - base_tiling_size, + UpdateAndExpandInvalidation(&invalidation, base_tiling_size, CornerSinglePixelRect(corner, base_tiling_size)); - // We should have lost the recordings that are now outside the tiling only. + // When shrinking, we should have lost all the recordings in the bottom row + // not touching the interest rect. EXPECT_EQ(6, pile_->tiling().num_tiles_x()); EXPECT_EQ(6, pile_->tiling().num_tiles_y()); for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { @@ -655,22 +655,60 @@ TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { TestPicturePile::PictureMapKey key(i, j); TestPicturePile::PictureMap& map = pile_->picture_map(); TestPicturePile::PictureMap::iterator it = map.find(key); - EXPECT_EQ(j < 6, it != map.end() && it->second.GetPicture()); + bool expect_tile; + switch (corner) { + case TOP_LEFT: + case TOP_RIGHT: + expect_tile = j < 5; + break; + case BOTTOM_LEFT: + // The interest rect in the bottom left tile means we'll record it. + expect_tile = j < 5 || (j == 5 && i == 0); + break; + case BOTTOM_RIGHT: + // The interest rect in the bottom right tile means we'll record it. + expect_tile = j < 5 || (j == 5 && i == 5); + break; + } + EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); } } - // No invalidation when shrinking. - expected_invalidation.Clear(); + // When shrinking, the previously exposed region is invalidated. + expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size), + gfx::Rect(base_tiling_size)); + // The whole bottom row of tiles (except any with the interest rect) are + // dropped. + gfx::Rect bottom_row_minus_existing_corner = gfx::UnionRects( + pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(5, 5)); + switch (corner) { + case TOP_LEFT: + case TOP_RIGHT: + // No tiles are kept in the changed region because it doesn't + // intersect with the interest rect. + break; + case BOTTOM_LEFT: + bottom_row_minus_existing_corner.Subtract( + pile_->tiling().TileBounds(0, 5)); + break; + case BOTTOM_RIGHT: + bottom_row_minus_existing_corner.Subtract( + pile_->tiling().TileBounds(5, 5)); + break; + } + + expected_invalidation.Union(bottom_row_minus_existing_corner); EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); UpdateWholePile(); UpdateAndExpandInvalidation( - &invalidation, - grow_right_tiling_size, + &invalidation, grow_right_tiling_size, CornerSinglePixelRect(corner, grow_right_tiling_size)); - // We should have lost the recordings in the right column. + // We should have lost all of the recordings in the right column as none of + // them are in the current interest rect (which is either entirely left or + // right of it). EXPECT_EQ(8, pile_->tiling().num_tiles_x()); EXPECT_EQ(6, pile_->tiling().num_tiles_y()); for (int i = 0; i < 6; ++i) { @@ -695,11 +733,11 @@ TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { invalidation.Clear(); UpdateWholePile(); - UpdateAndExpandInvalidation(&invalidation, - base_tiling_size, + UpdateAndExpandInvalidation(&invalidation, base_tiling_size, CornerSinglePixelRect(corner, base_tiling_size)); - // We should have lost the recordings that are now outside the tiling only. + // When shrinking, we should have lost all the recordings in the right column + // not touching the interest rect. EXPECT_EQ(6, pile_->tiling().num_tiles_x()); EXPECT_EQ(6, pile_->tiling().num_tiles_y()); for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { @@ -707,19 +745,54 @@ TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { TestPicturePile::PictureMapKey key(i, j); TestPicturePile::PictureMap& map = pile_->picture_map(); TestPicturePile::PictureMap::iterator it = map.find(key); - EXPECT_EQ(i < 6, it != map.end() && it->second.GetPicture()); + bool expect_tile; + switch (corner) { + case TOP_LEFT: + case BOTTOM_LEFT: + // No tiles are kept in the changed region because it doesn't + // intersect with the interest rect. + expect_tile = i < 5; + break; + case TOP_RIGHT: + // The interest rect in the top right tile means we'll record it. + expect_tile = i < 5 || (j == 0 && i == 5); + break; + case BOTTOM_RIGHT: + // The interest rect in the bottom right tile means we'll record it. + expect_tile = i < 5 || (j == 5 && i == 5); + break; + } + EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); } } - // No invalidation when shrinking. - expected_invalidation.Clear(); + // When shrinking, the previously exposed region is invalidated. + expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size), + gfx::Rect(base_tiling_size)); + // The whole right column of tiles (except for ones with the interest rect) + // are dropped. + gfx::Rect right_column_minus_existing_corner = gfx::UnionRects( + pile_->tiling().TileBounds(5, 0), pile_->tiling().TileBounds(5, 5)); + switch (corner) { + case TOP_LEFT: + case BOTTOM_LEFT: + break; + case TOP_RIGHT: + right_column_minus_existing_corner.Subtract( + pile_->tiling().TileBounds(5, 0)); + break; + case BOTTOM_RIGHT: + right_column_minus_existing_corner.Subtract( + pile_->tiling().TileBounds(5, 5)); + break; + } + expected_invalidation.Union(right_column_minus_existing_corner); EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); UpdateWholePile(); UpdateAndExpandInvalidation( - &invalidation, - grow_both_tiling_size, + &invalidation, grow_both_tiling_size, CornerSinglePixelRect(corner, grow_both_tiling_size)); // We should have lost the recordings in the right column and bottom row. @@ -737,7 +810,7 @@ TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { // We invalidated all new pixels in the recording. expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size), gfx::Rect(base_tiling_size)); - // But the new pixels don't cover the whole right_column. + // But the new pixels don't cover the whole right column or bottom row. Region right_column_and_bottom_row = UnionRegions(gfx::UnionRects(pile_->tiling().TileBounds(5, 0), pile_->tiling().TileBounds(5, 5)), @@ -750,9 +823,11 @@ TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { invalidation.Clear(); UpdateWholePile(); - UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect()); + UpdateAndExpandInvalidation(&invalidation, base_tiling_size, + CornerSinglePixelRect(corner, base_tiling_size)); - // We should have lost the recordings that are now outside the tiling only. + // We should have lost the recordings in the right column and bottom row, + // except where it intersects the interest rect. EXPECT_EQ(6, pile_->tiling().num_tiles_x()); EXPECT_EQ(6, pile_->tiling().num_tiles_y()); for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { @@ -760,12 +835,54 @@ TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { TestPicturePile::PictureMapKey key(i, j); TestPicturePile::PictureMap& map = pile_->picture_map(); TestPicturePile::PictureMap::iterator it = map.find(key); - EXPECT_EQ(i < 6 && j < 6, it != map.end() && it->second.GetPicture()); + bool expect_tile; + switch (corner) { + case TOP_LEFT: + expect_tile = i < 5 && j < 5; + break; + case TOP_RIGHT: + // The interest rect in the top right tile means we'll record it. + expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5); + break; + case BOTTOM_LEFT: + // The interest rect in the bottom left tile means we'll record it. + expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0); + break; + case BOTTOM_RIGHT: + // The interest rect in the bottom right tile means we'll record it. + expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5); + break; + } + EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()) + << i << "," << j; } } - // No invalidation when shrinking. - expected_invalidation.Clear(); + // We invalidated all previous pixels in the recording. + expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size), + gfx::Rect(base_tiling_size)); + // The whole right column and bottom row of tiles (except for ones with the + // interest rect) are dropped. + Region right_column_and_bottom_row_minus_existing_corner = + right_column_and_bottom_row; + switch (corner) { + case TOP_LEFT: + break; + case BOTTOM_LEFT: + right_column_and_bottom_row_minus_existing_corner.Subtract( + pile_->tiling().TileBounds(0, 5)); + break; + case TOP_RIGHT: + right_column_and_bottom_row_minus_existing_corner.Subtract( + pile_->tiling().TileBounds(5, 0)); + break; + case BOTTOM_RIGHT: + right_column_and_bottom_row_minus_existing_corner.Subtract( + pile_->tiling().TileBounds(5, 5)); + break; + } + expected_invalidation.Union( + right_column_and_bottom_row_minus_existing_corner); EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); } @@ -805,261 +922,238 @@ TEST_P(PicturePileResizeCornerTest, SmallResizePileOutsideInterestRect) { } } - UpdateAndExpandInvalidation( - &invalidation, - grow_down_tiling_size, - CornerSinglePixelRect(corner, grow_down_tiling_size)); + // In this test (unlike the large resize test), as all growing and shrinking + // happens within tiles, the resulting invalidation is symmetrical, so use + // this enum to repeat the test both ways. + enum ChangeDirection { GROW, SHRINK, LAST_DIRECTION = SHRINK }; - // We should have lost the recordings in the bottom row that do not intersect - // the interest rect. - EXPECT_EQ(6, pile_->tiling().num_tiles_x()); - EXPECT_EQ(6, pile_->tiling().num_tiles_y()); - for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { - for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { - TestPicturePile::PictureMapKey key(i, j); - TestPicturePile::PictureMap& map = pile_->picture_map(); - TestPicturePile::PictureMap::iterator it = map.find(key); - bool expect_tile; + // Grow downward. + for (int dir = 0; dir <= LAST_DIRECTION; ++dir) { + gfx::Size new_tiling_size = + dir == GROW ? grow_down_tiling_size : base_tiling_size; + UpdateWholePile(); + UpdateAndExpandInvalidation(&invalidation, new_tiling_size, + CornerSinglePixelRect(corner, new_tiling_size)); + + // We should have lost the recordings in the bottom row that do not + // intersect the interest rect. + EXPECT_EQ(6, pile_->tiling().num_tiles_x()); + EXPECT_EQ(6, pile_->tiling().num_tiles_y()); + for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { + for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { + TestPicturePile::PictureMapKey key(i, j); + TestPicturePile::PictureMap& map = pile_->picture_map(); + TestPicturePile::PictureMap::iterator it = map.find(key); + bool expect_tile; + switch (corner) { + case TOP_LEFT: + case TOP_RIGHT: + expect_tile = j < 5; + break; + case BOTTOM_LEFT: + // The interest rect in the bottom left tile means we'll record it. + expect_tile = j < 5 || (j == 5 && i == 0); + break; + case BOTTOM_RIGHT: + // The interest rect in the bottom right tile means we'll record it. + expect_tile = j < 5 || (j == 5 && i == 5); + break; + } + EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); + } + } + + // We invalidated the bottom row outside the new interest rect. The tile + // that insects the interest rect in invalidated only on its newly + // exposed or previously exposed pixels. + if (dir == GROW) { + // Only calculate the expected invalidation while growing, as the tile + // bounds post-growing is the newly exposed / previously exposed sizes. + // Post-shrinking, the tile bounds are smaller, so can't be used. switch (corner) { case TOP_LEFT: case TOP_RIGHT: - expect_tile = j < 5; + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(0, 5), + pile_->tiling().TileBounds(5, 5)); break; case BOTTOM_LEFT: - // The interest rect in the bottom left tile means we'll record it. - expect_tile = j < 5 || (j == 5 && i == 0); + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(1, 5), + pile_->tiling().TileBounds(5, 5)); + expected_invalidation.Union(SubtractRects( + pile_->tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size))); break; case BOTTOM_RIGHT: - // The interest rect in the bottom right tile means we'll record it. - expect_tile = j < 5 || (j == 5 && i == 5); + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(0, 5), + pile_->tiling().TileBounds(4, 5)); + expected_invalidation.Union(SubtractRects( + pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size))); break; } - EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); } + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); + invalidation.Clear(); } - // We invalidated the bottom row outside the new interest rect. The tile that - // insects the interest rect in invalidated only on its new pixels. - switch (corner) { - case TOP_LEFT: - case TOP_RIGHT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(0, 5), - pile_->tiling().TileBounds(5, 5)); - break; - case BOTTOM_LEFT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(1, 5), - pile_->tiling().TileBounds(5, 5)); - expected_invalidation.Union(SubtractRects( - pile_->tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size))); - break; - case BOTTOM_RIGHT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(0, 5), - pile_->tiling().TileBounds(4, 5)); - expected_invalidation.Union(SubtractRects( - pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size))); - break; - } - EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); - invalidation.Clear(); - - UpdateWholePile(); - UpdateAndExpandInvalidation(&invalidation, - base_tiling_size, - CornerSinglePixelRect(corner, base_tiling_size)); - - // We should have lost nothing. - EXPECT_EQ(6, pile_->tiling().num_tiles_x()); - EXPECT_EQ(6, pile_->tiling().num_tiles_y()); - for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { - for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { - TestPicturePile::PictureMapKey key(i, j); - TestPicturePile::PictureMap& map = pile_->picture_map(); - TestPicturePile::PictureMap::iterator it = map.find(key); - EXPECT_TRUE(it != map.end() && it->second.GetPicture()); + // Grow right. + for (int dir = 0; dir <= LAST_DIRECTION; ++dir) { + gfx::Size new_tiling_size = + dir == GROW ? grow_right_tiling_size : base_tiling_size; + UpdateWholePile(); + UpdateAndExpandInvalidation(&invalidation, new_tiling_size, + CornerSinglePixelRect(corner, new_tiling_size)); + + // We should have lost the recordings in the right column. + EXPECT_EQ(6, pile_->tiling().num_tiles_x()); + EXPECT_EQ(6, pile_->tiling().num_tiles_y()); + for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { + for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { + TestPicturePile::PictureMapKey key(i, j); + TestPicturePile::PictureMap& map = pile_->picture_map(); + TestPicturePile::PictureMap::iterator it = map.find(key); + bool expect_tile; + switch (corner) { + case TOP_LEFT: + case BOTTOM_LEFT: + expect_tile = i < 5; + break; + case TOP_RIGHT: + // The interest rect in the top right tile means we'll record it. + expect_tile = i < 5 || (j == 0 && i == 5); + break; + case BOTTOM_RIGHT: + // The interest rect in the bottom right tile means we'll record it. + expect_tile = i < 5 || (j == 5 && i == 5); + break; + } + EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); + } } - } - // We invalidated nothing. - expected_invalidation.Clear(); - EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); - invalidation.Clear(); - - UpdateWholePile(); - UpdateAndExpandInvalidation( - &invalidation, - grow_right_tiling_size, - CornerSinglePixelRect(corner, grow_right_tiling_size)); - - // We should have lost the recordings in the right column. - EXPECT_EQ(6, pile_->tiling().num_tiles_x()); - EXPECT_EQ(6, pile_->tiling().num_tiles_y()); - for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { - for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { - TestPicturePile::PictureMapKey key(i, j); - TestPicturePile::PictureMap& map = pile_->picture_map(); - TestPicturePile::PictureMap::iterator it = map.find(key); - bool expect_tile; + // We invalidated the right column outside the new interest rect. The tile + // that insects the interest rect in invalidated only on its new or + // previously exposed pixels. + if (dir == GROW) { + // Calculate the expected invalidation the first time through the loop. switch (corner) { case TOP_LEFT: case BOTTOM_LEFT: - expect_tile = i < 5; + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(5, 0), + pile_->tiling().TileBounds(5, 5)); break; case TOP_RIGHT: - // The interest rect in the top right tile means we'll record it. - expect_tile = i < 5 || (j == 0 && i == 5); + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(5, 1), + pile_->tiling().TileBounds(5, 5)); + expected_invalidation.Union(SubtractRects( + pile_->tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size))); break; case BOTTOM_RIGHT: - // The interest rect in the bottom right tile means we'll record it. - expect_tile = i < 5 || (j == 5 && i == 5); + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(5, 0), + pile_->tiling().TileBounds(5, 4)); + expected_invalidation.Union(SubtractRects( + pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size))); break; } - EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); } + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); + invalidation.Clear(); } - // We invalidated the right column outside the new interest rect. The tile - // that insects the interest rect in invalidated only on its new pixels. - switch (corner) { - case TOP_LEFT: - case BOTTOM_LEFT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0), - pile_->tiling().TileBounds(5, 5)); - break; - case TOP_RIGHT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 1), - pile_->tiling().TileBounds(5, 5)); - expected_invalidation.Union(SubtractRects( - pile_->tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size))); - break; - case BOTTOM_RIGHT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0), - pile_->tiling().TileBounds(5, 4)); - expected_invalidation.Union(SubtractRects( - pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size))); - break; - } - EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); - invalidation.Clear(); - - UpdateWholePile(); - UpdateAndExpandInvalidation(&invalidation, - base_tiling_size, - CornerSinglePixelRect(corner, base_tiling_size)); - - // We should have lost nothing. - EXPECT_EQ(6, pile_->tiling().num_tiles_x()); - EXPECT_EQ(6, pile_->tiling().num_tiles_y()); - for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { - for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { - TestPicturePile::PictureMapKey key(i, j); - TestPicturePile::PictureMap& map = pile_->picture_map(); - TestPicturePile::PictureMap::iterator it = map.find(key); - EXPECT_TRUE(it != map.end() && it->second.GetPicture()); + // Grow both. + for (int dir = 0; dir <= LAST_DIRECTION; ++dir) { + gfx::Size new_tiling_size = + dir == GROW ? grow_both_tiling_size : base_tiling_size; + UpdateWholePile(); + UpdateAndExpandInvalidation(&invalidation, new_tiling_size, + CornerSinglePixelRect(corner, new_tiling_size)); + + // We should have lost the recordings in the right column and bottom row. + // The tile that insects the interest rect in invalidated only on its new + // or previously exposed pixels. + EXPECT_EQ(6, pile_->tiling().num_tiles_x()); + EXPECT_EQ(6, pile_->tiling().num_tiles_y()); + for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { + for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { + TestPicturePile::PictureMapKey key(i, j); + TestPicturePile::PictureMap& map = pile_->picture_map(); + TestPicturePile::PictureMap::iterator it = map.find(key); + bool expect_tile; + switch (corner) { + case TOP_LEFT: + expect_tile = i < 5 && j < 5; + break; + case TOP_RIGHT: + // The interest rect in the top right tile means we'll record it. + expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5); + break; + case BOTTOM_LEFT: + // The interest rect in the bottom left tile means we'll record it. + expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0); + break; + case BOTTOM_RIGHT: + // The interest rect in the bottom right tile means we'll record it. + expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5); + break; + } + EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()) + << i << "," << j; + } } - } - - // We invalidated nothing. - expected_invalidation.Clear(); - EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); - invalidation.Clear(); - - UpdateWholePile(); - UpdateAndExpandInvalidation( - &invalidation, - grow_both_tiling_size, - CornerSinglePixelRect(corner, grow_both_tiling_size)); - // We should have lost the recordings in the right column and bottom row. The - // tile that insects the interest rect in invalidated only on its new pixels. - EXPECT_EQ(6, pile_->tiling().num_tiles_x()); - EXPECT_EQ(6, pile_->tiling().num_tiles_y()); - for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { - for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { - TestPicturePile::PictureMapKey key(i, j); - TestPicturePile::PictureMap& map = pile_->picture_map(); - TestPicturePile::PictureMap::iterator it = map.find(key); - bool expect_tile; + // We invalidated the right column and the bottom row outside the new + // interest rect. The tile that insects the interest rect in invalidated + // only on its new or previous exposed pixels. + if (dir == GROW) { + // Calculate the expected invalidation the first time through the loop. switch (corner) { case TOP_LEFT: - expect_tile = i < 5 && j < 5; + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(5, 0), + pile_->tiling().TileBounds(5, 5)); + expected_invalidation.Union( + gfx::UnionRects(pile_->tiling().TileBounds(0, 5), + pile_->tiling().TileBounds(5, 5))); break; case TOP_RIGHT: - // The interest rect in the top right tile means we'll record it. - expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5); + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(5, 1), + pile_->tiling().TileBounds(5, 5)); + expected_invalidation.Union( + gfx::UnionRects(pile_->tiling().TileBounds(0, 5), + pile_->tiling().TileBounds(5, 5))); + expected_invalidation.Union(SubtractRects( + pile_->tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size))); break; case BOTTOM_LEFT: - // The interest rect in the bottom left tile means we'll record it. - expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0); + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(5, 0), + pile_->tiling().TileBounds(5, 5)); + expected_invalidation.Union( + gfx::UnionRects(pile_->tiling().TileBounds(1, 5), + pile_->tiling().TileBounds(5, 5))); + expected_invalidation.Union(SubtractRects( + pile_->tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size))); break; case BOTTOM_RIGHT: - // The interest rect in the bottom right tile means we'll record it. - expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5); + expected_invalidation = + gfx::UnionRects(pile_->tiling().TileBounds(5, 0), + pile_->tiling().TileBounds(5, 4)); + expected_invalidation.Union( + gfx::UnionRects(pile_->tiling().TileBounds(0, 5), + pile_->tiling().TileBounds(4, 5))); + expected_invalidation.Union(SubtractRegions( + pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size))); break; } - EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()) - << i << "," << j; } + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); + invalidation.Clear(); } - - // We invalidated the right column and the bottom row outside the new interest - // rect. The tile that insects the interest rect in invalidated only on its - // new pixels. - switch (corner) { - case TOP_LEFT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0), - pile_->tiling().TileBounds(5, 5)); - expected_invalidation.Union(gfx::UnionRects( - pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(5, 5))); - break; - case TOP_RIGHT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 1), - pile_->tiling().TileBounds(5, 5)); - expected_invalidation.Union(gfx::UnionRects( - pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(5, 5))); - expected_invalidation.Union(SubtractRects( - pile_->tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size))); - break; - case BOTTOM_LEFT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0), - pile_->tiling().TileBounds(5, 5)); - expected_invalidation.Union(gfx::UnionRects( - pile_->tiling().TileBounds(1, 5), pile_->tiling().TileBounds(5, 5))); - expected_invalidation.Union(SubtractRects( - pile_->tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size))); - break; - case BOTTOM_RIGHT: - expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0), - pile_->tiling().TileBounds(5, 4)); - expected_invalidation.Union(gfx::UnionRects( - pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(4, 5))); - expected_invalidation.Union(SubtractRegions( - pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size))); - break; - } - EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); - invalidation.Clear(); - - UpdateWholePile(); - UpdateAndExpandInvalidation(&invalidation, - base_tiling_size, - CornerSinglePixelRect(corner, base_tiling_size)); - - // We should have lost nothing. - EXPECT_EQ(6, pile_->tiling().num_tiles_x()); - EXPECT_EQ(6, pile_->tiling().num_tiles_y()); - for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) { - for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) { - TestPicturePile::PictureMapKey key(i, j); - TestPicturePile::PictureMap& map = pile_->picture_map(); - TestPicturePile::PictureMap::iterator it = map.find(key); - EXPECT_TRUE(it != map.end() && it->second.GetPicture()); - } - } - - // We invalidated nothing. - expected_invalidation.Clear(); - EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); - invalidation.Clear(); } INSTANTIATE_TEST_CASE_P( @@ -1136,8 +1230,11 @@ TEST_F(PicturePileTest, ResizePileInsideInterestRect) { } } - // No invalidation when shrinking. - EXPECT_EQ(Region().ToString(), invalidation.ToString()); + // We invalidated the previously exposed pixels on the bottom row of tiles. + expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size), + gfx::Rect(base_tiling_size)); + EXPECT_TRUE(expected_invalidation.Contains(bottom_row_new_pixels)); + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); UpdateWholePile(); @@ -1182,8 +1279,11 @@ TEST_F(PicturePileTest, ResizePileInsideInterestRect) { } } - // No invalidation when shrinking. - EXPECT_EQ(Region().ToString(), invalidation.ToString()); + // We invalidated the previously exposed pixels on the right column of tiles. + expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size), + gfx::Rect(base_tiling_size)); + EXPECT_TRUE(expected_invalidation.Contains(right_column_new_pixels)); + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); UpdateWholePile(); @@ -1232,8 +1332,13 @@ TEST_F(PicturePileTest, ResizePileInsideInterestRect) { } } - // No invalidation when shrinking. - EXPECT_EQ(Region().ToString(), invalidation.ToString()); + // We invalidated the previously exposed pixels on the bottom row and right + // column of tiles. + expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size), + gfx::Rect(base_tiling_size)); + EXPECT_TRUE( + expected_invalidation.Contains(bottom_row_and_right_column_new_pixels)); + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); } @@ -1301,8 +1406,10 @@ TEST_F(PicturePileTest, SmallResizePileInsideInterestRect) { } } - // No invalidation when shrinking. - EXPECT_EQ(Region().ToString(), invalidation.ToString()); + // We invalidated the previously exposed pixels. + expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size), + gfx::Rect(base_tiling_size)); + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); UpdateWholePile(); @@ -1342,8 +1449,10 @@ TEST_F(PicturePileTest, SmallResizePileInsideInterestRect) { } } - // No invalidation when shrinking. - EXPECT_EQ(Region().ToString(), invalidation.ToString()); + // We invalidated the previously exposed pixels. + expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size), + gfx::Rect(base_tiling_size)); + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); UpdateWholePile(); @@ -1383,8 +1492,10 @@ TEST_F(PicturePileTest, SmallResizePileInsideInterestRect) { } } - // No invalidation when shrinking. - EXPECT_EQ(Region().ToString(), invalidation.ToString()); + // We invalidated the previously exposed pixels. + expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size), + gfx::Rect(base_tiling_size)); + EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); invalidation.Clear(); } |