#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/test_context_provider.h"
+#include "cc/test/test_shared_bitmap_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/size_conversions.h"
return ToEnclosingRect(viewport_in_layer_space);
}
+static void UpdateAllTilePriorities(PictureLayerTilingSet* set,
+ WhichTree tree,
+ const gfx::Rect& visible_layer_rect,
+ float layer_contents_scale,
+ double current_frame_time_in_seconds) {
+ for (size_t i = 0; i < set->num_tilings(); ++i) {
+ set->tiling_at(i)->UpdateTilePriorities(tree,
+ visible_layer_rect,
+ layer_contents_scale,
+ current_frame_time_in_seconds,
+ Occlusion());
+ }
+}
+
class TestablePictureLayerTiling : public PictureLayerTiling {
public:
using PictureLayerTiling::SetLiveTilesRect;
client));
}
+ gfx::Rect live_tiles_rect() const { return live_tiles_rect_; }
+
using PictureLayerTiling::ComputeSkewport;
protected:
float contents_scale,
const gfx::Size& layer_bounds) {
client_.SetTileSize(tile_size);
+ client_.set_tree(PENDING_TREE);
tiling_ = TestablePictureLayerTiling::Create(contents_scale,
layer_bounds,
&client_);
const gfx::Rect& dest_rect) {
float dest_to_contents_scale = tiling_->contents_scale() / rect_scale;
gfx::Rect clamped_rect = gfx::ScaleToEnclosingRect(
- tiling_->ContentRect(), 1.f / dest_to_contents_scale);
+ gfx::Rect(tiling_->tiling_size()), 1.f / dest_to_contents_scale);
clamped_rect.Intersect(dest_rect);
VerifyTilesExactlyCoverRect(rect_scale, dest_rect, clamped_rect);
}
DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest);
};
+TEST_F(PictureLayerTilingIteratorTest, ResizeDeletesTiles) {
+ // Verifies that a resize with invalidation for newly exposed pixels will
+ // deletes tiles that intersect that invalidation.
+ gfx::Size tile_size(100, 100);
+ gfx::Size original_layer_size(10, 10);
+ Initialize(tile_size, 1.f, original_layer_size);
+ SetLiveRectAndVerifyTiles(gfx::Rect(original_layer_size));
+
+ // Tiling only has one tile, since its total size is less than one.
+ EXPECT_TRUE(tiling_->TileAt(0, 0));
+
+ // Stop creating tiles so that any invalidations are left as holes.
+ client_.set_allow_create_tile(false);
+
+ Region invalidation =
+ SubtractRegions(gfx::Rect(tile_size), gfx::Rect(original_layer_size));
+ tiling_->UpdateTilesToCurrentPile(invalidation, gfx::Size(200, 200));
+ EXPECT_FALSE(tiling_->TileAt(0, 0));
+}
+
+TEST_F(PictureLayerTilingIteratorTest, CreateMissingTilesStaysInsideLiveRect) {
+ // The tiling has three rows and columns.
+ Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 250));
+ EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
+ EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_y());
+
+ // The live tiles rect is at the very edge of the right-most and
+ // bottom-most tiles. Their border pixels would still be inside the live
+ // tiles rect, but the tiles should not exist just for that.
+ int right = tiling_->TilingDataForTesting().TileBounds(2, 2).x();
+ int bottom = tiling_->TilingDataForTesting().TileBounds(2, 2).y();
+
+ SetLiveRectAndVerifyTiles(gfx::Rect(right, bottom));
+ EXPECT_FALSE(tiling_->TileAt(2, 0));
+ EXPECT_FALSE(tiling_->TileAt(2, 1));
+ EXPECT_FALSE(tiling_->TileAt(2, 2));
+ EXPECT_FALSE(tiling_->TileAt(1, 2));
+ EXPECT_FALSE(tiling_->TileAt(0, 2));
+
+ // Verify CreateMissingTilesInLiveTilesRect respects this.
+ tiling_->CreateMissingTilesInLiveTilesRect();
+ EXPECT_FALSE(tiling_->TileAt(2, 0));
+ EXPECT_FALSE(tiling_->TileAt(2, 1));
+ EXPECT_FALSE(tiling_->TileAt(2, 2));
+ EXPECT_FALSE(tiling_->TileAt(1, 2));
+ EXPECT_FALSE(tiling_->TileAt(0, 2));
+}
+
+TEST_F(PictureLayerTilingIteratorTest, ResizeTilingOverTileBorders) {
+ // The tiling has four rows and three columns.
+ Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
+ EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
+ EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
+
+ // The live tiles rect covers the whole tiling.
+ SetLiveRectAndVerifyTiles(gfx::Rect(250, 350));
+
+ // Tiles in the bottom row and right column exist.
+ EXPECT_TRUE(tiling_->TileAt(2, 0));
+ EXPECT_TRUE(tiling_->TileAt(2, 1));
+ EXPECT_TRUE(tiling_->TileAt(2, 2));
+ EXPECT_TRUE(tiling_->TileAt(2, 3));
+ EXPECT_TRUE(tiling_->TileAt(1, 3));
+ EXPECT_TRUE(tiling_->TileAt(0, 3));
+
+ int right = tiling_->TilingDataForTesting().TileBounds(2, 2).x();
+ int bottom = tiling_->TilingDataForTesting().TileBounds(2, 3).y();
+
+ // Shrink the tiling so that the last tile row/column is entirely in the
+ // border pixels of the interior tiles. That row/column is removed.
+ Region invalidation;
+ tiling_->UpdateTilesToCurrentPile(invalidation,
+ gfx::Size(right + 1, bottom + 1));
+ EXPECT_EQ(2, tiling_->TilingDataForTesting().num_tiles_x());
+ EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_y());
+
+ // The live tiles rect was clamped to the pile size.
+ EXPECT_EQ(gfx::Rect(right + 1, bottom + 1), tiling_->live_tiles_rect());
+
+ // Since the row/column is gone, the tiles should be gone too.
+ EXPECT_FALSE(tiling_->TileAt(2, 0));
+ EXPECT_FALSE(tiling_->TileAt(2, 1));
+ EXPECT_FALSE(tiling_->TileAt(2, 2));
+ EXPECT_FALSE(tiling_->TileAt(2, 3));
+ EXPECT_FALSE(tiling_->TileAt(1, 3));
+ EXPECT_FALSE(tiling_->TileAt(0, 3));
+
+ // Growing outside the current right/bottom tiles border pixels should create
+ // the tiles again, even though the live rect has not changed size.
+ tiling_->UpdateTilesToCurrentPile(invalidation,
+ gfx::Size(right + 2, bottom + 2));
+ EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
+ EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
+
+ // Not changed.
+ EXPECT_EQ(gfx::Rect(right + 1, bottom + 1), tiling_->live_tiles_rect());
+
+ // The last row/column tiles are inside the live tiles rect.
+ EXPECT_TRUE(gfx::Rect(right + 1, bottom + 1).Intersects(
+ tiling_->TilingDataForTesting().TileBounds(2, 0)));
+ EXPECT_TRUE(gfx::Rect(right + 1, bottom + 1).Intersects(
+ tiling_->TilingDataForTesting().TileBounds(0, 3)));
+
+ EXPECT_TRUE(tiling_->TileAt(2, 0));
+ EXPECT_TRUE(tiling_->TileAt(2, 1));
+ EXPECT_TRUE(tiling_->TileAt(2, 2));
+ EXPECT_TRUE(tiling_->TileAt(2, 3));
+ EXPECT_TRUE(tiling_->TileAt(1, 3));
+ EXPECT_TRUE(tiling_->TileAt(0, 3));
+}
+
+TEST_F(PictureLayerTilingIteratorTest, ResizeLiveTileRectOverTileBorders) {
+ // The tiling has three rows and columns.
+ Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
+ EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
+ EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
+
+ // The live tiles rect covers the whole tiling.
+ SetLiveRectAndVerifyTiles(gfx::Rect(250, 350));
+
+ // Tiles in the bottom row and right column exist.
+ EXPECT_TRUE(tiling_->TileAt(2, 0));
+ EXPECT_TRUE(tiling_->TileAt(2, 1));
+ EXPECT_TRUE(tiling_->TileAt(2, 2));
+ EXPECT_TRUE(tiling_->TileAt(2, 3));
+ EXPECT_TRUE(tiling_->TileAt(1, 3));
+ EXPECT_TRUE(tiling_->TileAt(0, 3));
+
+ // Shrink the live tiles rect to the very edge of the right-most and
+ // bottom-most tiles. Their border pixels would still be inside the live
+ // tiles rect, but the tiles should not exist just for that.
+ int right = tiling_->TilingDataForTesting().TileBounds(2, 3).x();
+ int bottom = tiling_->TilingDataForTesting().TileBounds(2, 3).y();
+
+ SetLiveRectAndVerifyTiles(gfx::Rect(right, bottom));
+ EXPECT_FALSE(tiling_->TileAt(2, 0));
+ EXPECT_FALSE(tiling_->TileAt(2, 1));
+ EXPECT_FALSE(tiling_->TileAt(2, 2));
+ EXPECT_FALSE(tiling_->TileAt(2, 3));
+ EXPECT_FALSE(tiling_->TileAt(1, 3));
+ EXPECT_FALSE(tiling_->TileAt(0, 3));
+
+ // Including the bottom row and right column again, should create the tiles.
+ SetLiveRectAndVerifyTiles(gfx::Rect(right + 1, bottom + 1));
+ EXPECT_TRUE(tiling_->TileAt(2, 0));
+ EXPECT_TRUE(tiling_->TileAt(2, 1));
+ EXPECT_TRUE(tiling_->TileAt(2, 2));
+ EXPECT_TRUE(tiling_->TileAt(2, 3));
+ EXPECT_TRUE(tiling_->TileAt(1, 2));
+ EXPECT_TRUE(tiling_->TileAt(0, 2));
+
+ // Shrink the live tiles rect to the very edge of the left-most and
+ // top-most tiles. Their border pixels would still be inside the live
+ // tiles rect, but the tiles should not exist just for that.
+ int left = tiling_->TilingDataForTesting().TileBounds(0, 0).right();
+ int top = tiling_->TilingDataForTesting().TileBounds(0, 0).bottom();
+
+ SetLiveRectAndVerifyTiles(gfx::Rect(left, top, 250 - left, 350 - top));
+ EXPECT_FALSE(tiling_->TileAt(0, 3));
+ EXPECT_FALSE(tiling_->TileAt(0, 2));
+ EXPECT_FALSE(tiling_->TileAt(0, 1));
+ EXPECT_FALSE(tiling_->TileAt(0, 0));
+ EXPECT_FALSE(tiling_->TileAt(1, 0));
+ EXPECT_FALSE(tiling_->TileAt(2, 0));
+
+ // Including the top row and left column again, should create the tiles.
+ SetLiveRectAndVerifyTiles(
+ gfx::Rect(left - 1, top - 1, 250 - left, 350 - top));
+ EXPECT_TRUE(tiling_->TileAt(0, 3));
+ EXPECT_TRUE(tiling_->TileAt(0, 2));
+ EXPECT_TRUE(tiling_->TileAt(0, 1));
+ EXPECT_TRUE(tiling_->TileAt(0, 0));
+ EXPECT_TRUE(tiling_->TileAt(1, 0));
+ EXPECT_TRUE(tiling_->TileAt(2, 0));
+}
+
+TEST_F(PictureLayerTilingIteratorTest, ResizeLiveTileRectOverSameTiles) {
+ // The tiling has four rows and three columns.
+ Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
+ EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
+ EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
+
+ // The live tiles rect covers the whole tiling.
+ SetLiveRectAndVerifyTiles(gfx::Rect(250, 350));
+
+ // All tiles exist.
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 4; ++j)
+ EXPECT_TRUE(tiling_->TileAt(i, j)) << i << "," << j;
+ }
+
+ // Shrink the live tiles rect, but still cover all the tiles.
+ SetLiveRectAndVerifyTiles(gfx::Rect(1, 1, 249, 349));
+
+ // All tiles still exist.
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 4; ++j)
+ EXPECT_TRUE(tiling_->TileAt(i, j)) << i << "," << j;
+ }
+
+ // Grow the live tiles rect, but still cover all the same tiles.
+ SetLiveRectAndVerifyTiles(gfx::Rect(0, 0, 250, 350));
+
+ // All tiles still exist.
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 4; ++j)
+ EXPECT_TRUE(tiling_->TileAt(i, j)) << i << "," << j;
+ }
+}
+
+TEST_F(PictureLayerTilingIteratorTest, ResizeOverBorderPixelsDeletesTiles) {
+ // Verifies that a resize with invalidation for newly exposed pixels will
+ // deletes tiles that intersect that invalidation.
+ gfx::Size tile_size(100, 100);
+ gfx::Size original_layer_size(99, 99);
+ Initialize(tile_size, 1.f, original_layer_size);
+ SetLiveRectAndVerifyTiles(gfx::Rect(original_layer_size));
+
+ // Tiling only has one tile, since its total size is less than one.
+ EXPECT_TRUE(tiling_->TileAt(0, 0));
+
+ // Stop creating tiles so that any invalidations are left as holes.
+ client_.set_allow_create_tile(false);
+
+ Region invalidation =
+ SubtractRegions(gfx::Rect(tile_size), gfx::Rect(original_layer_size));
+ tiling_->UpdateTilesToCurrentPile(invalidation, gfx::Size(200, 200));
+ EXPECT_FALSE(tiling_->TileAt(0, 0));
+
+ // The original tile was the same size after resize, but it would include new
+ // border pixels.
+ EXPECT_EQ(gfx::Rect(original_layer_size),
+ tiling_->TilingDataForTesting().TileBounds(0, 0));
+}
+
TEST_F(PictureLayerTilingIteratorTest, LiveTilesExactlyCoverLiveTileRect) {
Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
SetLiveRectAndVerifyTiles(gfx::Rect(100, 100));
TEST(PictureLayerTilingTest, SkewportLimits) {
FakePictureLayerTilingClient client;
client.set_skewport_extrapolation_limit_in_content_pixels(75);
+ client.set_tree(ACTIVE_TREE);
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Rect viewport(0, 0, 100, 100);
client.SetTileSize(gfx::Size(100, 100));
tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
- tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
// Move viewport down 50 pixels in 0.5 seconds.
gfx::Rect down_skewport =
gfx::Size layer_bounds(200, 200);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
- tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
// Move viewport down 50 pixels in 0.5 seconds.
gfx::Rect down_skewport =
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Rect viewport(0, 0, 100, 100);
- gfx::Size layer_bounds(200, 200);
+ gfx::Size layer_bounds(1500, 1500);
client.SetTileSize(gfx::Size(10, 10));
+ client.set_tree(ACTIVE_TREE);
- // Tiling at 0.25 scale: this should create 36 tiles (6x6) of size 10x10.
+ // Tiling at 0.25 scale: this should create 47x47 tiles of size 10x10.
// The reason is that each tile has a one pixel border, so tile at (1, 2)
- // for instance begins at (8, 16) pixels. So tile at (5, 5) will begin at
- // (40, 40) and extend right to the end of 200 * 0.25 = 50 edge of the
+ // for instance begins at (8, 16) pixels. So tile at (46, 46) will begin at
+ // (368, 368) and extend to the end of 1500 * 0.25 = 375 edge of the
// tiling.
tiling = TestablePictureLayerTiling::Create(0.25f, layer_bounds, &client);
gfx::Rect viewport_in_content_space =
gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
- tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
+
+ gfx::Rect soon_rect = viewport;
+ soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
+ gfx::Rect soon_rect_in_content_space =
+ gfx::ToEnclosedRect(gfx::ScaleRect(soon_rect, 0.25f));
// Sanity checks.
- for (int i = 0; i < 6; ++i) {
- for (int j = 0; j < 6; ++j) {
+ for (int i = 0; i < 47; ++i) {
+ for (int j = 0; j < 47; ++j) {
EXPECT_TRUE(tiling->TileAt(i, j)) << "i: " << i << " j: " << j;
}
}
- for (int i = 0; i < 7; ++i) {
- EXPECT_FALSE(tiling->TileAt(i, 6)) << "i: " << i;
- EXPECT_FALSE(tiling->TileAt(6, i)) << "i: " << i;
+ for (int i = 0; i < 47; ++i) {
+ EXPECT_FALSE(tiling->TileAt(i, 47)) << "i: " << i;
+ EXPECT_FALSE(tiling->TileAt(47, i)) << "i: " << i;
}
// No movement in the viewport implies that tiles will either be NOW
- // or EVENTUALLY.
+ // or EVENTUALLY, with the exception of tiles that are between 0 and 312
+ // pixels away from the viewport, which will be in the SOON bin.
bool have_now = false;
bool have_eventually = false;
- for (int i = 0; i < 6; ++i) {
- for (int j = 0; j < 6; ++j) {
+ bool have_soon = false;
+ for (int i = 0; i < 47; ++i) {
+ for (int j = 0; j < 47; ++j) {
Tile* tile = tiling->TileAt(i, j);
TilePriority priority = tile->priority(ACTIVE_TREE);
- if (viewport_in_content_space.Intersects(tile->content_rect())) {
+ gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j);
+ if (viewport_in_content_space.Intersects(tile_rect)) {
EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
have_now = true;
+ } else if (soon_rect_in_content_space.Intersects(tile_rect)) {
+ EXPECT_EQ(TilePriority::SOON, priority.priority_bin);
+ have_soon = true;
} else {
EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin);
EXPECT_GT(priority.distance_to_visible, 0.f);
}
EXPECT_TRUE(have_now);
+ EXPECT_TRUE(have_soon);
EXPECT_TRUE(have_eventually);
// Spot check some distances.
gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
gfx::Rect skewport = tiling->ComputeSkewport(2.0, viewport_in_content_space);
+ soon_rect = viewport;
+ soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
+ soon_rect_in_content_space =
+ gfx::ToEnclosedRect(gfx::ScaleRect(soon_rect, 0.25f));
+
EXPECT_EQ(0, skewport.x());
EXPECT_EQ(10, skewport.y());
EXPECT_EQ(25, skewport.width());
EXPECT_EQ(35, skewport.height());
- tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 2.0);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 2.0, Occlusion());
have_now = false;
have_eventually = false;
- bool have_soon = false;
+ have_soon = false;
// Viewport moved, so we expect to find some NOW tiles, some SOON tiles and
// some EVENTUALLY tiles.
- for (int i = 0; i < 6; ++i) {
- for (int j = 0; j < 6; ++j) {
+ for (int i = 0; i < 47; ++i) {
+ for (int j = 0; j < 47; ++j) {
Tile* tile = tiling->TileAt(i, j);
TilePriority priority = tile->priority(ACTIVE_TREE);
- if (viewport_in_content_space.Intersects(tile->content_rect())) {
+ gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j);
+ if (viewport_in_content_space.Intersects(tile_rect)) {
EXPECT_EQ(TilePriority::NOW, priority.priority_bin) << "i: " << i
<< " j: " << j;
EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i
<< " j: " << j;
have_now = true;
- } else if (skewport.Intersects(tile->content_rect())) {
+ } else if (skewport.Intersects(tile_rect) ||
+ soon_rect_in_content_space.Intersects(tile_rect)) {
EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i
<< " j: " << j;
EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
EXPECT_FLOAT_EQ(28.f, priority.distance_to_visible);
priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
- EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
+ EXPECT_FLOAT_EQ(4.f, priority.distance_to_visible);
// Change the underlying layer scale.
- tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 2.0f, 3.0);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 2.0f, 3.0, Occlusion());
priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
- EXPECT_FLOAT_EQ(34.f, priority.distance_to_visible);
+ EXPECT_FLOAT_EQ(136.f, priority.distance_to_visible);
priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
- EXPECT_FLOAT_EQ(14.f, priority.distance_to_visible);
+ EXPECT_FLOAT_EQ(56.f, priority.distance_to_visible);
priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
- EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
+ EXPECT_FLOAT_EQ(8.f, priority.distance_to_visible);
+
+ // Test additional scales.
+ tiling = TestablePictureLayerTiling::Create(0.2f, layer_bounds, &client);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 4.0, Occlusion());
+
+ priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(110.f, priority.distance_to_visible);
+
+ priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(70.f, priority.distance_to_visible);
+
+ priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(60.f, priority.distance_to_visible);
+
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 0.5f, 5.0, Occlusion());
+
+ priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(55.f, priority.distance_to_visible);
+
+ priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(35.f, priority.distance_to_visible);
+
+ priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
+ EXPECT_FLOAT_EQ(30.f, priority.distance_to_visible);
}
TEST(PictureLayerTilingTest, ExpandRectEqual) {
EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
EXPECT_EQ(out.width() - in.width(), out.height() - in.height());
- EXPECT_NEAR(100 * 100, out.width() * out.height(), 50);
+
+ // |in| represents the visible rect, and |out| represents the eventually rect.
+ // If the eventually rect doesn't contain the visible rect, we will start
+ // losing tiles.
+ EXPECT_TRUE(out.Contains(in));
EXPECT_TRUE(bounds.Contains(out));
}
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Rect viewport(50, 50, 100, 100);
- gfx::Size layer_bounds(200, 200);
+ gfx::Size layer_bounds(800, 800);
+
+ gfx::Rect soon_rect = viewport;
+ soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
client.SetTileSize(gfx::Size(30, 30));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
- tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
PictureLayerTiling::TilingRasterTileIterator empty_iterator;
EXPECT_FALSE(empty_iterator);
std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
// Sanity check.
- EXPECT_EQ(64u, all_tiles.size());
+ EXPECT_EQ(841u, all_tiles.size());
// The explanation of each iteration is as follows:
// 1. First iteration tests that we can get all of the tiles correctly.
new_priority.distance_to_visible;
eventually_bin_order_correct_count += order_correct;
eventually_bin_order_incorrect_count += !order_correct;
- } else {
+ } else if (!soon_rect.Intersects(new_tile->content_rect()) &&
+ !soon_rect.Intersects(last_tile->content_rect())) {
EXPECT_LE(last_priority.distance_to_visible,
new_priority.distance_to_visible);
+ EXPECT_EQ(TilePriority::NOW, new_priority.priority_bin);
+ } else if (new_priority.distance_to_visible > 0.f) {
+ EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
}
}
have_tiles[new_priority.priority_bin] = true;
EXPECT_GT(eventually_bin_order_correct_count,
eventually_bin_order_incorrect_count);
- // We should have now and eventually tiles, but not soon tiles because the
- // viewport is static.
+ // We should have now and eventually tiles, as well as soon tiles from
+ // the border region.
EXPECT_TRUE(have_tiles[TilePriority::NOW]);
- EXPECT_FALSE(have_tiles[TilePriority::SOON]);
+ EXPECT_TRUE(have_tiles[TilePriority::SOON]);
EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
EXPECT_EQ(unique_tiles.size(), all_tiles.size());
scoped_ptr<TestablePictureLayerTiling> tiling;
gfx::Rect viewport(50, 0, 100, 100);
- gfx::Rect moved_viewport(50, 0, 100, 250);
- gfx::Size layer_bounds(500, 500);
+ gfx::Rect moved_viewport(50, 0, 100, 500);
+ gfx::Size layer_bounds(1000, 1000);
client.SetTileSize(gfx::Size(30, 30));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.f, layer_bounds, &client);
- tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0);
- tiling->UpdateTilePriorities(ACTIVE_TREE, moved_viewport, 1.0f, 2.0);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
+ tiling->UpdateTilePriorities(
+ ACTIVE_TREE, moved_viewport, 1.0f, 2.0, Occlusion());
+
+ gfx::Rect soon_rect = moved_viewport;
+ soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
// There are 3 bins in TilePriority.
bool have_tiles[3] = {};
new_priority.distance_to_visible;
eventually_bin_order_correct_count += order_correct;
eventually_bin_order_incorrect_count += !order_correct;
- } else {
+ } else if (!soon_rect.Intersects(new_tile->content_rect()) &&
+ !soon_rect.Intersects(last_tile->content_rect())) {
EXPECT_LE(last_priority.distance_to_visible,
new_priority.distance_to_visible);
+ } else if (new_priority.distance_to_visible > 0.f) {
+ EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
}
}
last_tile = new_tile;
EXPECT_EQ(exists, tile != NULL) << geometry_rect.ToString();
}
+TEST(PictureLayerTilingTest, TilingEvictionTileIteratorStaticViewport) {
+ FakeOutputSurfaceClient output_surface_client;
+ scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d();
+ CHECK(output_surface->BindToClient(&output_surface_client));
+ TestSharedBitmapManager shared_bitmap_manager;
+ scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
+ output_surface.get(), &shared_bitmap_manager, NULL, 0, false, 1, false);
+
+ FakePictureLayerTilingClient client(resource_provider.get());
+ scoped_ptr<TestablePictureLayerTiling> tiling;
+
+ gfx::Rect viewport(50, 50, 100, 100);
+ gfx::Size layer_bounds(2000, 2000);
+
+ client.SetTileSize(gfx::Size(30, 30));
+ client.set_tree(ACTIVE_TREE);
+
+ tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
+
+ PictureLayerTiling::TilingRasterTileIterator empty_iterator;
+ EXPECT_FALSE(empty_iterator);
+
+ std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
+
+ PictureLayerTiling::TilingEvictionTileIterator it(
+ tiling.get(), SMOOTHNESS_TAKES_PRIORITY, PictureLayerTiling::NOW);
+
+ // Tiles don't have resources to evict.
+ EXPECT_FALSE(it);
+
+ // Sanity check.
+ EXPECT_EQ(5184u, all_tiles.size());
+
+ client.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles);
+
+ std::set<Tile*> all_tiles_set(all_tiles.begin(), all_tiles.end());
+
+ std::set<Tile*> eviction_tiles;
+
+ it = PictureLayerTiling::TilingEvictionTileIterator(
+ tiling.get(), SMOOTHNESS_TAKES_PRIORITY, PictureLayerTiling::EVENTUALLY);
+ EXPECT_TRUE(it);
+ for (; it; ++it) {
+ Tile* tile = *it;
+ EXPECT_TRUE(tile);
+ EXPECT_EQ(TilePriority::EVENTUALLY,
+ tile->priority(ACTIVE_TREE).priority_bin);
+ EXPECT_FALSE(tile->required_for_activation());
+ eviction_tiles.insert(tile);
+ }
+
+ it = PictureLayerTiling::TilingEvictionTileIterator(
+ tiling.get(), SMOOTHNESS_TAKES_PRIORITY, PictureLayerTiling::SOON);
+ EXPECT_TRUE(it);
+ for (; it; ++it) {
+ Tile* tile = *it;
+ EXPECT_TRUE(tile);
+ EXPECT_EQ(TilePriority::SOON, tile->priority(ACTIVE_TREE).priority_bin);
+ EXPECT_FALSE(tile->required_for_activation());
+ eviction_tiles.insert(tile);
+ }
+
+ it = PictureLayerTiling::TilingEvictionTileIterator(
+ tiling.get(), SMOOTHNESS_TAKES_PRIORITY, PictureLayerTiling::NOW);
+ EXPECT_TRUE(it);
+ for (; it; ++it) {
+ Tile* tile = *it;
+ EXPECT_TRUE(tile);
+ EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin);
+ EXPECT_FALSE(tile->required_for_activation());
+ eviction_tiles.insert(tile);
+ }
+
+ it = PictureLayerTiling::TilingEvictionTileIterator(
+ tiling.get(),
+ SMOOTHNESS_TAKES_PRIORITY,
+ PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION);
+ EXPECT_FALSE(it);
+
+ EXPECT_GT(all_tiles_set.size(), 0u);
+ EXPECT_EQ(all_tiles_set, eviction_tiles);
+}
+
TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
gfx::Size layer_bounds(1099, 801);
Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
+ client_.set_tree(ACTIVE_TREE);
tiling_->UpdateTilePriorities(
ACTIVE_TREE,
gfx::Rect(layer_bounds), // visible content rect
1.f, // current contents scale
- 1.0); // current frame time
+ 1.0, // current frame time
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
// Make the viewport rect empty. All tiles are killed and become zombies.
tiling_->UpdateTilePriorities(ACTIVE_TREE,
gfx::Rect(), // visible content rect
1.f, // current contents scale
- 2.0); // current frame time
+ 2.0, // current frame time
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
}
gfx::Rect giant_rect(-10000000, -10000000, 1000000000, 1000000000);
+ client_.set_tree(ACTIVE_TREE);
tiling_->UpdateTilePriorities(
ACTIVE_TREE,
gfx::Rect(layer_bounds), // visible content rect
1.f, // current contents scale
- 1.0); // current frame time
+ 1.0, // current frame time
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
// If the visible content rect is empty, it should still have live tiles.
tiling_->UpdateTilePriorities(ACTIVE_TREE,
giant_rect, // visible content rect
1.f, // current contents scale
- 2.0); // current frame time
+ 2.0, // current frame time
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
}
gfx::Rect viewport_rect(1100, 0, 1000, 1000);
EXPECT_FALSE(viewport_rect.Intersects(gfx::Rect(layer_bounds)));
+ client_.set_tree(ACTIVE_TREE);
tiling_->UpdateTilePriorities(ACTIVE_TREE,
viewport_rect, // visible content rect
1.f, // current contents scale
- 1.0); // current frame time
+ 1.0, // current frame time
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
}
gfx::Rect visible_rect(8000, 8000, 50, 50);
+ client_.set_tree(ACTIVE_TREE);
set_max_tiles_for_interest_area(1);
tiling_->UpdateTilePriorities(ACTIVE_TREE,
visible_rect, // visible content rect
1.f, // current contents scale
- 1.0); // current frame time
+ 1.0, // current frame time
+ Occlusion());
VerifyTiles(1.f,
gfx::Rect(layer_bounds),
base::Bind(&TilesIntersectingRectExist, visible_rect, true));
}
-static void CountExistingTiles(int *count,
- Tile* tile,
- const gfx::Rect& geometry_rect) {
- if (tile != NULL)
- ++(*count);
-}
-
-TEST_F(PictureLayerTilingIteratorTest,
- TilesExistLargeViewportAndLayerWithLargeVisibleArea) {
- gfx::Size layer_bounds(10000, 10000);
- Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
- VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
- VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
-
- set_max_tiles_for_interest_area(1);
- tiling_->UpdateTilePriorities(
- ACTIVE_TREE,
- gfx::Rect(layer_bounds), // visible content rect
- 1.f, // current contents scale
- 1.0); // current frame time
-
- int num_tiles = 0;
- VerifyTiles(1.f,
- gfx::Rect(layer_bounds),
- base::Bind(&CountExistingTiles, &num_tiles));
- // If we're making a rect the size of one tile, it can only overlap up to 4
- // tiles depending on its position.
- EXPECT_LE(num_tiles, 4);
- VerifyTiles(1.f, gfx::Rect(), base::Bind(&TileExists, false));
-}
-
TEST_F(PictureLayerTilingIteratorTest, AddTilingsToMatchScale) {
gfx::Size layer_bounds(1099, 801);
gfx::Size tile_size(100, 100);
client_.SetTileSize(tile_size);
+ client_.set_tree(PENDING_TREE);
PictureLayerTilingSet active_set(&client_, layer_bounds);
gfx::Rect(layer_bounds),
base::Bind(&TileExists, false));
- active_set.UpdateTilePriorities(
- PENDING_TREE,
- gfx::Rect(layer_bounds), // visible content rect
- 1.f, // current contents scale
- 1.0); // current frame time
+ UpdateAllTilePriorities(&active_set,
+ PENDING_TREE,
+ gfx::Rect(layer_bounds), // visible content rect
+ 1.f, // current contents scale
+ 1.0); // current frame time
// The active tiling has tiles now.
VerifyTiles(active_set.tiling_at(0),
// UpdateTilePriorities on the pending tiling at the same frame time. The
// pending tiling should get tiles.
- pending_set.UpdateTilePriorities(
- PENDING_TREE,
- gfx::Rect(layer_bounds), // visible content rect
- 1.f, // current contents scale
- 1.0); // current frame time
+ UpdateAllTilePriorities(&pending_set,
+ PENDING_TREE,
+ gfx::Rect(layer_bounds), // visible content rect
+ 1.f, // current contents scale
+ 1.0); // current frame time
VerifyTiles(pending_set.tiling_at(0),
1.f,
current_screen_transform, device_viewport);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
- current_frame_time_in_seconds);
+ current_frame_time_in_seconds,
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
current_screen_transform, device_viewport);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
- current_frame_time_in_seconds);
+ current_frame_time_in_seconds,
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
current_screen_transform, device_viewport);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
- current_frame_time_in_seconds);
+ current_frame_time_in_seconds,
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
current_screen_transform, device_viewport);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
- current_frame_time_in_seconds);
+ current_frame_time_in_seconds,
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
current_screen_transform, device_viewport);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
- current_frame_time_in_seconds);
+ current_frame_time_in_seconds,
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
current_screen_transform, device_viewport);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
- current_frame_time_in_seconds);
+ current_frame_time_in_seconds,
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
current_screen_transform, device_viewport);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
last_layer_contents_scale,
- last_frame_time_in_seconds);
+ last_frame_time_in_seconds,
+ Occlusion());
// current frame
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
- current_frame_time_in_seconds);
+ current_frame_time_in_seconds,
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
current_screen_transform, device_viewport);
client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
current_layer_bounds,
&client);
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
last_layer_contents_scale,
- last_frame_time_in_seconds);
+ last_frame_time_in_seconds,
+ Occlusion());
// current frame
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
- current_frame_time_in_seconds);
+ current_frame_time_in_seconds,
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
}
+TEST(PictureLayerTilingTest, ResetClearsPriorities) {
+ FakePictureLayerTilingClient client;
+ scoped_ptr<TestablePictureLayerTiling> tiling;
+
+ client.SetTileSize(gfx::Size(100, 100));
+ client.set_tree(ACTIVE_TREE);
+ tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
+ gfx::Size(100, 100),
+ &client);
+ tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
+
+ std::vector<scoped_refptr<Tile> > tiles = tiling->AllRefTilesForTesting();
+ ASSERT_GT(tiles.size(), 0u);
+ for (std::vector<scoped_refptr<Tile> >::const_iterator it = tiles.begin();
+ it != tiles.end();
+ ++it) {
+ EXPECT_NE(TilePriority(), (*it)->priority(ACTIVE_TREE));
+ }
+
+ tiling->Reset();
+ for (std::vector<scoped_refptr<Tile> >::const_iterator it = tiles.begin();
+ it != tiles.end();
+ ++it) {
+ EXPECT_EQ(TilePriority(), (*it)->priority(ACTIVE_TREE));
+ }
+ tiles.clear();
+}
+
+TEST(PictureLayerTilingTest, RecycledTilesCleared) {
+ // This test performs the following:
+ // Setup:
+ // - Two tilings, one active one recycled with all tiles shared.
+ // Procedure:
+ // - Viewport moves somewhere far away and active tiling clears tiles.
+ // - Viewport moves back and a new active tiling tile is created.
+ // Result:
+ // - Recycle tiling does _not_ have the tile in the same location (thus it
+ // will be shared next time a pending tiling is created).
+
+ FakePictureLayerTilingClient active_client;
+ scoped_ptr<TestablePictureLayerTiling> active_tiling;
+
+ active_client.SetTileSize(gfx::Size(100, 100));
+ active_client.set_tree(ACTIVE_TREE);
+ active_client.set_max_tiles_for_interest_area(10);
+ active_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
+ gfx::Size(10000, 10000),
+ &active_client);
+ // Create all tiles on this tiling.
+ active_tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
+
+ FakePictureLayerTilingClient recycle_client;
+ recycle_client.SetTileSize(gfx::Size(100, 100));
+ recycle_client.set_tree(PENDING_TREE);
+ recycle_client.set_twin_tiling(active_tiling.get());
+ recycle_client.set_max_tiles_for_interest_area(10);
+
+ scoped_ptr<TestablePictureLayerTiling> recycle_tiling;
+ recycle_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
+ gfx::Size(10000, 10000),
+ &recycle_client);
+
+ // Create all tiles on the second tiling. All tiles should be shared.
+ recycle_tiling->UpdateTilePriorities(
+ PENDING_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
+
+ // Set the second tiling as recycled.
+ active_client.set_twin_tiling(NULL);
+ active_client.set_recycled_twin_tiling(recycle_tiling.get());
+ recycle_client.set_twin_tiling(NULL);
+
+ // Verify that tiles exist and are shared.
+ EXPECT_TRUE(active_tiling->TileAt(0, 0));
+ EXPECT_TRUE(recycle_tiling->TileAt(0, 0));
+ EXPECT_EQ(active_tiling->TileAt(0, 0), recycle_tiling->TileAt(0, 0));
+
+ // Move the viewport far away from the (0, 0) tile.
+ active_tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(9000, 9000, 100, 100), 1.0f, 2.0, Occlusion());
+ // Ensure the tile was deleted on both tilings.
+ EXPECT_FALSE(active_tiling->TileAt(0, 0));
+ EXPECT_FALSE(recycle_tiling->TileAt(0, 0));
+
+ // Move the viewport back to (0, 0) tile.
+ active_tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 3.0, Occlusion());
+
+ // Ensure that we now have a tile here, but the recycle tiling does not.
+ EXPECT_TRUE(active_tiling->TileAt(0, 0));
+ EXPECT_FALSE(recycle_tiling->TileAt(0, 0));
+}
+
+TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) {
+ FakePictureLayerTilingClient active_client;
+ scoped_ptr<TestablePictureLayerTiling> active_tiling;
+
+ active_client.SetTileSize(gfx::Size(100, 100));
+ active_client.set_tree(ACTIVE_TREE);
+ active_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
+ gfx::Size(100, 100),
+ &active_client);
+ // Create all tiles on this tiling.
+ active_tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
+
+ FakePictureLayerTilingClient recycle_client;
+ recycle_client.SetTileSize(gfx::Size(100, 100));
+ recycle_client.set_tree(PENDING_TREE);
+ recycle_client.set_twin_tiling(active_tiling.get());
+ recycle_client.set_max_tiles_for_interest_area(10);
+
+ scoped_ptr<TestablePictureLayerTiling> recycle_tiling;
+ recycle_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
+ gfx::Size(100, 100),
+ &recycle_client);
+
+ // Create all tiles on the recycle tiling. All tiles should be shared.
+ recycle_tiling->UpdateTilePriorities(
+ PENDING_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
+
+ // Set the second tiling as recycled.
+ active_client.set_twin_tiling(NULL);
+ active_client.set_recycled_twin_tiling(recycle_tiling.get());
+ recycle_client.set_twin_tiling(NULL);
+
+ // Verify that tiles exist and are shared.
+ EXPECT_TRUE(active_tiling->TileAt(0, 0));
+ EXPECT_TRUE(recycle_tiling->TileAt(0, 0));
+ EXPECT_EQ(active_tiling->TileAt(0, 0), recycle_tiling->TileAt(0, 0));
+
+ // Reset the active tiling. The recycle tiles should be released too.
+ active_tiling->Reset();
+ EXPECT_FALSE(active_tiling->TileAt(0, 0));
+ EXPECT_FALSE(recycle_tiling->TileAt(0, 0));
+}
+
} // namespace
} // namespace cc