// 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/rect_conversions.h"
#include "ui/gfx/size_conversions.h"

namespace cc {
namespace {

class TestPicturePile : public PicturePile {
 public:
  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(const gfx::Rect& layer_rect) {
    return CanRaster(1.f, layer_rect);
  }

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

 protected:
    virtual ~TestPicturePile() {}
};

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

  void InitializeData() {
    pile_ = make_scoped_refptr(new TestPicturePile());
    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_;
  scoped_refptr<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 the recordings in the bottom row.
  EXPECT_EQ(6, pile_->tiling().num_tiles_x());
  EXPECT_EQ(8, pile_->tiling().num_tiles_y());
  for (int i = 0; i < 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));

  // 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_EQ(j < 6, it != map.end() && it->second.GetPicture());
    }
  }

  // No invalidation when shrinking.
  expected_invalidation.Clear();
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost the recordings in the right column.
  EXPECT_EQ(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));

  // 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_EQ(i < 6, it != map.end() && it->second.GetPicture());
    }
  }

  // No invalidation when shrinking.
  expected_invalidation.Clear();
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost the recordings in the right column and bottom row.
  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.
  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, 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_EQ(i < 6 && j < 6, it != map.end() && it->second.GetPicture());
    }
  }

  // No invalidation when shrinking.
  expected_invalidation.Clear();
  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());
    }
  }

  UpdateAndExpandInvalidation(
      &invalidation,
      grow_down_tiling_size,
      CornerSinglePixelRect(corner, grow_down_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 new pixels.
  switch (corner) {
    case TOP_LEFT:
    case TOP_RIGHT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(0, 5),
                                              pile_->tiling().TileBounds(5, 5));
      break;
    case BOTTOM_LEFT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(1, 5),
                                              pile_->tiling().TileBounds(5, 5));
      expected_invalidation.Union(SubtractRects(
          pile_->tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size)));
      break;
    case BOTTOM_RIGHT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(0, 5),
                                              pile_->tiling().TileBounds(4, 5));
      expected_invalidation.Union(SubtractRects(
          pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
      break;
  }
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost nothing.
  EXPECT_EQ(6, pile_->tiling().num_tiles_x());
  EXPECT_EQ(6, pile_->tiling().num_tiles_y());
  for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
      TestPicturePile::PictureMapKey key(i, j);
      TestPicturePile::PictureMap& map = pile_->picture_map();
      TestPicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated nothing.
  expected_invalidation.Clear();
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost the recordings in the right column.
  EXPECT_EQ(6, pile_->tiling().num_tiles_x());
  EXPECT_EQ(6, pile_->tiling().num_tiles_y());
  for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
      TestPicturePile::PictureMapKey key(i, j);
      TestPicturePile::PictureMap& map = pile_->picture_map();
      TestPicturePile::PictureMap::iterator it = map.find(key);
      bool expect_tile;
      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 pixels.
  switch (corner) {
    case TOP_LEFT:
    case BOTTOM_LEFT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
                                              pile_->tiling().TileBounds(5, 5));
      break;
    case TOP_RIGHT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 1),
                                              pile_->tiling().TileBounds(5, 5));
      expected_invalidation.Union(SubtractRects(
          pile_->tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size)));
      break;
    case BOTTOM_RIGHT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
                                              pile_->tiling().TileBounds(5, 4));
      expected_invalidation.Union(SubtractRects(
          pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
      break;
  }
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost nothing.
  EXPECT_EQ(6, pile_->tiling().num_tiles_x());
  EXPECT_EQ(6, pile_->tiling().num_tiles_y());
  for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
      TestPicturePile::PictureMapKey key(i, j);
      TestPicturePile::PictureMap& map = pile_->picture_map();
      TestPicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated nothing.
  expected_invalidation.Clear();
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost the recordings in the right column and bottom row. The
  // tile that insects the interest rect in invalidated only on its new pixels.
  EXPECT_EQ(6, pile_->tiling().num_tiles_x());
  EXPECT_EQ(6, pile_->tiling().num_tiles_y());
  for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
      TestPicturePile::PictureMapKey key(i, j);
      TestPicturePile::PictureMap& map = pile_->picture_map();
      TestPicturePile::PictureMap::iterator it = map.find(key);
      bool expect_tile;
      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 pixels.
  switch (corner) {
    case TOP_LEFT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
                                              pile_->tiling().TileBounds(5, 5));
      expected_invalidation.Union(gfx::UnionRects(
          pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(5, 5)));
      break;
    case TOP_RIGHT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 1),
                                              pile_->tiling().TileBounds(5, 5));
      expected_invalidation.Union(gfx::UnionRects(
          pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(5, 5)));
      expected_invalidation.Union(SubtractRects(
          pile_->tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size)));
      break;
    case BOTTOM_LEFT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
                                              pile_->tiling().TileBounds(5, 5));
      expected_invalidation.Union(gfx::UnionRects(
          pile_->tiling().TileBounds(1, 5), pile_->tiling().TileBounds(5, 5)));
      expected_invalidation.Union(SubtractRects(
          pile_->tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size)));
      break;
    case BOTTOM_RIGHT:
      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
                                              pile_->tiling().TileBounds(5, 4));
      expected_invalidation.Union(gfx::UnionRects(
          pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(4, 5)));
      expected_invalidation.Union(SubtractRegions(
          pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
      break;
  }
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost nothing.
  EXPECT_EQ(6, pile_->tiling().num_tiles_x());
  EXPECT_EQ(6, pile_->tiling().num_tiles_y());
  for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
      TestPicturePile::PictureMapKey key(i, j);
      TestPicturePile::PictureMap& map = pile_->picture_map();
      TestPicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_TRUE(it != map.end() && it->second.GetPicture());
    }
  }

  // We invalidated nothing.
  expected_invalidation.Clear();
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();
}

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

  // No invalidation when shrinking.
  EXPECT_EQ(Region().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());
    }
  }

  // No invalidation when shrinking.
  EXPECT_EQ(Region().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());
    }
  }

  // No invalidation when shrinking.
  EXPECT_EQ(Region().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());
    }
  }

  // No invalidation when shrinking.
  EXPECT_EQ(Region().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());
    }
  }

  // No invalidation when shrinking.
  EXPECT_EQ(Region().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());
    }
  }

  // No invalidation when shrinking.
  EXPECT_EQ(Region().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());
}

}  // namespace
}  // namespace cc
