Cherry-pick: (Reland) cc: Remove recycled tilings when active tree removes them.

Clean cherry-pick of crrev.com/285114

BUG: 16548433

Original description:

This patch is the second part of ensuring that recycle tree does not
contain any unshared tiles.

This is done by removing recycle tree tilings when active tree removes
those tilings.

This includes a check in RemoveTilings for NULL tilings. When the first
pending tree activates, it swaps with active tree's NULL tilings, which
become the recycle tilings. When removing tilings, we have to ensure
that tilings is not NULL before accessing its members.

Change-Id: I29b3c0514cac1fc8f31251ff00f65a82631eaf65
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 15dd95c..3e87da0 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -963,6 +963,9 @@
 }
 
 void PictureLayerImpl::RemoveTiling(float contents_scale) {
+  if (!tilings_ || tilings_->num_tilings() == 0)
+    return;
+
   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
     PictureLayerTiling* tiling = tilings_->tiling_at(i);
     if (tiling->contents_scale() == contents_scale) {
@@ -1231,18 +1234,28 @@
     to_remove.push_back(tiling);
   }
 
+  if (to_remove.empty())
+    return;
+
+  PictureLayerImpl* recycled_twin = static_cast<PictureLayerImpl*>(
+      layer_tree_impl()->FindRecycleTreeLayerById(id()));
+  // 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]);
     // Only remove tilings from the twin layer if they have
     // NON_IDEAL_RESOLUTION.
     if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
       twin->RemoveTiling(to_remove[i]->contents_scale());
+    // Remove the tiling from the recycle tree. Note that we ignore resolution,
+    // since we don't need to maintain high/low res on the recycle tree.
+    if (recycled_twin)
+      recycled_twin->RemoveTiling(to_remove[i]->contents_scale());
     // TODO(enne): temporary sanity CHECK for http://crbug.com/358350
     CHECK_NE(HIGH_RESOLUTION, to_remove[i]->resolution());
     tilings_->Remove(to_remove[i]);
   }
-  DCHECK_GT(tilings_->num_tilings(), 0u);
 
+  DCHECK_GT(tilings_->num_tilings(), 0u);
   SanityCheckTilingState();
 }
 
@@ -1291,6 +1304,10 @@
 
 void PictureLayerImpl::SanityCheckTilingState() const {
 #if DCHECK_IS_ON
+  // Recycle tree doesn't have any restrictions.
+  if (layer_tree_impl()->IsRecycleTree())
+    return;
+
   if (!CanHaveTilings()) {
     DCHECK_EQ(0u, tilings_->num_tilings());
     return;
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index d1a6e33..94055d5 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -299,6 +299,7 @@
   const LayerTreeImpl* active_tree() const { return active_tree_.get(); }
   LayerTreeImpl* pending_tree() { return pending_tree_.get(); }
   const LayerTreeImpl* pending_tree() const { return pending_tree_.get(); }
+  LayerTreeImpl* recycle_tree() { return recycle_tree_.get(); }
   const LayerTreeImpl* recycle_tree() const { return recycle_tree_.get(); }
   // Returns the tree LTH synchronizes with.
   LayerTreeImpl* sync_tree() {
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 9ca3308..6bcc9fc 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -693,6 +693,13 @@
   return tree->LayerById(id);
 }
 
+LayerImpl* LayerTreeImpl::FindRecycleTreeLayerById(int id) {
+  LayerTreeImpl* tree = layer_tree_host_impl_->recycle_tree();
+  if (!tree)
+    return NULL;
+  return tree->LayerById(id);
+}
+
 int LayerTreeImpl::MaxTextureSize() const {
   return layer_tree_host_impl_->GetRendererCapabilities().max_texture_size;
 }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 47f3ce1..55e6fb1 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -80,6 +80,7 @@
   bool IsRecycleTree() const;
   LayerImpl* FindActiveTreeLayerById(int id);
   LayerImpl* FindPendingTreeLayerById(int id);
+  LayerImpl* FindRecycleTreeLayerById(int id);
   int MaxTextureSize() const;
   bool PinchGestureActive() const;
   base::TimeTicks CurrentFrameTimeTicks() const;