// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <map>
#include <utility>

#include "cc/resources/picture_pile.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_picture_pile.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"

namespace cc {
namespace {

class PicturePileTestBase {
 public:
  PicturePileTestBase()
      : min_scale_(0.125),
        pile_(min_scale_, gfx::Size(1000, 1000)),
        frame_number_(0) {}

  void InitializeData() {
    pile_.SetTileGridSize(gfx::Size(1000, 1000));
    pile_.SetMinContentsScale(min_scale_);
    client_ = FakeContentLayerClient();
    SetTilingSize(pile_.tiling().max_texture_size());
  }

  void SetTilingSize(const gfx::Size& tiling_size) {
    Region invalidation;
    gfx::Rect viewport_rect(tiling_size);
    UpdateAndExpandInvalidation(&invalidation, tiling_size, viewport_rect);
  }

  gfx::Size tiling_size() const { return pile_.GetSize(); }
  gfx::Rect tiling_rect() const { return gfx::Rect(pile_.GetSize()); }

  bool UpdateAndExpandInvalidation(Region* invalidation,
                                   const gfx::Size& layer_size,
                                   const gfx::Rect& visible_layer_rect) {
    frame_number_++;
    return pile_.UpdateAndExpandInvalidation(
        &client_, invalidation, false, layer_size, visible_layer_rect,
        frame_number_, Picture::RECORD_NORMALLY);
  }

  bool UpdateWholePile() {
    Region invalidation = tiling_rect();
    bool result = UpdateAndExpandInvalidation(&invalidation, tiling_size(),
                                              tiling_rect());
    EXPECT_EQ(tiling_rect().ToString(), invalidation.ToString());
    return result;
  }

  FakeContentLayerClient client_;
  float min_scale_;
  FakePicturePile pile_;
  int frame_number_;
};

class PicturePileTest : public PicturePileTestBase, public testing::Test {
 public:
  void SetUp() override { InitializeData(); }
};

TEST_F(PicturePileTest, InvalidationOnTileBorderOutsideInterestRect) {
  // Don't expand the interest rect past what we invalidate.
  pile_.SetPixelRecordDistance(0);

  gfx::Size tile_size(100, 100);
  pile_.tiling().SetMaxTextureSize(tile_size);

  gfx::Size pile_size(400, 400);
  SetTilingSize(pile_size);

  // We have multiple tiles.
  EXPECT_GT(pile_.tiling().num_tiles_x(), 2);
  EXPECT_GT(pile_.tiling().num_tiles_y(), 2);

  // Record everything.
  Region invalidation(tiling_rect());
  UpdateAndExpandInvalidation(&invalidation, tiling_size(), tiling_rect());

  // +----------+-----------------+-----------+
  // |          |     VVVV     1,0|           |
  // |          |     VVVV        |           |
  // |          |     VVVV        |           |
  // |       ...|.................|...        |
  // |       ...|.................|...        |
  // +----------+-----------------+-----------+
  // |       ...|                 |...        |
  // |       ...|                 |...        |
  // |       ...|                 |...        |
  // |       ...|                 |...        |
  // |       ...|              1,1|...        |
  // +----------+-----------------+-----------+
  // |       ...|.................|...        |
  // |       ...|.................|...        |
  // +----------+-----------------+-----------+
  //
  // .. = border pixels for tile 1,1
  // VV = interest rect (what we will record)
  //
  // The first invalidation is inside VV, so it does not touch border pixels of
  // tile 1,1.
  //
  // The second invalidation goes below VV into the .. border pixels of 1,1.

  // This is the VV interest rect which will be entirely inside 1,0 and not
  // touch the border of 1,1.
  gfx::Rect interest_rect(
      pile_.tiling().TilePositionX(1) + pile_.tiling().border_texels(),
      0,
      10,
      pile_.tiling().TileSizeY(0) - pile_.tiling().border_texels());

  // Invalidate tile 1,0 only. This is a rect that avoids the borders of any
  // other tiles.
  gfx::Rect invalidate_tile = interest_rect;
  // This should cause the tile 1,0 to be invalidated and re-recorded. The
  // invalidation did not need to be expanded.
  invalidation = invalidate_tile;
  UpdateAndExpandInvalidation(&invalidation, tiling_size(), interest_rect);
  EXPECT_EQ(invalidate_tile, invalidation);

  // Invalidate tile 1,0 and 1,1 by invalidating something that only touches the
  // border of 1,1 (and is inside the tile bounds of 1,0). This is a 10px wide
  // strip from the top of the tiling onto the border pixels of tile 1,1 that
  // avoids border pixels of any other tiles.
  gfx::Rect invalidate_border = interest_rect;
  invalidate_border.Inset(0, 0, 0, -1);
  // This should cause the tile 1,0 and 1,1 to be invalidated. The 1,1 tile will
  // not be re-recorded since it does not touch the interest rect, so the
  // invalidation should be expanded to cover all of 1,1.
  invalidation = invalidate_border;
  UpdateAndExpandInvalidation(&invalidation, tiling_size(), interest_rect);
  Region expected_invalidation = invalidate_border;
  expected_invalidation.Union(pile_.tiling().TileBounds(1, 1));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
}

TEST_F(PicturePileTest, SmallInvalidateInflated) {
  // Invalidate something inside a tile.
  Region invalidate_rect(gfx::Rect(50, 50, 1, 1));
  UpdateAndExpandInvalidation(&invalidate_rect, tiling_size(), tiling_rect());
  EXPECT_EQ(gfx::Rect(50, 50, 1, 1).ToString(), invalidate_rect.ToString());

  EXPECT_EQ(1, pile_.tiling().num_tiles_x());
  EXPECT_EQ(1, pile_.tiling().num_tiles_y());

  FakePicturePile::PictureInfo& picture_info =
      pile_.picture_map().find(FakePicturePile::PictureMapKey(0, 0))->second;
  // We should have a picture.
  EXPECT_TRUE(!!picture_info.GetPicture());
  gfx::Rect picture_rect = gfx::ScaleToEnclosedRect(
      picture_info.GetPicture()->LayerRect(), min_scale_);

  // The the picture should be large enough that scaling it never makes a rect
  // smaller than 1 px wide or tall.
  EXPECT_FALSE(picture_rect.IsEmpty()) << "Picture rect " <<
      picture_rect.ToString();
}

TEST_F(PicturePileTest, LargeInvalidateInflated) {
  // Invalidate something inside a tile.
  Region invalidate_rect(gfx::Rect(50, 50, 100, 100));
  UpdateAndExpandInvalidation(&invalidate_rect, tiling_size(), tiling_rect());
  EXPECT_EQ(gfx::Rect(50, 50, 100, 100).ToString(), invalidate_rect.ToString());

  EXPECT_EQ(1, pile_.tiling().num_tiles_x());
  EXPECT_EQ(1, pile_.tiling().num_tiles_y());

  FakePicturePile::PictureInfo& picture_info =
      pile_.picture_map().find(FakePicturePile::PictureMapKey(0, 0))->second;
  EXPECT_TRUE(!!picture_info.GetPicture());

  int expected_inflation = pile_.buffer_pixels();

  const Picture* base_picture = picture_info.GetPicture();
  gfx::Rect base_picture_rect(tiling_size());
  base_picture_rect.Inset(-expected_inflation, -expected_inflation);
  EXPECT_EQ(base_picture_rect.ToString(),
            base_picture->LayerRect().ToString());
}

TEST_F(PicturePileTest, InvalidateOnTileBoundaryInflated) {
  gfx::Size new_tiling_size =
      gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 2.f));
  // This creates initial pictures.
  SetTilingSize(new_tiling_size);

  // Due to border pixels, we should have 3 tiles.
  EXPECT_EQ(3, pile_.tiling().num_tiles_x());
  EXPECT_EQ(3, pile_.tiling().num_tiles_y());

  // We should have 1/.125 - 1 = 7 border pixels.
  EXPECT_EQ(7, pile_.buffer_pixels());
  EXPECT_EQ(7, pile_.tiling().border_texels());

  // Invalidate everything to have a non zero invalidation frequency.
  UpdateWholePile();

  // Invalidate something just over a tile boundary by a single pixel.
  // This will invalidate the tile (1, 1), as well as 1 row of pixels in (1, 0).
  Region invalidate_rect(
      gfx::Rect(pile_.tiling().TileBoundsWithBorder(0, 0).right(),
                pile_.tiling().TileBoundsWithBorder(0, 0).bottom() - 1,
                50,
                50));
  Region expected_invalidation = invalidate_rect;
  UpdateAndExpandInvalidation(&invalidate_rect, tiling_size(), tiling_rect());
  EXPECT_EQ(expected_invalidation.ToString(), invalidate_rect.ToString());

  for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureInfo& picture_info =
          pile_.picture_map()
              .find(FakePicturePile::PictureMapKey(i, j))
              ->second;

      // Expect (1, 1) and (1, 0) to be invalidated once more
      // than the rest of the tiles.
      if (i == 1 && (j == 0 || j == 1)) {
        EXPECT_FLOAT_EQ(
            2.0f / FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
            picture_info.GetInvalidationFrequencyForTesting());
      } else {
        EXPECT_FLOAT_EQ(
            1.0f / FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
            picture_info.GetInvalidationFrequencyForTesting());
      }
    }
  }
}

TEST_F(PicturePileTest, InvalidateOnFullLayer) {
  UpdateWholePile();

  // Everything was invalidated once so far.
  for (auto& it : pile_.picture_map()) {
    EXPECT_FLOAT_EQ(
        1.0f / FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
        it.second.GetInvalidationFrequencyForTesting());
  }

  // Invalidate everything,
  Region invalidation = tiling_rect();
  UpdateAndExpandInvalidation(&invalidation, tiling_size(), tiling_rect());

  // Everything was invalidated again.
  for (auto& it : pile_.picture_map()) {
    EXPECT_FLOAT_EQ(
        2.0f / FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
        it.second.GetInvalidationFrequencyForTesting());
  }
}

TEST_F(PicturePileTest, StopRecordingOffscreenInvalidations) {
  gfx::Size new_tiling_size =
      gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 4.f));
  SetTilingSize(new_tiling_size);

  gfx::Rect viewport(tiling_size().width(), 1);

  // Update the whole pile until the invalidation frequency is high.
  for (int frame = 0; frame < 33; ++frame) {
    UpdateWholePile();
  }

  // Make sure we have a high invalidation frequency.
  for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureInfo& picture_info =
          pile_.picture_map()
              .find(FakePicturePile::PictureMapKey(i, j))
              ->second;
      EXPECT_FLOAT_EQ(1.0f, picture_info.GetInvalidationFrequencyForTesting())
          << "i " << i << " j " << j;
    }
  }

  // Update once more with a small viewport.
  Region invalidation(tiling_rect());
  UpdateAndExpandInvalidation(&invalidation, tiling_size(), viewport);
  EXPECT_EQ(tiling_rect().ToString(), invalidation.ToString());

  for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureInfo& picture_info =
          pile_.picture_map()
              .find(FakePicturePile::PictureMapKey(i, j))
              ->second;
      EXPECT_FLOAT_EQ(1.0f, picture_info.GetInvalidationFrequencyForTesting());

      // If the y far enough away we expect to find no picture (no re-recording
      // happened). For close y, the picture should change.
      if (j >= 2)
        EXPECT_FALSE(picture_info.GetPicture()) << "i " << i << " j " << j;
      else
        EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j;
    }
  }

  // Update a partial tile that doesn't get recorded. We should expand the
  // invalidation to the entire tiles that overlap it.
  Region small_invalidation =
      gfx::Rect(pile_.tiling().TileBounds(3, 4).x(),
                pile_.tiling().TileBounds(3, 4).y() + 10,
                1,
                1);
  UpdateAndExpandInvalidation(&small_invalidation, tiling_size(), viewport);
  EXPECT_TRUE(small_invalidation.Contains(gfx::UnionRects(
      pile_.tiling().TileBounds(2, 4), pile_.tiling().TileBounds(3, 4))))
      << small_invalidation.ToString();

  // Now update with no invalidation and full viewport
  Region empty_invalidation;
  UpdateAndExpandInvalidation(&empty_invalidation, tiling_size(),
                              tiling_rect());
  EXPECT_EQ(Region().ToString(), empty_invalidation.ToString());

  for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureInfo& picture_info =
          pile_.picture_map()
              .find(FakePicturePile::PictureMapKey(i, j))
              ->second;
      // Expect the invalidation frequency to be less than 1, since we just
      // updated with no invalidations.
      EXPECT_LT(picture_info.GetInvalidationFrequencyForTesting(), 1.f);

      // We expect that there are pictures everywhere now.
      EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j;
    }
  }
}

TEST_F(PicturePileTest, ClearingInvalidatesRecordedRect) {
  gfx::Rect rect(0, 0, 5, 5);
  EXPECT_TRUE(pile_.CanRasterLayerRect(rect));
  EXPECT_TRUE(pile_.CanRasterSlowTileCheck(rect));

  pile_.Clear();

  // Make sure both the cache-aware check (using recorded region) and the normal
  // check are both false after clearing.
  EXPECT_FALSE(pile_.CanRasterLayerRect(rect));
  EXPECT_FALSE(pile_.CanRasterSlowTileCheck(rect));
}

TEST_F(PicturePileTest, FrequentInvalidationCanRaster) {
  // This test makes sure that if part of the page is frequently invalidated
  // and doesn't get re-recorded, then CanRaster is not true for any
  // tiles touching it, but is true for adjacent tiles, even if it
  // overlaps on borders (edge case).
  gfx::Size new_tiling_size =
      gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 4.f));
  SetTilingSize(new_tiling_size);

  gfx::Rect tile01_borders = pile_.tiling().TileBoundsWithBorder(0, 1);
  gfx::Rect tile02_borders = pile_.tiling().TileBoundsWithBorder(0, 2);
  gfx::Rect tile01_noborders = pile_.tiling().TileBounds(0, 1);
  gfx::Rect tile02_noborders = pile_.tiling().TileBounds(0, 2);

  // Sanity check these two tiles are overlapping with borders, since this is
  // what the test is trying to repro.
  EXPECT_TRUE(tile01_borders.Intersects(tile02_borders));
  EXPECT_FALSE(tile01_noborders.Intersects(tile02_noborders));
  UpdateWholePile();
  EXPECT_TRUE(pile_.CanRasterLayerRect(tile01_noborders));
  EXPECT_TRUE(pile_.CanRasterSlowTileCheck(tile01_noborders));
  EXPECT_TRUE(pile_.CanRasterLayerRect(tile02_noborders));
  EXPECT_TRUE(pile_.CanRasterSlowTileCheck(tile02_noborders));
  // Sanity check that an initial paint goes down the fast path of having
  // a valid recorded viewport.
  EXPECT_TRUE(!pile_.recorded_viewport().IsEmpty());

  // Update the whole layer until the invalidation frequency is high.
  for (int frame = 0; frame < 33; ++frame) {
    UpdateWholePile();
  }

  // Update once more with a small viewport.
  gfx::Rect viewport(tiling_size().width(), 1);
  Region invalidation(tiling_rect());
  UpdateAndExpandInvalidation(&invalidation, tiling_size(), viewport);
  EXPECT_EQ(tiling_rect().ToString(), invalidation.ToString());

  // Sanity check some pictures exist and others don't.
  EXPECT_TRUE(pile_.picture_map()
                  .find(FakePicturePile::PictureMapKey(0, 1))
                  ->second.GetPicture());
  EXPECT_FALSE(pile_.picture_map()
                   .find(FakePicturePile::PictureMapKey(0, 2))
                   ->second.GetPicture());

  EXPECT_TRUE(pile_.CanRasterLayerRect(tile01_noborders));
  EXPECT_TRUE(pile_.CanRasterSlowTileCheck(tile01_noborders));
  EXPECT_FALSE(pile_.CanRasterLayerRect(tile02_noborders));
  EXPECT_FALSE(pile_.CanRasterSlowTileCheck(tile02_noborders));
}

TEST_F(PicturePileTest, NoInvalidationValidViewport) {
  // This test validates that the recorded_viewport cache of full tiles
  // is still valid for some use cases.  If it's not, it's a performance
  // issue because CanRaster checks will go down the slow path.
  EXPECT_TRUE(!pile_.recorded_viewport().IsEmpty());

  // No invalidation, same viewport.
  Region invalidation;
  UpdateAndExpandInvalidation(&invalidation, tiling_size(), tiling_rect());
  EXPECT_TRUE(!pile_.recorded_viewport().IsEmpty());
  EXPECT_EQ(Region().ToString(), invalidation.ToString());

  // Partial invalidation, same viewport.
  invalidation = gfx::Rect(0, 0, 1, 1);
  UpdateAndExpandInvalidation(&invalidation, tiling_size(), tiling_rect());
  EXPECT_TRUE(!pile_.recorded_viewport().IsEmpty());
  EXPECT_EQ(gfx::Rect(0, 0, 1, 1).ToString(), invalidation.ToString());

  // No invalidation, changing viewport.
  invalidation = Region();
  UpdateAndExpandInvalidation(&invalidation, tiling_size(),
                              gfx::Rect(5, 5, 5, 5));
  EXPECT_TRUE(!pile_.recorded_viewport().IsEmpty());
  EXPECT_EQ(Region().ToString(), invalidation.ToString());
}

TEST_F(PicturePileTest, BigFullLayerInvalidation) {
  gfx::Size huge_layer_size(100000000, 100000000);
  gfx::Rect viewport(300000, 400000, 5000, 6000);

  // Resize the pile.
  Region invalidation;
  UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport);

  // Invalidating a huge layer should be fast.
  base::TimeTicks start = base::TimeTicks::Now();
  invalidation = gfx::Rect(huge_layer_size);
  UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport);
  base::TimeTicks end = base::TimeTicks::Now();
  base::TimeDelta length = end - start;
  // This is verrrry generous to avoid flake.
  EXPECT_LT(length.InSeconds(), 5);
}

TEST_F(PicturePileTest, BigFullLayerInvalidationWithResizeGrow) {
  gfx::Size huge_layer_size(100000000, 100000000);
  gfx::Rect viewport(300000, 400000, 5000, 6000);

  // Resize the pile.
  Region invalidation;
  UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport);

  // Resize the pile even larger, while invalidating everything in the old size.
  // Invalidating the whole thing should be fast.
  base::TimeTicks start = base::TimeTicks::Now();
  gfx::Size bigger_layer_size(huge_layer_size.width() * 2,
                              huge_layer_size.height() * 2);
  invalidation = gfx::Rect(huge_layer_size);
  UpdateAndExpandInvalidation(&invalidation, bigger_layer_size, viewport);
  base::TimeTicks end = base::TimeTicks::Now();
  base::TimeDelta length = end - start;
  // This is verrrry generous to avoid flake.
  EXPECT_LT(length.InSeconds(), 5);
}

TEST_F(PicturePileTest, BigFullLayerInvalidationWithResizeShrink) {
  gfx::Size huge_layer_size(100000000, 100000000);
  gfx::Rect viewport(300000, 400000, 5000, 6000);

  // Resize the pile.
  Region invalidation;
  UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport);

  // Resize the pile smaller, while invalidating everything in the new size.
  // Invalidating the whole thing should be fast.
  base::TimeTicks start = base::TimeTicks::Now();
  gfx::Size smaller_layer_size(huge_layer_size.width() - 1000,
                               huge_layer_size.height() - 1000);
  invalidation = gfx::Rect(smaller_layer_size);
  UpdateAndExpandInvalidation(&invalidation, smaller_layer_size, viewport);
  base::TimeTicks end = base::TimeTicks::Now();
  base::TimeDelta length = end - start;
  // This is verrrry generous to avoid flake.
  EXPECT_LT(length.InSeconds(), 5);
}

TEST_F(PicturePileTest, InvalidationOutsideRecordingRect) {
  gfx::Size huge_layer_size(10000000, 20000000);
  gfx::Rect viewport(300000, 400000, 5000, 6000);

  // Resize the pile and set up the interest rect.
  Region invalidation;
  UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport);

  // Invalidation inside the recording rect does not need to be expanded.
  invalidation = viewport;
  UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport);
  EXPECT_EQ(viewport.ToString(), invalidation.ToString());

  // Invalidation outside the recording rect should expand to the tiles it
  // covers.
  gfx::Rect recorded_over_tiles =
      pile_.tiling().ExpandRectToTileBounds(pile_.recorded_viewport());
  gfx::Rect invalidation_outside(
      recorded_over_tiles.right(), recorded_over_tiles.y(), 30, 30);
  invalidation = invalidation_outside;
  UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport);
  gfx::Rect expanded_recorded_viewport =
      pile_.tiling().ExpandRectToTileBounds(pile_.recorded_viewport());
  Region expected_invalidation =
      pile_.tiling().ExpandRectToTileBounds(invalidation_outside);
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
}

enum Corner {
  TOP_LEFT,
  TOP_RIGHT,
  BOTTOM_LEFT,
  BOTTOM_RIGHT,
};

class PicturePileResizeCornerTest : public PicturePileTestBase,
                                    public testing::TestWithParam<Corner> {
 protected:
  void SetUp() override { InitializeData(); }

  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;
  // 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;

  pile_.tiling().SetMaxTextureSize(gfx::Size(tile_size, tile_size));
  SetTilingSize(base_tiling_size);

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  UpdateAndExpandInvalidation(
      &invalidation,
      grow_down_tiling_size,
      CornerSinglePixelRect(corner, grow_down_tiling_size));

  // 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) {
    for (int j = 0; j < 6; ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_EQ(j < 5, it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated all new pixels in the recording.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
                                          gfx::Rect(base_tiling_size));
  // But the new pixels don't cover the whole bottom row.
  gfx::Rect bottom_row = gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
                                         pile_.tiling().TileBounds(5, 5));
  EXPECT_FALSE(expected_invalidation.Contains(bottom_row));
  // We invalidated the entire old bottom row.
  expected_invalidation.Union(bottom_row);
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

  UpdateWholePile();
  UpdateAndExpandInvalidation(&invalidation,
                              base_tiling_size,
                              CornerSinglePixelRect(corner, base_tiling_size));

  // 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) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::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());
    }
  }

  // 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,
      CornerSinglePixelRect(corner, grow_right_tiling_size));

  // 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) {
    for (int j = 0; j < 6; ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_EQ(i < 5, it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated all new pixels in the recording.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
                                          gfx::Rect(base_tiling_size));
  // But the new pixels don't cover the whole right_column.
  gfx::Rect right_column = gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
                                           pile_.tiling().TileBounds(5, 5));
  EXPECT_FALSE(expected_invalidation.Contains(right_column));
  // We invalidated the entire old right column.
  expected_invalidation.Union(right_column);
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

  UpdateWholePile();
  UpdateAndExpandInvalidation(&invalidation,
                              base_tiling_size,
                              CornerSinglePixelRect(corner, base_tiling_size));

  // 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) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      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());
    }
  }

  // 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,
      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 < 6; ++i) {
    for (int j = 0; j < 6; ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_EQ(i < 5 && j < 5, it != map.end() && it->second.GetPicture());
    }
  }

  // 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 or bottom row.
  Region right_column_and_bottom_row =
      UnionRegions(gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
                                   pile_.tiling().TileBounds(5, 5)),
                   gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
                                   pile_.tiling().TileBounds(5, 5)));
  EXPECT_FALSE(expected_invalidation.Contains(right_column_and_bottom_row));
  // We invalidated the entire old right column and the old bottom row.
  expected_invalidation.Union(right_column_and_bottom_row);
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

  UpdateWholePile();
  UpdateAndExpandInvalidation(&invalidation, base_tiling_size,
                              CornerSinglePixelRect(corner, base_tiling_size));

  // 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) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::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 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();
}

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;
  // 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;

  pile_.tiling().SetMaxTextureSize(gfx::Size(tile_size, tile_size));
  SetTilingSize(base_tiling_size);

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // 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 };

  // 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) {
        FakePicturePile::PictureMapKey key(i, j);
        FakePicturePile::PictureMap& map = pile_.picture_map();
        FakePicturePile::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:
          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();
  }

  // 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) {
        FakePicturePile::PictureMapKey key(i, j);
        FakePicturePile::PictureMap& map = pile_.picture_map();
        FakePicturePile::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 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:
          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();
  }

  // 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) {
        FakePicturePile::PictureMapKey key(i, j);
        FakePicturePile::PictureMap& map = pile_.picture_map();
        FakePicturePile::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 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:
          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();
  }
}

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
  // dimension.
  int tile_size = 100;
  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);

  Region invalidation;
  Region expected_invalidation;

  pile_.tiling().SetMaxTextureSize(gfx::Size(tile_size, tile_size));
  SetTilingSize(base_tiling_size);

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  UpdateAndExpandInvalidation(
      &invalidation, grow_down_tiling_size, gfx::Rect(1, 1));

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated the newly exposed pixels on the bottom row of tiles.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
                                          gfx::Rect(base_tiling_size));
  Region bottom_row_new_pixels =
      SubtractRegions(gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
                                      pile_.tiling().TileBounds(5, 5)),
                      gfx::Rect(base_tiling_size));
  EXPECT_TRUE(expected_invalidation.Contains(bottom_row_new_pixels));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

  UpdateWholePile();
  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // 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();
  UpdateAndExpandInvalidation(
      &invalidation, grow_right_tiling_size, gfx::Rect(1, 1));

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated the newly exposed pixels on the right column of tiles.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
                                          gfx::Rect(base_tiling_size));
  Region right_column_new_pixels =
      SubtractRegions(gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
                                      pile_.tiling().TileBounds(5, 5)),
                      gfx::Rect(base_tiling_size));
  EXPECT_TRUE(expected_invalidation.Contains(right_column_new_pixels));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

  UpdateWholePile();
  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));

  // We should have lost the recordings that are now outside the tiling only.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // 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();
  UpdateAndExpandInvalidation(
      &invalidation, grow_both_tiling_size, gfx::Rect(1, 1));

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated the newly 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));
  Region bottom_row_and_right_column_new_pixels = SubtractRegions(
      UnionRegions(gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
                                   pile_.tiling().TileBounds(5, 5)),
                   gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
                                   pile_.tiling().TileBounds(5, 5))),
      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();

  UpdateWholePile();
  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect());

  // We should have lost the recordings that are now outside the tiling only.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // 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();
}

TEST_F(PicturePileTest, SmallResizePileInsideInterestRect) {
  // 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
  // dimension.
  int tile_size = 100;
  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);

  Region invalidation;
  Region expected_invalidation;

  pile_.tiling().SetMaxTextureSize(gfx::Size(tile_size, tile_size));
  SetTilingSize(base_tiling_size);

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  UpdateAndExpandInvalidation(
      &invalidation, grow_down_tiling_size, gfx::Rect(1, 1));

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated the newly 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();
  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // 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();
  UpdateAndExpandInvalidation(
      &invalidation, grow_right_tiling_size, gfx::Rect(1, 1));

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated the newly 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();
  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));

  // We should have lost the recordings that are now outside the tiling only.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // 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();
  UpdateAndExpandInvalidation(
      &invalidation, grow_both_tiling_size, gfx::Rect(1, 1));

  // We should have a recording for every tile.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated the newly 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();

  UpdateWholePile();
  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect());

  // We should have lost the recordings that are now outside the tiling only.
  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) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // 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();
}

TEST_F(PicturePileTest, SolidRectangleIsSolid) {
  // If the client has no contents, the solid state will be true.
  Region invalidation1(tiling_rect());
  UpdateAndExpandInvalidation(&invalidation1, tiling_size(), tiling_rect());
  EXPECT_TRUE(pile_.is_solid_color());
  EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), pile_.solid_color());

  // If there is a single rect that covers the view, the solid
  // state will be true.
  SkPaint paint;
  paint.setColor(SK_ColorCYAN);
  client_.add_draw_rect(tiling_rect(), paint);
  Region invalidation2(tiling_rect());
  UpdateAndExpandInvalidation(&invalidation2, tiling_size(), tiling_rect());
  EXPECT_TRUE(pile_.is_solid_color());
  EXPECT_EQ(SK_ColorCYAN, pile_.solid_color());

  // If a second smaller rect is draw that doesn't cover the viewport
  // completely, the solid state will be false.
  gfx::Rect smallRect = tiling_rect();
  smallRect.Inset(10, 10, 10, 10);
  client_.add_draw_rect(smallRect, paint);
  Region invalidation3(tiling_rect());
  UpdateAndExpandInvalidation(&invalidation3, tiling_size(), tiling_rect());
  EXPECT_FALSE(pile_.is_solid_color());

  // If a third rect is drawn over everything, we should be solid again.
  paint.setColor(SK_ColorRED);
  client_.add_draw_rect(tiling_rect(), paint);
  Region invalidation4(tiling_rect());
  UpdateAndExpandInvalidation(&invalidation4, tiling_size(), tiling_rect());
  EXPECT_TRUE(pile_.is_solid_color());
  EXPECT_EQ(SK_ColorRED, pile_.solid_color());

  // If we draw too many, we don't bother doing the analysis and we should no
  // longer be in a solid state.  There are 8 rects, two clips and a translate.
  client_.add_draw_rect(tiling_rect(), paint);
  client_.add_draw_rect(tiling_rect(), paint);
  client_.add_draw_rect(tiling_rect(), paint);
  client_.add_draw_rect(tiling_rect(), paint);
  client_.add_draw_rect(tiling_rect(), paint);
  Region invalidation5(tiling_rect());
  UpdateAndExpandInvalidation(&invalidation5, tiling_size(), tiling_rect());
  EXPECT_FALSE(pile_.is_solid_color());
}

TEST_F(PicturePileTest, NonSolidRectangleOnOffsettedLayerIsNonSolid) {
  gfx::Rect visible_rect(tiling_rect());
  visible_rect.Offset(gfx::Vector2d(1000, 1000));
  // The picture pile requires that the tiling completely encompass the viewport
  // to make this test work correctly since the recorded viewport is an
  // intersection of the tile size and viewport rect.  This is possibly a flaw
  // in |PicturePile|.
  gfx::Size tiling_size(visible_rect.right(), visible_rect.bottom());
  // |Setup()| will create pictures here that mess with the test, clear it!
  pile_.Clear();

  SkPaint paint;
  paint.setColor(SK_ColorCYAN);

  // Add a rect that doesn't cover the viewport completely, the solid state
  // will be false.
  gfx::Rect smallRect = visible_rect;
  smallRect.Inset(10, 10, 10, 10);
  client_.add_draw_rect(smallRect, paint);
  Region invalidation(visible_rect);
  UpdateAndExpandInvalidation(&invalidation, tiling_size, visible_rect);
  EXPECT_FALSE(pile_.is_solid_color());
}

TEST_F(PicturePileTest, SetEmptyBounds) {
  EXPECT_TRUE(pile_.is_solid_color());
  EXPECT_FALSE(pile_.GetSize().IsEmpty());
  EXPECT_FALSE(pile_.picture_map().empty());
  EXPECT_TRUE(pile_.HasRecordings());
  pile_.SetEmptyBounds();
  EXPECT_FALSE(pile_.is_solid_color());
  EXPECT_TRUE(pile_.GetSize().IsEmpty());
  EXPECT_TRUE(pile_.picture_map().empty());
  EXPECT_FALSE(pile_.HasRecordings());
}

}  // namespace
}  // namespace cc
