diff options
author | vmpstr <vmpstr@chromium.org> | 2015-04-29 14:25:25 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-29 21:26:09 +0000 |
commit | a960b5558d7210bb5bfa67a832f800bb36e629a7 (patch) | |
tree | b98424ed0d3d144bef903b745fbbe7310499db5d | |
parent | a5080f268e879b41a34a3f912fb5dabfc6b7a2dd (diff) | |
download | chromium_src-a960b5558d7210bb5bfa67a832f800bb36e629a7.zip chromium_src-a960b5558d7210bb5bfa67a832f800bb36e629a7.tar.gz chromium_src-a960b5558d7210bb5bfa67a832f800bb36e629a7.tar.bz2 |
cc: Remove tile sharing from tilings.
This patch removes sharing tiles from tilings. Previously, tiles
that were not invalidated were shared between the pending and
the active trees. With this patch, tiles that are exist on the
active tree and are not invalidated are not created on the pending
tree, resulting in fewer overall tiles. This improves performance
of updating and managing tiles.
Also, this patch opens up opportunities for a lot of code clean
up that can otherwise be confusing when two trees are involved.
R=danakj, enne
Committed: https://crrev.com/0061b75e810f088900a0a8fbdd29ba5595c73016
Cr-Commit-Position: refs/heads/master@{#326804}
Review URL: https://codereview.chromium.org/1051993002
Cr-Commit-Position: refs/heads/master@{#327553}
25 files changed, 1281 insertions, 1064 deletions
diff --git a/cc/base/tiling_data.cc b/cc/base/tiling_data.cc index c9b2fd9..cf2bb57 100644 --- a/cc/base/tiling_data.cc +++ b/cc/base/tiling_data.cc @@ -418,6 +418,9 @@ bool TilingData::BaseDifferenceIterator::HasConsiderRect() const { return consider_left_ != -1; } +TilingData::DifferenceIterator::DifferenceIterator() { +} + TilingData::DifferenceIterator::DifferenceIterator( const TilingData* tiling_data, const gfx::Rect& consider_rect, diff --git a/cc/base/tiling_data.h b/cc/base/tiling_data.h index a35be59..c95a672 100644 --- a/cc/base/tiling_data.h +++ b/cc/base/tiling_data.h @@ -132,6 +132,7 @@ class CC_EXPORT TilingData { // with |consider| but which also do not intersect with |ignore|. class CC_EXPORT DifferenceIterator : public BaseDifferenceIterator { public: + DifferenceIterator(); DifferenceIterator(const TilingData* tiling_data, const gfx::Rect& consider_rect, const gfx::Rect& ignore_rect); diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 2d2e330..67ca4f5 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -288,15 +288,19 @@ class PictureLayerImplTest : public testing::Test { } void ResetTilingsAndRasterScales() { - pending_layer_->ReleaseResources(); - EXPECT_FALSE(pending_layer_->tilings()); - pending_layer_->RecreateResources(); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); - - active_layer_->ReleaseResources(); - EXPECT_FALSE(active_layer_->tilings()); - active_layer_->RecreateResources(); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + if (pending_layer_) { + pending_layer_->ReleaseResources(); + EXPECT_FALSE(pending_layer_->tilings()); + pending_layer_->RecreateResources(); + EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); + } + + if (active_layer_) { + active_layer_->ReleaseResources(); + EXPECT_FALSE(active_layer_->tilings()); + active_layer_->RecreateResources(); + EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + } } size_t NumberOfTilesRequired(PictureLayerTiling* tiling) { @@ -416,7 +420,7 @@ TEST_F(PictureLayerImplTest, CloneNoInvalidation) { const PictureLayerTilingSet* tilings = pending_layer_->tilings(); EXPECT_GT(tilings->num_tilings(), 0u); for (size_t i = 0; i < tilings->num_tilings(); ++i) - VerifyAllTilesExistAndHavePile(tilings->tiling_at(i), pending_pile.get()); + EXPECT_TRUE(tilings->tiling_at(i)->AllTilesForTesting().empty()); } TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { @@ -667,7 +671,7 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { SetupPendingTreeWithFixedTileSize(lost_pile, gfx::Size(50, 50), Region()); ActivateTree(); - // Add a non-shared tiling on the active tree. + // Add a unique tiling on the active tree. PictureLayerTiling* tiling = active_layer_->AddTiling(3.f); tiling->CreateAllTilesForTesting(); @@ -694,9 +698,16 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { gfx::Rect(tiling->tiling_size())); iter; ++iter) { - EXPECT_TRUE(*iter); - EXPECT_FALSE(iter.geometry_rect().IsEmpty()); - EXPECT_EQ(pending_pile.get(), iter->raster_source()); + // We don't always have a tile, but when we do it's because it was + // invalidated and it has the latest raster source. + if (*iter) { + EXPECT_FALSE(iter.geometry_rect().IsEmpty()); + EXPECT_EQ(pending_pile.get(), iter->raster_source()); + EXPECT_TRUE(iter.geometry_rect().Intersects(content_invalidation)); + } else { + // We don't create tiles in non-invalidated regions. + EXPECT_FALSE(iter.geometry_rect().Intersects(content_invalidation)); + } } } @@ -714,12 +725,8 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { ++iter) { EXPECT_TRUE(*iter); EXPECT_FALSE(iter.geometry_rect().IsEmpty()); - if (iter.geometry_rect().Intersects(content_invalidation)) - EXPECT_EQ(active_pile.get(), iter->raster_source()); - else if (!active_layer_->GetPendingOrActiveTwinTiling(tiling)) - EXPECT_EQ(active_pile.get(), iter->raster_source()); - else - EXPECT_EQ(pending_pile.get(), iter->raster_source()); + // Pile will be updated upon activation. + EXPECT_EQ(active_pile.get(), iter->raster_source()); } } } @@ -1537,17 +1544,15 @@ TEST_F(PictureLayerImplTest, ReleaseResources) { EXPECT_EQ(2u, pending_layer_->tilings()->num_tilings()); } -TEST_F(PictureLayerImplTest, ClampTilesToToMaxTileSize) { +TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) { // The default max tile size is larger than 400x400. gfx::Size tile_size(400, 400); gfx::Size layer_bounds(5000, 5000); scoped_refptr<FakePicturePileImpl> pending_pile = FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); - scoped_refptr<FakePicturePileImpl> active_pile = - FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); - SetupTrees(pending_pile, active_pile); + SetupPendingTree(pending_pile); EXPECT_GE(pending_layer_->tilings()->num_tilings(), 1u); pending_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); @@ -1592,16 +1597,16 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) { FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); SetupTrees(pending_pile, active_pile); - EXPECT_GE(pending_layer_->tilings()->num_tilings(), 1u); + EXPECT_GE(active_layer_->tilings()->num_tilings(), 1u); - pending_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); + active_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); // The default value. The layer is smaller than this. EXPECT_EQ(gfx::Size(512, 512).ToString(), host_impl_.settings().max_untiled_layer_size.ToString()); // There should be a single tile since the layer is small. - PictureLayerTiling* high_res_tiling = pending_layer_->tilings()->tiling_at(0); + PictureLayerTiling* high_res_tiling = active_layer_->tilings()->tiling_at(0); EXPECT_EQ(1u, high_res_tiling->AllTilesForTesting().size()); ResetTilingsAndRasterScales(); @@ -1614,18 +1619,18 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) { host_impl_.InitializeRenderer( FakeOutputSurface::Create3d(context.Pass()).Pass()); - SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false); - ASSERT_LE(1u, pending_layer_->tilings()->num_tilings()); + SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false); + ASSERT_LE(1u, active_layer_->tilings()->num_tilings()); - pending_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); + active_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); // There should be more than one tile since the max texture size won't cover // the layer. - high_res_tiling = pending_layer_->tilings()->tiling_at(0); + high_res_tiling = active_layer_->tilings()->tiling_at(0); EXPECT_LT(1u, high_res_tiling->AllTilesForTesting().size()); // Verify the tiles are not larger than the context's max texture size. - Tile* tile = pending_layer_->tilings()->tiling_at(0)->AllTilesForTesting()[0]; + Tile* tile = active_layer_->tilings()->tiling_at(0)->AllTilesForTesting()[0]; EXPECT_GE(140, tile->content_rect().width()); EXPECT_GE(140, tile->content_rect().height()); } @@ -1749,7 +1754,7 @@ TEST_F(NoLowResPictureLayerImplTest, MarkRequiredOffscreenTiles) { for (; !queue->IsEmpty(); queue->Pop()) { const Tile* tile = queue->Top(); DCHECK(tile); - if (tile->priority(PENDING_TREE).distance_to_visible == 0.f) { + if (tile->priority().distance_to_visible == 0.f) { EXPECT_TRUE(tile->required_for_activation()); num_visible++; } else { @@ -1814,10 +1819,12 @@ TEST_F(NoLowResPictureLayerImplTest, pending_layer_->viewport_rect_for_tile_priority_in_content_space(); viewport_for_tile_priority.Intersect(pending_layer_->visible_content_rect()); + EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); + int num_inside = 0; int num_outside = 0; - for (PictureLayerTiling::CoverageIterator iter( - pending_layer_->HighResTiling(), 1.f, gfx::Rect(layer_bounds)); + for (PictureLayerTiling::CoverageIterator iter(active_layer_->HighResTiling(), + 1.f, gfx::Rect(layer_bounds)); iter; ++iter) { if (!*iter) continue; @@ -2046,18 +2053,17 @@ TEST_F(PictureLayerImplTest, EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads()); } -TEST_F(PictureLayerImplTest, HighResRequiredWhenUnsharedActiveAllReady) { +TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveAllReady) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); - // No tiles shared. SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, gfx::Rect(layer_bounds)); active_layer_->SetAllTilesReady(); - // No shared tiles and all active tiles ready, so pending can only - // activate with all high res tiles. + // All active tiles ready, so pending can only activate with all high res + // tiles. pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); @@ -2069,7 +2075,7 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); - // All tiles shared (no invalidation). + // No invalidation. SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); // Verify active tree not ready. @@ -2077,18 +2083,22 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) { active_layer_->HighResTiling()->AllTilesForTesting()[0]; EXPECT_FALSE(some_active_tile->IsReadyToDraw()); - // When high res are required, even if the active tree is not ready, - // the high res tiles must be ready. + // When high res are required, all tiles in active high res tiling should be + // required for activation. host_impl_.SetRequiresHighResToDraw(); pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); + active_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); + active_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); - AssertAllTilesRequired(pending_layer_->HighResTiling()); - AssertNoTilesRequired(pending_layer_->LowResTiling()); + EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); + EXPECT_TRUE(pending_layer_->LowResTiling()->AllTilesForTesting().empty()); + AssertAllTilesRequired(active_layer_->HighResTiling()); + AssertNoTilesRequired(active_layer_->LowResTiling()); } -TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfShared) { +TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); @@ -2098,13 +2108,15 @@ TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfShared) { active_layer_->HighResTiling()->AllTilesForTesting()[0]; EXPECT_FALSE(some_active_tile->IsReadyToDraw()); - // All tiles shared (no invalidation), so even though the active tree's - // tiles aren't ready, the high res tiles are required for activation. - pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); - pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); + // Since there are no invalidations, pending tree should have no tiles. + EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); + EXPECT_TRUE(pending_layer_->LowResTiling()->AllTilesForTesting().empty()); - AssertAllTilesRequired(pending_layer_->HighResTiling()); - AssertNoTilesRequired(pending_layer_->LowResTiling()); + active_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); + active_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); + + AssertAllTilesRequired(active_layer_->HighResTiling()); + AssertNoTilesRequired(active_layer_->LowResTiling()); } TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) { @@ -2117,15 +2129,19 @@ TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) { active_layer_->HighResTiling()->AllTilesForTesting()[0]; EXPECT_FALSE(some_active_tile->IsReadyToDraw()); + EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); + EXPECT_TRUE(pending_layer_->LowResTiling()->AllTilesForTesting().empty()); + active_layer_->HighResTiling()->set_can_require_tiles_for_activation(false); + active_layer_->LowResTiling()->set_can_require_tiles_for_activation(false); pending_layer_->HighResTiling()->set_can_require_tiles_for_activation(false); pending_layer_->LowResTiling()->set_can_require_tiles_for_activation(false); // If we disallow required for activation, no tiles can be required. - pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); - pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); + active_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); + active_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); - AssertNoTilesRequired(pending_layer_->HighResTiling()); - AssertNoTilesRequired(pending_layer_->LowResTiling()); + AssertNoTilesRequired(active_layer_->HighResTiling()); + AssertNoTilesRequired(active_layer_->LowResTiling()); } TEST_F(PictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { @@ -2199,9 +2215,16 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveHasDifferentBounds) { // high res tiles in order to activate. pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); + active_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); + active_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); AssertAllTilesRequired(pending_layer_->HighResTiling()); - AssertNoTilesRequired(pending_layer_->LowResTiling()); + AssertAllTilesRequired(active_layer_->HighResTiling()); + AssertNoTilesRequired(active_layer_->LowResTiling()); + // Since the test doesn't invalidate the resized region, we expect that the + // same low res tile would exist (which means we don't create a new one of the + // pending tree). + EXPECT_TRUE(pending_layer_->LowResTiling()->AllTilesForTesting().empty()); } TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) { @@ -2270,40 +2293,41 @@ TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) { // pending_tiling->CreateAllTilesForTesting(); - // Tile 0,0 should be shared, but tile 1,1 should not be. - EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0)); - EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0)); - EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1)); + // Tile 0,0 not exist on pending, but tile 1,1 should. + EXPECT_TRUE(active_tiling->TileAt(0, 0)); + EXPECT_TRUE(active_tiling->TileAt(1, 0)); + EXPECT_TRUE(active_tiling->TileAt(0, 1)); + EXPECT_FALSE(pending_tiling->TileAt(0, 0)); + EXPECT_FALSE(pending_tiling->TileAt(1, 0)); + EXPECT_FALSE(pending_tiling->TileAt(0, 1)); EXPECT_NE(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1)); - EXPECT_TRUE(pending_tiling->TileAt(0, 0)->is_shared()); - EXPECT_TRUE(pending_tiling->TileAt(1, 0)->is_shared()); - EXPECT_TRUE(pending_tiling->TileAt(0, 1)->is_shared()); - EXPECT_FALSE(pending_tiling->TileAt(1, 1)->is_shared()); + EXPECT_TRUE(active_tiling->TileAt(1, 1)); + EXPECT_TRUE(pending_tiling->TileAt(1, 1)); - // Drop the tiles on the active tree and recreate them. The same tiles - // should be shared or not. + // Drop the tiles on the active tree and recreate them. active_tiling->ComputeTilePriorityRects(gfx::Rect(), 1.f, 1.0, Occlusion()); EXPECT_TRUE(active_tiling->AllTilesForTesting().empty()); active_tiling->CreateAllTilesForTesting(); - // Tile 0,0 should be shared, but tile 1,1 should not be. - EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0)); - EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0)); - EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1)); + // Tile 0,0 not exist on pending, but tile 1,1 should. + EXPECT_TRUE(active_tiling->TileAt(0, 0)); + EXPECT_TRUE(active_tiling->TileAt(1, 0)); + EXPECT_TRUE(active_tiling->TileAt(0, 1)); + EXPECT_FALSE(pending_tiling->TileAt(0, 0)); + EXPECT_FALSE(pending_tiling->TileAt(1, 0)); + EXPECT_FALSE(pending_tiling->TileAt(0, 1)); EXPECT_NE(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1)); - EXPECT_TRUE(pending_tiling->TileAt(0, 0)->is_shared()); - EXPECT_TRUE(pending_tiling->TileAt(1, 0)->is_shared()); - EXPECT_TRUE(pending_tiling->TileAt(0, 1)->is_shared()); - EXPECT_FALSE(pending_tiling->TileAt(1, 1)->is_shared()); + EXPECT_TRUE(active_tiling->TileAt(1, 1)); + EXPECT_TRUE(pending_tiling->TileAt(1, 1)); } -TEST_F(PictureLayerImplTest, ShareTilesWithNoInvalidation) { +TEST_F(PictureLayerImplTest, PendingHasNoTilesWithNoInvalidation) { SetupDefaultTrees(gfx::Size(1500, 1500)); EXPECT_GE(active_layer_->num_tilings(), 1u); EXPECT_GE(pending_layer_->num_tilings(), 1u); - // No invalidation, so all tiles are shared. + // No invalidation. PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0); PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0); ASSERT_TRUE(active_tiling); @@ -2314,19 +2338,10 @@ TEST_F(PictureLayerImplTest, ShareTilesWithNoInvalidation) { EXPECT_TRUE(active_tiling->TileAt(0, 1)); EXPECT_TRUE(active_tiling->TileAt(1, 1)); - EXPECT_TRUE(pending_tiling->TileAt(0, 0)); - EXPECT_TRUE(pending_tiling->TileAt(1, 0)); - EXPECT_TRUE(pending_tiling->TileAt(0, 1)); - EXPECT_TRUE(pending_tiling->TileAt(1, 1)); - - EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0)); - EXPECT_TRUE(active_tiling->TileAt(0, 0)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0)); - EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1)); - EXPECT_TRUE(active_tiling->TileAt(0, 1)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1)); - EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared()); + EXPECT_FALSE(pending_tiling->TileAt(0, 0)); + EXPECT_FALSE(pending_tiling->TileAt(1, 0)); + EXPECT_FALSE(pending_tiling->TileAt(0, 1)); + EXPECT_FALSE(pending_tiling->TileAt(1, 1)); } TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTiles) { @@ -2348,8 +2363,7 @@ TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTiles) { EXPECT_GE(active_layer_->num_tilings(), 1u); EXPECT_GE(pending_layer_->num_tilings(), 1u); - // The active tree invalidation was handled by the active tiles, so they - // can be shared with the pending tree. + // The active tree invalidation was handled by the active tiles. PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0); PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0); ASSERT_TRUE(active_tiling); @@ -2360,19 +2374,10 @@ TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTiles) { EXPECT_TRUE(active_tiling->TileAt(0, 1)); EXPECT_TRUE(active_tiling->TileAt(1, 1)); - EXPECT_TRUE(pending_tiling->TileAt(0, 0)); - EXPECT_TRUE(pending_tiling->TileAt(1, 0)); - EXPECT_TRUE(pending_tiling->TileAt(0, 1)); - EXPECT_TRUE(pending_tiling->TileAt(1, 1)); - - EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0)); - EXPECT_TRUE(active_tiling->TileAt(0, 0)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0)); - EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1)); - EXPECT_TRUE(active_tiling->TileAt(0, 1)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1)); - EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared()); + EXPECT_FALSE(pending_tiling->TileAt(0, 0)); + EXPECT_FALSE(pending_tiling->TileAt(1, 0)); + EXPECT_FALSE(pending_tiling->TileAt(0, 1)); + EXPECT_FALSE(pending_tiling->TileAt(1, 1)); } TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) { @@ -2383,8 +2388,7 @@ TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) { EXPECT_GE(active_layer_->num_tilings(), 1u); EXPECT_GE(pending_layer_->num_tilings(), 1u); - // The pending tree invalidation means tiles can not be shared with the - // active tree. + // The pending tree invalidation creates tiles on the pending tree. PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0); PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0); ASSERT_TRUE(active_tiling); @@ -2396,19 +2400,11 @@ TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) { EXPECT_TRUE(active_tiling->TileAt(1, 1)); EXPECT_TRUE(pending_tiling->TileAt(0, 0)); - EXPECT_TRUE(pending_tiling->TileAt(1, 0)); - EXPECT_TRUE(pending_tiling->TileAt(0, 1)); - EXPECT_TRUE(pending_tiling->TileAt(1, 1)); + EXPECT_FALSE(pending_tiling->TileAt(1, 0)); + EXPECT_FALSE(pending_tiling->TileAt(0, 1)); + EXPECT_FALSE(pending_tiling->TileAt(1, 1)); EXPECT_NE(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0)); - EXPECT_FALSE(active_tiling->TileAt(0, 0)->is_shared()); - EXPECT_FALSE(pending_tiling->TileAt(0, 0)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0)); - EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1)); - EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared()); - EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1)); - EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared()); } TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { @@ -2531,17 +2527,16 @@ TEST_F(PictureLayerImplTest, RequiredTilesWithGpuRasterization) { EXPECT_TRUE(host_impl_.use_gpu_rasterization()); // Should only have the high-res tiling. - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, active_layer_->tilings()->num_tilings()); - active_layer_->SetAllTilesReady(); - pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); + active_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); // High res tiling should have 64 tiles (4x16 tile grid). - EXPECT_EQ(64u, pending_layer_->HighResTiling()->AllTilesForTesting().size()); + EXPECT_EQ(64u, active_layer_->HighResTiling()->AllTilesForTesting().size()); // Visible viewport should be covered by 4 tiles. No other // tiles should be required for activation. - EXPECT_EQ(4u, NumberOfTilesRequired(pending_layer_->HighResTiling())); + EXPECT_EQ(4u, NumberOfTilesRequired(active_layer_->HighResTiling())); } TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) { @@ -2875,7 +2870,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { pending_layer_->picture_layer_tiling_set(), false)); while (!queue->IsEmpty()) { Tile* tile = queue->Top(); - TilePriority priority = tile->priority(PENDING_TREE); + TilePriority priority = tile->priority(); EXPECT_TRUE(tile); @@ -2949,7 +2944,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { pending_layer_->picture_layer_tiling_set(), false)); while (!queue->IsEmpty()) { Tile* tile = queue->Top(); - TilePriority priority = tile->priority(PENDING_TREE); + TilePriority priority = tile->priority(); EXPECT_TRUE(tile); @@ -2991,7 +2986,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { pending_layer_->picture_layer_tiling_set(), true)); while (!queue->IsEmpty()) { Tile* tile = queue->Top(); - TilePriority priority = tile->priority(PENDING_TREE); + TilePriority priority = tile->priority(); EXPECT_TRUE(tile); @@ -3137,7 +3132,7 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { EXPECT_TRUE(tile); - TilePriority priority = tile->priority(PENDING_TREE); + TilePriority priority = tile->priority(); if (priority.priority_bin == TilePriority::NOW) { reached_visible = true; @@ -3161,7 +3156,7 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { std::abs(tile->contents_scale() - last_tile->contents_scale()) < std::numeric_limits<float>::epsilon()) { if (priority.distance_to_visible <= - last_tile->priority(PENDING_TREE).distance_to_visible) + last_tile->priority().distance_to_visible) ++distance_decreasing; else ++distance_increasing; @@ -3183,7 +3178,7 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { Tile* tile = queue->Top(); EXPECT_TRUE(tile); - TilePriority priority = tile->priority(PENDING_TREE); + TilePriority priority = tile->priority(); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); if (reached_required) { @@ -3304,7 +3299,7 @@ TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(1000, 1000); - // Make sure some tiles are not shared. + // Make sure pending tree has tiles. gfx::Rect invalidation(gfx::Point(50, 50), tile_size); SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation); @@ -3313,12 +3308,14 @@ TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) { // Initialize all low-res tiles. pending_layer_->SetAllTilesReadyInTiling(pending_layer_->LowResTiling()); + pending_layer_->SetAllTilesReadyInTiling(active_layer_->LowResTiling()); // Low-res tiles should not be enough. EXPECT_FALSE(host_impl_.tile_manager()->IsReadyToActivate()); // Initialize remaining tiles. pending_layer_->SetAllTilesReady(); + active_layer_->SetAllTilesReady(); EXPECT_TRUE(host_impl_.tile_manager()->IsReadyToActivate()); } @@ -3327,7 +3324,7 @@ TEST_F(PictureLayerImplTest, HighResReadyToDrawEnoughToActivate) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(1000, 1000); - // Make sure some tiles are not shared. + // Make sure pending tree has tiles. gfx::Rect invalidation(gfx::Point(50, 50), tile_size); SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation); @@ -3336,17 +3333,18 @@ TEST_F(PictureLayerImplTest, HighResReadyToDrawEnoughToActivate) { // Initialize all high-res tiles. pending_layer_->SetAllTilesReadyInTiling(pending_layer_->HighResTiling()); + active_layer_->SetAllTilesReadyInTiling(active_layer_->HighResTiling()); // High-res tiles should be enough, since they cover everything visible. EXPECT_TRUE(host_impl_.tile_manager()->IsReadyToActivate()); } TEST_F(PictureLayerImplTest, - SharedActiveHighResReadyAndPendingLowResReadyNotEnoughToActivate) { + ActiveHighResReadyAndPendingLowResReadyNotEnoughToActivate) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(1000, 1000); - // Make sure some tiles are not shared. + // Make sure pending tree has tiles. gfx::Rect invalidation(gfx::Point(50, 50), tile_size); SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation); @@ -3355,29 +3353,29 @@ TEST_F(PictureLayerImplTest, // And all the low-res tiles in the pending layer. pending_layer_->SetAllTilesReadyInTiling(pending_layer_->LowResTiling()); - // The unshared high-res tiles are not ready, so we cannot activate. + // The pending high-res tiles are not ready, so we cannot activate. EXPECT_FALSE(host_impl_.tile_manager()->IsReadyToActivate()); - // When the unshared pending high-res tiles are ready, we can activate. + // When the pending high-res tiles are ready, we can activate. pending_layer_->SetAllTilesReadyInTiling(pending_layer_->HighResTiling()); EXPECT_TRUE(host_impl_.tile_manager()->IsReadyToActivate()); } -TEST_F(PictureLayerImplTest, SharedActiveHighResReadyNotEnoughToActivate) { +TEST_F(PictureLayerImplTest, ActiveHighResReadyNotEnoughToActivate) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(1000, 1000); - // Make sure some tiles are not shared. + // Make sure pending tree has tiles. gfx::Rect invalidation(gfx::Point(50, 50), tile_size); SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation); // Initialize all high-res tiles in the active layer. active_layer_->SetAllTilesReadyInTiling(active_layer_->HighResTiling()); - // The unshared high-res tiles are not ready, so we cannot activate. + // The pending high-res tiles are not ready, so we cannot activate. EXPECT_FALSE(host_impl_.tile_manager()->IsReadyToActivate()); - // When the unshared pending high-res tiles are ready, we can activate. + // When the pending pending high-res tiles are ready, we can activate. pending_layer_->SetAllTilesReadyInTiling(pending_layer_->HighResTiling()); EXPECT_TRUE(host_impl_.tile_manager()->IsReadyToActivate()); } @@ -3504,7 +3502,7 @@ TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { pending_layer_->tilings()->tiling_at(0)->contents_scale()); } -TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfShared) { +TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); @@ -3514,15 +3512,18 @@ TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfShared) { active_layer_->HighResTiling()->AllTilesForTesting()[0]; EXPECT_FALSE(some_active_tile->IsReadyToDraw()); - // All tiles shared (no invalidation), so even though the active tree's - // tiles aren't ready, there is nothing required. - pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); + // Since there is no invalidation, pending tree should have no tiles. + EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); if (host_impl_.settings().create_low_res_tiling) - pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); + EXPECT_TRUE(pending_layer_->LowResTiling()->AllTilesForTesting().empty()); - AssertAllTilesRequired(pending_layer_->HighResTiling()); + active_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting(); if (host_impl_.settings().create_low_res_tiling) - AssertNoTilesRequired(pending_layer_->LowResTiling()); + active_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting(); + + AssertAllTilesRequired(active_layer_->HighResTiling()); + if (host_impl_.settings().create_low_res_tiling) + AssertNoTilesRequired(active_layer_->LowResTiling()); } TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { @@ -3908,11 +3909,10 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest { void VerifyEvictionConsidersOcclusion(FakePictureLayerImpl* layer, FakePictureLayerImpl* twin_layer, WhichTree tree, - size_t expected_occluded_tile_count) { - WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; + size_t expected_occluded_tile_count, + int source_line) { size_t occluded_tile_count = 0u; Tile* last_tile = nullptr; - std::set<Tile*> shared_tiles; scoped_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue( layer->picture_layer_tiling_set(), layer && twin_layer)); @@ -3920,73 +3920,32 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest { Tile* tile = queue->Top(); if (!last_tile) last_tile = tile; - if (tile->is_shared()) - EXPECT_TRUE(shared_tiles.insert(tile).second); // The only way we will encounter an occluded tile after an unoccluded // tile is if the priorty bin decreased, the tile is required for // activation, or the scale changed. - bool tile_is_occluded = tile->is_occluded(tree); + bool tile_is_occluded = tile->is_occluded(); if (tile_is_occluded) { occluded_tile_count++; - bool last_tile_is_occluded = last_tile->is_occluded(tree); + bool last_tile_is_occluded = last_tile->is_occluded(); if (!last_tile_is_occluded) { TilePriority::PriorityBin tile_priority_bin = - tile->priority(tree).priority_bin; + tile->priority().priority_bin; TilePriority::PriorityBin last_tile_priority_bin = - last_tile->priority(tree).priority_bin; + last_tile->priority().priority_bin; EXPECT_TRUE(tile_priority_bin < last_tile_priority_bin || tile->required_for_activation() || - tile->contents_scale() != last_tile->contents_scale()); + tile->contents_scale() != last_tile->contents_scale()) + << "line: " << source_line; } } last_tile = tile; queue->Pop(); } - // Count also shared tiles which are occluded in the tree but which were - // not returned by the tiling set eviction queue. Those shared tiles - // shall be returned by the twin tiling set eviction queue. - queue.reset(new TilingSetEvictionQueue( - twin_layer->picture_layer_tiling_set(), layer && twin_layer)); - while (!queue->IsEmpty()) { - Tile* tile = queue->Top(); - if (tile->is_shared()) { - EXPECT_TRUE(shared_tiles.insert(tile).second); - if (tile->is_occluded(tree)) - ++occluded_tile_count; - // Check the reasons why the shared tile was not returned by - // the first tiling set eviction queue. - const TilePriority& combined_priority = tile->combined_priority(); - const TilePriority& priority = tile->priority(tree); - const TilePriority& twin_priority = tile->priority(twin_tree); - // Check if the shared tile was not returned by the first tiling - // set eviction queue because it was out of order for the first - // tiling set eviction queue but not for the twin tiling set - // eviction queue. - if (priority.priority_bin != twin_priority.priority_bin) { - EXPECT_LT(combined_priority.priority_bin, priority.priority_bin); - EXPECT_EQ(combined_priority.priority_bin, twin_priority.priority_bin); - } else if (tile->is_occluded(tree) != tile->is_occluded(twin_tree)) { - EXPECT_TRUE(tile->is_occluded(tree)); - EXPECT_FALSE(tile->is_occluded(twin_tree)); - EXPECT_FALSE(tile->is_occluded_combined()); - } else if (priority.distance_to_visible != - twin_priority.distance_to_visible) { - EXPECT_LT(combined_priority.distance_to_visible, - priority.distance_to_visible); - EXPECT_EQ(combined_priority.distance_to_visible, - twin_priority.distance_to_visible); - } else { - // Shared tiles having the same active and pending priorities - // should be returned only by a pending tree eviction queue. - EXPECT_EQ(ACTIVE_TREE, tree); - } - } - queue->Pop(); - } - EXPECT_EQ(expected_occluded_tile_count, occluded_tile_count); + EXPECT_EQ(expected_occluded_tile_count, occluded_tile_count) + << "line: " << source_line; } }; @@ -4016,7 +3975,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, Tile* tile = queue->Top(); // Occluded tiles should not be iterated over. - EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); + EXPECT_FALSE(tile->is_occluded()); // Some tiles may not be visible (i.e. outside the viewport). The rest are // visible and at least partially unoccluded, verified by the above expect. @@ -4049,7 +4008,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, while (!queue->IsEmpty()) { Tile* tile = queue->Top(); - EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); + EXPECT_FALSE(tile->is_occluded()); bool tile_is_visible = tile->content_rect().Intersects(pending_layer_->visible_content_rect()); @@ -4073,7 +4032,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, while (!queue->IsEmpty()) { Tile* tile = queue->Top(); - EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); + EXPECT_FALSE(tile->is_occluded()); bool tile_is_visible = tile->content_rect().Intersects(pending_layer_->visible_content_rect()); @@ -4106,6 +4065,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, int occluded_tile_count = 0; for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + tiling->UpdateAllTilePrioritiesForTesting(); occluded_tile_count = 0; for (PictureLayerTiling::CoverageIterator iter( @@ -4119,7 +4079,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, const Tile* tile = *iter; // Fully occluded tiles are not required for activation. - if (tile->is_occluded(PENDING_TREE)) { + if (tile->is_occluded()) { EXPECT_FALSE(tile->required_for_activation()); occluded_tile_count++; } @@ -4157,7 +4117,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, continue; const Tile* tile = *iter; - if (tile->is_occluded(PENDING_TREE)) { + if (tile->is_occluded()) { EXPECT_FALSE(tile->required_for_activation()); occluded_tile_count++; } @@ -4197,7 +4157,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, continue; const Tile* tile = *iter; - if (tile->is_occluded(PENDING_TREE)) { + if (tile->is_occluded()) { EXPECT_FALSE(tile->required_for_activation()); occluded_tile_count++; } @@ -4267,7 +4227,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { occluded_tile_count = 0; for (size_t j = 0; j < tiles.size(); ++j) { - if (tiles[j]->is_occluded(PENDING_TREE)) { + if (tiles[j]->is_occluded()) { gfx::Rect scaled_content_rect = ScaleToEnclosingRect( tiles[j]->content_rect(), 1.0f / tiles[j]->contents_scale()); EXPECT_GE(scaled_content_rect.x(), occluding_layer_position.x()); @@ -4321,50 +4281,33 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { ActivateTree(); - // Partially invalidate the pending layer. - SetupPendingTreeWithInvalidation(pending_pile, invalidation_rect); - - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); tiling->UpdateAllTilePrioritiesForTesting(); - for (PictureLayerTiling::CoverageIterator iter( - tiling, - pending_layer_->contents_scale_x(), - gfx::Rect(layer_bounds)); - iter; - ++iter) { + for ( + PictureLayerTiling::CoverageIterator iter( + tiling, active_layer_->contents_scale_x(), gfx::Rect(layer_bounds)); + iter; ++iter) { if (!*iter) continue; const Tile* tile = *iter; - // All tiles are unoccluded on the pending tree. - EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); - - Tile* twin_tile = pending_layer_->GetPendingOrActiveTwinTiling(tiling) - ->TileAt(iter.i(), iter.j()); gfx::Rect scaled_content_rect = ScaleToEnclosingRect( tile->content_rect(), 1.0f / tile->contents_scale()); - - if (scaled_content_rect.Intersects(invalidation_rect)) { - // Tiles inside the invalidation rect are only on the pending tree. - EXPECT_NE(tile, twin_tile); - - // Unshared tiles should be unoccluded on the active tree by default. - EXPECT_FALSE(tile->is_occluded(ACTIVE_TREE)); - } else { - // Tiles outside the invalidation rect are shared between both trees. - EXPECT_EQ(tile, twin_tile); - // Shared tiles are occluded on the active tree iff they lie beneath the - // occluding layer. - EXPECT_EQ(tile->is_occluded(ACTIVE_TREE), - scaled_content_rect.x() >= occluding_layer_position.x()); - } + // Tiles are occluded on the active tree iff they lie beneath the + // occluding layer. + EXPECT_EQ(tile->is_occluded(), + scaled_content_rect.x() >= occluding_layer_position.x()); } } + // Partially invalidate the pending layer. + SetupPendingTreeWithInvalidation(pending_pile, invalidation_rect); + for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + tiling->UpdateAllTilePrioritiesForTesting(); for (PictureLayerTiling::CoverageIterator iter( tiling, @@ -4376,24 +4319,24 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { continue; const Tile* tile = *iter; + // All tiles are unoccluded, because the pending tree has no occlusion. + EXPECT_FALSE(tile->is_occluded()); + EXPECT_FALSE(tile->is_occluded()); + Tile* twin_tile = active_layer_->GetPendingOrActiveTwinTiling(tiling) ->TileAt(iter.i(), iter.j()); gfx::Rect scaled_content_rect = ScaleToEnclosingRect( tile->content_rect(), 1.0f / tile->contents_scale()); - // Since we've already checked the shared tiles, only consider tiles in - // the invalidation rect. if (scaled_content_rect.Intersects(invalidation_rect)) { - // Tiles inside the invalidation rect are only on the active tree. + // Tiles inside the invalidation rect exist on both trees. + EXPECT_TRUE(tile); + EXPECT_TRUE(twin_tile); EXPECT_NE(tile, twin_tile); - - // Unshared tiles should be unoccluded on the pending tree by default. - EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); - - // Unshared tiles are occluded on the active tree iff they lie beneath - // the occluding layer. - EXPECT_EQ(tile->is_occluded(ACTIVE_TREE), - scaled_content_rect.x() >= occluding_layer_position.x()); + } else { + // Tiles outside the invalidation rect only exist on the active tree. + EXPECT_TRUE(tile); + EXPECT_FALSE(twin_tile); } } } @@ -4411,7 +4354,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, gfx::Size viewport_size(1000, 1000); gfx::Point pending_occluding_layer_position(310, 0); gfx::Point active_occluding_layer_position(0, 310); - gfx::Rect invalidation_rect(230, 230, 102, 102); + gfx::Rect invalidation_rect(230, 230, 152, 152); host_impl_.SetViewportSize(viewport_size); host_impl_.SetDeviceScaleFactor(2.f); @@ -4435,7 +4378,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, ActivateTree(); // Partially invalidate the pending layer. Tiles inside the invalidation rect - // are not shared between trees. + // are created. SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, invalidation_rect); // Partially occlude the pending layer in a different way. @@ -4459,11 +4402,9 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, // The expected number of occluded tiles on each of the 2 tilings for each of // the 3 tree priorities. - size_t expected_occluded_tile_count_on_both[] = {9u, 1u}; - size_t expected_occluded_tile_count_on_active[] = {30u, 3u}; - size_t expected_occluded_tile_count_on_pending[] = {30u, 3u}; - - size_t total_expected_occluded_tile_count_on_trees[] = {33u, 33u}; + size_t expected_occluded_tile_count_on_pending[] = {4u, 0u}; + size_t expected_occluded_tile_count_on_active[] = {12u, 1u}; + size_t total_expected_occluded_tile_count_on_trees[] = {13u, 4u}; // Verify number of occluded tiles on the pending layer for each tiling. for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { @@ -4471,31 +4412,24 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, tiling->UpdateAllTilePrioritiesForTesting(); size_t occluded_tile_count_on_pending = 0u; - size_t occluded_tile_count_on_active = 0u; - size_t occluded_tile_count_on_both = 0u; for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, gfx::Rect(layer_bounds)); iter; ++iter) { Tile* tile = *iter; + if (invalidation_rect.Intersects(iter.geometry_rect())) + EXPECT_TRUE(tile); + else + EXPECT_FALSE(tile); + if (!tile) continue; - if (tile->is_occluded(PENDING_TREE)) + if (tile->is_occluded()) occluded_tile_count_on_pending++; - if (tile->is_occluded(ACTIVE_TREE)) - occluded_tile_count_on_active++; - if (tile->is_occluded(PENDING_TREE) && tile->is_occluded(ACTIVE_TREE)) - occluded_tile_count_on_both++; } EXPECT_EQ(expected_occluded_tile_count_on_pending[i], occluded_tile_count_on_pending) << tiling->contents_scale(); - EXPECT_EQ(expected_occluded_tile_count_on_active[i], - occluded_tile_count_on_active) - << tiling->contents_scale(); - EXPECT_EQ(expected_occluded_tile_count_on_both[i], - occluded_tile_count_on_both) - << tiling->contents_scale(); } // Verify number of occluded tiles on the active layer for each tiling. @@ -4503,9 +4437,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); tiling->UpdateAllTilePrioritiesForTesting(); - size_t occluded_tile_count_on_pending = 0u; size_t occluded_tile_count_on_active = 0u; - size_t occluded_tile_count_on_both = 0u; for (PictureLayerTiling::CoverageIterator iter( tiling, pending_layer_->contents_scale_x(), @@ -4516,22 +4448,12 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, if (!tile) continue; - if (tile->is_occluded(PENDING_TREE)) - occluded_tile_count_on_pending++; - if (tile->is_occluded(ACTIVE_TREE)) + if (tile->is_occluded()) occluded_tile_count_on_active++; - if (tile->is_occluded(PENDING_TREE) && tile->is_occluded(ACTIVE_TREE)) - occluded_tile_count_on_both++; } - EXPECT_EQ(expected_occluded_tile_count_on_pending[i], - occluded_tile_count_on_pending) - << i; EXPECT_EQ(expected_occluded_tile_count_on_active[i], occluded_tile_count_on_active) << i; - EXPECT_EQ(expected_occluded_tile_count_on_both[i], - occluded_tile_count_on_both) - << i; } std::vector<Tile*> all_tiles; @@ -4540,32 +4462,39 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, std::vector<Tile*> tiles = tiling->AllTilesForTesting(); all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end()); } + for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + std::vector<Tile*> tiles = tiling->AllTilesForTesting(); + all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end()); + } host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles); VerifyEvictionConsidersOcclusion( pending_layer_, active_layer_, PENDING_TREE, - total_expected_occluded_tile_count_on_trees[PENDING_TREE]); + total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__); VerifyEvictionConsidersOcclusion( active_layer_, pending_layer_, ACTIVE_TREE, - total_expected_occluded_tile_count_on_trees[ACTIVE_TREE]); + total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__); // Repeat the tests without valid active tree priorities. active_layer_->set_has_valid_tile_priorities(false); VerifyEvictionConsidersOcclusion( pending_layer_, active_layer_, PENDING_TREE, - total_expected_occluded_tile_count_on_trees[PENDING_TREE]); + total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__); VerifyEvictionConsidersOcclusion( - active_layer_, pending_layer_, ACTIVE_TREE, 0u); + active_layer_, pending_layer_, ACTIVE_TREE, + total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__); active_layer_->set_has_valid_tile_priorities(true); // Repeat the tests without valid pending tree priorities. pending_layer_->set_has_valid_tile_priorities(false); VerifyEvictionConsidersOcclusion( active_layer_, pending_layer_, ACTIVE_TREE, - total_expected_occluded_tile_count_on_trees[ACTIVE_TREE]); + total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__); VerifyEvictionConsidersOcclusion( - pending_layer_, active_layer_, PENDING_TREE, 0u); + pending_layer_, active_layer_, PENDING_TREE, + total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__); pending_layer_->set_has_valid_tile_priorities(true); } @@ -4794,6 +4723,13 @@ TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) { if (*iter) tiles.push_back(*iter); } + for (PictureLayerTiling::CoverageIterator iter( + active_layer_->HighResTiling(), 1.f, + active_layer_->HighResTiling()->GetCurrentVisibleRectForTesting()); + iter; ++iter) { + if (*iter) + tiles.push_back(*iter); + } host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles); @@ -4823,8 +4759,8 @@ TEST_F(PictureLayerImplTest, CloneMissingRecordings) { PictureLayerTiling* pending_tiling = old_pending_layer_->HighResTiling(); PictureLayerTiling* active_tiling = active_layer_->HighResTiling(); - // We should have all tiles in both tile sets. - EXPECT_EQ(5u * 5u, pending_tiling->AllTilesForTesting().size()); + // We should have all tiles on active, and none on pending. + EXPECT_EQ(0u, pending_tiling->AllTilesForTesting().size()); EXPECT_EQ(5u * 5u, active_tiling->AllTilesForTesting().size()); // Now put a partially-recorded pile on the pending tree (and invalidate @@ -4852,16 +4788,110 @@ TEST_F(PictureLayerImplTest, CloneMissingRecordings) { SetupPendingTreeWithFixedTileSize(filled_pile, tile_size, Region(gfx::Rect(layer_bounds))); EXPECT_EQ(5u * 5u, pending_tiling->AllTilesForTesting().size()); + Tile* tile00 = pending_tiling->TileAt(0, 0); + Tile* tile11 = pending_tiling->TileAt(1, 1); + Tile* tile22 = pending_tiling->TileAt(2, 2); // Active is not affected yet. EXPECT_EQ(3u * 3u, active_tiling->AllTilesForTesting().size()); - // Activate the tree. The tiles are created and shared on the active tree. + // Activate the tree. The tiles are moved to the active tree. ActivateTree(); EXPECT_EQ(5u * 5u, active_tiling->AllTilesForTesting().size()); - EXPECT_TRUE(active_tiling->TileAt(0, 0)->is_shared()); - EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared()); - EXPECT_TRUE(active_tiling->TileAt(2, 2)->is_shared()); + EXPECT_EQ(tile00, active_tiling->TileAt(0, 0)); + EXPECT_EQ(tile11, active_tiling->TileAt(1, 1)); + EXPECT_EQ(tile22, active_tiling->TileAt(2, 2)); +} + +TEST_F(PictureLayerImplTest, ScrollPastLiveTilesRectAndBack) { + base::TimeTicks time_ticks; + time_ticks += base::TimeDelta::FromMilliseconds(1); + host_impl_.SetCurrentBeginFrameArgs( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); + + gfx::Size tile_size(102, 102); + gfx::Size layer_bounds(100, 100); + gfx::Size viewport_size(100, 100); + + host_impl_.SetViewportSize(viewport_size); + host_impl_.SetDeviceScaleFactor(1.f); + + scoped_refptr<FakePicturePileImpl> pending_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + scoped_refptr<FakePicturePileImpl> active_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + + SetupPendingTreeWithFixedTileSize(active_pile, tile_size, Region()); + + ActivateTree(); + EXPECT_TRUE(active_layer_->HighResTiling()->has_tiles()); + + host_impl_.SetExternalDrawConstraints( + gfx::Transform(), // transform + gfx::Rect(), // clip + gfx::Rect(), // viewport + gfx::Rect(0, 1000, 100, 100), // viewport_rect_for_tile_priority + gfx::Transform(), // transform_for_tile_priority + false); + + SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, gfx::Rect()); + + EXPECT_FALSE(pending_layer_->HighResTiling()->has_tiles()); + EXPECT_TRUE(pending_layer_->HighResTiling()->live_tiles_rect().IsEmpty()); + ActivateTree(); + EXPECT_FALSE(active_layer_->HighResTiling()->has_tiles()); + EXPECT_TRUE(active_layer_->HighResTiling()->live_tiles_rect().IsEmpty()); + + host_impl_.SetExternalDrawConstraints( + gfx::Transform(), // transform + gfx::Rect(), // clip + gfx::Rect(), // viewport + gfx::Rect(0, 110, 100, 100), // viewport_rect_for_tile_priority + gfx::Transform(), // transform_for_tile_priority + false); + + SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, gfx::Rect()); + + EXPECT_FALSE(pending_layer_->HighResTiling()->has_tiles()); + EXPECT_FALSE(pending_layer_->HighResTiling()->live_tiles_rect().IsEmpty()); + ActivateTree(); + EXPECT_TRUE(active_layer_->HighResTiling()->has_tiles()); + EXPECT_FALSE(active_layer_->HighResTiling()->live_tiles_rect().IsEmpty()); +} + +TEST_F(PictureLayerImplTest, UpdateLCDInvalidatesPendingTree) { + base::TimeTicks time_ticks; + time_ticks += base::TimeDelta::FromMilliseconds(1); + host_impl_.SetCurrentBeginFrameArgs( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); + + gfx::Size tile_size(102, 102); + gfx::Size layer_bounds(100, 100); + gfx::Size viewport_size(100, 100); + + host_impl_.SetViewportSize(viewport_size); + host_impl_.SetDeviceScaleFactor(1.f); + + scoped_refptr<FakePicturePileImpl> pending_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region()); + + EXPECT_TRUE(pending_layer_->RasterSourceUsesLCDText()); + EXPECT_TRUE(pending_layer_->HighResTiling()->has_tiles()); + std::vector<Tile*> tiles = + pending_layer_->HighResTiling()->AllTilesForTesting(); + for (Tile* tile : tiles) + EXPECT_EQ(pending_layer_->raster_source(), tile->raster_source()); + + pending_layer_->draw_properties().can_use_lcd_text = false; + pending_layer_->UpdateCanUseLCDTextAfterCommit(); + + EXPECT_FALSE(pending_layer_->RasterSourceUsesLCDText()); + EXPECT_NE(pending_pile.get(), pending_layer_->raster_source()); + EXPECT_TRUE(pending_layer_->HighResTiling()->has_tiles()); + tiles = pending_layer_->HighResTiling()->AllTilesForTesting(); + for (Tile* tile : tiles) + EXPECT_EQ(pending_layer_->raster_source(), tile->raster_source()); } class TileSizeSettings : public ImplSidePaintingSettings { diff --git a/cc/resources/eviction_tile_priority_queue.cc b/cc/resources/eviction_tile_priority_queue.cc index 3f55469..96da962 100644 --- a/cc/resources/eviction_tile_priority_queue.cc +++ b/cc/resources/eviction_tile_priority_queue.cc @@ -33,8 +33,8 @@ class EvictionOrderComparator { const Tile* a_tile = a_queue->Top(); const Tile* b_tile = b_queue->Top(); - const TilePriority& a_priority = a_tile->combined_priority(); - const TilePriority& b_priority = b_tile->combined_priority(); + const TilePriority& a_priority = a_tile->priority(); + const TilePriority& b_priority = b_tile->priority(); bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; // If the priority bin differs, b is lower priority if it has the higher @@ -61,8 +61,8 @@ class EvictionOrderComparator { // Otherwise if the occlusion differs, b is lower priority if it is // occluded. - bool a_is_occluded = a_tile->is_occluded_combined(); - bool b_is_occluded = b_tile->is_occluded_combined(); + bool a_is_occluded = a_tile->is_occluded(); + bool b_is_occluded = b_tile->is_occluded(); if (a_is_occluded != b_is_occluded) return b_is_occluded; @@ -184,8 +184,8 @@ EvictionTilePriorityQueue::PairedTilingSetQueue::NextTileIteratorTree() const { if (active_tile == pending_tile) return ACTIVE_TREE; - const TilePriority& active_priority = active_tile->combined_priority(); - const TilePriority& pending_priority = pending_tile->combined_priority(); + const TilePriority& active_priority = active_tile->priority(); + const TilePriority& pending_priority = pending_tile->priority(); // If the bins are the same and activation differs, then return the tree of // the tile not required for activation. diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index 51c8ca73..30a73b8 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -79,8 +79,6 @@ PictureLayerTiling::PictureLayerTiling( } PictureLayerTiling::~PictureLayerTiling() { - for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) - it->second->set_shared(false); } // static @@ -94,13 +92,7 @@ float PictureLayerTiling::CalculateSoonBorderDistance( max_dimension * kSoonBorderDistanceViewportPercentage); } -Tile* PictureLayerTiling::CreateTile(int i, - int j, - const PictureLayerTiling* twin_tiling, - PictureLayerTiling* recycled_twin) { - // Can't have both a (pending or active) twin and a recycled twin tiling. - DCHECK_IMPLIES(twin_tiling, !recycled_twin); - DCHECK_IMPLIES(recycled_twin, !twin_tiling); +Tile* PictureLayerTiling::CreateTile(int i, int j) { TileMapKey key(i, j); DCHECK(tiles_.find(key) == tiles_.end()); @@ -108,116 +100,73 @@ Tile* PictureLayerTiling::CreateTile(int i, gfx::Rect tile_rect = paint_rect; tile_rect.set_size(tiling_data_.max_texture_size()); - // Check our twin for a valid tile. - if (twin_tiling && - tiling_data_.max_texture_size() == - twin_tiling->tiling_data_.max_texture_size()) { - if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { - gfx::Rect rect = - gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); - const Region* invalidation = client_->GetPendingInvalidation(); - if (!invalidation || !invalidation->Intersects(rect)) { - DCHECK(!candidate_tile->is_shared()); - DCHECK_EQ(i, candidate_tile->tiling_i_index()); - DCHECK_EQ(j, candidate_tile->tiling_j_index()); - candidate_tile->set_shared(true); - tiles_[key] = candidate_tile; - return candidate_tile; - } - } - } - if (!raster_source_->CoversRect(tile_rect, contents_scale_)) return nullptr; - // Create a new tile because our twin didn't have a valid one. scoped_refptr<Tile> tile = client_->CreateTile(contents_scale_, tile_rect); - DCHECK(!tile->is_shared()); tile->set_tiling_index(i, j); tiles_[key] = tile; - - if (recycled_twin) { - DCHECK(recycled_twin->tiles_.find(key) == recycled_twin->tiles_.end()); - // Do what recycled_twin->CreateTile() would do. - tile->set_shared(true); - recycled_twin->tiles_[key] = tile; - } return tile.get(); } void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { - const PictureLayerTiling* twin_tiling = - client_->GetPendingOrActiveTwinTiling(this); - // There is no recycled twin during commit from the main thread which is when - // this occurs. - PictureLayerTiling* null_recycled_twin = nullptr; - DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); bool include_borders = false; - for (TilingData::Iterator iter( - &tiling_data_, live_tiles_rect_, include_borders); - iter; - ++iter) { + for (TilingData::Iterator iter(&tiling_data_, live_tiles_rect_, + include_borders); + iter; ++iter) { TileMapKey key = iter.index(); TileMap::iterator find = tiles_.find(key); if (find != tiles_.end()) continue; - CreateTile(key.first, key.second, twin_tiling, null_recycled_twin); - } + if (ShouldCreateTileAt(key.first, key.second)) + CreateTile(key.first, key.second); + } VerifyLiveTilesRect(false); } -void PictureLayerTiling::CloneTilesAndPropertiesFrom( - const PictureLayerTiling& twin_tiling) { - DCHECK_EQ(&twin_tiling, client_->GetPendingOrActiveTwinTiling(this)); +void PictureLayerTiling::TakeTilesAndPropertiesFrom( + PictureLayerTiling* pending_twin, + const Region& layer_invalidation) { + TRACE_EVENT0("cc", "TakeTilesAndPropertiesFrom"); + SetRasterSourceAndResize(pending_twin->raster_source_); - SetRasterSourceAndResize(twin_tiling.raster_source_); - DCHECK_EQ(twin_tiling.contents_scale_, contents_scale_); - DCHECK_EQ(twin_tiling.raster_source_, raster_source_); - DCHECK_EQ(twin_tiling.tile_size().ToString(), tile_size().ToString()); + RemoveTilesInRegion(layer_invalidation, false /* recreate tiles */); - resolution_ = twin_tiling.resolution_; + for (TileMap::value_type& tile_pair : tiles_) + tile_pair.second->set_raster_source(raster_source_.get()); - SetLiveTilesRect(twin_tiling.live_tiles_rect()); - - // Recreate unshared tiles. - std::vector<TileMapKey> to_remove; - for (const auto& tile_map_pair : tiles_) { - TileMapKey key = tile_map_pair.first; - Tile* tile = tile_map_pair.second.get(); - if (!tile->is_shared()) - to_remove.push_back(key); - } - // The recycled twin does not exist since there is a pending twin (which is - // |twin_tiling|). - PictureLayerTiling* null_recycled_twin = nullptr; - DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); - for (const auto& key : to_remove) { - RemoveTileAt(key.first, key.second, null_recycled_twin); - CreateTile(key.first, key.second, &twin_tiling, null_recycled_twin); + resolution_ = pending_twin->resolution_; + bool create_missing_tiles = false; + if (live_tiles_rect_.IsEmpty()) { + live_tiles_rect_ = pending_twin->live_tiles_rect(); + create_missing_tiles = true; + } else { + SetLiveTilesRect(pending_twin->live_tiles_rect()); } - // Create any missing tiles from the |twin_tiling|. - for (const auto& tile_map_pair : twin_tiling.tiles_) { - TileMapKey key = tile_map_pair.first; - Tile* tile = tile_map_pair.second.get(); - if (!tile->is_shared()) - CreateTile(key.first, key.second, &twin_tiling, null_recycled_twin); + if (tiles_.size() < pending_twin->tiles_.size()) { + tiles_.swap(pending_twin->tiles_); + tiles_.insert(pending_twin->tiles_.begin(), pending_twin->tiles_.end()); + } else { + for (TileMap::value_type& tile_pair : pending_twin->tiles_) { + tiles_[tile_pair.first].swap(tile_pair.second); + DCHECK(tiles_[tile_pair.first]->raster_source() == raster_source_.get()); + } } + pending_twin->tiles_.clear(); + + if (create_missing_tiles) + CreateMissingTilesInLiveTilesRect(); - DCHECK_EQ(twin_tiling.tiles_.size(), tiles_.size()); -#if DCHECK_IS_ON() - for (const auto& tile_map_pair : tiles_) - DCHECK(tile_map_pair.second->is_shared()); VerifyLiveTilesRect(false); -#endif - UpdateTilePriorityRects(twin_tiling.current_content_to_screen_scale_, - twin_tiling.current_visible_rect_, - twin_tiling.current_skewport_rect_, - twin_tiling.current_soon_border_rect_, - twin_tiling.current_eventually_rect_, - twin_tiling.current_occlusion_in_layer_space_); + SetTilePriorityRects(pending_twin->current_content_to_screen_scale_, + pending_twin->current_visible_rect_, + pending_twin->current_skewport_rect_, + pending_twin->current_soon_border_rect_, + pending_twin->current_eventually_rect_, + pending_twin->current_occlusion_in_layer_space_); } void PictureLayerTiling::SetRasterSourceAndResize( @@ -270,36 +219,42 @@ void PictureLayerTiling::SetRasterSourceAndResize( // There is no recycled twin since this is run on the pending tiling // during commit, and on the active tree during activate. - PictureLayerTiling* null_recycled_twin = nullptr; - DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); - // Drop tiles outside the new layer bounds if the layer shrank. for (int i = after_right + 1; i <= before_right; ++i) { for (int j = before_top; j <= before_bottom; ++j) - RemoveTileAt(i, j, null_recycled_twin); + RemoveTileAt(i, j); } for (int i = before_left; i <= after_right; ++i) { for (int j = after_bottom + 1; j <= before_bottom; ++j) - RemoveTileAt(i, j, null_recycled_twin); + RemoveTileAt(i, j); } - // If the layer grew, the live_tiles_rect_ is not changed, but a new row - // and/or column of tiles may now exist inside the same live_tiles_rect_. - const PictureLayerTiling* twin_tiling = - client_->GetPendingOrActiveTwinTiling(this); if (after_right > before_right) { DCHECK_EQ(after_right, before_right + 1); - for (int j = before_top; j <= after_bottom; ++j) - CreateTile(after_right, j, twin_tiling, null_recycled_twin); + for (int j = before_top; j <= after_bottom; ++j) { + if (ShouldCreateTileAt(after_right, j)) + CreateTile(after_right, j); + } } if (after_bottom > before_bottom) { DCHECK_EQ(after_bottom, before_bottom + 1); - for (int i = before_left; i <= before_right; ++i) - CreateTile(i, after_bottom, twin_tiling, null_recycled_twin); + for (int i = before_left; i <= before_right; ++i) { + if (ShouldCreateTileAt(i, after_bottom)) + CreateTile(i, after_bottom); + } } } void PictureLayerTiling::Invalidate(const Region& layer_invalidation) { + DCHECK_IMPLIES(client_->GetTree() == ACTIVE_TREE, + !client_->GetPendingOrActiveTwinTiling(this)); + RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); +} + +void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, + bool recreate_tiles) { + // We only invalidate the active tiling when it's orphaned: it has no pending + // twin, so it's slated for removal in the future. if (live_tiles_rect_.IsEmpty()) return; std::vector<TileMapKey> new_tile_keys; @@ -323,41 +278,82 @@ void PictureLayerTiling::Invalidate(const Region& layer_invalidation) { // Since the content_rect includes border pixels already, don't include // borders when iterating to avoid double counting them. bool include_borders = false; - for (TilingData::Iterator iter( - &tiling_data_, content_rect, include_borders); - iter; - ++iter) { - // There is no recycled twin for the pending tree during commit, or for - // the active tree during activation. - PictureLayerTiling* null_recycled_twin = nullptr; - DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); - if (RemoveTileAt(iter.index_x(), iter.index_y(), null_recycled_twin)) - new_tile_keys.push_back(iter.index()); + for ( + TilingData::Iterator iter(&tiling_data_, content_rect, include_borders); + iter; ++iter) { + if (RemoveTileAt(iter.index_x(), iter.index_y())) { + if (recreate_tiles) + new_tile_keys.push_back(iter.index()); + } } } - if (!new_tile_keys.empty()) { - // During commit from the main thread, invalidations can never be shared - // with the active tree since the active tree has different content there. - // And when invalidating an active-tree tiling, it means there was no - // pending tiling to clone from. - const PictureLayerTiling* null_twin_tiling = nullptr; - PictureLayerTiling* null_recycled_twin = nullptr; - DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); - for (size_t i = 0; i < new_tile_keys.size(); ++i) { - CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, - null_twin_tiling, null_recycled_twin); - } - } + for (const auto& key : new_tile_keys) + CreateTile(key.first, key.second); } void PictureLayerTiling::SetRasterSourceOnTiles() { - // Shared (ie. non-invalidated) tiles on the pending tree are updated to use - // the new raster source. When this raster source is activated, the raster - // source will remain valid for shared tiles in the active tree. - for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) - it->second->set_raster_source(raster_source_); - VerifyLiveTilesRect(false); + if (client_->GetTree() == PENDING_TREE) + return; + + for (TileMap::value_type& tile_pair : tiles_) + tile_pair.second->set_raster_source(raster_source_.get()); +} + +bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const { + // Active tree should always create a tile. The reason for this is that active + // tree represents content that we draw on screen, which means that whenever + // we check whether a tile should exist somewhere, the answer is yes. This + // doesn't mean it will actually be created (if raster source doesn't cover + // the tile for instance). Pending tree, on the other hand, should only be + // creating tiles that are different from the current active tree, which is + // represented by the logic in the rest of the function. + if (client_->GetTree() == ACTIVE_TREE) + return true; + + // If the pending tree has no active twin, then it needs to create all tiles. + const PictureLayerTiling* active_twin = + client_->GetPendingOrActiveTwinTiling(this); + if (!active_twin) + return true; + + // Pending tree will override the entire active tree if indices don't match. + if (!TilingMatchesTileIndices(active_twin)) + return true; + + gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); + gfx::Rect tile_rect = paint_rect; + tile_rect.set_size(tiling_data_.max_texture_size()); + + // If the active tree can't create a tile, because of its raster source, then + // the pending tree should create one. + if (!active_twin->raster_source()->CoversRect(tile_rect, contents_scale())) + return true; + + const Region* layer_invalidation = client_->GetPendingInvalidation(); + gfx::Rect layer_rect = + gfx::ScaleToEnclosingRect(tile_rect, 1.f / contents_scale()); + + // If this tile is invalidated, then the pending tree should create one. + if (layer_invalidation && layer_invalidation->Intersects(layer_rect)) + return true; + + // If the active tree doesn't have a tile here, but it's in the pending tree's + // visible rect, then the pending tree should create a tile. This can happen + // if the pending visible rect is outside of the active tree's live tiles + // rect. In those situations, we need to block activation until we're ready to + // display content, which will have to come from the pending tree. + if (!active_twin->TileAt(i, j) && current_visible_rect_.Intersects(tile_rect)) + return true; + + // In all other cases, the pending tree doesn't need to create a tile. + return false; +} + +bool PictureLayerTiling::TilingMatchesTileIndices( + const PictureLayerTiling* twin) const { + return tiling_data_.max_texture_size() == + twin->tiling_data_.max_texture_size(); } PictureLayerTiling::CoverageIterator::CoverageIterator() @@ -499,29 +495,16 @@ gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const { return texture_rect; } -bool PictureLayerTiling::RemoveTileAt(int i, - int j, - PictureLayerTiling* recycled_twin) { +bool PictureLayerTiling::RemoveTileAt(int i, int j) { TileMap::iterator found = tiles_.find(TileMapKey(i, j)); if (found == tiles_.end()) return false; - found->second->set_shared(false); tiles_.erase(found); - if (recycled_twin) { - // Recycled twin does not also have a recycled twin, so pass null. - recycled_twin->RemoveTileAt(i, j, nullptr); - } return true; } void PictureLayerTiling::Reset() { live_tiles_rect_ = gfx::Rect(); - PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); - for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { - it->second->set_shared(false); - if (recycled_twin) - recycled_twin->RemoveTileAt(it->first.first, it->first.second, nullptr); - } tiles_.clear(); } @@ -631,14 +614,14 @@ bool PictureLayerTiling::ComputeTilePriorityRects( visible_rect_in_content_space); last_viewport_in_layer_space_ = viewport_in_layer_space; + SetTilePriorityRects(content_to_screen_scale, visible_rect_in_content_space, + skewport, soon_border_rect, eventually_rect, + occlusion_in_layer_space); SetLiveTilesRect(eventually_rect); - UpdateTilePriorityRects( - content_to_screen_scale, visible_rect_in_content_space, skewport, - soon_border_rect, eventually_rect, occlusion_in_layer_space); return true; } -void PictureLayerTiling::UpdateTilePriorityRects( +void PictureLayerTiling::SetTilePriorityRects( float content_to_screen_scale, const gfx::Rect& visible_rect_in_content_space, const gfx::Rect& skewport, @@ -669,36 +652,24 @@ void PictureLayerTiling::SetLiveTilesRect( if (live_tiles_rect_ == new_live_tiles_rect) return; - PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); - // Iterate to delete all tiles outside of our new live_tiles rect. - for (TilingData::DifferenceIterator iter(&tiling_data_, - live_tiles_rect_, + for (TilingData::DifferenceIterator iter(&tiling_data_, live_tiles_rect_, new_live_tiles_rect); - iter; - ++iter) { - RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin); + iter; ++iter) { + RemoveTileAt(iter.index_x(), iter.index_y()); } - const PictureLayerTiling* twin_tiling = - client_->GetPendingOrActiveTwinTiling(this); - // Iterate to allocate new tiles for all regions with newly exposed area. - for (TilingData::DifferenceIterator iter(&tiling_data_, - new_live_tiles_rect, + for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, live_tiles_rect_); - iter; - ++iter) { + iter; ++iter) { TileMapKey key(iter.index()); - CreateTile(key.first, key.second, twin_tiling, recycled_twin); + if (ShouldCreateTileAt(key.first, key.second)) + CreateTile(key.first, key.second); } live_tiles_rect_ = new_live_tiles_rect; VerifyLiveTilesRect(false); - if (recycled_twin) { - recycled_twin->live_tiles_rect_ = live_tiles_rect_; - recycled_twin->VerifyLiveTilesRect(true); - } } void PictureLayerTiling::VerifyLiveTilesRect(bool is_on_recycle_tree) const { @@ -720,136 +691,126 @@ void PictureLayerTiling::VerifyLiveTilesRect(bool is_on_recycle_tree) const { << " tile bounds " << tiling_data_.TileBounds(it->first.first, it->first.second).ToString() << " live_tiles_rect " << live_tiles_rect_.ToString(); - DCHECK_IMPLIES(is_on_recycle_tree, it->second->is_shared()); } #endif } bool PictureLayerTiling::IsTileOccluded(const Tile* tile) const { - DCHECK(tile); + // If this tile is not occluded on this tree, then it is not occluded. + if (!IsTileOccludedOnCurrentTree(tile)) + return false; + + // Otherwise, if this is the pending tree, we're done and the tile is + // occluded. + if (client_->GetTree() == PENDING_TREE) + return true; + + // On the active tree however, we need to check if this tile will be + // unoccluded upon activation, in which case it has to be considered + // unoccluded. + const PictureLayerTiling* pending_twin = + client_->GetPendingOrActiveTwinTiling(this); + if (pending_twin) { + // If there's a pending tile in the same position. Or if the pending twin + // would have to be creating all tiles, then we don't need to worry about + // occlusion on the twin. + if (!TilingMatchesTileIndices(pending_twin) || + pending_twin->TileAt(tile->tiling_i_index(), tile->tiling_j_index())) { + return true; + } + return pending_twin->IsTileOccludedOnCurrentTree(tile); + } + return true; +} +bool PictureLayerTiling::IsTileOccludedOnCurrentTree(const Tile* tile) const { if (!current_occlusion_in_layer_space_.HasOcclusion()) return false; - gfx::Rect tile_query_rect = gfx::IntersectRects(tile->content_rect(), current_visible_rect_); - // Explicitly check if the tile is outside the viewport. If so, we need to // return false, since occlusion for this tile is unknown. - // TODO(vmpstr): Since the current visible rect is really a viewport in - // layer space, we should probably clip tile query rect to tiling bounds - // or live tiles rect. if (tile_query_rect.IsEmpty()) return false; if (contents_scale_ != 1.f) { tile_query_rect = - gfx::ScaleToEnclosingRect(tile_query_rect, 1.0f / contents_scale_); + gfx::ScaleToEnclosingRect(tile_query_rect, 1.f / contents_scale_); } - return current_occlusion_in_layer_space_.IsOccluded(tile_query_rect); } -bool PictureLayerTiling::IsTileRequiredForActivationIfVisible( - const Tile* tile) const { - DCHECK_EQ(PENDING_TREE, client_->GetTree()); +bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const { + if (client_->GetTree() == PENDING_TREE) { + if (!can_require_tiles_for_activation_) + return false; - // This function assumes that the tile is visible (i.e. in the viewport). The - // caller needs to make sure that this condition is met to ensure we don't - // block activation on tiles outside of the viewport. + if (resolution_ != HIGH_RESOLUTION) + return false; - // If we are not allowed to mark tiles as required for activation, then don't - // do it. - if (!can_require_tiles_for_activation_) - return false; + if (IsTileOccluded(tile)) + return false; - if (resolution_ != HIGH_RESOLUTION) - return false; + bool tile_is_visible = + tile->content_rect().Intersects(current_visible_rect_); + if (!tile_is_visible) + return false; - if (IsTileOccluded(tile)) - return false; + if (client_->RequiresHighResToDraw()) + return true; - if (client_->RequiresHighResToDraw()) - return true; + const PictureLayerTiling* active_twin = + client_->GetPendingOrActiveTwinTiling(this); + if (!active_twin || !TilingMatchesTileIndices(active_twin)) + return true; - const PictureLayerTiling* twin_tiling = - client_->GetPendingOrActiveTwinTiling(this); - if (!twin_tiling) - return true; + if (active_twin->raster_source()->GetSize() != raster_source()->GetSize()) + return true; - if (twin_tiling->raster_source()->GetSize() != raster_source()->GetSize()) - return true; + if (active_twin->current_visible_rect_ != current_visible_rect_) + return true; - if (twin_tiling->current_visible_rect_ != current_visible_rect_) + Tile* twin_tile = + active_twin->TileAt(tile->tiling_i_index(), tile->tiling_j_index()); + if (!twin_tile) + return false; return true; + } - Tile* twin_tile = - twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()); - // If twin tile is missing, it might not have a recording, so we don't need - // this tile to be required for activation. - if (!twin_tile) + DCHECK(client_->GetTree() == ACTIVE_TREE); + const PictureLayerTiling* pending_twin = + client_->GetPendingOrActiveTwinTiling(this); + // If we don't have a pending tree, or the pending tree will overwrite the + // given tile, then it is not required for activation. + if (!pending_twin || !TilingMatchesTileIndices(pending_twin) || + pending_twin->TileAt(tile->tiling_i_index(), tile->tiling_j_index())) { return false; - - return true; + } + // Otherwise, ask the pending twin if this tile is required for activation. + return pending_twin->IsTileRequiredForActivation(tile); } -bool PictureLayerTiling::IsTileRequiredForDrawIfVisible( - const Tile* tile) const { - DCHECK_EQ(ACTIVE_TREE, client_->GetTree()); - - // This function assumes that the tile is visible (i.e. in the viewport). +bool PictureLayerTiling::IsTileRequiredForDraw(const Tile* tile) const { + if (client_->GetTree() == PENDING_TREE) + return false; if (resolution_ != HIGH_RESOLUTION) return false; - if (IsTileOccluded(tile)) + bool tile_is_visible = current_visible_rect_.Intersects(tile->content_rect()); + if (!tile_is_visible) return false; + if (IsTileOccludedOnCurrentTree(tile)) + return false; return true; } void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const { - WhichTree tree = client_->GetTree(); - WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; - - tile->SetPriority(tree, ComputePriorityForTile(tile)); - UpdateRequiredStateForTile(tile, tree); - - const PictureLayerTiling* twin_tiling = - client_->GetPendingOrActiveTwinTiling(this); - if (!tile->is_shared() || !twin_tiling) { - tile->SetPriority(twin_tree, TilePriority()); - tile->set_is_occluded(twin_tree, false); - if (twin_tree == PENDING_TREE) - tile->set_required_for_activation(false); - else - tile->set_required_for_draw(false); - return; - } - - tile->SetPriority(twin_tree, twin_tiling->ComputePriorityForTile(tile)); - twin_tiling->UpdateRequiredStateForTile(tile, twin_tree); -} - -void PictureLayerTiling::UpdateRequiredStateForTile(Tile* tile, - WhichTree tree) const { - if (tile->priority(tree).priority_bin == TilePriority::NOW) { - if (tree == PENDING_TREE) { - tile->set_required_for_activation( - IsTileRequiredForActivationIfVisible(tile)); - } else { - tile->set_required_for_draw(IsTileRequiredForDrawIfVisible(tile)); - } - tile->set_is_occluded(tree, IsTileOccluded(tile)); - return; - } - - // Non-NOW bin tiles are not required or occluded. - if (tree == PENDING_TREE) - tile->set_required_for_activation(false); - else - tile->set_required_for_draw(false); - tile->set_is_occluded(tree, false); + tile->set_priority(ComputePriorityForTile(tile)); + tile->set_is_occluded(IsTileOccluded(tile)); + tile->set_required_for_activation(IsTileRequiredForActivation(tile)); + tile->set_required_for_draw(IsTileRequiredForDraw(tile)); } void PictureLayerTiling::VerifyAllTilesHaveCurrentRasterSource() const { @@ -874,6 +835,11 @@ TilePriority PictureLayerTiling::ComputePriorityForTile( return TilePriority(resolution_, TilePriority::NOW, 0); } + if (max_tile_priority_bin <= TilePriority::SOON && + pending_visible_rect().Intersects(tile_bounds)) { + return TilePriority(resolution_, TilePriority::SOON, 0); + } + DCHECK_GT(current_content_to_screen_scale_, 0.f); float distance_to_visible = current_visible_rect_.ManhattanInternalDistance(tile_bounds) * @@ -891,20 +857,11 @@ TilePriority PictureLayerTiling::ComputePriorityForTile( void PictureLayerTiling::GetAllTilesAndPrioritiesForTracing( std::map<const Tile*, TilePriority>* tile_map) const { - const PictureLayerTiling* twin_tiling = - client_->GetPendingOrActiveTwinTiling(this); for (const auto& tile_pair : tiles_) { const Tile* tile = tile_pair.second.get(); const TilePriority& priority = ComputePriorityForTile(tile); - // If the tile is shared, it means the twin also has the same tile. - // Otherwise, use the default priority. - const TilePriority& twin_priority = - (twin_tiling && tile->is_shared()) - ? twin_tiling->ComputePriorityForTile(tile) - : TilePriority(); - // Store combined priority. - (*tile_map)[tile] = TilePriority(priority, twin_priority); + (*tile_map)[tile] = priority; } } diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h index 34e7def..ad56a24 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h @@ -58,6 +58,7 @@ class CC_EXPORT PictureLayerTiling { public: static const int kBorderTexels = 1; + PictureLayerTilingClient* client() const { return client_; } ~PictureLayerTiling(); static float CalculateSoonBorderDistance( @@ -77,8 +78,11 @@ class CC_EXPORT PictureLayerTiling { void Invalidate(const Region& layer_invalidation); void SetRasterSourceOnTiles(); void CreateMissingTilesInLiveTilesRect(); + void TakeTilesAndPropertiesFrom(PictureLayerTiling* pending_twin, + const Region& layer_invalidation); - void CloneTilesAndPropertiesFrom(const PictureLayerTiling& twin_tiling); + bool IsTileRequiredForActivation(const Tile* tile) const; + bool IsTileRequiredForDraw(const Tile* tile) const; void set_resolution(TileResolution resolution) { resolution_ = resolution; } TileResolution resolution() const { return resolution_; } @@ -95,34 +99,32 @@ class CC_EXPORT PictureLayerTiling { Tile* TileAt(int i, int j) const { TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); - return (iter == tiles_.end()) ? NULL : iter->second.get(); + return iter == tiles_.end() ? nullptr : iter->second.get(); } + bool has_tiles() const { return !tiles_.empty(); } + + // For testing functionality. void CreateAllTilesForTesting() { SetLiveTilesRect(gfx::Rect(tiling_data_.tiling_size())); } - const TilingData& TilingDataForTesting() const { return tiling_data_; } - std::vector<Tile*> AllTilesForTesting() const { std::vector<Tile*> all_tiles; for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) all_tiles.push_back(it->second.get()); return all_tiles; } - void UpdateAllTilePrioritiesForTesting() { for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) UpdateTileAndTwinPriority(it->second.get()); } - std::vector<scoped_refptr<Tile>> AllRefTilesForTesting() const { std::vector<scoped_refptr<Tile>> all_tiles; for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) all_tiles.push_back(it->second); return all_tiles; } - void SetAllTilesOccludedForTesting() { gfx::Rect viewport_in_layer_space = ScaleToEnclosingRect(current_visible_rect_, 1.0f / contents_scale_); @@ -131,37 +133,10 @@ class CC_EXPORT PictureLayerTiling { SimpleEnclosedRegion(viewport_in_layer_space), SimpleEnclosedRegion(viewport_in_layer_space)); } - const gfx::Rect& GetCurrentVisibleRectForTesting() const { return current_visible_rect_; } - bool IsTileOccluded(const Tile* tile) const; - bool IsTileRequiredForActivationIfVisible(const Tile* tile) const; - bool IsTileRequiredForDrawIfVisible(const Tile* tile) const; - - void UpdateTileAndTwinPriority(Tile* tile) const; - TilePriority ComputePriorityForTile(const Tile* tile) const; - void UpdateRequiredStateForTile(Tile* tile, WhichTree tree) const; - bool has_visible_rect_tiles() const { return has_visible_rect_tiles_; } - bool has_skewport_rect_tiles() const { return has_skewport_rect_tiles_; } - bool has_soon_border_rect_tiles() const { - return has_soon_border_rect_tiles_; - } - bool has_eventually_rect_tiles() const { return has_eventually_rect_tiles_; } - - const gfx::Rect& current_visible_rect() const { - return current_visible_rect_; - } - const gfx::Rect& current_skewport_rect() const { - return current_skewport_rect_; - } - const gfx::Rect& current_soon_border_rect() const { - return current_soon_border_rect_; - } - const gfx::Rect& current_eventually_rect() const { - return current_eventually_rect_; - } void VerifyAllTilesHaveCurrentRasterSource() const; // Iterate over all tiles to fill content_rect. Even if tiles are invalid @@ -236,10 +211,6 @@ class CC_EXPORT PictureLayerTiling { const gfx::Rect& bounding_rect, RectExpansionCache* cache); - bool has_ever_been_updated() const { - return visible_rect_history_[0].frame_time_in_seconds != 0.0; - } - protected: friend class CoverageIterator; friend class TilingSetRasterQueueAll; @@ -262,12 +233,10 @@ class CC_EXPORT PictureLayerTiling { int skewport_extrapolation_limit_in_content_pixels); void SetLiveTilesRect(const gfx::Rect& live_tiles_rect); void VerifyLiveTilesRect(bool is_on_recycle_tree) const; - Tile* CreateTile(int i, - int j, - const PictureLayerTiling* twin_tiling, - PictureLayerTiling* recycled_twin); + Tile* CreateTile(int i, int j); // Returns true if the Tile existed and was removed from the tiling. - bool RemoveTileAt(int i, int j, PictureLayerTiling* recycled_twin); + bool RemoveTileAt(int i, int j); + bool TilingMatchesTileIndices(const PictureLayerTiling* twin) const; // Computes a skewport. The calculation extrapolates the last visible // rect and the current visible rect to expand the skewport to where it @@ -278,14 +247,13 @@ class CC_EXPORT PictureLayerTiling { const; // Save the required data for computing tile priorities later. - void UpdateTilePriorityRects(float content_to_screen_scale_, - const gfx::Rect& visible_rect_in_content_space, - const gfx::Rect& skewport, - const gfx::Rect& soon_border_rect, - const gfx::Rect& eventually_rect, - const Occlusion& occlusion_in_layer_space); - - void UpdateTilePriorityForTree(Tile* tile, WhichTree tree) const; + void SetTilePriorityRects(float content_to_screen_scale_, + const gfx::Rect& visible_rect_in_content_space, + const gfx::Rect& skewport, + const gfx::Rect& soon_border_rect, + const gfx::Rect& eventually_rect, + const Occlusion& occlusion_in_layer_space); + bool NeedsUpdateForFrameAtTimeAndViewport( double frame_time_in_seconds, const gfx::Rect& viewport_in_layer_space) { @@ -304,6 +272,43 @@ class CC_EXPORT PictureLayerTiling { if (visible_rect_history_[1].frame_time_in_seconds == 0.0) visible_rect_history_[1] = visible_rect_history_[0]; } + bool IsTileOccludedOnCurrentTree(const Tile* tile) const; + bool ShouldCreateTileAt(int i, int j) const; + bool IsTileOccluded(const Tile* tile) const; + void UpdateTileAndTwinPriority(Tile* tile) const; + TilePriority ComputePriorityForTile(const Tile* tile) const; + bool has_visible_rect_tiles() const { return has_visible_rect_tiles_; } + bool has_skewport_rect_tiles() const { return has_skewport_rect_tiles_; } + bool has_soon_border_rect_tiles() const { + return has_soon_border_rect_tiles_; + } + bool has_eventually_rect_tiles() const { return has_eventually_rect_tiles_; } + + const gfx::Rect& current_visible_rect() const { + return current_visible_rect_; + } + gfx::Rect pending_visible_rect() const { + const PictureLayerTiling* pending_tiling = + client_->GetTree() == ACTIVE_TREE + ? client_->GetPendingOrActiveTwinTiling(this) + : this; + if (pending_tiling) + return pending_tiling->current_visible_rect(); + return gfx::Rect(); + } + const gfx::Rect& current_skewport_rect() const { + return current_skewport_rect_; + } + const gfx::Rect& current_soon_border_rect() const { + return current_soon_border_rect_; + } + const gfx::Rect& current_eventually_rect() const { + return current_eventually_rect_; + } + bool has_ever_been_updated() const { + return visible_rect_history_[0].frame_time_in_seconds != 0.0; + } + void RemoveTilesInRegion(const Region& layer_region, bool recreate_tiles); const size_t max_tiles_for_interest_area_; const float skewport_target_time_in_seconds_; diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc index 93d85f7b..7c482bd 100644 --- a/cc/resources/picture_layer_tiling_set.cc +++ b/cc/resources/picture_layer_tiling_set.cc @@ -55,7 +55,8 @@ PictureLayerTilingSet::~PictureLayerTilingSet() { void PictureLayerTilingSet::CopyTilingsAndPropertiesFromPendingTwin( const PictureLayerTilingSet* pending_twin_set, - const scoped_refptr<RasterSource>& raster_source) { + const scoped_refptr<RasterSource>& raster_source, + const Region& layer_invalidation) { if (pending_twin_set->tilings_.empty()) { // If the twin (pending) tiling set is empty, it was not updated for the // current frame. So we drop tilings from our set as well, instead of @@ -77,7 +78,8 @@ void PictureLayerTilingSet::CopyTilingsAndPropertiesFromPendingTwin( this_tiling = tilings_.back(); tiling_sort_required = true; } - this_tiling->CloneTilesAndPropertiesFrom(*pending_twin_tiling); + this_tiling->TakeTilesAndPropertiesFrom(pending_twin_tiling, + layer_invalidation); } if (tiling_sort_required) @@ -95,7 +97,8 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForActivation( // Copy over tilings that are shared with the |pending_twin_set| tiling set. // Also, copy all of the properties from twin tilings. - CopyTilingsAndPropertiesFromPendingTwin(pending_twin_set, raster_source); + CopyTilingsAndPropertiesFromPendingTwin(pending_twin_set, raster_source, + layer_invalidation); // If the tiling is not shared (FindTilingWithScale returns nullptr), then // invalidate tiles and update them to the new raster source. @@ -146,6 +149,9 @@ void PictureLayerTilingSet::UpdateRasterSourceDueToLCDChange( for (PictureLayerTiling* tiling : tilings_) { tiling->SetRasterSourceAndResize(raster_source); tiling->Invalidate(layer_invalidation); + // Since the invalidation changed, we need to create any missing tiles in + // the live tiles rect again. + tiling->CreateMissingTilesInLiveTilesRect(); tiling->VerifyAllTilesHaveCurrentRasterSource(); } } diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h index cf95935..d04d8d4 100644 --- a/cc/resources/picture_layer_tiling_set.h +++ b/cc/resources/picture_layer_tiling_set.h @@ -179,7 +179,8 @@ class CC_EXPORT PictureLayerTilingSet { void CopyTilingsAndPropertiesFromPendingTwin( const PictureLayerTilingSet* pending_twin_set, - const scoped_refptr<RasterSource>& raster_source); + const scoped_refptr<RasterSource>& raster_source, + const Region& layer_invalidation); // Remove one tiling. void Remove(PictureLayerTiling* tiling); diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc index 5999ecd..ab0e68c 100644 --- a/cc/resources/picture_layer_tiling_unittest.cc +++ b/cc/resources/picture_layer_tiling_unittest.cc @@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/resources/picture_layer_tiling.h" - #include <limits> #include <set> #include "cc/base/math_util.h" +#include "cc/resources/picture_layer_tiling.h" #include "cc/resources/picture_layer_tiling_set.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" @@ -89,6 +88,17 @@ class PictureLayerTilingIteratorTest : public testing::Test { LayerTreeSettings()); } + void InitializeActive(const gfx::Size& tile_size, + float contents_scale, + const gfx::Size& layer_bounds) { + client_.SetTileSize(tile_size); + client_.set_tree(ACTIVE_TREE); + scoped_refptr<FakePicturePileImpl> pile = + FakePicturePileImpl::CreateFilledPileWithDefaultTileSize(layer_bounds); + tiling_ = TestablePictureLayerTiling::Create(contents_scale, pile, &client_, + LayerTreeSettings()); + } + void SetLiveRectAndVerifyTiles(const gfx::Rect& live_tiles_rect) { tiling_->SetLiveTilesRect(live_tiles_rect); @@ -189,7 +199,7 @@ TEST_F(PictureLayerTilingIteratorTest, ResizeDeletesTiles) { // 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); + InitializeActive(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. @@ -405,7 +415,7 @@ TEST_F(PictureLayerTilingIteratorTest, ResizeOverBorderPixelsDeletesTiles) { // 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); + InitializeActive(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. @@ -803,7 +813,7 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { 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); + TilePriority priority = tile->priority(); gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j); if (viewport_in_content_space.Intersects(tile_rect)) { @@ -835,13 +845,13 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { // 41,9 8x8 on all sides. EXPECT_EQ(tiling->TileAt(5, 1)->content_rect().ToString(), "40,8 10x10"); - TilePriority priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(5, 1)->priority(); EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); - priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE); + priority = tiling->TileAt(2, 5)->priority(); EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); - priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE); + priority = tiling->TileAt(3, 4)->priority(); EXPECT_FLOAT_EQ(40.f, priority.distance_to_visible); // Move the viewport down 40 pixels. @@ -873,7 +883,7 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { 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); + TilePriority priority = tile->priority(); gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j); if (viewport_in_content_space.Intersects(tile_rect)) { @@ -903,26 +913,26 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { EXPECT_TRUE(have_soon); EXPECT_TRUE(have_eventually); - priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(5, 1)->priority(); EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); - priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE); + priority = tiling->TileAt(2, 5)->priority(); EXPECT_FLOAT_EQ(28.f, priority.distance_to_visible); - priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE); + priority = tiling->TileAt(3, 4)->priority(); EXPECT_FLOAT_EQ(4.f, priority.distance_to_visible); // Change the underlying layer scale. tiling->ComputeTilePriorityRects(viewport, 2.0f, 3.0, Occlusion()); tiling->UpdateAllTilePrioritiesForTesting(); - priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(5, 1)->priority(); EXPECT_FLOAT_EQ(136.f, priority.distance_to_visible); - priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE); + priority = tiling->TileAt(2, 5)->priority(); EXPECT_FLOAT_EQ(56.f, priority.distance_to_visible); - priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE); + priority = tiling->TileAt(3, 4)->priority(); EXPECT_FLOAT_EQ(8.f, priority.distance_to_visible); // Test additional scales. @@ -931,25 +941,25 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { tiling->ComputeTilePriorityRects(viewport, 1.0f, 4.0, Occlusion()); tiling->UpdateAllTilePrioritiesForTesting(); - priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(5, 1)->priority(); EXPECT_FLOAT_EQ(110.f, priority.distance_to_visible); - priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE); + priority = tiling->TileAt(2, 5)->priority(); EXPECT_FLOAT_EQ(70.f, priority.distance_to_visible); - priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE); + priority = tiling->TileAt(3, 4)->priority(); EXPECT_FLOAT_EQ(60.f, priority.distance_to_visible); tiling->ComputeTilePriorityRects(viewport, 0.5f, 5.0, Occlusion()); tiling->UpdateAllTilePrioritiesForTesting(); - priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(5, 1)->priority(); EXPECT_FLOAT_EQ(55.f, priority.distance_to_visible); - priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE); + priority = tiling->TileAt(2, 5)->priority(); EXPECT_FLOAT_EQ(35.f, priority.distance_to_visible); - priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE); + priority = tiling->TileAt(3, 4)->priority(); EXPECT_FLOAT_EQ(30.f, priority.distance_to_visible); } @@ -1317,19 +1327,19 @@ TEST(ComputeTilePriorityRectsTest, VisibleTiles) { ASSERT_TRUE(tiling->TileAt(1, 0)); ASSERT_TRUE(tiling->TileAt(1, 1)); - TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(0, 0)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(0, 1)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 0)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 1)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin); } @@ -1373,30 +1383,30 @@ TEST(ComputeTilePriorityRectsTest, OffscreenTiles) { ASSERT_TRUE(tiling->TileAt(1, 0)); ASSERT_TRUE(tiling->TileAt(1, 1)); - TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(0, 0)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(0, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 0)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); // Furthermore, in this scenario tiles on the right hand side should have a // larger distance to visible. - TilePriority left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); - TilePriority right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + TilePriority left = tiling->TileAt(0, 0)->priority(); + TilePriority right = tiling->TileAt(1, 0)->priority(); EXPECT_GT(right.distance_to_visible, left.distance_to_visible); - left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); - right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + left = tiling->TileAt(0, 1)->priority(); + right = tiling->TileAt(1, 1)->priority(); EXPECT_GT(right.distance_to_visible, left.distance_to_visible); } @@ -1439,19 +1449,19 @@ TEST(ComputeTilePriorityRectsTest, PartiallyOffscreenLayer) { ASSERT_TRUE(tiling->TileAt(1, 0)); ASSERT_TRUE(tiling->TileAt(1, 1)); - TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(0, 0)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(0, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 0)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); } @@ -1499,27 +1509,27 @@ TEST(ComputeTilePriorityRectsTest, PartiallyOffscreenRotatedLayer) { ASSERT_TRUE(tiling->TileAt(1, 0)); ASSERT_TRUE(tiling->TileAt(1, 1)); - TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(0, 0)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(0, 1)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 0)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); // Furthermore, in this scenario the bottom-right tile should have the larger // distance to visible. - TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); - TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); - TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + TilePriority top_left = tiling->TileAt(0, 0)->priority(); + TilePriority top_right = tiling->TileAt(1, 0)->priority(); + TilePriority bottom_right = tiling->TileAt(1, 1)->priority(); EXPECT_GT(top_right.distance_to_visible, top_left.distance_to_visible); EXPECT_EQ(bottom_right.distance_to_visible, top_right.distance_to_visible); @@ -1585,29 +1595,29 @@ TEST(ComputeTilePriorityRectsTest, PerspectiveLayer) { // All tiles will have a positive distance_to_visible // and an infinite time_to_visible. - TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(0, 0)->priority(); EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(0, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 0)->priority(); EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); // Furthermore, in this scenario the top-left distance_to_visible // will be smallest, followed by top-right. The bottom layers // will of course be further than the top layers. - TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); - TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); - TilePriority bottom_left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); - TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + TilePriority top_left = tiling->TileAt(0, 0)->priority(); + TilePriority top_right = tiling->TileAt(1, 0)->priority(); + TilePriority bottom_left = tiling->TileAt(0, 1)->priority(); + TilePriority bottom_right = tiling->TileAt(1, 1)->priority(); EXPECT_GT(bottom_right.distance_to_visible, top_right.distance_to_visible); @@ -1679,21 +1689,21 @@ TEST(ComputeTilePriorityRectsTest, PerspectiveLayerClippedByW) { // Left-side tiles will be clipped by the transform, so we have to assume // they are visible just in case. - TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(0, 0)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(0, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); // Right-side tiles will have a positive distance_to_visible // and an infinite time_to_visible. - priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 0)->priority(); EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); } @@ -1748,21 +1758,21 @@ TEST(ComputeTilePriorityRectsTest, BasicMotion) { ASSERT_TRUE(tiling->TileAt(1, 0)); ASSERT_TRUE(tiling->TileAt(1, 1)); - TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(0, 0)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(0, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); // time_to_visible for the right hand side layers needs an extra 0.099 // seconds because this tile is 99 pixels further away. - priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 0)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 1)->priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); } @@ -1826,15 +1836,15 @@ TEST(ComputeTilePriorityRectsTest, RotationMotion) { ASSERT_TRUE(tiling->TileAt(1, 0)); ASSERT_TRUE(tiling->TileAt(1, 1)); - TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE); + TilePriority priority = tiling->TileAt(0, 0)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE); + priority = tiling->TileAt(0, 1)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE); + priority = tiling->TileAt(1, 0)->priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_EQ(TilePriority::NOW, priority.priority_bin); } @@ -1885,15 +1895,13 @@ TEST(PictureLayerTilingTest, RecycledTilesCleared) { 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)); + EXPECT_FALSE(recycle_tiling->TileAt(0, 0)); // Move the viewport far away from the (0, 0) tile. active_tiling->ComputeTilePriorityRects(gfx::Rect(9000, 9000, 100, 100), 1.0f, 2.0, Occlusion()); - // Ensure the tile was deleted on both tilings. + // Ensure the tile was deleted. EXPECT_FALSE(active_tiling->TileAt(0, 0)); EXPECT_FALSE(recycle_tiling->TileAt(0, 0)); @@ -1901,9 +1909,9 @@ TEST(PictureLayerTilingTest, RecycledTilesCleared) { active_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, 3.0, Occlusion()); - // Ensure that we now have a tile here on both tilings again. + // Ensure that we now have a tile here on both active. EXPECT_TRUE(active_tiling->TileAt(0, 0)); - EXPECT_TRUE(recycle_tiling->TileAt(0, 0)); + EXPECT_FALSE(recycle_tiling->TileAt(0, 0)); } TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) { @@ -1943,10 +1951,8 @@ TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) { 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)); + EXPECT_FALSE(recycle_tiling->TileAt(0, 0)); // Reset the active tiling. The recycle tiles should be released too. active_tiling->Reset(); diff --git a/cc/resources/raster_tile_priority_queue_all.cc b/cc/resources/raster_tile_priority_queue_all.cc index 9b1ce90..e9b3182 100644 --- a/cc/resources/raster_tile_priority_queue_all.cc +++ b/cc/resources/raster_tile_priority_queue_all.cc @@ -35,28 +35,10 @@ class RasterOrderComparator { const Tile* a_tile = a_queue->Top(); const Tile* b_tile = b_queue->Top(); - const TilePriority& a_priority = - a_tile->priority_for_tree_priority(tree_priority_); - const TilePriority& b_priority = - b_tile->priority_for_tree_priority(tree_priority_); + const TilePriority& a_priority = a_tile->priority(); + const TilePriority& b_priority = b_tile->priority(); bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; - // In smoothness mode, we should return pending NOW tiles before active - // EVENTUALLY tiles. So if both priorities here are eventually, we need to - // check the pending priority. - if (prioritize_low_res && - a_priority.priority_bin == TilePriority::EVENTUALLY && - b_priority.priority_bin == TilePriority::EVENTUALLY) { - bool a_is_pending_now = - a_tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW; - bool b_is_pending_now = - b_tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW; - if (a_is_pending_now || b_is_pending_now) - return a_is_pending_now < b_is_pending_now; - - // In case neither one is pending now, fall through. - } - // If the bin is the same but the resolution is not, then the order will be // determined by whether we prioritize low res or not. // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile @@ -84,27 +66,15 @@ class RasterOrderComparator { WhichTree HigherPriorityTree(TreePriority tree_priority, const TilingSetRasterQueueAll* active_queue, - const TilingSetRasterQueueAll* pending_queue, - const Tile* shared_tile) { - // In cases when we're given an active tile with a non ideal active resolution - // (or pending tile with non ideal pending resolution), we should return the - // other tree. The reason for this is that tiling set iterators will not - // return non ideal tiles and the only way we get here is if we're skipping - // twin tiles, but since it's non-ideal on the twin, we shouldn't skip it. - // TODO(vmpstr): Remove when tiles aren't shared. - const Tile* active_tile = shared_tile ? shared_tile : active_queue->Top(); - const Tile* pending_tile = shared_tile ? shared_tile : pending_queue->Top(); - if (active_tile->priority(ACTIVE_TREE).resolution == NON_IDEAL_RESOLUTION) - return PENDING_TREE; - if (pending_tile->priority(PENDING_TREE).resolution == NON_IDEAL_RESOLUTION) - return ACTIVE_TREE; + const TilingSetRasterQueueAll* pending_queue) { + const Tile* active_tile = active_queue->Top(); + const Tile* pending_tile = pending_queue->Top(); + + const TilePriority& active_priority = active_tile->priority(); + const TilePriority& pending_priority = pending_tile->priority(); switch (tree_priority) { case SMOOTHNESS_TAKES_PRIORITY: { - const TilePriority& active_priority = active_tile->priority(ACTIVE_TREE); - const TilePriority& pending_priority = - pending_tile->priority(PENDING_TREE); - // If we're down to eventually bin tiles on the active tree, process the // pending tree to allow tiles required for activation to be initialized // when memory policy only allows prepaint. @@ -114,13 +84,18 @@ WhichTree HigherPriorityTree(TreePriority tree_priority, } return ACTIVE_TREE; } - case NEW_CONTENT_TAKES_PRIORITY: + case NEW_CONTENT_TAKES_PRIORITY: { + // If we're down to soon bin tiles on the pending tree, process the + // active tree to allow tiles required for activation to be initialized + // when memory policy only allows prepaint. Note that active required for + // activation tiles might come from either now or soon bins. + if (pending_priority.priority_bin >= TilePriority::SOON && + active_priority.priority_bin <= TilePriority::SOON) { + return ACTIVE_TREE; + } return PENDING_TREE; + } case SAME_PRIORITY_FOR_BOTH_TREES: { - const TilePriority& active_priority = active_tile->priority(ACTIVE_TREE); - const TilePriority& pending_priority = - pending_tile->priority(PENDING_TREE); - if (active_priority.IsHigherPriorityThan(pending_priority)) return ACTIVE_TREE; return PENDING_TREE; @@ -190,10 +165,7 @@ RasterTilePriorityQueueAll::PairedTilingSetQueue::PairedTilingSetQueue( : active_queue_( CreateTilingSetRasterQueue(layer_pair.active, tree_priority)), pending_queue_( - CreateTilingSetRasterQueue(layer_pair.pending, tree_priority)), - has_both_layers_(layer_pair.active && layer_pair.pending) { - SkipTilesReturnedByTwin(tree_priority); - + CreateTilingSetRasterQueue(layer_pair.pending, tree_priority)) { TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "PairedTilingSetQueue::PairedTilingSetQueue", TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); @@ -235,40 +207,10 @@ void RasterTilePriorityQueueAll::PairedTilingSetQueue::Pop( DCHECK(returned_tiles_for_debug_.insert(next_queue->Top()).second); next_queue->Pop(); - SkipTilesReturnedByTwin(tree_priority); - // If no empty, use Top to do DCHECK the next iterator. DCHECK(IsEmpty() || Top(tree_priority)); } -void RasterTilePriorityQueueAll::PairedTilingSetQueue::SkipTilesReturnedByTwin( - TreePriority tree_priority) { - if (!has_both_layers_) - return; - - // We have both layers (active and pending) thus we can encounter shared - // tiles twice (from the active iterator and from the pending iterator). - while (!IsEmpty()) { - WhichTree next_tree = NextTileIteratorTree(tree_priority); - TilingSetRasterQueueAll* next_queue = - next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get(); - DCHECK(next_queue && !next_queue->IsEmpty()); - - // Accept all non-shared tiles. - const Tile* tile = next_queue->Top(); - if (!tile->is_shared()) - break; - - // Accept a shared tile if the next tree is the higher priority one - // corresponding the iterator (active or pending) which usually (but due - // to spiral iterators not always) returns the shared tile first. - if (next_tree == HigherPriorityTree(tree_priority, nullptr, nullptr, tile)) - break; - - next_queue->Pop(); - } -} - WhichTree RasterTilePriorityQueueAll::PairedTilingSetQueue::NextTileIteratorTree( TreePriority tree_priority) const { @@ -282,7 +224,7 @@ RasterTilePriorityQueueAll::PairedTilingSetQueue::NextTileIteratorTree( // Now both iterators have tiles, so we have to decide based on tree priority. return HigherPriorityTree(tree_priority, active_queue_.get(), - pending_queue_.get(), nullptr); + pending_queue_.get()); } scoped_refptr<base::trace_event::ConvertableToTraceFormat> @@ -294,10 +236,8 @@ RasterTilePriorityQueueAll::PairedTilingSetQueue::StateAsValue() const { TilePriority::PriorityBin active_priority_bin = TilePriority::EVENTUALLY; TilePriority::PriorityBin pending_priority_bin = TilePriority::EVENTUALLY; if (active_queue_has_tile) { - active_priority_bin = - active_queue_->Top()->priority(ACTIVE_TREE).priority_bin; - pending_priority_bin = - active_queue_->Top()->priority(PENDING_TREE).priority_bin; + active_priority_bin = active_queue_->Top()->priority().priority_bin; + pending_priority_bin = active_queue_->Top()->priority().priority_bin; } state->BeginDictionary("active_queue"); @@ -310,10 +250,8 @@ RasterTilePriorityQueueAll::PairedTilingSetQueue::StateAsValue() const { active_priority_bin = TilePriority::EVENTUALLY; pending_priority_bin = TilePriority::EVENTUALLY; if (pending_queue_has_tile) { - active_priority_bin = - pending_queue_->Top()->priority(ACTIVE_TREE).priority_bin; - pending_priority_bin = - pending_queue_->Top()->priority(PENDING_TREE).priority_bin; + active_priority_bin = pending_queue_->Top()->priority().priority_bin; + pending_priority_bin = pending_queue_->Top()->priority().priority_bin; } state->BeginDictionary("pending_queue"); diff --git a/cc/resources/raster_tile_priority_queue_all.h b/cc/resources/raster_tile_priority_queue_all.h index 4bd1085..192516f 100644 --- a/cc/resources/raster_tile_priority_queue_all.h +++ b/cc/resources/raster_tile_priority_queue_all.h @@ -31,7 +31,6 @@ class CC_EXPORT RasterTilePriorityQueueAll : public RasterTilePriorityQueue { void Pop(TreePriority tree_priority); WhichTree NextTileIteratorTree(TreePriority tree_priority) const; - void SkipTilesReturnedByTwin(TreePriority tree_priority); scoped_refptr<base::trace_event::ConvertableToTraceFormat> StateAsValue() const; @@ -46,7 +45,6 @@ class CC_EXPORT RasterTilePriorityQueueAll : public RasterTilePriorityQueue { private: scoped_ptr<TilingSetRasterQueueAll> active_queue_; scoped_ptr<TilingSetRasterQueueAll> pending_queue_; - bool has_both_layers_; // Set of returned tiles (excluding the current one) for DCHECKing. std::set<const Tile*> returned_tiles_for_debug_; diff --git a/cc/resources/raster_tile_priority_queue_required.cc b/cc/resources/raster_tile_priority_queue_required.cc index 3bf00ed..a6605fd 100644 --- a/cc/resources/raster_tile_priority_queue_required.cc +++ b/cc/resources/raster_tile_priority_queue_required.cc @@ -18,24 +18,48 @@ void RasterTilePriorityQueueRequired::Build( const std::vector<PictureLayerImpl::Pair>& paired_layers, Type type) { DCHECK_NE(static_cast<int>(type), static_cast<int>(Type::ALL)); - for (const auto& pair : paired_layers) { - PictureLayerTilingSet* tiling_set = nullptr; - if (type == Type::REQUIRED_FOR_DRAW && pair.active) - tiling_set = pair.active->picture_layer_tiling_set(); - else if (type == Type::REQUIRED_FOR_ACTIVATION && pair.pending) - tiling_set = pair.pending->picture_layer_tiling_set(); + if (type == Type::REQUIRED_FOR_DRAW) + BuildRequiredForDraw(paired_layers); + else + BuildRequiredForActivation(paired_layers); +} - if (!tiling_set) +void RasterTilePriorityQueueRequired::BuildRequiredForDraw( + const std::vector<PictureLayerImpl::Pair>& paired_layers) { + for (const auto& pair : paired_layers) { + if (!pair.active) continue; - scoped_ptr<TilingSetRasterQueueRequired> tiling_set_queue( - new TilingSetRasterQueueRequired(tiling_set, type)); + new TilingSetRasterQueueRequired( + pair.active->picture_layer_tiling_set(), Type::REQUIRED_FOR_DRAW)); if (tiling_set_queue->IsEmpty()) continue; tiling_set_queues_.push_back(tiling_set_queue.Pass()); } } +void RasterTilePriorityQueueRequired::BuildRequiredForActivation( + const std::vector<PictureLayerImpl::Pair>& paired_layers) { + for (const auto& pair : paired_layers) { + if (pair.active) { + scoped_ptr<TilingSetRasterQueueRequired> tiling_set_queue( + new TilingSetRasterQueueRequired( + pair.active->picture_layer_tiling_set(), + Type::REQUIRED_FOR_ACTIVATION)); + if (!tiling_set_queue->IsEmpty()) + tiling_set_queues_.push_back(tiling_set_queue.Pass()); + } + if (pair.pending) { + scoped_ptr<TilingSetRasterQueueRequired> tiling_set_queue( + new TilingSetRasterQueueRequired( + pair.pending->picture_layer_tiling_set(), + Type::REQUIRED_FOR_ACTIVATION)); + if (!tiling_set_queue->IsEmpty()) + tiling_set_queues_.push_back(tiling_set_queue.Pass()); + } + } +} + bool RasterTilePriorityQueueRequired::IsEmpty() const { return tiling_set_queues_.empty(); } diff --git a/cc/resources/raster_tile_priority_queue_required.h b/cc/resources/raster_tile_priority_queue_required.h index 02af2a6..56c04e4 100644 --- a/cc/resources/raster_tile_priority_queue_required.h +++ b/cc/resources/raster_tile_priority_queue_required.h @@ -28,6 +28,10 @@ class RasterTilePriorityQueueRequired : public RasterTilePriorityQueue { void Build(const std::vector<PictureLayerImpl::Pair>& paired_layers, Type type); + void BuildRequiredForDraw( + const std::vector<PictureLayerImpl::Pair>& paired_layers); + void BuildRequiredForActivation( + const std::vector<PictureLayerImpl::Pair>& paired_layers); ScopedPtrVector<TilingSetRasterQueueRequired> tiling_set_queues_; diff --git a/cc/resources/tile.cc b/cc/resources/tile.cc index 45b4a30..7467d93 100644 --- a/cc/resources/tile.cc +++ b/cc/resources/tile.cc @@ -32,14 +32,11 @@ Tile::Tile(TileManager* tile_manager, flags_(flags), tiling_i_index_(-1), tiling_j_index_(-1), - is_shared_(false), required_for_activation_(false), required_for_draw_(false), id_(s_next_id_++), scheduled_priority_(0) { set_raster_source(raster_source); - for (int i = 0; i <= LAST_TREE; i++) - is_occluded_[i] = false; } Tile::~Tile() { @@ -62,11 +59,11 @@ void Tile::AsValueWithPriorityInto(const TilePriority& priority, // TODO(vmpstr): Remove active and pending priority once tracing is using // combined priority or at least can support both. res->BeginDictionary("active_priority"); - priority_[ACTIVE_TREE].AsValueInto(res); + priority_.AsValueInto(res); res->EndDictionary(); res->BeginDictionary("pending_priority"); - priority_[PENDING_TREE].AsValueInto(res); + priority_.AsValueInto(res); res->EndDictionary(); res->BeginDictionary("combined_priority"); @@ -79,8 +76,7 @@ void Tile::AsValueWithPriorityInto(const TilePriority& priority, res->SetBoolean("has_resource", HasResource()); res->SetBoolean("is_using_gpu_memory", HasResource() || HasRasterTask()); - res->SetString("resolution", - TileResolutionToString(combined_priority().resolution)); + res->SetString("resolution", TileResolutionToString(priority_.resolution)); res->SetInteger("scheduled_priority", scheduled_priority_); diff --git a/cc/resources/tile.h b/cc/resources/tile.h index dcc8566..45c2b04 100644 --- a/cc/resources/tile.h +++ b/cc/resources/tile.h @@ -31,46 +31,13 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { const RasterSource* raster_source() const { return raster_source_.get(); } - const TilePriority& priority(WhichTree tree) const { - return priority_[tree]; - } - - TilePriority priority_for_tree_priority(TreePriority tree_priority) const { - switch (tree_priority) { - case SMOOTHNESS_TAKES_PRIORITY: - return priority_[ACTIVE_TREE]; - case NEW_CONTENT_TAKES_PRIORITY: - return priority_[PENDING_TREE]; - case SAME_PRIORITY_FOR_BOTH_TREES: - return combined_priority(); - default: - NOTREACHED(); - return TilePriority(); - } - } + const TilePriority& priority() const { return priority_; } - TilePriority combined_priority() const { - return TilePriority(priority_[ACTIVE_TREE], - priority_[PENDING_TREE]); - } - - void SetPriority(WhichTree tree, const TilePriority& priority) { - priority_[tree] = priority; - } + void set_priority(const TilePriority& priority) { priority_ = priority; } // TODO(vmpstr): Move this to the iterators. - void set_is_occluded(WhichTree tree, bool is_occluded) { - is_occluded_[tree] = is_occluded; - } - - bool is_occluded(WhichTree tree) const { return is_occluded_[tree]; } - - void set_shared(bool is_shared) { is_shared_ = is_shared; } - bool is_shared() const { return is_shared_; } - - bool is_occluded_combined() const { - return is_occluded_[ACTIVE_TREE] && is_occluded_[PENDING_TREE]; - } + void set_is_occluded(bool is_occluded) { is_occluded_ = is_occluded; } + bool is_occluded() const { return is_occluded_; } // TODO(vmpstr): Move this to the iterators. bool required_for_activation() const { return required_for_activation_; } @@ -108,7 +75,7 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { int source_frame_number() const { return source_frame_number_; } - void set_raster_source(scoped_refptr<RasterSource> raster_source) { + void set_raster_source(RasterSource* raster_source) { DCHECK(raster_source->CoversRect(content_rect_, contents_scale_)) << "Recording rect: " << gfx::ScaleToEnclosingRect(content_rect_, 1.f / contents_scale_) @@ -151,9 +118,9 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { gfx::Size desired_texture_size_; gfx::Rect content_rect_; float contents_scale_; - bool is_occluded_[LAST_TREE + 1]; + bool is_occluded_; - TilePriority priority_[LAST_TREE + 1]; + TilePriority priority_; TileDrawInfo draw_info_; int layer_id_; @@ -161,7 +128,6 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { int flags_; int tiling_i_index_; int tiling_j_index_; - bool is_shared_ : 1; bool required_for_activation_ : 1; bool required_for_draw_ : 1; diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index b98b7a6..8bf6120 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -451,7 +451,7 @@ TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( break; Tile* tile = eviction_priority_queue->Top(); - if (!other_priority.IsHigherPriorityThan(tile->combined_priority())) + if (!other_priority.IsHigherPriorityThan(tile->priority())) break; *usage -= MemoryUsage::FromTile(tile); @@ -506,7 +506,7 @@ void TileManager::AssignGpuMemoryToTiles( scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue; for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { Tile* tile = raster_priority_queue->Top(); - TilePriority priority = tile->combined_priority(); + TilePriority priority = tile->priority(); if (TilePriorityViolatesMemoryPolicy(priority)) { TRACE_EVENT_INSTANT0( @@ -698,9 +698,9 @@ scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) { return make_scoped_refptr(new RasterTaskImpl( const_resource, tile->raster_source(), tile->content_rect(), - tile->contents_scale(), tile->combined_priority().resolution, - tile->layer_id(), static_cast<const void*>(tile), - tile->source_frame_number(), tile->use_picture_analysis(), + tile->contents_scale(), tile->priority().resolution, tile->layer_id(), + static_cast<const void*>(tile), tile->source_frame_number(), + tile->use_picture_analysis(), base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), tile->id(), base::Passed(&resource)), &decode_tasks)); @@ -805,6 +805,15 @@ bool TileManager::AreRequiredTilesReadyToDraw( if (!raster_priority_queue->Top()->IsReadyToDraw()) return false; } + +#if DCHECK_IS_ON() + scoped_ptr<RasterTilePriorityQueue> all_queue( + client_->BuildRasterQueue(global_state_.tree_priority, type)); + for (; !all_queue->IsEmpty(); all_queue->Pop()) { + auto* tile = all_queue->Top(); + DCHECK_IMPLIES(tile->required_for_activation(), tile->IsReadyToDraw()); + } +#endif return true; } bool TileManager::IsReadyToActivate() const { diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc index 310cdc6..2ac504a 100644 --- a/cc/resources/tile_manager_unittest.cc +++ b/cc/resources/tile_manager_unittest.cc @@ -183,9 +183,8 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { while (!queue->IsEmpty()) { Tile* tile = queue->Top(); EXPECT_TRUE(tile); - EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin); - EXPECT_EQ(TilePriority::NOW, tile->priority(PENDING_TREE).priority_bin); - if (tile->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) + EXPECT_EQ(TilePriority::NOW, tile->priority().priority_bin); + if (tile->priority().resolution == LOW_RESOLUTION) had_low_res = true; else smoothness_tiles.insert(tile); @@ -284,28 +283,23 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { if (!last_tile) last_tile = tile; - EXPECT_LE(last_tile->priority(ACTIVE_TREE).priority_bin, - tile->priority(ACTIVE_TREE).priority_bin); + EXPECT_LE(last_tile->priority().priority_bin, + tile->priority().priority_bin); bool skip_updating_last_tile = false; - if (last_tile->priority(ACTIVE_TREE).priority_bin == - tile->priority(ACTIVE_TREE).priority_bin) { - correct_order_tiles += - last_tile->priority(ACTIVE_TREE).distance_to_visible <= - tile->priority(ACTIVE_TREE).distance_to_visible; - } else if (tile->priority(ACTIVE_TREE).priority_bin == - TilePriority::EVENTUALLY && - tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW) { + if (last_tile->priority().priority_bin == tile->priority().priority_bin) { + correct_order_tiles += last_tile->priority().distance_to_visible <= + tile->priority().distance_to_visible; + } else if (tile->priority().priority_bin == TilePriority::NOW) { // Since we'd return pending tree now tiles before the eventually tiles on // the active tree, update the value. ++correct_order_tiles; skip_updating_last_tile = true; } - if (tile->priority(ACTIVE_TREE).priority_bin == TilePriority::NOW && - last_tile->priority(ACTIVE_TREE).resolution != - tile->priority(ACTIVE_TREE).resolution) { + if (tile->priority().priority_bin == TilePriority::NOW && + last_tile->priority().resolution != tile->priority().resolution) { // Low resolution should come first. - EXPECT_EQ(LOW_RESOLUTION, last_tile->priority(ACTIVE_TREE).resolution); + EXPECT_EQ(LOW_RESOLUTION, last_tile->priority().resolution); } if (!skip_updating_last_tile) @@ -368,20 +362,17 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { if (!last_tile) last_tile = tile; - EXPECT_LE(last_tile->priority(PENDING_TREE).priority_bin, - tile->priority(PENDING_TREE).priority_bin); - if (last_tile->priority(PENDING_TREE).priority_bin == - tile->priority(PENDING_TREE).priority_bin) { - increasing_distance_tiles += - last_tile->priority(PENDING_TREE).distance_to_visible <= - tile->priority(PENDING_TREE).distance_to_visible; + EXPECT_LE(last_tile->priority().priority_bin, + tile->priority().priority_bin); + if (last_tile->priority().priority_bin == tile->priority().priority_bin) { + increasing_distance_tiles += last_tile->priority().distance_to_visible <= + tile->priority().distance_to_visible; } - if (tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW && - last_tile->priority(PENDING_TREE).resolution != - tile->priority(PENDING_TREE).resolution) { + if (tile->priority().priority_bin == TilePriority::NOW && + last_tile->priority().resolution != tile->priority().resolution) { // High resolution should come first. - EXPECT_EQ(HIGH_RESOLUTION, last_tile->priority(PENDING_TREE).resolution); + EXPECT_EQ(HIGH_RESOLUTION, last_tile->priority().resolution); } last_tile = tile; @@ -435,6 +426,8 @@ TEST_F(TileManagerTilePriorityQueueTest, pending_layer_->tilings()->AddTiling(1.5f, pending_layer_->raster_source()); active_layer_->tilings()->AddTiling(1.5f, active_layer_->raster_source()); + pending_layer_->tilings()->AddTiling(1.7f, pending_layer_->raster_source()); + active_layer_->tilings()->AddTiling(1.7f, active_layer_->raster_source()); pending_layer_->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0, Occlusion(), true); @@ -444,7 +437,6 @@ TEST_F(TileManagerTilePriorityQueueTest, std::set<Tile*> all_expected_tiles; for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); - tiling->CreateAllTilesForTesting(); if (tiling->contents_scale() == 1.f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); @@ -456,13 +448,21 @@ TEST_F(TileManagerTilePriorityQueueTest, for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); - tiling->CreateAllTilesForTesting(); if (tiling->contents_scale() == 1.5f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); all_expected_tiles.insert(all_tiles.begin(), all_tiles.end()); } else { tiling->set_resolution(NON_IDEAL_RESOLUTION); + // Non ideal tilings with a high res pending twin have to be processed + // because of possible activation tiles. + if (tiling->contents_scale() == 1.f) { + tiling->UpdateAllTilePrioritiesForTesting(); + const auto& all_tiles = tiling->AllTilesForTesting(); + for (auto* tile : all_tiles) + EXPECT_TRUE(tile->required_for_activation()); + all_expected_tiles.insert(all_tiles.begin(), all_tiles.end()); + } } } @@ -492,19 +492,19 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { // Use a tile's content rect as an invalidation. We should inset it a bit to // ensure that border math doesn't invalidate neighbouring tiles. gfx::Rect invalidation = - pending_layer_->HighResTiling()->TileAt(1, 0)->content_rect(); + active_layer_->HighResTiling()->TileAt(1, 0)->content_rect(); invalidation.Inset(2, 2); pending_layer_->set_invalidation(invalidation); pending_layer_->HighResTiling()->Invalidate(invalidation); + pending_layer_->HighResTiling()->CreateMissingTilesInLiveTilesRect(); pending_layer_->LowResTiling()->Invalidate(invalidation); + pending_layer_->LowResTiling()->CreateMissingTilesInLiveTilesRect(); - // Sanity checks: Tile at 0, 0 should be the same on both trees, tile at 1, 0 - // should be different. - EXPECT_TRUE(pending_layer_->HighResTiling()->TileAt(0, 0)); + // Sanity checks: Tile at 0, 0 not exist on the pending tree (it's not + // invalidated). Tile 1, 0 should exist on both. + EXPECT_FALSE(pending_layer_->HighResTiling()->TileAt(0, 0)); EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(0, 0)); - EXPECT_EQ(pending_layer_->HighResTiling()->TileAt(0, 0), - active_layer_->HighResTiling()->TileAt(0, 0)); EXPECT_TRUE(pending_layer_->HighResTiling()->TileAt(1, 0)); EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(1, 0)); EXPECT_NE(pending_layer_->HighResTiling()->TileAt(1, 0), @@ -515,13 +515,20 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { std::set<Tile*> expected_required_for_activation_tiles; for (int i = 0; i <= 1; ++i) { for (int j = 0; j <= 1; ++j) { - expected_now_tiles.insert(pending_layer_->HighResTiling()->TileAt(i, j)); - expected_now_tiles.insert(active_layer_->HighResTiling()->TileAt(i, j)); - - expected_required_for_activation_tiles.insert( - pending_layer_->HighResTiling()->TileAt(i, j)); - expected_required_for_draw_tiles.insert( - active_layer_->HighResTiling()->TileAt(i, j)); + bool have_pending_tile = false; + if (pending_layer_->HighResTiling()->TileAt(i, j)) { + expected_now_tiles.insert( + pending_layer_->HighResTiling()->TileAt(i, j)); + expected_required_for_activation_tiles.insert( + pending_layer_->HighResTiling()->TileAt(i, j)); + have_pending_tile = true; + } + Tile* active_tile = active_layer_->HighResTiling()->TileAt(i, j); + EXPECT_TRUE(active_tile); + expected_now_tiles.insert(active_tile); + expected_required_for_draw_tiles.insert(active_tile); + if (!have_pending_tile) + expected_required_for_activation_tiles.insert(active_tile); } } // Expect 3 shared tiles and 1 unshared tile in total. @@ -535,7 +542,10 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { std::set<Tile*> expected_all_tiles; for (int i = 0; i <= 3; ++i) { for (int j = 0; j <= 3; ++j) { - expected_all_tiles.insert(pending_layer_->HighResTiling()->TileAt(i, j)); + if (pending_layer_->HighResTiling()->TileAt(i, j)) + expected_all_tiles.insert( + pending_layer_->HighResTiling()->TileAt(i, j)); + EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(i, j)); expected_all_tiles.insert(active_layer_->HighResTiling()->TileAt(i, j)); } } @@ -551,7 +561,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { while (!queue->IsEmpty()) { Tile* tile = queue->Top(); queue->Pop(); - if (tile->combined_priority().priority_bin == TilePriority::NOW) + if (tile->priority().priority_bin == TilePriority::NOW) actual_now_tiles.insert(tile); actual_all_tiles.insert(tile); } @@ -620,7 +630,7 @@ TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) { std::vector<Tile*> all_tiles; while (!queue->IsEmpty()) { Tile* tile = queue->Top(); - if (tile->combined_priority().priority_bin >= TilePriority::EVENTUALLY) + if (tile->priority().priority_bin >= TilePriority::EVENTUALLY) break; all_tiles.push_back(tile); @@ -669,8 +679,7 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { while (!queue->IsEmpty()) { Tile* tile = queue->Top(); EXPECT_TRUE(tile); - EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin); - EXPECT_EQ(TilePriority::NOW, tile->priority(PENDING_TREE).priority_bin); + EXPECT_EQ(TilePriority::NOW, tile->priority().priority_bin); EXPECT_TRUE(tile->HasResource()); smoothness_tiles.insert(tile); queue->Pop(); @@ -685,7 +694,9 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { // Invalidate the pending tree. pending_layer_->set_invalidation(invalidation); pending_layer_->HighResTiling()->Invalidate(invalidation); + pending_layer_->HighResTiling()->CreateMissingTilesInLiveTilesRect(); pending_layer_->LowResTiling()->Invalidate(invalidation); + pending_layer_->LowResTiling()->CreateMissingTilesInLiveTilesRect(); active_layer_->ResetAllTilesPriorities(); pending_layer_->ResetAllTilesPriorities(); @@ -741,8 +752,8 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { if (!last_tile) last_tile = tile; - const TilePriority& last_priority = last_tile->combined_priority(); - const TilePriority& priority = tile->combined_priority(); + const TilePriority& last_priority = last_tile->priority(); + const TilePriority& priority = tile->priority(); EXPECT_GE(last_priority.priority_bin, priority.priority_bin); if (last_priority.priority_bin == priority.priority_bin) { @@ -782,8 +793,8 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { if (!last_tile) last_tile = tile; - const TilePriority& last_priority = last_tile->combined_priority(); - const TilePriority& priority = tile->combined_priority(); + const TilePriority& last_priority = last_tile->priority(); + const TilePriority& priority = tile->priority(); EXPECT_GE(last_priority.priority_bin, priority.priority_bin); if (last_priority.priority_bin == priority.priority_bin) { @@ -922,7 +933,7 @@ TEST_F(TileManagerTilePriorityQueueTest, if (!last_tile) last_tile = tile; - bool tile_is_occluded = tile->is_occluded_combined(); + bool tile_is_occluded = tile->is_occluded(); // The only way we will encounter an occluded tile after an unoccluded // tile is if the priorty bin decreased, the tile is required for @@ -930,12 +941,12 @@ TEST_F(TileManagerTilePriorityQueueTest, if (tile_is_occluded) { occluded_count++; - bool last_tile_is_occluded = last_tile->is_occluded_combined(); + bool last_tile_is_occluded = last_tile->is_occluded(); if (!last_tile_is_occluded) { TilePriority::PriorityBin tile_priority_bin = - tile->priority_for_tree_priority(tree_priority).priority_bin; + tile->priority().priority_bin; TilePriority::PriorityBin last_tile_priority_bin = - last_tile->priority_for_tree_priority(tree_priority).priority_bin; + last_tile->priority().priority_bin; EXPECT_TRUE((tile_priority_bin < last_tile_priority_bin) || tile->required_for_activation() || @@ -1045,7 +1056,7 @@ TEST_F(TileManagerTilePriorityQueueTest, host_impl_.BuildEvictionQueue(tree_priority)); while (!queue->IsEmpty()) { Tile* tile = queue->Top(); - const TilePriority& pending_priority = tile->priority(PENDING_TREE); + const TilePriority& pending_priority = tile->priority(); EXPECT_NE(std::numeric_limits<float>::infinity(), pending_priority.distance_to_visible); if (all_pending_child_tiles.find(tile) != all_pending_child_tiles.end()) @@ -1208,7 +1219,7 @@ TEST_F(TileManagerTilePriorityQueueTest, std::set<Tile*> unique_tiles; unique_tiles.insert(queue->Top()); Tile* last_tile = queue->Top(); - have_tiles[last_tile->priority(ACTIVE_TREE).priority_bin] = true; + have_tiles[last_tile->priority().priority_bin] = true; // On the second iteration, mark everything as ready to draw (solid color). if (i == 1) { @@ -1223,8 +1234,8 @@ TEST_F(TileManagerTilePriorityQueueTest, queue->Pop(); unique_tiles.insert(new_tile); - TilePriority last_priority = last_tile->priority(ACTIVE_TREE); - TilePriority new_priority = new_tile->priority(ACTIVE_TREE); + TilePriority last_priority = last_tile->priority(); + TilePriority new_priority = new_tile->priority(); EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin); if (last_priority.priority_bin == new_priority.priority_bin) { if (last_priority.priority_bin == TilePriority::EVENTUALLY) { @@ -1311,8 +1322,8 @@ TEST_F(TileManagerTilePriorityQueueTest, Tile* new_tile = queue->Top(); - TilePriority last_priority = last_tile->priority(ACTIVE_TREE); - TilePriority new_priority = new_tile->priority(ACTIVE_TREE); + TilePriority last_priority = last_tile->priority(); + TilePriority new_priority = new_tile->priority(); have_tiles[new_priority.priority_bin] = true; diff --git a/cc/resources/tiling_set_eviction_queue.cc b/cc/resources/tiling_set_eviction_queue.cc index 43d085b..bbe689d 100644 --- a/cc/resources/tiling_set_eviction_queue.cc +++ b/cc/resources/tiling_set_eviction_queue.cc @@ -7,33 +7,6 @@ #include "cc/resources/tiling_set_eviction_queue.h" namespace cc { -namespace { - -bool IsSharedOutOfOrderTile(WhichTree tree, const Tile* tile) { - if (!tile->is_shared()) - return false; - - // The priority for tile priority of a shared tile will be a combined - // priority thus return shared tiles from a higher priority tree as - // it is out of order for a lower priority tree. - WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; - const TilePriority& priority = tile->priority(tree); - const TilePriority& twin_priority = tile->priority(twin_tree); - if (priority.priority_bin != twin_priority.priority_bin) - return priority.priority_bin > twin_priority.priority_bin; - const bool occluded = tile->is_occluded(tree); - const bool twin_occluded = tile->is_occluded(twin_tree); - if (occluded != twin_occluded) - return occluded; - if (priority.distance_to_visible != twin_priority.distance_to_visible) - return priority.distance_to_visible > twin_priority.distance_to_visible; - - // If priorities are the same, it does not matter which tree returns - // the tile. Let's pick the pending tree. - return tree != PENDING_TREE; -} - -} // namespace TilingSetEvictionQueue::TilingSetEvictionQueue( PictureLayerTilingSet* tiling_set, @@ -63,28 +36,43 @@ void TilingSetEvictionQueue::GenerateTilingOrder( tilings_.reserve(tiling_set->num_tilings()); // Generate all of the tilings in the order described in the header comment // for this class. - auto range = + PictureLayerTilingSet::TilingRange range = tiling_set->GetTilingRange(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES); - for (int i = range.start; i < range.end; ++i) - tilings_.push_back(tiling_set->tiling_at(i)); + for (int i = range.start; i < range.end; ++i) { + PictureLayerTiling* tiling = tiling_set->tiling_at(i); + if (tiling->has_tiles()) + tilings_.push_back(tiling); + } range = tiling_set->GetTilingRange(PictureLayerTilingSet::LOWER_THAN_LOW_RES); - for (int i = range.end - 1; i >= range.start; --i) - tilings_.push_back(tiling_set->tiling_at(i)); + for (int i = range.end - 1; i >= range.start; --i) { + PictureLayerTiling* tiling = tiling_set->tiling_at(i); + if (tiling->has_tiles()) + tilings_.push_back(tiling); + } range = tiling_set->GetTilingRange( PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES); - for (int i = range.end - 1; i >= range.start; --i) - tilings_.push_back(tiling_set->tiling_at(i)); + for (int i = range.end - 1; i >= range.start; --i) { + PictureLayerTiling* tiling = tiling_set->tiling_at(i); + if (tiling->has_tiles()) + tilings_.push_back(tiling); + } range = tiling_set->GetTilingRange(PictureLayerTilingSet::LOW_RES); - for (int i = range.start; i < range.end; ++i) - tilings_.push_back(tiling_set->tiling_at(i)); + for (int i = range.start; i < range.end; ++i) { + PictureLayerTiling* tiling = tiling_set->tiling_at(i); + if (tiling->has_tiles()) + tilings_.push_back(tiling); + } range = tiling_set->GetTilingRange(PictureLayerTilingSet::HIGH_RES); - for (int i = range.start; i < range.end; ++i) - tilings_.push_back(tiling_set->tiling_at(i)); - DCHECK_EQ(tiling_set->num_tilings(), tilings_.size()); + for (int i = range.start; i < range.end; ++i) { + PictureLayerTiling* tiling = tiling_set->tiling_at(i); + if (tiling->has_tiles()) + tilings_.push_back(tiling); + } + DCHECK_GE(tiling_set->num_tilings(), tilings_.size()); } void TilingSetEvictionQueue::AdvancePhase() { @@ -108,6 +96,20 @@ void TilingSetEvictionQueue::AdvancePhase() { if (!skewport_iterator_.done()) current_tile_ = *skewport_iterator_; break; + case PENDING_VISIBLE_RECT: + pending_visible_iterator_ = PendingVisibleTilingIterator( + &tilings_, tree_, skip_shared_out_of_order_tiles_, + false /* return required for activation tiles */); + if (!pending_visible_iterator_.done()) + current_tile_ = *pending_visible_iterator_; + break; + case PENDING_VISIBLE_RECT_REQUIRED_FOR_ACTIVATION: + pending_visible_iterator_ = PendingVisibleTilingIterator( + &tilings_, tree_, skip_shared_out_of_order_tiles_, + true /* return required for activation tiles */); + if (!pending_visible_iterator_.done()) + current_tile_ = *pending_visible_iterator_; + break; case VISIBLE_RECT_OCCLUDED: visible_iterator_ = VisibleTilingIterator( &tilings_, tree_, skip_shared_out_of_order_tiles_, @@ -177,6 +179,12 @@ void TilingSetEvictionQueue::Pop() { if (!skewport_iterator_.done()) current_tile_ = *skewport_iterator_; break; + case PENDING_VISIBLE_RECT: + case PENDING_VISIBLE_RECT_REQUIRED_FOR_ACTIVATION: + ++pending_visible_iterator_; + if (!pending_visible_iterator_.done()) + current_tile_ = *pending_visible_iterator_; + break; case VISIBLE_RECT_OCCLUDED: case VISIBLE_RECT_UNOCCLUDED: case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_OCCLUDED: @@ -202,11 +210,13 @@ TilingSetEvictionQueue::EvictionRectIterator::EvictionRectIterator() TilingSetEvictionQueue::EvictionRectIterator::EvictionRectIterator( std::vector<PictureLayerTiling*>* tilings, WhichTree tree, - bool skip_shared_out_of_order_tiles) + bool skip_shared_out_of_order_tiles, + bool skip_pending_visible_rect) : tile_(nullptr), tilings_(tilings), tree_(tree), skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles), + skip_pending_visible_rect_(skip_pending_visible_rect), tiling_index_(0) { } @@ -228,15 +238,16 @@ bool TilingSetEvictionQueue::EvictionRectIterator::AdvanceToNextTile( template <typename TilingIteratorType> bool TilingSetEvictionQueue::EvictionRectIterator::GetFirstTileAndCheckIfValid( TilingIteratorType* iterator) { - tile_ = (*tilings_)[tiling_index_]->TileAt(iterator->index_x(), - iterator->index_y()); + PictureLayerTiling* tiling = (*tilings_)[tiling_index_]; + tile_ = tiling->TileAt(iterator->index_x(), iterator->index_y()); // If there's nothing to evict, return false. if (!tile_ || !tile_->HasResource()) return false; - (*tilings_)[tiling_index_]->UpdateTileAndTwinPriority(tile_); - // If the tile is out of order, return false. - if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tree_, tile_)) + if (skip_pending_visible_rect_ && + tiling->pending_visible_rect().Intersects(tile_->content_rect())) { return false; + } + (*tilings_)[tiling_index_]->UpdateTileAndTwinPriority(tile_); // In other cases, the tile we got is a viable candidate, return true. return true; } @@ -246,18 +257,21 @@ TilingSetEvictionQueue::EventuallyTilingIterator::EventuallyTilingIterator( std::vector<PictureLayerTiling*>* tilings, WhichTree tree, bool skip_shared_out_of_order_tiles) - : EvictionRectIterator(tilings, tree, skip_shared_out_of_order_tiles) { + : EvictionRectIterator(tilings, + tree, + skip_shared_out_of_order_tiles, + true /* skip_pending_visible_rect */) { // Find the first tiling with a tile. while (tiling_index_ < tilings_->size()) { - if (!((*tilings_))[tiling_index_]->has_eventually_rect_tiles()) { + if (!(*tilings_)[tiling_index_]->has_eventually_rect_tiles()) { ++tiling_index_; continue; } iterator_ = TilingData::ReverseSpiralDifferenceIterator( - ((*tilings_))[tiling_index_]->tiling_data(), - ((*tilings_))[tiling_index_]->current_eventually_rect(), - ((*tilings_))[tiling_index_]->current_skewport_rect(), - ((*tilings_))[tiling_index_]->current_soon_border_rect()); + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->current_eventually_rect(), + (*tilings_)[tiling_index_]->current_skewport_rect(), + (*tilings_)[tiling_index_]->current_soon_border_rect()); if (!iterator_) { ++tiling_index_; continue; @@ -276,13 +290,13 @@ TilingSetEvictionQueue::EventuallyTilingIterator& bool found_tile = AdvanceToNextTile(&iterator_); while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { ++tiling_index_; - if (!((*tilings_))[tiling_index_]->has_eventually_rect_tiles()) + if (!(*tilings_)[tiling_index_]->has_eventually_rect_tiles()) continue; iterator_ = TilingData::ReverseSpiralDifferenceIterator( - ((*tilings_))[tiling_index_]->tiling_data(), - ((*tilings_))[tiling_index_]->current_eventually_rect(), - ((*tilings_))[tiling_index_]->current_skewport_rect(), - ((*tilings_))[tiling_index_]->current_soon_border_rect()); + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->current_eventually_rect(), + (*tilings_)[tiling_index_]->current_skewport_rect(), + (*tilings_)[tiling_index_]->current_soon_border_rect()); if (!iterator_) continue; found_tile = GetFirstTileAndCheckIfValid(&iterator_); @@ -297,18 +311,21 @@ TilingSetEvictionQueue::SoonBorderTilingIterator::SoonBorderTilingIterator( std::vector<PictureLayerTiling*>* tilings, WhichTree tree, bool skip_shared_out_of_order_tiles) - : EvictionRectIterator(tilings, tree, skip_shared_out_of_order_tiles) { + : EvictionRectIterator(tilings, + tree, + skip_shared_out_of_order_tiles, + true /* skip_pending_visible_rect */) { // Find the first tiling with a tile. while (tiling_index_ < tilings_->size()) { - if (!((*tilings_))[tiling_index_]->has_soon_border_rect_tiles()) { + if (!(*tilings_)[tiling_index_]->has_soon_border_rect_tiles()) { ++tiling_index_; continue; } iterator_ = TilingData::ReverseSpiralDifferenceIterator( - ((*tilings_))[tiling_index_]->tiling_data(), - ((*tilings_))[tiling_index_]->current_soon_border_rect(), - ((*tilings_))[tiling_index_]->current_skewport_rect(), - ((*tilings_))[tiling_index_]->current_visible_rect()); + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->current_soon_border_rect(), + (*tilings_)[tiling_index_]->current_skewport_rect(), + (*tilings_)[tiling_index_]->current_visible_rect()); if (!iterator_) { ++tiling_index_; continue; @@ -327,13 +344,13 @@ TilingSetEvictionQueue::SoonBorderTilingIterator& bool found_tile = AdvanceToNextTile(&iterator_); while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { ++tiling_index_; - if (!((*tilings_))[tiling_index_]->has_soon_border_rect_tiles()) + if (!(*tilings_)[tiling_index_]->has_soon_border_rect_tiles()) continue; iterator_ = TilingData::ReverseSpiralDifferenceIterator( - ((*tilings_))[tiling_index_]->tiling_data(), - ((*tilings_))[tiling_index_]->current_soon_border_rect(), - ((*tilings_))[tiling_index_]->current_skewport_rect(), - ((*tilings_))[tiling_index_]->current_visible_rect()); + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->current_soon_border_rect(), + (*tilings_)[tiling_index_]->current_skewport_rect(), + (*tilings_)[tiling_index_]->current_visible_rect()); if (!iterator_) continue; found_tile = GetFirstTileAndCheckIfValid(&iterator_); @@ -348,18 +365,21 @@ TilingSetEvictionQueue::SkewportTilingIterator::SkewportTilingIterator( std::vector<PictureLayerTiling*>* tilings, WhichTree tree, bool skip_shared_out_of_order_tiles) - : EvictionRectIterator(tilings, tree, skip_shared_out_of_order_tiles) { + : EvictionRectIterator(tilings, + tree, + skip_shared_out_of_order_tiles, + true /* skip_pending_visible_rect */) { // Find the first tiling with a tile. while (tiling_index_ < tilings_->size()) { - if (!((*tilings_))[tiling_index_]->has_skewport_rect_tiles()) { + if (!(*tilings_)[tiling_index_]->has_skewport_rect_tiles()) { ++tiling_index_; continue; } iterator_ = TilingData::ReverseSpiralDifferenceIterator( - ((*tilings_))[tiling_index_]->tiling_data(), - ((*tilings_))[tiling_index_]->current_skewport_rect(), - ((*tilings_))[tiling_index_]->current_visible_rect(), - ((*tilings_))[tiling_index_]->current_visible_rect()); + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->current_skewport_rect(), + (*tilings_)[tiling_index_]->current_visible_rect(), + (*tilings_)[tiling_index_]->current_visible_rect()); if (!iterator_) { ++tiling_index_; continue; @@ -378,22 +398,89 @@ TilingSetEvictionQueue::SkewportTilingIterator& bool found_tile = AdvanceToNextTile(&iterator_); while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { ++tiling_index_; - if (!((*tilings_))[tiling_index_]->has_skewport_rect_tiles()) + if (!(*tilings_)[tiling_index_]->has_skewport_rect_tiles()) continue; iterator_ = TilingData::ReverseSpiralDifferenceIterator( - ((*tilings_))[tiling_index_]->tiling_data(), - ((*tilings_))[tiling_index_]->current_skewport_rect(), - ((*tilings_))[tiling_index_]->current_visible_rect(), - ((*tilings_))[tiling_index_]->current_visible_rect()); + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->current_skewport_rect(), + (*tilings_)[tiling_index_]->current_visible_rect(), + (*tilings_)[tiling_index_]->current_visible_rect()); + if (!iterator_) + continue; + found_tile = GetFirstTileAndCheckIfValid(&iterator_); + if (!found_tile) + found_tile = AdvanceToNextTile(&iterator_); + } + return *this; +} + +// PendingVisibleIterator +TilingSetEvictionQueue::PendingVisibleTilingIterator:: + PendingVisibleTilingIterator(std::vector<PictureLayerTiling*>* tilings, + WhichTree tree, + bool skip_shared_out_of_order_tiles, + bool return_required_for_activation_tiles) + : EvictionRectIterator(tilings, + tree, + skip_shared_out_of_order_tiles, + false /* skip_pending_visible_rect */), + return_required_for_activation_tiles_( + return_required_for_activation_tiles) { + // Find the first tiling with a tile. + while (tiling_index_ < tilings_->size()) { + iterator_ = TilingData::DifferenceIterator( + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->pending_visible_rect(), + (*tilings_)[tiling_index_]->current_visible_rect()); + if (!iterator_) { + ++tiling_index_; + continue; + } + break; + } + if (tiling_index_ >= tilings_->size()) + return; + if (!GetFirstTileAndCheckIfValid(&iterator_)) { + ++(*this); + return; + } + if (!TileMatchesRequiredFlags(tile_)) { + ++(*this); + return; + } +} + +TilingSetEvictionQueue::PendingVisibleTilingIterator& + TilingSetEvictionQueue::PendingVisibleTilingIterator:: + operator++() { + bool found_tile = AdvanceToNextTile(&iterator_); + while (found_tile && !TileMatchesRequiredFlags(tile_)) + found_tile = AdvanceToNextTile(&iterator_); + + while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { + ++tiling_index_; + iterator_ = TilingData::DifferenceIterator( + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->pending_visible_rect(), + (*tilings_)[tiling_index_]->current_visible_rect()); if (!iterator_) continue; found_tile = GetFirstTileAndCheckIfValid(&iterator_); if (!found_tile) found_tile = AdvanceToNextTile(&iterator_); + while (found_tile && !TileMatchesRequiredFlags(tile_)) + found_tile = AdvanceToNextTile(&iterator_); } return *this; } +bool TilingSetEvictionQueue::PendingVisibleTilingIterator:: + TileMatchesRequiredFlags(const Tile* tile) const { + bool activation_flag_matches = + tile->required_for_activation() == return_required_for_activation_tiles_; + return activation_flag_matches; +} + // VisibleTilingIterator TilingSetEvictionQueue::VisibleTilingIterator::VisibleTilingIterator( std::vector<PictureLayerTiling*>* tilings, @@ -401,19 +488,22 @@ TilingSetEvictionQueue::VisibleTilingIterator::VisibleTilingIterator( bool skip_shared_out_of_order_tiles, bool return_occluded_tiles, bool return_required_for_activation_tiles) - : EvictionRectIterator(tilings, tree, skip_shared_out_of_order_tiles), + : EvictionRectIterator(tilings, + tree, + skip_shared_out_of_order_tiles, + false /* skip_pending_visible_rect */), return_occluded_tiles_(return_occluded_tiles), return_required_for_activation_tiles_( return_required_for_activation_tiles) { // Find the first tiling with a tile. while (tiling_index_ < tilings_->size()) { - if (!((*tilings_))[tiling_index_]->has_visible_rect_tiles()) { + if (!(*tilings_)[tiling_index_]->has_visible_rect_tiles()) { ++tiling_index_; continue; } iterator_ = TilingData::Iterator( - ((*tilings_))[tiling_index_]->tiling_data(), - ((*tilings_))[tiling_index_]->current_visible_rect(), false); + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->current_visible_rect(), false); if (!iterator_) { ++tiling_index_; continue; @@ -441,11 +531,11 @@ TilingSetEvictionQueue::VisibleTilingIterator& while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { ++tiling_index_; - if (!((*tilings_))[tiling_index_]->has_visible_rect_tiles()) + if (!(*tilings_)[tiling_index_]->has_visible_rect_tiles()) continue; iterator_ = TilingData::Iterator( - ((*tilings_))[tiling_index_]->tiling_data(), - ((*tilings_))[tiling_index_]->current_visible_rect(), false); + (*tilings_)[tiling_index_]->tiling_data(), + (*tilings_)[tiling_index_]->current_visible_rect(), false); if (!iterator_) continue; found_tile = GetFirstTileAndCheckIfValid(&iterator_); @@ -461,8 +551,7 @@ bool TilingSetEvictionQueue::VisibleTilingIterator::TileMatchesRequiredFlags( const Tile* tile) const { bool activation_flag_matches = tile->required_for_activation() == return_required_for_activation_tiles_; - bool occluded_flag_matches = - tile->is_occluded(tree_) == return_occluded_tiles_; + bool occluded_flag_matches = tile->is_occluded() == return_occluded_tiles_; return activation_flag_matches && occluded_flag_matches; } diff --git a/cc/resources/tiling_set_eviction_queue.h b/cc/resources/tiling_set_eviction_queue.h index 439bdbb..c89f2aa 100644 --- a/cc/resources/tiling_set_eviction_queue.h +++ b/cc/resources/tiling_set_eviction_queue.h @@ -23,6 +23,10 @@ namespace cc { // EVENTUALLY_RECT - Tiles in the eventually region of the tiling. // SOON_BORDER_RECT - Tiles in the prepainting skirt of the tiling. // SKEWPORT_RECT - Tiles in the skewport of the tiling. +// PENDING_VISIBLE_RECT - Tiles that will be visible upon activation, not +// required for activation. +// PENDING_VISIBLE_RECT_REQUIRED_FOR_ACTIVATION - Tiles that will be visible +// upon activation, required for activation. // VISIBLE_RECT_OCCLUDED - Occluded, not required for activation, visible tiles. // VISIBLE_RECT_UNOCCLUDED - Unoccluded, not required for activation, visible // tiles. @@ -74,6 +78,8 @@ class CC_EXPORT TilingSetEvictionQueue { EVENTUALLY_RECT, SOON_BORDER_RECT, SKEWPORT_RECT, + PENDING_VISIBLE_RECT, + PENDING_VISIBLE_RECT_REQUIRED_FOR_ACTIVATION, VISIBLE_RECT_OCCLUDED, VISIBLE_RECT_UNOCCLUDED, VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_OCCLUDED, @@ -88,7 +94,8 @@ class CC_EXPORT TilingSetEvictionQueue { EvictionRectIterator(); EvictionRectIterator(std::vector<PictureLayerTiling*>* tilings, WhichTree tree, - bool skip_shared_out_of_order_tiles); + bool skip_shared_out_of_order_tiles, + bool skip_pending_visible_rect); bool done() const { return !tile_; } Tile* operator*() const { return tile_; } @@ -105,9 +112,27 @@ class CC_EXPORT TilingSetEvictionQueue { std::vector<PictureLayerTiling*>* tilings_; WhichTree tree_; bool skip_shared_out_of_order_tiles_; + bool skip_pending_visible_rect_; size_t tiling_index_; }; + class PendingVisibleTilingIterator : public EvictionRectIterator { + public: + PendingVisibleTilingIterator() = default; + PendingVisibleTilingIterator(std::vector<PictureLayerTiling*>* tilings, + WhichTree tree, + bool skip_shared_out_of_order_tiles, + bool return_required_for_activation_tiles); + + PendingVisibleTilingIterator& operator++(); + + private: + bool TileMatchesRequiredFlags(const Tile* tile) const; + + TilingData::DifferenceIterator iterator_; + bool return_required_for_activation_tiles_; + }; + class VisibleTilingIterator : public EvictionRectIterator { public: VisibleTilingIterator() = default; @@ -177,6 +202,7 @@ class CC_EXPORT TilingSetEvictionQueue { EventuallyTilingIterator eventually_iterator_; SoonBorderTilingIterator soon_iterator_; SkewportTilingIterator skewport_iterator_; + PendingVisibleTilingIterator pending_visible_iterator_; VisibleTilingIterator visible_iterator_; }; diff --git a/cc/resources/tiling_set_raster_queue_all.cc b/cc/resources/tiling_set_raster_queue_all.cc index 2ccba67..7f05558 100644 --- a/cc/resources/tiling_set_raster_queue_all.cc +++ b/cc/resources/tiling_set_raster_queue_all.cc @@ -12,6 +12,12 @@ namespace cc { +TilingSetRasterQueueAll::IterationStage::IterationStage( + IteratorType type, + TilePriority::PriorityBin bin) + : iterator_type(type), tile_type(bin) { +} + TilingSetRasterQueueAll::TilingSetRasterQueueAll( PictureLayerTilingSet* tiling_set, bool prioritize_low_res) @@ -19,39 +25,72 @@ TilingSetRasterQueueAll::TilingSetRasterQueueAll( DCHECK(tiling_set_); // Early out if the tiling set has no tilings. - if (!tiling_set_->num_tilings()) { - current_stage_ = arraysize(stages_); + if (!tiling_set_->num_tilings()) return; - } + const PictureLayerTilingClient* client = tiling_set->client(); + WhichTree tree = client->GetTree(); // Find high and low res tilings and initialize the iterators. + PictureLayerTiling* high_res_tiling = nullptr; + PictureLayerTiling* low_res_tiling = nullptr; + // This variable would point to a tiling that has a NON_IDEAL_RESOLUTION + // resolution on the active tree, but HIGH_RESOLUTION on the pending tree. + // These tilings are the only non-ideal tilings that could have required for + // activation tiles, so they need to be considered for rasterization. + PictureLayerTiling* active_non_ideal_pending_high_res_tiling = nullptr; for (size_t i = 0; i < tiling_set_->num_tilings(); ++i) { PictureLayerTiling* tiling = tiling_set_->tiling_at(i); if (tiling->resolution() == HIGH_RESOLUTION) - iterators_[HIGH_RES] = TilingIterator(tiling, &tiling->tiling_data_); + high_res_tiling = tiling; if (prioritize_low_res && tiling->resolution() == LOW_RESOLUTION) - iterators_[LOW_RES] = TilingIterator(tiling, &tiling->tiling_data_); + low_res_tiling = tiling; + if (tree == ACTIVE_TREE && tiling->resolution() == NON_IDEAL_RESOLUTION) { + const PictureLayerTiling* twin = + client->GetPendingOrActiveTwinTiling(tiling); + if (twin && twin->resolution() == HIGH_RESOLUTION) + active_non_ideal_pending_high_res_tiling = tiling; + } } - if (prioritize_low_res) { - stages_[0].iterator_type = LOW_RES; - stages_[0].tile_type = TilePriority::NOW; + bool use_low_res_tiling = low_res_tiling && low_res_tiling->has_tiles(); + if (use_low_res_tiling && prioritize_low_res) { + iterators_[LOW_RES] = + TilingIterator(low_res_tiling, &low_res_tiling->tiling_data_); + stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW)); + } - stages_[1].iterator_type = HIGH_RES; - stages_[1].tile_type = TilePriority::NOW; - } else { - stages_[0].iterator_type = HIGH_RES; - stages_[0].tile_type = TilePriority::NOW; + bool use_high_res_tiling = high_res_tiling && high_res_tiling->has_tiles(); + if (use_high_res_tiling) { + iterators_[HIGH_RES] = + TilingIterator(high_res_tiling, &high_res_tiling->tiling_data_); + stages_->push_back(IterationStage(HIGH_RES, TilePriority::NOW)); + } - stages_[1].iterator_type = LOW_RES; - stages_[1].tile_type = TilePriority::NOW; + if (low_res_tiling && !prioritize_low_res) { + iterators_[LOW_RES] = + TilingIterator(low_res_tiling, &low_res_tiling->tiling_data_); + stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW)); } - stages_[2].iterator_type = HIGH_RES; - stages_[2].tile_type = TilePriority::SOON; + if (active_non_ideal_pending_high_res_tiling && + active_non_ideal_pending_high_res_tiling->has_tiles()) { + iterators_[ACTIVE_NON_IDEAL_PENDING_HIGH_RES] = + TilingIterator(active_non_ideal_pending_high_res_tiling, + &active_non_ideal_pending_high_res_tiling->tiling_data_); - stages_[3].iterator_type = HIGH_RES; - stages_[3].tile_type = TilePriority::EVENTUALLY; + stages_->push_back( + IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES, TilePriority::NOW)); + stages_->push_back( + IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES, TilePriority::SOON)); + } + + if (use_high_res_tiling) { + stages_->push_back(IterationStage(HIGH_RES, TilePriority::SOON)); + stages_->push_back(IterationStage(HIGH_RES, TilePriority::EVENTUALLY)); + } + + if (stages_->empty()) + return; IteratorType index = stages_[current_stage_].iterator_type; TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type; @@ -63,7 +102,7 @@ TilingSetRasterQueueAll::~TilingSetRasterQueueAll() { } bool TilingSetRasterQueueAll::IsEmpty() const { - return current_stage_ >= arraysize(stages_); + return current_stage_ >= stages_->size(); } void TilingSetRasterQueueAll::Pop() { @@ -100,9 +139,9 @@ const Tile* TilingSetRasterQueueAll::Top() const { } void TilingSetRasterQueueAll::AdvanceToNextStage() { - DCHECK_LT(current_stage_, arraysize(stages_)); + DCHECK_LT(current_stage_, stages_->size()); ++current_stage_; - while (current_stage_ < arraysize(stages_)) { + while (current_stage_ < stages_->size()) { IteratorType index = stages_[current_stage_].iterator_type; TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type; @@ -173,11 +212,33 @@ TilingSetRasterQueueAll::VisibleTilingIterator& return *this; } +// PendingVisibleTilingIterator. +TilingSetRasterQueueAll::PendingVisibleTilingIterator:: + PendingVisibleTilingIterator(PictureLayerTiling* tiling, + TilingData* tiling_data) + : OnePriorityRectIterator(tiling, tiling_data) { + iterator_ = TilingData::DifferenceIterator(tiling_data_, + tiling_->pending_visible_rect(), + tiling_->current_visible_rect()); + if (!iterator_) + return; + if (!GetFirstTileAndCheckIfValid(&iterator_)) + ++(*this); +} + +TilingSetRasterQueueAll::PendingVisibleTilingIterator& + TilingSetRasterQueueAll::PendingVisibleTilingIterator:: + operator++() { + AdvanceToNextTile(&iterator_); + return *this; +} + // SkewportTilingIterator. TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator( PictureLayerTiling* tiling, TilingData* tiling_data) - : OnePriorityRectIterator(tiling, tiling_data) { + : OnePriorityRectIterator(tiling, tiling_data), + pending_visible_rect_(tiling->pending_visible_rect()) { if (!tiling_->has_skewport_rect_tiles()) return; iterator_ = TilingData::SpiralDifferenceIterator( @@ -185,7 +246,11 @@ TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator( tiling_->current_visible_rect(), tiling_->current_visible_rect()); if (!iterator_) return; - if (!GetFirstTileAndCheckIfValid(&iterator_)) + if (!GetFirstTileAndCheckIfValid(&iterator_)) { + ++(*this); + return; + } + if (tile_->content_rect().Intersects(pending_visible_rect_)) ++(*this); } @@ -193,6 +258,11 @@ TilingSetRasterQueueAll::SkewportTilingIterator& TilingSetRasterQueueAll::SkewportTilingIterator:: operator++() { AdvanceToNextTile(&iterator_); + while (!done()) { + if (!tile_->content_rect().Intersects(pending_visible_rect_)) + break; + AdvanceToNextTile(&iterator_); + } return *this; } @@ -200,7 +270,8 @@ TilingSetRasterQueueAll::SkewportTilingIterator& TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator( PictureLayerTiling* tiling, TilingData* tiling_data) - : OnePriorityRectIterator(tiling, tiling_data) { + : OnePriorityRectIterator(tiling, tiling_data), + pending_visible_rect_(tiling->pending_visible_rect()) { if (!tiling_->has_soon_border_rect_tiles()) return; iterator_ = TilingData::SpiralDifferenceIterator( @@ -208,7 +279,11 @@ TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator( tiling_->current_skewport_rect(), tiling_->current_visible_rect()); if (!iterator_) return; - if (!GetFirstTileAndCheckIfValid(&iterator_)) + if (!GetFirstTileAndCheckIfValid(&iterator_)) { + ++(*this); + return; + } + if (tile_->content_rect().Intersects(pending_visible_rect_)) ++(*this); } @@ -216,6 +291,11 @@ TilingSetRasterQueueAll::SoonBorderTilingIterator& TilingSetRasterQueueAll::SoonBorderTilingIterator:: operator++() { AdvanceToNextTile(&iterator_); + while (!done()) { + if (!tile_->content_rect().Intersects(pending_visible_rect_)) + break; + AdvanceToNextTile(&iterator_); + } return *this; } @@ -223,7 +303,8 @@ TilingSetRasterQueueAll::SoonBorderTilingIterator& TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator( PictureLayerTiling* tiling, TilingData* tiling_data) - : OnePriorityRectIterator(tiling, tiling_data) { + : OnePriorityRectIterator(tiling, tiling_data), + pending_visible_rect_(tiling->pending_visible_rect()) { if (!tiling_->has_eventually_rect_tiles()) return; iterator_ = TilingData::SpiralDifferenceIterator( @@ -231,7 +312,11 @@ TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator( tiling_->current_skewport_rect(), tiling_->current_soon_border_rect()); if (!iterator_) return; - if (!GetFirstTileAndCheckIfValid(&iterator_)) + if (!GetFirstTileAndCheckIfValid(&iterator_)) { + ++(*this); + return; + } + if (tile_->content_rect().Intersects(pending_visible_rect_)) ++(*this); } @@ -239,6 +324,11 @@ TilingSetRasterQueueAll::EventuallyTilingIterator& TilingSetRasterQueueAll::EventuallyTilingIterator:: operator++() { AdvanceToNextTile(&iterator_); + while (!done()) { + if (!tile_->content_rect().Intersects(pending_visible_rect_)) + break; + AdvanceToNextTile(&iterator_); + } return *this; } @@ -262,6 +352,9 @@ TilingSetRasterQueueAll::TilingIterator::TilingIterator( current_tile_ = *visible_iterator_; } +TilingSetRasterQueueAll::TilingIterator::~TilingIterator() { +} + void TilingSetRasterQueueAll::TilingIterator::AdvancePhase() { DCHECK_LT(phase_, EVENTUALLY_RECT); @@ -272,6 +365,12 @@ void TilingSetRasterQueueAll::TilingIterator::AdvancePhase() { case VISIBLE_RECT: NOTREACHED(); return; + case PENDING_VISIBLE_RECT: + pending_visible_iterator_ = + PendingVisibleTilingIterator(tiling_, tiling_data_); + if (!pending_visible_iterator_.done()) + current_tile_ = *pending_visible_iterator_; + break; case SKEWPORT_RECT: skewport_iterator_ = SkewportTilingIterator(tiling_, tiling_data_); if (!skewport_iterator_.done()) @@ -303,6 +402,14 @@ TilingSetRasterQueueAll::TilingIterator& } current_tile_ = *visible_iterator_; break; + case PENDING_VISIBLE_RECT: + ++pending_visible_iterator_; + if (pending_visible_iterator_.done()) { + AdvancePhase(); + return *this; + } + current_tile_ = *pending_visible_iterator_; + break; case SKEWPORT_RECT: ++skewport_iterator_; if (skewport_iterator_.done()) { diff --git a/cc/resources/tiling_set_raster_queue_all.h b/cc/resources/tiling_set_raster_queue_all.h index ebca838..e210f28 100644 --- a/cc/resources/tiling_set_raster_queue_all.h +++ b/cc/resources/tiling_set_raster_queue_all.h @@ -5,6 +5,7 @@ #ifndef CC_RESOURCES_TILING_SET_RASTER_QUEUE_ALL_H_ #define CC_RESOURCES_TILING_SET_RASTER_QUEUE_ALL_H_ +#include "base/containers/stack_container.h" #include "cc/base/cc_export.h" #include "cc/resources/picture_layer_tiling_set.h" #include "cc/resources/tile.h" @@ -64,6 +65,18 @@ class CC_EXPORT TilingSetRasterQueueAll { TilingData::Iterator iterator_; }; + class PendingVisibleTilingIterator : public OnePriorityRectIterator { + public: + PendingVisibleTilingIterator() = default; + PendingVisibleTilingIterator(PictureLayerTiling* tiling, + TilingData* tiling_data); + + PendingVisibleTilingIterator& operator++(); + + private: + TilingData::DifferenceIterator iterator_; + }; + // Iterates over skewport only, spiral around the visible rect. class SkewportTilingIterator : public OnePriorityRectIterator { public: @@ -74,6 +87,7 @@ class CC_EXPORT TilingSetRasterQueueAll { private: TilingData::SpiralDifferenceIterator iterator_; + gfx::Rect pending_visible_rect_; }; // Iterates over soon border only, spiral around the visible rect. @@ -87,6 +101,7 @@ class CC_EXPORT TilingSetRasterQueueAll { private: TilingData::SpiralDifferenceIterator iterator_; + gfx::Rect pending_visible_rect_; }; // Iterates over eventually rect only, spiral around the soon rect. @@ -100,6 +115,7 @@ class CC_EXPORT TilingSetRasterQueueAll { private: TilingData::SpiralDifferenceIterator iterator_; + gfx::Rect pending_visible_rect_; }; // Iterates over all of the above phases in the following order: visible, @@ -109,7 +125,7 @@ class CC_EXPORT TilingSetRasterQueueAll { TilingIterator(); explicit TilingIterator(PictureLayerTiling* tiling, TilingData* tiling_data); - ~TilingIterator() = default; + ~TilingIterator(); bool done() const { return current_tile_ == nullptr; } const Tile* operator*() const { return current_tile_; } @@ -118,6 +134,7 @@ class CC_EXPORT TilingSetRasterQueueAll { switch (phase_) { case VISIBLE_RECT: return TilePriority::NOW; + case PENDING_VISIBLE_RECT: case SKEWPORT_RECT: case SOON_BORDER_RECT: return TilePriority::SOON; @@ -131,8 +148,14 @@ class CC_EXPORT TilingSetRasterQueueAll { TilingIterator& operator++(); private: + // PENDING VISIBLE RECT refers to the visible rect that will become current + // upon activation (ie, the pending tree's visible rect). Tiles in this + // region that are not part of the current visible rect are all handled + // here. Note that when processing a pending tree, this rect is the same as + // the visible rect so no tiles are processed in this case. enum Phase { VISIBLE_RECT, + PENDING_VISIBLE_RECT, SKEWPORT_RECT, SOON_BORDER_RECT, EVENTUALLY_RECT @@ -147,26 +170,34 @@ class CC_EXPORT TilingSetRasterQueueAll { Tile* current_tile_; VisibleTilingIterator visible_iterator_; + PendingVisibleTilingIterator pending_visible_iterator_; SkewportTilingIterator skewport_iterator_; SoonBorderTilingIterator soon_border_iterator_; EventuallyTilingIterator eventually_iterator_; }; - enum IteratorType { LOW_RES, HIGH_RES, NUM_ITERATORS }; + enum IteratorType { + LOW_RES, + HIGH_RES, + ACTIVE_NON_IDEAL_PENDING_HIGH_RES, + NUM_ITERATORS + }; void AdvanceToNextStage(); PictureLayerTilingSet* tiling_set_; struct IterationStage { + IterationStage(IteratorType type, TilePriority::PriorityBin bin); IteratorType iterator_type; TilePriority::PriorityBin tile_type; }; size_t current_stage_; - // One low res stage, and three high res stages. - IterationStage stages_[4]; + // The max number of stages is 6: 1 low res, 3 high res, and 2 active non + // ideal pending high res. + base::StackVector<IterationStage, 6> stages_; TilingIterator iterators_[NUM_ITERATORS]; }; diff --git a/cc/resources/tiling_set_raster_queue_required.cc b/cc/resources/tiling_set_raster_queue_required.cc index 89ddb04..b44ee08 100644 --- a/cc/resources/tiling_set_raster_queue_required.cc +++ b/cc/resources/tiling_set_raster_queue_required.cc @@ -19,19 +19,39 @@ TilingSetRasterQueueRequired::TilingSetRasterQueueRequired( DCHECK_NE(static_cast<int>(type), static_cast<int>(RasterTilePriorityQueue::Type::ALL)); - // Any type of required tile would only come from a high resolution tiling. - // The functions that determine this value is - // PictureLayerTiling::IsTileRequiredFor*, which all return false if the - // resolution is not HIGH_RESOLUTION. - PictureLayerTiling* tiling = - tiling_set->FindTilingWithResolution(HIGH_RESOLUTION); - // If we don't have a high res tiling, then this queue will yield no tiles. - // See PictureLayerImpl::CanHaveTilings for examples of when a HIGH_RESOLUTION + // Required tiles should only come from HIGH_RESOLUTION tilings. However, if + // we want required for activation tiles on the active tree, then it will come + // from tilings whose pending twin is high resolution. + PictureLayerTiling* tiling = nullptr; + if (type == RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION && + tiling_set->client()->GetTree() == ACTIVE_TREE) { + for (size_t i = 0; i < tiling_set->num_tilings(); ++i) { + PictureLayerTiling* active_tiling = tiling_set->tiling_at(i); + const PictureLayerTiling* pending_twin = + tiling_set->client()->GetPendingOrActiveTwinTiling(active_tiling); + if (pending_twin && pending_twin->resolution() == HIGH_RESOLUTION) { + tiling = active_tiling; + break; + } + } + } else { + tiling = tiling_set->FindTilingWithResolution(HIGH_RESOLUTION); + } + + // If we don't have a tiling, then this queue will yield no tiles. See + // PictureLayerImpl::CanHaveTilings for examples of when a HIGH_RESOLUTION // tiling would not be generated. if (!tiling) return; - iterator_ = TilingIterator(tiling, &tiling->tiling_data_); + if (type == RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION) { + iterator_ = TilingIterator(tiling, &tiling->tiling_data_, + tiling->pending_visible_rect()); + } else { + iterator_ = TilingIterator(tiling, &tiling->tiling_data_, + tiling->current_visible_rect()); + } + while (!iterator_.done() && !IsTileRequired(*iterator_)) ++iterator_; } @@ -73,19 +93,11 @@ TilingSetRasterQueueRequired::TilingIterator::TilingIterator() TilingSetRasterQueueRequired::TilingIterator::TilingIterator( PictureLayerTiling* tiling, - TilingData* tiling_data) + TilingData* tiling_data, + const gfx::Rect& rect) : tiling_(tiling), tiling_data_(tiling_data), current_tile_(nullptr) { - if (!tiling_->has_visible_rect_tiles()) { - // Verify that if we would create the iterator, then it would be empty (ie - // it would return false when evaluated as a bool). - DCHECK(!TilingData::Iterator(tiling_data_, tiling->current_visible_rect(), - false)); - return; - } - visible_iterator_ = - TilingData::Iterator(tiling_data_, tiling_->current_visible_rect(), - false /* include_borders */); + TilingData::Iterator(tiling_data_, rect, false /* include_borders */); if (!visible_iterator_) return; diff --git a/cc/resources/tiling_set_raster_queue_required.h b/cc/resources/tiling_set_raster_queue_required.h index 6e278e6..0290dc48 100644 --- a/cc/resources/tiling_set_raster_queue_required.h +++ b/cc/resources/tiling_set_raster_queue_required.h @@ -34,7 +34,8 @@ class CC_EXPORT TilingSetRasterQueueRequired { public: TilingIterator(); explicit TilingIterator(PictureLayerTiling* tiling, - TilingData* tiling_data); + TilingData* tiling_data, + const gfx::Rect& rect); ~TilingIterator(); bool done() const { return current_tile_ == nullptr; } diff --git a/cc/test/fake_picture_layer_impl.cc b/cc/test/fake_picture_layer_impl.cc index 75f7fda..dba0c6e 100644 --- a/cc/test/fake_picture_layer_impl.cc +++ b/cc/test/fake_picture_layer_impl.cc @@ -148,9 +148,6 @@ void FakePictureLayerImpl::CreateAllTiles() { } void FakePictureLayerImpl::SetAllTilesVisible() { - WhichTree tree = - layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE; - for (size_t tiling_idx = 0; tiling_idx < tilings_->num_tilings(); ++tiling_idx) { PictureLayerTiling* tiling = tilings_->tiling_at(tiling_idx); @@ -161,7 +158,7 @@ void FakePictureLayerImpl::SetAllTilesVisible() { priority.resolution = HIGH_RESOLUTION; priority.priority_bin = TilePriority::NOW; priority.distance_to_visible = 0.f; - tile->SetPriority(tree, priority); + tile->set_priority(priority); } } } @@ -173,8 +170,7 @@ void FakePictureLayerImpl::ResetAllTilesPriorities() { std::vector<Tile*> tiles = tiling->AllTilesForTesting(); for (size_t tile_idx = 0; tile_idx < tiles.size(); ++tile_idx) { Tile* tile = tiles[tile_idx]; - tile->SetPriority(ACTIVE_TREE, TilePriority()); - tile->SetPriority(PENDING_TREE, TilePriority()); + tile->set_priority(TilePriority()); } } } @@ -260,16 +256,14 @@ size_t FakePictureLayerImpl::CountTilesRequiredForActivation() const { if (!layer_tree_impl()->IsPendingTree()) return 0; - return CountTilesRequired( - &PictureLayerTiling::IsTileRequiredForActivationIfVisible); + return CountTilesRequired(&PictureLayerTiling::IsTileRequiredForActivation); } size_t FakePictureLayerImpl::CountTilesRequiredForDraw() const { if (!layer_tree_impl()->IsActiveTree()) return 0; - return CountTilesRequired( - &PictureLayerTiling::IsTileRequiredForDrawIfVisible); + return CountTilesRequired(&PictureLayerTiling::IsTileRequiredForDraw); } void FakePictureLayerImpl::ReleaseResources() { diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc index 7d3d525..6f222f7 100644 --- a/cc/trees/layer_tree_host_unittest_picture.cc +++ b/cc/trees/layer_tree_host_unittest_picture.cc @@ -242,8 +242,8 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree EXPECT_TRUE(tiling->TileAt(0, 0)); EXPECT_FALSE(tiling->TileAt(0, num_tiles_y)); - // The recycled tiling matches it. - EXPECT_TRUE(recycled_tiling->TileAt(0, 0)); + // The recycled tiling has no tiles. + EXPECT_FALSE(recycled_tiling->TileAt(0, 0)); EXPECT_FALSE(recycled_tiling->TileAt(0, num_tiles_y)); // The live tiles rect matches on the recycled tree. @@ -266,10 +266,6 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree // either. EXPECT_FALSE(recycled_tiling->TileAt(0, 0)); - // The live tiles rect matches on the recycled tree. - EXPECT_EQ(tiling->live_tiles_rect(), - recycled_tiling->live_tiles_rect()); - // Make the top of the layer visible again. picture_impl->SetPosition(gfx::PointF()); impl->SetNeedsRedraw(); @@ -284,8 +280,8 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree EXPECT_TRUE(tiling->TileAt(0, 0)); EXPECT_FALSE(tiling->TileAt(0, num_tiles_y)); - // The recycled tiling should also have tiles at the top. - EXPECT_TRUE(recycled_tiling->TileAt(0, 0)); + // The recycled tiling should have no tiles. + EXPECT_FALSE(recycled_tiling->TileAt(0, 0)); EXPECT_FALSE(recycled_tiling->TileAt(0, num_tiles_y)); // The live tiles rect matches on the recycled tree. @@ -308,9 +304,15 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree PictureLayerTiling* tiling = picture_impl->HighResTiling(); int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y(); - // The pending layer should always have tiles at the top of it each commit. - // The tile is part of the required for activation set so it should exist. - EXPECT_TRUE(tiling->TileAt(0, 0)); + if (!impl->active_tree()->root_layer()) { + // If active tree doesn't have the layer, then pending tree should have + // all needed tiles. + EXPECT_TRUE(tiling->TileAt(0, 0)); + } else { + // Since there was no invalidation, the pending tree shouldn't have any + // tiles. + EXPECT_FALSE(tiling->TileAt(0, 0)); + } EXPECT_FALSE(tiling->TileAt(0, num_tiles_y)); if (did_post_commit_) |