summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorvmpstr <vmpstr@chromium.org>2014-08-26 11:51:52 -0700
committerCommit bot <commit-bot@chromium.org>2014-08-26 18:59:35 +0000
commit7fceb77977afd9af22215eb9cd28ab667567668e (patch)
treeaa487b33e9a6b81dd5d2c5c2b0287eef5bf4278e /cc
parentaa7e9b61d69dfa8e0a1557d900037bfb8b1e6e78 (diff)
downloadchromium_src-7fceb77977afd9af22215eb9cd28ab667567668e.zip
chromium_src-7fceb77977afd9af22215eb9cd28ab667567668e.tar.gz
chromium_src-7fceb77977afd9af22215eb9cd28ab667567668e.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). R=danakj, enne Review URL: https://codereview.chromium.org/502453003 Cr-Commit-Position: refs/heads/master@{#291949}
Diffstat (limited to 'cc')
-rw-r--r--cc/debug/rasterize_and_record_benchmark_impl.cc5
-rw-r--r--cc/layers/picture_layer_impl.cc19
-rw-r--r--cc/layers/picture_layer_impl.h3
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc34
-rw-r--r--cc/resources/picture_layer_tiling.cc12
-rw-r--r--cc/resources/picture_layer_tiling.h3
-rw-r--r--cc/resources/picture_layer_tiling_unittest.cc83
-rw-r--r--cc/test/fake_picture_layer_impl.h1
-rw-r--r--cc/test/fake_picture_layer_tiling_client.cc13
-rw-r--r--cc/test/fake_picture_layer_tiling_client.h6
-rw-r--r--cc/trees/layer_tree_host_impl.cc6
-rw-r--r--cc/trees/layer_tree_host_impl.h1
12 files changed, 180 insertions, 6 deletions
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc
index aee0271..d0a4726 100644
--- a/cc/debug/rasterize_and_record_benchmark_impl.cc
+++ b/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -118,6 +118,11 @@ class FixedInvalidationPictureLayerTilingClient
return base_client_->GetTwinTiling(tiling);
}
+ virtual PictureLayerTiling* GetRecycledTwinTiling(
+ const PictureLayerTiling* tiling) OVERRIDE {
+ return base_client_->GetRecycledTwinTiling(tiling);
+ }
+
virtual size_t GetMaxTilesForInterestArea() const OVERRIDE {
return base_client_->GetMaxTilesForInterestArea();
}
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index fb8f701..b3a095f 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -109,7 +109,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;
@@ -541,6 +541,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 =
@@ -613,6 +619,14 @@ const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
return twin_layer_->tilings_->TilingAtScale(tiling->contents_scale());
}
+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;
}
@@ -1253,8 +1267,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 f9b2dbb..f9845be 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 ca4306c..9e80f92 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -53,7 +53,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()),
@@ -86,6 +89,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_));
@@ -266,6 +271,7 @@ class PictureLayerImplTest : public testing::Test {
FakeLayerTreeHostImpl host_impl_;
int id_;
FakePictureLayerImpl* pending_layer_;
+ FakePictureLayerImpl* old_pending_layer_;
FakePictureLayerImpl* active_layer_;
private:
@@ -4145,5 +4151,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 e7a5158..b302873 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -607,6 +607,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() ||
@@ -617,6 +626,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);
@@ -629,6 +639,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 415ad42..f2e5e73 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;
@@ -295,6 +297,7 @@ class CC_EXPORT PictureLayerTiling {
PictureLayerTilingClient* client);
void SetLiveTilesRect(const gfx::Rect& live_tiles_rect);
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 a8caf489..01d2f32 100644
--- a/cc/resources/picture_layer_tiling_unittest.cc
+++ b/cc/resources/picture_layer_tiling_unittest.cc
@@ -1948,5 +1948,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 1efb35c..915b740 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 e8d9142d..a6d50c6 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1167,6 +1167,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 f33a19b..3a1509f 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;