// 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_rendering_stats_instrumentation.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 TestPicturePile : public PicturePile {
 public:
  ~TestPicturePile() override {}

  using PicturePile::buffer_pixels;
  using PicturePile::CanRasterSlowTileCheck;
  using PicturePile::Clear;

  PictureMap& picture_map() { return picture_map_; }
  const gfx::Rect& recorded_viewport() const { return recorded_viewport_; }

  bool CanRasterLayerRect(gfx::Rect layer_rect) {
    layer_rect.Intersect(gfx::Rect(tiling_.tiling_size()));
    if (recorded_viewport_.Contains(layer_rect))
      return true;
    return CanRasterSlowTileCheck(layer_rect);
  }

  bool HasRecordings() const { return has_any_recordings_; }

  typedef PicturePile::PictureInfo PictureInfo;
  typedef PicturePile::PictureMapKey PictureMapKey;
  typedef PicturePile::PictureMap PictureMap;
};

class PicturePileTestBase {
 public:
  PicturePileTestBase()
      : background_color_(SK_ColorBLUE),
        min_scale_(0.125),
        frame_number_(0),
        contents_opaque_(false) {}

  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_.tiling_size(); }
  gfx::Rect tiling_rect() const { return gfx::Rect(pile_.tiling_size()); }

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

  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_;
  FakeRenderingStatsInstrumentation stats_instrumentation_;
  TestPicturePile pile_;
  SkColor background_color_;
  float min_scale_;
  int frame_number_;
  bool contents_opaque_;
};

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

TEST_F(PicturePileTest, InvalidationOnTileBorderOutsideInterestRect) {
  // Don't expand the interest rect past what we invalidate.
  pile_.SetPixelRecordDistanceForTesting(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());

  TestPicturePile::PictureInfo& picture_info =
      pile_.picture_map().find(TestPicturePile::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());

  TestPicturePile::PictureInfo& picture_info =
      pile_.picture_map().find(TestPicturePile::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(pile_.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(pile_.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) {
      TestPicturePile::PictureInfo& picture_info =
          pile_.picture_map()
              .find(TestPicturePile::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 / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
            picture_info.GetInvalidationFrequencyForTesting());
      } else {
        EXPECT_FLOAT_EQ(
            1.0f / TestPicturePile::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 / TestPicturePile::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 / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
        it.second.GetInvalidationFrequencyForTesting());
  }
}

TEST_F(PicturePileTest, StopRecordingOffscreenInvalidations) {
  gfx::Size new_tiling_size =
      gfx::ToCeiledSize(gfx::ScaleSize(pile_.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) {
      TestPicturePile::PictureInfo& picture_info =
          pile_.picture_map()
              .find(TestPicturePile::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) {
      TestPicturePile::PictureInfo& picture_info =
          pile_.picture_map()
              .find(TestPicturePile::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) {
      TestPicturePile::PictureInfo& picture_info =
          pile_.picture_map()
              .find(TestPicturePile::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(pile_.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(TestPicturePile::PictureMapKey(0, 1))
                  ->second.GetPicture());
  EXPECT_FALSE(pile_.picture_map()
                   .find(TestPicturePile::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:
  virtual 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) {
      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());
    }
  }

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

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

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

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

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

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

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

  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) {
      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 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) {
      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 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) {
      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 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) {
      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 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) {
      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 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) {
      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 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_.tiling_size().IsEmpty());
  EXPECT_FALSE(pile_.picture_map().empty());
  EXPECT_TRUE(pile_.HasRecordings());
  pile_.SetEmptyBounds();
  EXPECT_FALSE(pile_.is_solid_color());
  EXPECT_TRUE(pile_.tiling_size().IsEmpty());
  EXPECT_TRUE(pile_.picture_map().empty());
  EXPECT_FALSE(pile_.HasRecordings());
}

}  // namespace
}  // namespace cc
