diff options
author | Vladimir Levin <vmpstr@chromium.org> | 2014-09-09 11:38:36 -0700 |
---|---|---|
committer | Vladimir Levin <vmpstr@chromium.org> | 2014-09-09 18:46:21 +0000 |
commit | e9d3d0540b881468a8de05a05c682b4d2e520d58 (patch) | |
tree | b097710f742b8aa17dce56bd299dd05af902d51a | |
parent | bd227b55ed73b3328665307e1f9e2419bbc95996 (diff) | |
download | chromium_src-e9d3d0540b881468a8de05a05c682b4d2e520d58.zip chromium_src-e9d3d0540b881468a8de05a05c682b4d2e520d58.tar.gz chromium_src-e9d3d0540b881468a8de05a05c682b4d2e520d58.tar.bz2 |
cc: Remove tiles from recycle tree that were deleted on active.
This patch removes tiles from the recycle tree that were deleted from
the active tree as a result of a shifting live tiles rect. It is
important to do this, since if the active tree then would recreate
the deleted tile (ie, live tiles rect shift back), we have to ensure
that this tile will be shared when the next pending tree is created.
If we don't do it, we can run into a situation in which we will
continuously raster the same tile.
The patch does the following:
- Adds a way to get a recycled tree twin tiling.
- During LiveTilesRect tile deletion, deletes tiles from the same
location from the recycle twin (if one exists).
TBR=danakj, enne@chromium.org
BUG=403094
Review URL: https://codereview.chromium.org/502453003
Cr-Commit-Position: refs/heads/master@{#291949}
(cherry picked from commit 7fceb77977afd9af22215eb9cd28ab667567668e)
Conflicts:
cc/debug/rasterize_and_record_benchmark_impl.cc
Review URL: https://codereview.chromium.org/542203006
Cr-Commit-Position: refs/branch-heads/2125@{#279}
Cr-Branched-From: b68026d94bda36dd106a3d91a098719f952a9477-refs/heads/master@{#290040}
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 19 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.h | 3 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl_unittest.cc | 34 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.cc | 12 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.h | 3 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_unittest.cc | 83 | ||||
-rw-r--r-- | cc/test/fake_picture_layer_impl.h | 1 | ||||
-rw-r--r-- | cc/test/fake_picture_layer_tiling_client.cc | 13 | ||||
-rw-r--r-- | cc/test/fake_picture_layer_tiling_client.h | 6 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 6 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.h | 1 |
11 files changed, 175 insertions, 6 deletions
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index c477720..cedb7a1 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -108,7 +108,7 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { LayerImpl::PushPropertiesTo(base_layer); // When the pending tree pushes to the active tree, the pending twin - // disappears. + // becomes recycled. layer_impl->twin_layer_ = NULL; twin_layer_ = NULL; @@ -533,6 +533,12 @@ gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const { return visible_rect_in_content_space; } +PictureLayerImpl* PictureLayerImpl::GetRecycledTwinLayer() { + // TODO(vmpstr): Maintain recycled twin as a member. crbug.com/407418 + return static_cast<PictureLayerImpl*>( + layer_tree_impl()->FindRecycleTreeLayerById(id())); +} + void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) { if (layer_tree_impl()->IsActiveTree()) { gfx::RectF layer_damage_rect = @@ -609,6 +615,14 @@ const PictureLayerTiling* PictureLayerImpl::GetTwinTiling( return NULL; } +PictureLayerTiling* PictureLayerImpl::GetRecycledTwinTiling( + const PictureLayerTiling* tiling) { + PictureLayerImpl* recycled_twin = GetRecycledTwinLayer(); + if (!recycled_twin || !recycled_twin->tilings_) + return NULL; + return recycled_twin->tilings_->TilingAtScale(tiling->contents_scale()); +} + size_t PictureLayerImpl::GetMaxTilesForInterestArea() const { return layer_tree_impl()->settings().max_tiles_for_interest_area; } @@ -1243,8 +1257,7 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer( if (to_remove.empty()) return; - PictureLayerImpl* recycled_twin = static_cast<PictureLayerImpl*>( - layer_tree_impl()->FindRecycleTreeLayerById(id())); + PictureLayerImpl* recycled_twin = GetRecycledTwinLayer(); // Remove tilings on this tree and the twin tree. for (size_t i = 0; i < to_remove.size(); ++i) { const PictureLayerTiling* twin_tiling = GetTwinTiling(to_remove[i]); diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index f70d3a2..308de67 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h @@ -124,6 +124,8 @@ class CC_EXPORT PictureLayerImpl virtual const Region* GetInvalidation() OVERRIDE; virtual const PictureLayerTiling* GetTwinTiling( const PictureLayerTiling* tiling) const OVERRIDE; + virtual PictureLayerTiling* GetRecycledTwinTiling( + const PictureLayerTiling* tiling) OVERRIDE; virtual size_t GetMaxTilesForInterestArea() const OVERRIDE; virtual float GetSkewportTargetTimeInSeconds() const OVERRIDE; virtual int GetSkewportExtrapolationLimitInContentPixels() const OVERRIDE; @@ -173,6 +175,7 @@ class CC_EXPORT PictureLayerImpl const gfx::Rect& rect, const Region& missing_region) const; gfx::Rect GetViewportForTilePriorityInContentSpace() const; + PictureLayerImpl* GetRecycledTwinLayer(); void DoPostCommitInitializationIfNeeded() { if (needs_post_commit_initialization_) diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index ec999e6..3331a5f 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -51,7 +51,10 @@ class PictureLayerImplTest : public testing::Test { host_impl_(ImplSidePaintingSettings(), &proxy_, &shared_bitmap_manager_), - id_(7) {} + id_(7), + pending_layer_(NULL), + old_pending_layer_(NULL), + active_layer_(NULL) {} explicit PictureLayerImplTest(const LayerTreeSettings& settings) : proxy_(base::MessageLoopProxy::current()), @@ -84,6 +87,8 @@ class PictureLayerImplTest : public testing::Test { void ActivateTree() { host_impl_.ActivateSyncTree(); CHECK(!host_impl_.pending_tree()); + CHECK(host_impl_.recycle_tree()); + old_pending_layer_ = pending_layer_; pending_layer_ = NULL; active_layer_ = static_cast<FakePictureLayerImpl*>( host_impl_.active_tree()->LayerById(id_)); @@ -264,6 +269,7 @@ class PictureLayerImplTest : public testing::Test { FakeLayerTreeHostImpl host_impl_; int id_; FakePictureLayerImpl* pending_layer_; + FakePictureLayerImpl* old_pending_layer_; FakePictureLayerImpl* active_layer_; private: @@ -3860,5 +3866,31 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, VerifyEvictionConsidersOcclusion(active_layer_, total_expected_occluded_tile_count); } + +TEST_F(PictureLayerImplTest, RecycledTwinLayer) { + gfx::Size tile_size(102, 102); + gfx::Size layer_bounds(1000, 1000); + + scoped_refptr<FakePicturePileImpl> pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + SetupPendingTree(pile); + EXPECT_FALSE(pending_layer_->GetRecycledTwinLayer()); + + ActivateTree(); + EXPECT_TRUE(active_layer_->GetRecycledTwinLayer()); + EXPECT_EQ(old_pending_layer_, active_layer_->GetRecycledTwinLayer()); + + SetupPendingTree(pile); + EXPECT_FALSE(pending_layer_->GetRecycledTwinLayer()); + EXPECT_FALSE(active_layer_->GetRecycledTwinLayer()); + + ActivateTree(); + EXPECT_TRUE(active_layer_->GetRecycledTwinLayer()); + EXPECT_EQ(old_pending_layer_, active_layer_->GetRecycledTwinLayer()); + + host_impl_.ResetRecycleTreeForTesting(); + EXPECT_FALSE(active_layer_->GetRecycledTwinLayer()); +} + } // namespace } // namespace cc diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index 6482dc6..adc4f04 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -667,6 +667,15 @@ void PictureLayerTiling::UpdateTilePriorities( current_eventually_rect_ = eventually_rect; } +void PictureLayerTiling::RemoveTileAt(int i, int j) { + TileMapKey key(i, j); + TileMap::iterator found = tiles_.find(key); + if (found == tiles_.end()) + return; + ReleaseTile(found->second.get(), client_->GetTree()); + tiles_.erase(found); +} + void PictureLayerTiling::SetLiveTilesRect( const gfx::Rect& new_live_tiles_rect) { DCHECK(new_live_tiles_rect.IsEmpty() || @@ -677,6 +686,7 @@ void PictureLayerTiling::SetLiveTilesRect( return; // Iterate to delete all tiles outside of our new live_tiles rect. + PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); for (TilingData::DifferenceIterator iter(&tiling_data_, live_tiles_rect_, new_live_tiles_rect); @@ -689,6 +699,8 @@ void PictureLayerTiling::SetLiveTilesRect( if (found != tiles_.end()) { ReleaseTile(found->second.get(), client_->GetTree()); tiles_.erase(found); + if (recycled_twin) + recycled_twin->RemoveTileAt(iter.index_x(), iter.index_y()); } } diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h index 5cf184b..9ca0d41 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h @@ -44,6 +44,8 @@ class CC_EXPORT PictureLayerTilingClient { virtual const Region* GetInvalidation() = 0; virtual const PictureLayerTiling* GetTwinTiling( const PictureLayerTiling* tiling) const = 0; + virtual PictureLayerTiling* GetRecycledTwinTiling( + const PictureLayerTiling* tiling) = 0; virtual size_t GetMaxTilesForInterestArea() const = 0; virtual float GetSkewportTargetTimeInSeconds() const = 0; virtual int GetSkewportExtrapolationLimitInContentPixels() const = 0; @@ -296,6 +298,7 @@ class CC_EXPORT PictureLayerTiling { void SetLiveTilesRect(const gfx::Rect& live_tiles_rect); void VerifyLiveTilesRect(); Tile* CreateTile(int i, int j, const PictureLayerTiling* twin_tiling); + void RemoveTileAt(int i, int j); // Computes a skewport. The calculation extrapolates the last visible // rect and the current visible rect to expand the skewport to where it diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc index 9bd93d8..f03c3bf 100644 --- a/cc/resources/picture_layer_tiling_unittest.cc +++ b/cc/resources/picture_layer_tiling_unittest.cc @@ -2142,5 +2142,88 @@ TEST(PictureLayerTilingTest, ResetClearsPriorities) { tiles.clear(); } +TEST(PictureLayerTilingTest, RecycledTilesCleared) { + // This test performs the following: + // Setup: + // - Two tilings, one active one recycled with all tiles shared. + // Procedure: + // - Viewport moves somewhere far away and active tiling clears tiles. + // - Viewport moves back and a new active tiling tile is created. + // Result: + // - Recycle tiling does _not_ have the tile in the same location (thus it + // will be shared next time a pending tiling is created). + + FakePictureLayerTilingClient client; + scoped_ptr<TestablePictureLayerTiling> tiling; + + client.SetTileSize(gfx::Size(100, 100)); + client.set_tree(ACTIVE_TREE); + client.set_max_tiles_for_interest_area(10); + tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale + gfx::Size(10000, 10000), + &client); + // Create all tiles on this tiling. + tiling->UpdateTilePriorities(ACTIVE_TREE, + gfx::Rect(0, 0, 100, 100), + 1.0f, + 1.0f, + NULL, // occlusion tracker + NULL, // render target + gfx::Transform()); // draw transform + + FakePictureLayerTilingClient second_client; + second_client.SetTileSize(gfx::Size(100, 100)); + second_client.set_tree(PENDING_TREE); + second_client.set_twin_tiling(tiling.get()); + second_client.set_max_tiles_for_interest_area(10); + + scoped_ptr<TestablePictureLayerTiling> second_tiling; + second_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale + gfx::Size(10000, 10000), + &second_client); + + // Create all tiles on the second tiling. All tiles should be shared. + second_tiling->UpdateTilePriorities(ACTIVE_TREE, + gfx::Rect(0, 0, 100, 100), + 1.0f, + 1.0f, + NULL, // occlusion tracker + NULL, // render target + gfx::Transform()); // draw transform + + // Verify that tiles exist and are shared. + ASSERT_TRUE(tiling->TileAt(0, 0)); + ASSERT_EQ(tiling->TileAt(0, 0), second_tiling->TileAt(0, 0)); + + // Set the second tiling as recycled. + client.set_twin_tiling(NULL); + client.set_recycled_twin_tiling(second_tiling.get()); + second_client.set_twin_tiling(NULL); + + // Move the viewport far away from the (0, 0) tile. + tiling->UpdateTilePriorities(ACTIVE_TREE, + gfx::Rect(9000, 9000, 100, 100), + 1.0f, + 2.0, + NULL, // occlusion tracker + NULL, // render target + gfx::Transform()); // draw transform + // Ensure the tile was deleted. + EXPECT_FALSE(tiling->TileAt(0, 0)); + + // Move the viewport back to (0, 0) tile. + tiling->UpdateTilePriorities(ACTIVE_TREE, + gfx::Rect(0, 0, 100, 100), + 1.0f, + 3.0, + NULL, // occlusion tracker + NULL, // render target + gfx::Transform()); // draw transform + + // Ensure that we now have a tile here, but the recycle tiling does not. + EXPECT_TRUE(tiling->TileAt(0, 0)); + EXPECT_FALSE(second_tiling->TileAt(0, 0)); +} + } // namespace } // namespace cc diff --git a/cc/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h index 4b68d7f..7b83226 100644 --- a/cc/test/fake_picture_layer_impl.h +++ b/cc/test/fake_picture_layer_impl.h @@ -60,6 +60,7 @@ class FakePictureLayerImpl : public PictureLayerImpl { using PictureLayerImpl::MinimumContentsScale; using PictureLayerImpl::GetViewportForTilePriorityInContentSpace; using PictureLayerImpl::SanityCheckTilingState; + using PictureLayerImpl::GetRecycledTwinLayer; using PictureLayerImpl::UpdateIdealScales; using PictureLayerImpl::MaximumTilingContentsScale; diff --git a/cc/test/fake_picture_layer_tiling_client.cc b/cc/test/fake_picture_layer_tiling_client.cc index 2bd756d..0503d22a 100644 --- a/cc/test/fake_picture_layer_tiling_client.cc +++ b/cc/test/fake_picture_layer_tiling_client.cc @@ -15,10 +15,12 @@ FakePictureLayerTilingClient::FakePictureLayerTilingClient() : tile_manager_(new FakeTileManager(&tile_manager_client_)), pile_(FakePicturePileImpl::CreateInfiniteFilledPile()), twin_tiling_(NULL), + recycled_twin_tiling_(NULL), allow_create_tile_(true), max_tiles_for_interest_area_(10000), skewport_target_time_in_seconds_(1.0f), - skewport_extrapolation_limit_in_content_pixels_(2000) {} + skewport_extrapolation_limit_in_content_pixels_(2000) { +} FakePictureLayerTilingClient::FakePictureLayerTilingClient( ResourceProvider* resource_provider) @@ -28,9 +30,11 @@ FakePictureLayerTilingClient::FakePictureLayerTilingClient( new FakeTileManager(&tile_manager_client_, resource_pool_.get())), pile_(FakePicturePileImpl::CreateInfiniteFilledPile()), twin_tiling_(NULL), + recycled_twin_tiling_(NULL), allow_create_tile_(true), max_tiles_for_interest_area_(10000), - skewport_target_time_in_seconds_(1.0f) {} + skewport_target_time_in_seconds_(1.0f) { +} FakePictureLayerTilingClient::~FakePictureLayerTilingClient() { } @@ -79,6 +83,11 @@ const PictureLayerTiling* FakePictureLayerTilingClient::GetTwinTiling( return twin_tiling_; } +PictureLayerTiling* FakePictureLayerTilingClient::GetRecycledTwinTiling( + const PictureLayerTiling* tiling) { + return recycled_twin_tiling_; +} + WhichTree FakePictureLayerTilingClient::GetTree() const { return tree_; } diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h index f46cc84..edd2a61 100644 --- a/cc/test/fake_picture_layer_tiling_client.h +++ b/cc/test/fake_picture_layer_tiling_client.h @@ -36,9 +36,14 @@ class FakePictureLayerTilingClient : public PictureLayerTilingClient { virtual const Region* GetInvalidation() OVERRIDE; virtual const PictureLayerTiling* GetTwinTiling( const PictureLayerTiling* tiling) const OVERRIDE; + virtual PictureLayerTiling* GetRecycledTwinTiling( + const PictureLayerTiling* tiling) OVERRIDE; virtual WhichTree GetTree() const OVERRIDE; void set_twin_tiling(PictureLayerTiling* tiling) { twin_tiling_ = tiling; } + void set_recycled_twin_tiling(PictureLayerTiling* tiling) { + recycled_twin_tiling_ = tiling; + } void set_text_rect(const gfx::Rect& rect) { text_rect_ = rect; } void set_allow_create_tile(bool allow) { allow_create_tile_ = allow; } void set_invalidation(const Region& region) { invalidation_ = region; } @@ -64,6 +69,7 @@ class FakePictureLayerTilingClient : public PictureLayerTilingClient { scoped_refptr<PicturePileImpl> pile_; gfx::Size tile_size_; PictureLayerTiling* twin_tiling_; + PictureLayerTiling* recycled_twin_tiling_; gfx::Rect text_rect_; bool allow_create_tile_; Region invalidation_; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 705598b..dd016003 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -1168,6 +1168,12 @@ void LayerTreeHostImpl::ResetTreesForTesting() { recycle_tree_.reset(); } +void LayerTreeHostImpl::ResetRecycleTreeForTesting() { + if (recycle_tree_) + recycle_tree_->DetachLayerTree(); + recycle_tree_.reset(); +} + void LayerTreeHostImpl::EnforceManagedMemoryPolicy( const ManagedMemoryPolicy& policy) { diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 8787478..74e9896 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -217,6 +217,7 @@ class CC_EXPORT LayerTreeHostImpl // Resets all of the trees to an empty state. void ResetTreesForTesting(); + void ResetRecycleTreeForTesting(); DrawMode GetDrawMode() const; |