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);
}
}
......
......@@ -36,9 +36,9 @@ class TestPicturePile : public PicturePile {
virtual ~TestPicturePile() {}
};
class PicturePileTest : public testing::Test {
class PicturePileTestBase {
public:
PicturePileTest()
PicturePileTestBase()
: pile_(new TestPicturePile()),
background_color_(SK_ColorBLUE),
min_scale_(0.125),
......@@ -91,6 +91,8 @@ class PicturePileTest : public testing::Test {
bool contents_opaque_;
};
class PicturePileTest : public PicturePileTestBase, public testing::Test {};
TEST_F(PicturePileTest, SmallInvalidateInflated) {
// Invalidate something inside a tile.
Region invalidate_rect(gfx::Rect(50, 50, 1, 1));
......@@ -384,14 +386,48 @@ TEST_F(PicturePileTest, InvalidationOutsideRecordingRect) {
EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
}
TEST_F(PicturePileTest, ResizePileOutsideInterestRect) {
enum Corner {
TOP_LEFT,
TOP_RIGHT,
BOTTOM_LEFT,
BOTTOM_RIGHT,
};
class PicturePileResizeCornerTest : public PicturePileTestBase,
public testing::TestWithParam<Corner> {
protected:
static gfx::Rect CornerSinglePixelRect(Corner corner, const gfx::Size& s) {
switch (corner) {
case TOP_LEFT:
return gfx::Rect(0, 0, 1, 1);
case TOP_RIGHT:
return gfx::Rect(s.width() - 1, 0, 1, 1);
case BOTTOM_LEFT:
return gfx::Rect(0, s.height() - 1, 1, 1);
case BOTTOM_RIGHT:
return gfx::Rect(s.width() - 1, s.height() - 1, 1, 1);
}
NOTREACHED();
return gfx::Rect();
}
};
TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) {
Corner corner = GetParam();
// This size chosen to be larger than the interest rect size, which is
// at least kPixelDistanceToRecord * 2 in each dimension.
int tile_size = 100000;
gfx::Size base_tiling_size(5 * tile_size, 5 * tile_size);
gfx::Size grow_down_tiling_size(5 * tile_size, 7 * tile_size);
gfx::Size grow_right_tiling_size(7 * tile_size, 5 * tile_size);
gfx::Size grow_both_tiling_size(7 * tile_size, 7 * tile_size);
// The small number subtracted keeps the last tile in each axis larger than
// the interest rect also.
int offset = -100;
gfx::Size base_tiling_size(6 * tile_size + offset, 6 * tile_size + offset);
gfx::Size grow_down_tiling_size(6 * tile_size + offset,
8 * tile_size + offset);
gfx::Size grow_right_tiling_size(8 * tile_size + offset,
6 * tile_size + offset);
gfx::Size grow_both_tiling_size(8 * tile_size + offset,
8 * tile_size + offset);
Region invalidation;
Region expected_invalidation;
......@@ -412,13 +448,15 @@ TEST_F(PicturePileTest, ResizePileOutsideInterestRect) {
}
UpdateAndExpandInvalidation(
&invalidation, grow_down_tiling_size, gfx::Rect(1, 1));
&invalidation,
grow_down_tiling_size,
CornerSinglePixelRect(corner, grow_down_tiling_size));
// We should have lost the recordings in the bottom row.
EXPECT_EQ(6, pile_->tiling().num_tiles_x());
EXPECT_EQ(8, 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) {
for (int i = 0; i < 6; ++i) {
for (int j = 0; j < 6; ++j) {
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_->picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
......@@ -433,7 +471,9 @@ TEST_F(PicturePileTest, ResizePileOutsideInterestRect) {
invalidation.Clear();
UpdateWholePile();
UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));
UpdateAndExpandInvalidation(&invalidation,
base_tiling_size,
CornerSinglePixelRect(corner, base_tiling_size));
// We should have lost the recordings that are now outside the tiling only.
EXPECT_EQ(6, pile_->tiling().num_tiles_x());
......@@ -454,13 +494,15 @@ TEST_F(PicturePileTest, ResizePileOutsideInterestRect) {
UpdateWholePile();
UpdateAndExpandInvalidation(
&invalidation, grow_right_tiling_size, gfx::Rect(1, 1));
&invalidation,
grow_right_tiling_size,
CornerSinglePixelRect(corner, grow_right_tiling_size));
// We should have lost the recordings in the right column.
EXPECT_EQ(8, 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) {
for (int i = 0; i < 6; ++i) {
for (int j = 0; j < 6; ++j) {
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_->picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
......@@ -475,7 +517,9 @@ TEST_F(PicturePileTest, ResizePileOutsideInterestRect) {
invalidation.Clear();
UpdateWholePile();
UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));
UpdateAndExpandInvalidation(&invalidation,
base_tiling_size,
CornerSinglePixelRect(corner, base_tiling_size));
// We should have lost the recordings that are now outside the tiling only.
EXPECT_EQ(6, pile_->tiling().num_tiles_x());
......@@ -496,13 +540,15 @@ TEST_F(PicturePileTest, ResizePileOutsideInterestRect) {
UpdateWholePile();
UpdateAndExpandInvalidation(
&invalidation, grow_both_tiling_size, gfx::Rect(1, 1));
&invalidation,
grow_both_tiling_size,
CornerSinglePixelRect(corner, grow_both_tiling_size));
// We should have lost the recordings in the right column and bottom row.
EXPECT_EQ(8, pile_->tiling().num_tiles_x());
EXPECT_EQ(8, 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) {
for (int i = 0; i < 6; ++i) {
for (int j = 0; j < 6; ++j) {
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_->picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
......@@ -539,14 +585,22 @@ TEST_F(PicturePileTest, ResizePileOutsideInterestRect) {
invalidation.Clear();
}
TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
TEST_P(PicturePileResizeCornerTest, SmallResizePileOutsideInterestRect) {
Corner corner = GetParam();
// This size chosen to be larger than the interest rect size, which is
// at least kPixelDistanceToRecord * 2 in each dimension.
int tile_size = 100000;
gfx::Size base_tiling_size(5 * tile_size, 5 * tile_size);
gfx::Size grow_down_tiling_size(5 * tile_size, 5 * tile_size + 5);
gfx::Size grow_right_tiling_size(5 * tile_size + 5, 5 * tile_size);
gfx::Size grow_both_tiling_size(5 * tile_size + 5, 5 * tile_size + 5);
// The small number subtracted keeps the last tile in each axis larger than
// the interest rect also.
int offset = -100;
gfx::Size base_tiling_size(6 * tile_size + offset, 6 * tile_size + offset);
gfx::Size grow_down_tiling_size(6 * tile_size + offset,
6 * tile_size + offset + 5);
gfx::Size grow_right_tiling_size(6 * tile_size + offset + 5,
6 * tile_size + offset);
gfx::Size grow_both_tiling_size(6 * tile_size + offset + 5,
6 * tile_size + offset + 5);
Region invalidation;
Region expected_invalidation;
......@@ -567,9 +621,12 @@ TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
}
UpdateAndExpandInvalidation(
&invalidation, grow_down_tiling_size, gfx::Rect(1, 1));
&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 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) {
......@@ -577,18 +634,53 @@ TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_->picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
EXPECT_EQ(j < 5, 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());
}
}
// We invalidated the bottom row.
expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(0, 5),
pile_->tiling().TileBounds(5, 5));
// 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, gfx::Rect(1, 1));
UpdateAndExpandInvalidation(&invalidation,
base_tiling_size,
CornerSinglePixelRect(corner, base_tiling_size));
// We should have lost nothing.
EXPECT_EQ(6, pile_->tiling().num_tiles_x());
......@@ -609,7 +701,9 @@ TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
UpdateWholePile();
UpdateAndExpandInvalidation(
&invalidation, grow_right_tiling_size, gfx::Rect(1, 1));
&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());
......@@ -619,18 +713,53 @@ TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_->picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
EXPECT_EQ(i < 5, it != map.end() && it->second.GetPicture());
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 the right column.
expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
pile_->tiling().TileBounds(5, 5));
// 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, gfx::Rect(1, 1));
UpdateAndExpandInvalidation(&invalidation,
base_tiling_size,
CornerSinglePixelRect(corner, base_tiling_size));
// We should have lost nothing.
EXPECT_EQ(6, pile_->tiling().num_tiles_x());
......@@ -651,9 +780,12 @@ TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
UpdateWholePile();
UpdateAndExpandInvalidation(
&invalidation, grow_both_tiling_size, gfx::Rect(1, 1));
&invalidation,
grow_both_tiling_size,
CornerSinglePixelRect(corner, grow_both_tiling_size));
// We should have lost the recordings in the right column and bottom row.
// 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) {
......@@ -661,20 +793,71 @@ TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_->picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
EXPECT_EQ(i < 5 && j < 5, 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;
}
}
// We invalidated the right column and the bottom row.
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)));
// 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, gfx::Rect(1, 1));
UpdateAndExpandInvalidation(&invalidation,
base_tiling_size,
CornerSinglePixelRect(corner, base_tiling_size));
// We should have lost nothing.
EXPECT_EQ(6, pile_->tiling().num_tiles_x());
......@@ -694,6 +877,11 @@ TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
invalidation.Clear();
}
INSTANTIATE_TEST_CASE_P(
PicturePileResizeCornerTests,
PicturePileResizeCornerTest,
::testing::Values(TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT));
TEST_F(PicturePileTest, ResizePileInsideInterestRect) {
// This size chosen to be small enough that all the rects below fit inside the
// the interest rect, so they are smaller than kPixelDistanceToRecord in each
......
......@@ -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