diff options
author | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 02:26:19 +0000 |
---|---|---|
committer | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 02:26:19 +0000 |
commit | d75301f3debec8a7be3b1e8508289c886871d5dd (patch) | |
tree | 07a313950da30239a74075bb9925e466111a8f30 /cc | |
parent | 88f7733bf8cd16ed138123062ae9bad578352b5b (diff) | |
download | chromium_src-d75301f3debec8a7be3b1e8508289c886871d5dd.zip chromium_src-d75301f3debec8a7be3b1e8508289c886871d5dd.tar.gz chromium_src-d75301f3debec8a7be3b1e8508289c886871d5dd.tar.bz2 |
cc: Move soon bin apron from tile manager to tiling.
We split our tiles into several regions: now, soon, eventually, among
others. Now tiles are tiles that are within the visible rect. Soon
tiles are close prepaint tiles (such as tiles coming from the
skewport). Eventually tiles are far away prepaint tiles. Since the
skewport is calculated using finite differences, the first time
visible rect moves, we might not have content prepainted. As a solution,
we put in a "backfling guard", a constant distance away from the
viewport where we promote tiles from eventually to soon.
This patch moves this guard from being a distance check in tile manager
to being an explicit region in the tiling.
R=enne
Review URL: https://codereview.chromium.org/271733003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269157 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/resources/picture_layer_tiling.cc | 41 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.h | 3 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_unittest.cc | 80 | ||||
-rw-r--r-- | cc/resources/tile_manager.cc | 5 |
4 files changed, 97 insertions, 32 deletions
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index a3664e7..46792d0 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -20,6 +20,8 @@ namespace cc { namespace { +const float kSoonBorderDistanceInScreenPixels = 312.f; + class TileEvictionOrder { public: explicit TileEvictionOrder(TreePriority tree_priority) @@ -532,6 +534,25 @@ void PictureLayerTiling::UpdateTilePriorities( resolution_, TilePriority::EVENTUALLY, distance_to_visible); tile->SetPriority(tree, priority); } + + // Upgrade the priority on border tiles to be SOON. + current_soon_border_rect_ = visible_rect_in_content_space; + float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale; + current_soon_border_rect_.Inset(-border, -border, -border, -border); + for (TilingData::DifferenceIterator iter( + &tiling_data_, current_soon_border_rect_, skewport); + iter; + ++iter) { + TileMap::iterator find = tiles_.find(iter.index()); + if (find == tiles_.end()) + continue; + Tile* tile = find->second.get(); + + TilePriority priority(resolution_, + TilePriority::SOON, + tile->priority(tree).distance_to_visible); + tile->SetPriority(tree, priority); + } } void PictureLayerTiling::SetLiveTilesRect( @@ -800,6 +821,7 @@ PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( tiling_->current_visible_rect_in_content_space_), skewport_in_content_space_(tiling_->current_skewport_), eventually_rect_in_content_space_(tiling_->current_eventually_rect_), + soon_border_rect_in_content_space_(tiling_->current_soon_border_rect_), tree_(tree), current_tile_(NULL), visible_iterator_(&tiling->tiling_data_, @@ -808,7 +830,8 @@ PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( spiral_iterator_(&tiling->tiling_data_, skewport_in_content_space_, visible_rect_in_content_space_, - visible_rect_in_content_space_) { + visible_rect_in_content_space_), + skewport_processed_(false) { if (!visible_iterator_) { AdvancePhase(); return; @@ -866,8 +889,20 @@ operator++() { case TilePriority::SOON: ++spiral_iterator_; if (!spiral_iterator_) { - AdvancePhase(); - return *this; + if (skewport_processed_) { + AdvancePhase(); + return *this; + } + skewport_processed_ = true; + spiral_iterator_ = TilingData::SpiralDifferenceIterator( + &tiling_->tiling_data_, + soon_border_rect_in_content_space_, + skewport_in_content_space_, + visible_rect_in_content_space_); + if (!spiral_iterator_) { + AdvancePhase(); + return *this; + } } next_index = spiral_iterator_.index(); break; diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h index 92c2879..538117c 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h @@ -82,11 +82,13 @@ class CC_EXPORT PictureLayerTiling { gfx::Rect visible_rect_in_content_space_; gfx::Rect skewport_in_content_space_; gfx::Rect eventually_rect_in_content_space_; + gfx::Rect soon_border_rect_in_content_space_; WhichTree tree_; Tile* current_tile_; TilingData::Iterator visible_iterator_; TilingData::SpiralDifferenceIterator spiral_iterator_; + bool skewport_processed_; }; class CC_EXPORT TilingEvictionTileIterator { @@ -299,6 +301,7 @@ class CC_EXPORT PictureLayerTiling { gfx::Rect current_visible_rect_in_content_space_; gfx::Rect current_skewport_; gfx::Rect current_eventually_rect_; + gfx::Rect current_soon_border_rect_; std::vector<Tile*> eviction_tiles_cache_; bool eviction_tiles_cache_valid_; diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc index 82a1080..3167c63 100644 --- a/cc/resources/picture_layer_tiling_unittest.cc +++ b/cc/resources/picture_layer_tiling_unittest.cc @@ -420,14 +420,14 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { 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)); - // 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 = @@ -435,23 +435,30 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0); + 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); @@ -459,6 +466,9 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { 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->content_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); @@ -468,6 +478,7 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { } EXPECT_TRUE(have_now); + EXPECT_TRUE(have_soon); EXPECT_TRUE(have_eventually); // Spot check some distances. @@ -495,6 +506,11 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { 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()); @@ -504,12 +520,12 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { 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); @@ -519,7 +535,8 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { 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->content_rect()) || + soon_rect_in_content_space.Intersects(tile->content_rect())) { EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i << " j: " << j; EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i @@ -784,7 +801,10 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) { 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)); @@ -797,7 +817,7 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) { 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. @@ -849,9 +869,13 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) { 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; @@ -871,10 +895,10 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) { 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()); @@ -886,8 +910,8 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorMovingViewport) { 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)); @@ -895,6 +919,9 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorMovingViewport) { tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0); tiling->UpdateTilePriorities(ACTIVE_TREE, moved_viewport, 1.0f, 2.0); + 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] = {}; Tile* last_tile = NULL; @@ -921,9 +948,12 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorMovingViewport) { 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; diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index d8fb17d..4128650 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -338,13 +338,10 @@ const ManagedTileBin kBinIsActiveMap[2][NUM_BINS] = { // Determine bin based on three categories of tiles: things we need now, // things we need soon, and eventually. inline ManagedTileBin BinFromTilePriority(const TilePriority& prio) { - const float kBackflingGuardDistancePixels = 314.0f; - if (prio.priority_bin == TilePriority::NOW) return NOW_BIN; - if (prio.priority_bin == TilePriority::SOON || - prio.distance_to_visible < kBackflingGuardDistancePixels) + if (prio.priority_bin == TilePriority::SOON) return SOON_BIN; if (prio.distance_to_visible == std::numeric_limits<float>::infinity()) |