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

#include <map>
#include <utility>

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

namespace cc {
namespace {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  int expected_inflation = pile_.buffer_pixels();

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

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

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

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

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

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

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

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

TEST_F(PicturePileTest, InvalidateOnFullLayer) {
  UpdateWholePile();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  pile_.Clear();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  static gfx::Rect CornerSinglePixelRect(Corner corner, const gfx::Size& s) {
    switch (corner) {
      case TOP_LEFT:
        return gfx::Rect(0, 0, 1, 1);
      case TOP_RIGHT:
        return gfx::Rect(s.width() - 1, 0, 1, 1);
      case BOTTOM_LEFT:
        return gfx::Rect(0, s.height() - 1, 1, 1);
      case BOTTOM_RIGHT:
        return gfx::Rect(s.width() - 1, s.height() - 1, 1, 1);
    }
    NOTREACHED();
    return gfx::Rect();
  }
};

TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) {
  Corner corner = GetParam();

  // This size chosen to be larger than the interest rect size, which is
  // at least kPixelDistanceToRecord * 2 in each dimension.
  int tile_size = 100000;
  // The small number subtracted keeps the last tile in each axis larger than
  // the interest rect also.
  int offset = -100;
  gfx::Size base_tiling_size(6 * tile_size + offset, 6 * tile_size + offset);
  gfx::Size grow_down_tiling_size(6 * tile_size + offset,
                                  8 * tile_size + offset);
  gfx::Size grow_right_tiling_size(8 * tile_size + offset,
                                   6 * tile_size + offset);
  gfx::Size grow_both_tiling_size(8 * tile_size + offset,
                                  8 * tile_size + offset);

  Region invalidation;
  Region expected_invalidation;

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

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

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

  // We should have lost all of the recordings in the bottom row as none of them
  // are in the current interest rect (which is either the above or below it).
  EXPECT_EQ(6, pile_.tiling().num_tiles_x());
  EXPECT_EQ(8, pile_.tiling().num_tiles_y());
  for (int i = 0; i < 6; ++i) {
    for (int j = 0; j < 6; ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_EQ(j < 5, it != map.end() && it->second.GetPicture());
    }
  }

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

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

  // When shrinking, we should have lost all the recordings in the bottom row
  // not touching the interest rect.
  EXPECT_EQ(6, pile_.tiling().num_tiles_x());
  EXPECT_EQ(6, pile_.tiling().num_tiles_y());
  for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      bool expect_tile;
      switch (corner) {
        case TOP_LEFT:
        case TOP_RIGHT:
          expect_tile = j < 5;
          break;
        case BOTTOM_LEFT:
          // The interest rect in the bottom left tile means we'll record it.
          expect_tile = j < 5 || (j == 5 && i == 0);
          break;
        case BOTTOM_RIGHT:
          // The interest rect in the bottom right tile means we'll record it.
          expect_tile = j < 5 || (j == 5 && i == 5);
          break;
      }
      EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
    }
  }

  // When shrinking, the previously exposed region is invalidated.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
                                          gfx::Rect(base_tiling_size));
  // The whole bottom row of tiles (except any with the interest rect) are
  // dropped.
  gfx::Rect bottom_row_minus_existing_corner = gfx::UnionRects(
      pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(5, 5));
  switch (corner) {
    case TOP_LEFT:
    case TOP_RIGHT:
      // No tiles are kept in the changed region because it doesn't
      // intersect with the interest rect.
      break;
    case BOTTOM_LEFT:
      bottom_row_minus_existing_corner.Subtract(
          pile_.tiling().TileBounds(0, 5));
      break;
    case BOTTOM_RIGHT:
      bottom_row_minus_existing_corner.Subtract(
          pile_.tiling().TileBounds(5, 5));
      break;
  }

  expected_invalidation.Union(bottom_row_minus_existing_corner);
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost all of the recordings in the right column as none of
  // them are in the current interest rect (which is either entirely left or
  // right of it).
  EXPECT_EQ(8, pile_.tiling().num_tiles_x());
  EXPECT_EQ(6, pile_.tiling().num_tiles_y());
  for (int i = 0; i < 6; ++i) {
    for (int j = 0; j < 6; ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_EQ(i < 5, it != map.end() && it->second.GetPicture());
    }
  }

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

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

  // When shrinking, we should have lost all the recordings in the right column
  // not touching the interest rect.
  EXPECT_EQ(6, pile_.tiling().num_tiles_x());
  EXPECT_EQ(6, pile_.tiling().num_tiles_y());
  for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      bool expect_tile;
      switch (corner) {
        case TOP_LEFT:
        case BOTTOM_LEFT:
          // No tiles are kept in the changed region because it doesn't
          // intersect with the interest rect.
          expect_tile = i < 5;
          break;
        case TOP_RIGHT:
          // The interest rect in the top right tile means we'll record it.
          expect_tile = i < 5 || (j == 0 && i == 5);
          break;
        case BOTTOM_RIGHT:
          // The interest rect in the bottom right tile means we'll record it.
          expect_tile = i < 5 || (j == 5 && i == 5);
          break;
      }
      EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
    }
  }

  // When shrinking, the previously exposed region is invalidated.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
                                          gfx::Rect(base_tiling_size));
  // The whole right column of tiles (except for ones with the interest rect)
  // are dropped.
  gfx::Rect right_column_minus_existing_corner = gfx::UnionRects(
      pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5));
  switch (corner) {
    case TOP_LEFT:
    case BOTTOM_LEFT:
      break;
    case TOP_RIGHT:
      right_column_minus_existing_corner.Subtract(
          pile_.tiling().TileBounds(5, 0));
      break;
    case BOTTOM_RIGHT:
      right_column_minus_existing_corner.Subtract(
          pile_.tiling().TileBounds(5, 5));
      break;
  }
  expected_invalidation.Union(right_column_minus_existing_corner);
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

  // We should have lost the recordings in the right column and bottom row.
  EXPECT_EQ(8, pile_.tiling().num_tiles_x());
  EXPECT_EQ(8, pile_.tiling().num_tiles_y());
  for (int i = 0; i < 6; ++i) {
    for (int j = 0; j < 6; ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      EXPECT_EQ(i < 5 && j < 5, it != map.end() && it->second.GetPicture());
    }
  }

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

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

  // We should have lost the recordings in the right column and bottom row,
  // except where it intersects the interest rect.
  EXPECT_EQ(6, pile_.tiling().num_tiles_x());
  EXPECT_EQ(6, pile_.tiling().num_tiles_y());
  for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
    for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
      FakePicturePile::PictureMapKey key(i, j);
      FakePicturePile::PictureMap& map = pile_.picture_map();
      FakePicturePile::PictureMap::iterator it = map.find(key);
      bool expect_tile;
      switch (corner) {
        case TOP_LEFT:
          expect_tile = i < 5 && j < 5;
          break;
        case TOP_RIGHT:
          // The interest rect in the top right tile means we'll record it.
          expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5);
          break;
        case BOTTOM_LEFT:
          // The interest rect in the bottom left tile means we'll record it.
          expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0);
          break;
        case BOTTOM_RIGHT:
          // The interest rect in the bottom right tile means we'll record it.
          expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5);
          break;
      }
      EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture())
          << i << "," << j;
    }
  }

  // We invalidated all previous pixels in the recording.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size),
                                          gfx::Rect(base_tiling_size));
  // The whole right column and bottom row of tiles (except for ones with the
  // interest rect) are dropped.
  Region right_column_and_bottom_row_minus_existing_corner =
      right_column_and_bottom_row;
  switch (corner) {
    case TOP_LEFT:
      break;
    case BOTTOM_LEFT:
      right_column_and_bottom_row_minus_existing_corner.Subtract(
          pile_.tiling().TileBounds(0, 5));
      break;
    case TOP_RIGHT:
      right_column_and_bottom_row_minus_existing_corner.Subtract(
          pile_.tiling().TileBounds(5, 0));
      break;
    case BOTTOM_RIGHT:
      right_column_and_bottom_row_minus_existing_corner.Subtract(
          pile_.tiling().TileBounds(5, 5));
      break;
  }
  expected_invalidation.Union(
      right_column_and_bottom_row_minus_existing_corner);
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();
}

TEST_P(PicturePileResizeCornerTest, SmallResizePileOutsideInterestRect) {
  Corner corner = GetParam();

  // This size chosen to be larger than the interest rect size, which is
  // at least kPixelDistanceToRecord * 2 in each dimension.
  int tile_size = 100000;
  // The small number subtracted keeps the last tile in each axis larger than
  // the interest rect also.
  int offset = -100;
  gfx::Size base_tiling_size(6 * tile_size + offset, 6 * tile_size + offset);
  gfx::Size grow_down_tiling_size(6 * tile_size + offset,
                                  6 * tile_size + offset + 5);
  gfx::Size grow_right_tiling_size(6 * tile_size + offset + 5,
                                   6 * tile_size + offset);
  gfx::Size grow_both_tiling_size(6 * tile_size + offset + 5,
                                  6 * tile_size + offset + 5);

  Region invalidation;
  Region expected_invalidation;

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

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

  // In this test (unlike the large resize test), as all growing and shrinking
  // happens within tiles, the resulting invalidation is symmetrical, so use
  // this enum to repeat the test both ways.
  enum ChangeDirection { GROW, SHRINK, LAST_DIRECTION = SHRINK };

  // Grow downward.
  for (int dir = 0; dir <= LAST_DIRECTION; ++dir) {
    gfx::Size new_tiling_size =
        dir == GROW ? grow_down_tiling_size : base_tiling_size;
    UpdateWholePile();
    UpdateAndExpandInvalidation(&invalidation, new_tiling_size,
                                CornerSinglePixelRect(corner, new_tiling_size));

    // We should have lost the recordings in the bottom row that do not
    // intersect the interest rect.
    EXPECT_EQ(6, pile_.tiling().num_tiles_x());
    EXPECT_EQ(6, pile_.tiling().num_tiles_y());
    for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
      for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
        FakePicturePile::PictureMapKey key(i, j);
        FakePicturePile::PictureMap& map = pile_.picture_map();
        FakePicturePile::PictureMap::iterator it = map.find(key);
        bool expect_tile;
        switch (corner) {
          case TOP_LEFT:
          case TOP_RIGHT:
            expect_tile = j < 5;
            break;
          case BOTTOM_LEFT:
            // The interest rect in the bottom left tile means we'll record it.
            expect_tile = j < 5 || (j == 5 && i == 0);
            break;
          case BOTTOM_RIGHT:
            // The interest rect in the bottom right tile means we'll record it.
            expect_tile = j < 5 || (j == 5 && i == 5);
            break;
        }
        EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
      }
    }

    // We invalidated the bottom row outside the new interest rect. The tile
    // that insects the interest rect in invalidated only on its newly
    // exposed or previously exposed pixels.
    if (dir == GROW) {
      // Only calculate the expected invalidation while growing, as the tile
      // bounds post-growing is the newly exposed / previously exposed sizes.
      // Post-shrinking, the tile bounds are smaller, so can't be used.
      switch (corner) {
        case TOP_LEFT:
        case TOP_RIGHT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(5, 5));
          break;
        case BOTTOM_LEFT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(1, 5), pile_.tiling().TileBounds(5, 5));
          expected_invalidation.Union(SubtractRects(
              pile_.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size)));
          break;
        case BOTTOM_RIGHT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(4, 5));
          expected_invalidation.Union(SubtractRects(
              pile_.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
          break;
      }
    }
    EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
    invalidation.Clear();
  }

  // Grow right.
  for (int dir = 0; dir <= LAST_DIRECTION; ++dir) {
    gfx::Size new_tiling_size =
        dir == GROW ? grow_right_tiling_size : base_tiling_size;
    UpdateWholePile();
    UpdateAndExpandInvalidation(&invalidation, new_tiling_size,
                                CornerSinglePixelRect(corner, new_tiling_size));

    // We should have lost the recordings in the right column.
    EXPECT_EQ(6, pile_.tiling().num_tiles_x());
    EXPECT_EQ(6, pile_.tiling().num_tiles_y());
    for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
      for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
        FakePicturePile::PictureMapKey key(i, j);
        FakePicturePile::PictureMap& map = pile_.picture_map();
        FakePicturePile::PictureMap::iterator it = map.find(key);
        bool expect_tile;
        switch (corner) {
          case TOP_LEFT:
          case BOTTOM_LEFT:
            expect_tile = i < 5;
            break;
          case TOP_RIGHT:
            // The interest rect in the top right tile means we'll record it.
            expect_tile = i < 5 || (j == 0 && i == 5);
            break;
          case BOTTOM_RIGHT:
            // The interest rect in the bottom right tile means we'll record it.
            expect_tile = i < 5 || (j == 5 && i == 5);
            break;
        }
        EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
      }
    }

    // We invalidated the right column outside the new interest rect. The tile
    // that insects the interest rect in invalidated only on its new or
    // previously exposed pixels.
    if (dir == GROW) {
      // Calculate the expected invalidation the first time through the loop.
      switch (corner) {
        case TOP_LEFT:
        case BOTTOM_LEFT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5));
          break;
        case TOP_RIGHT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(5, 1), pile_.tiling().TileBounds(5, 5));
          expected_invalidation.Union(SubtractRects(
              pile_.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size)));
          break;
        case BOTTOM_RIGHT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 4));
          expected_invalidation.Union(SubtractRects(
              pile_.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
          break;
      }
    }
    EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
    invalidation.Clear();
  }

  // Grow both.
  for (int dir = 0; dir <= LAST_DIRECTION; ++dir) {
    gfx::Size new_tiling_size =
        dir == GROW ? grow_both_tiling_size : base_tiling_size;
    UpdateWholePile();
    UpdateAndExpandInvalidation(&invalidation, new_tiling_size,
                                CornerSinglePixelRect(corner, new_tiling_size));

    // We should have lost the recordings in the right column and bottom row.
    // The tile that insects the interest rect in invalidated only on its new
    // or previously exposed pixels.
    EXPECT_EQ(6, pile_.tiling().num_tiles_x());
    EXPECT_EQ(6, pile_.tiling().num_tiles_y());
    for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
      for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
        FakePicturePile::PictureMapKey key(i, j);
        FakePicturePile::PictureMap& map = pile_.picture_map();
        FakePicturePile::PictureMap::iterator it = map.find(key);
        bool expect_tile;
        switch (corner) {
          case TOP_LEFT:
            expect_tile = i < 5 && j < 5;
            break;
          case TOP_RIGHT:
            // The interest rect in the top right tile means we'll record it.
            expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5);
            break;
          case BOTTOM_LEFT:
            // The interest rect in the bottom left tile means we'll record it.
            expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0);
            break;
          case BOTTOM_RIGHT:
            // The interest rect in the bottom right tile means we'll record it.
            expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5);
            break;
        }
        EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture())
            << i << "," << j;
      }
    }

    // We invalidated the right column and the bottom row outside the new
    // interest rect. The tile that insects the interest rect in invalidated
    // only on its new or previous exposed pixels.
    if (dir == GROW) {
      // Calculate the expected invalidation the first time through the loop.
      switch (corner) {
        case TOP_LEFT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5));
          expected_invalidation.Union(
              gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
                              pile_.tiling().TileBounds(5, 5)));
          break;
        case TOP_RIGHT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(5, 1), pile_.tiling().TileBounds(5, 5));
          expected_invalidation.Union(
              gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
                              pile_.tiling().TileBounds(5, 5)));
          expected_invalidation.Union(SubtractRects(
              pile_.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size)));
          break;
        case BOTTOM_LEFT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5));
          expected_invalidation.Union(
              gfx::UnionRects(pile_.tiling().TileBounds(1, 5),
                              pile_.tiling().TileBounds(5, 5)));
          expected_invalidation.Union(SubtractRects(
              pile_.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size)));
          break;
        case BOTTOM_RIGHT:
          expected_invalidation = gfx::UnionRects(
              pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 4));
          expected_invalidation.Union(
              gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
                              pile_.tiling().TileBounds(4, 5)));
          expected_invalidation.Union(SubtractRegions(
              pile_.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
          break;
      }
    }
    EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
    invalidation.Clear();
  }
}

INSTANTIATE_TEST_CASE_P(
    PicturePileResizeCornerTests,
    PicturePileResizeCornerTest,
    ::testing::Values(TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT));

TEST_F(PicturePileTest, ResizePileInsideInterestRect) {
  // This size chosen to be small enough that all the rects below fit inside the
  // the interest rect, so they are smaller than kPixelDistanceToRecord in each
  // dimension.
  int tile_size = 100;
  gfx::Size base_tiling_size(5 * tile_size, 5 * tile_size);
  gfx::Size grow_down_tiling_size(5 * tile_size, 7 * tile_size);
  gfx::Size grow_right_tiling_size(7 * tile_size, 5 * tile_size);
  gfx::Size grow_both_tiling_size(7 * tile_size, 7 * tile_size);

  Region invalidation;
  Region expected_invalidation;

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

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

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

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

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

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

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

  // We invalidated the previously exposed pixels on the bottom row of tiles.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_TRUE(expected_invalidation.Contains(bottom_row_new_pixels));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

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

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

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

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

  // We invalidated the previously exposed pixels on the right column of tiles.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_TRUE(expected_invalidation.Contains(right_column_new_pixels));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

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

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

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

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

  // We invalidated the previously exposed pixels on the bottom row and right
  // column of tiles.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_TRUE(
      expected_invalidation.Contains(bottom_row_and_right_column_new_pixels));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();
}

TEST_F(PicturePileTest, SmallResizePileInsideInterestRect) {
  // This size chosen to be small enough that all the rects below fit inside the
  // the interest rect, so they are smaller than kPixelDistanceToRecord in each
  // dimension.
  int tile_size = 100;
  gfx::Size base_tiling_size(5 * tile_size, 5 * tile_size);
  gfx::Size grow_down_tiling_size(5 * tile_size, 5 * tile_size + 5);
  gfx::Size grow_right_tiling_size(5 * tile_size + 5, 5 * tile_size);
  gfx::Size grow_both_tiling_size(5 * tile_size + 5, 5 * tile_size + 5);

  Region invalidation;
  Region expected_invalidation;

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

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

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

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

  // We invalidated the newly exposed pixels.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

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

  // We invalidated the previously exposed pixels.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

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

  // We invalidated the newly exposed pixels.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

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

  // We invalidated the previously exposed pixels.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

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

  // We invalidated the newly exposed pixels.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();

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

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

  // We invalidated the previously exposed pixels.
  expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size),
                                          gfx::Rect(base_tiling_size));
  EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
  invalidation.Clear();
}

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

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

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

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

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

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

  SkPaint paint;
  paint.setColor(SK_ColorCYAN);

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

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

}  // namespace
}  // namespace cc
