Cherry-pick: cc: Remove tiles from recycle tree that were deleted on active.

Cherry-pick with conflict of
crrev.com/7fceb77977afd9af22215eb9cd28ab667567668e

Conflicts:
	cc/debug/rasterize_and_record_benchmark_impl.cc
	cc/layers/picture_layer_impl_unittest.cc
	cc/resources/picture_layer_tiling.cc
	cc/resources/picture_layer_tiling_unittest.cc
	cc/test/fake_picture_layer_tiling_client.cc
	cc/test/fake_picture_layer_tiling_client.h

BUG: 16548433

Original description:

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).

Change-Id: I295cec01b476a97f68b0678d9d4322568662040f
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 3e87da0..fad8137 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -98,7 +98,7 @@
   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;
 
@@ -512,6 +512,12 @@
   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 =
@@ -601,6 +607,14 @@
   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;
 }
@@ -1237,8 +1251,7 @@
   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 c7ef303..df94b4b 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -108,6 +108,8 @@
   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;
@@ -155,6 +157,7 @@
       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 dac4ce1..cc68948 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -51,7 +51,10 @@
         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 @@
   void ActivateTree() {
     host_impl_.ActivatePendingTree();
     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_));
@@ -262,6 +267,7 @@
   FakeLayerTreeHostImpl host_impl_;
   int id_;
   FakePictureLayerImpl* pending_layer_;
+  FakePictureLayerImpl* old_pending_layer_;
   FakePictureLayerImpl* active_layer_;
 
  private:
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index 5a41951..9a7777d 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -543,6 +543,14 @@
   }
 }
 
+void PictureLayerTiling::RemoveTileAt(int i, int j) {
+  TileMapKey key(i, j);
+  TileMap::iterator found = tiles_.find(key);
+  if (found == tiles_.end())
+    return;
+  tiles_.erase(found);
+}
+
 void PictureLayerTiling::SetLiveTilesRect(
     const gfx::Rect& new_live_tiles_rect) {
   DCHECK(new_live_tiles_rect.IsEmpty() ||
@@ -551,6 +559,7 @@
     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);
@@ -560,8 +569,11 @@
     TileMap::iterator found = tiles_.find(key);
     // If the tile was outside of the recorded region, it won't exist even
     // though it was in the live rect.
-    if (found != tiles_.end())
+    if (found != tiles_.end()) {
       tiles_.erase(found);
+      if (recycled_twin)
+        recycled_twin->RemoveTileAt(iter.index_x(), iter.index_y());
+    }
   }
 
   const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index 79c5900..9c85a0e 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -35,6 +35,8 @@
   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;
@@ -269,6 +271,7 @@
                      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/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h
index 01f641a..37b9869 100644
--- a/cc/test/fake_picture_layer_impl.h
+++ b/cc/test/fake_picture_layer_impl.h
@@ -48,6 +48,7 @@
   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 dd64ac2..12239ca 100644
--- a/cc/test/fake_picture_layer_tiling_client.cc
+++ b/cc/test/fake_picture_layer_tiling_client.cc
@@ -15,10 +15,12 @@
     : 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 @@
           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() {
 }
@@ -75,4 +79,9 @@
   return twin_tiling_;
 }
 
+PictureLayerTiling* FakePictureLayerTilingClient::GetRecycledTwinTiling(
+    const PictureLayerTiling* tiling) {
+  return recycled_twin_tiling_;
+}
+
 }  // namespace cc
diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h
index 7440ea7..153dc71 100644
--- a/cc/test/fake_picture_layer_tiling_client.h
+++ b/cc/test/fake_picture_layer_tiling_client.h
@@ -38,8 +38,13 @@
   virtual const Region* GetInvalidation() OVERRIDE;
   virtual const PictureLayerTiling* GetTwinTiling(
       const PictureLayerTiling* tiling) const OVERRIDE;
+  virtual PictureLayerTiling* GetRecycledTwinTiling(
+      const PictureLayerTiling* tiling) 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 @@
   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 5b5d491..420c311 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1146,6 +1146,12 @@
   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 94055d5..3597137 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -212,6 +212,7 @@
 
   // Resets all of the trees to an empty state.
   void ResetTreesForTesting();
+  void ResetRecycleTreeForTesting();
 
   DrawMode GetDrawMode() const;