Cherry-pick: CC: Ensure recycle tree contains no 'active' tiles.

Cherry-pick of Chromium crrev.com/r226318

Conflicts:
	cc/layers/picture_layer_impl.cc

BUG: 11446261

Original description:

Active tilings become recycle tilings due to our tiling-swap
while activating. But some active tiles exist that are not
in the pending tree (due to invalidation).

We need to remove these tiles or reset their priorities,
as otherwise they will just take up memory in the Tile-
Manager.

This adds DidBecomeRecycled, which resets all active
priorities. Combined with DidBecomeActive, this should
eliminate any 'old active tiles' (that were active and were
invalidated) from being prioritized in the TileManager.

Change-Id: I9ecff16ebb3e7f94f341d6775db7cc1e970ecf95
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 124871c..bda2429 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -66,10 +66,19 @@
 }
 
 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
-  LayerImpl::PushPropertiesTo(base_layer);
-
   PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
 
+  // We have already synced the important bits from the the active layer, and
+  // we will soon swap out its tilings and use them for recycling. However,
+  // there are now tiles in this layer's tilings that were unref'd and replaced
+  // with new tiles (due to invalidation). This resets all active priorities on
+  // the to-be-recycled tiling to ensure replaced tiles don't linger and take
+  // memory (due to a stale 'active' priority).
+  if (layer_impl->tilings_)
+    layer_impl->tilings_->DidBecomeRecycled();
+
+  LayerImpl::PushPropertiesTo(base_layer);
+
   // When the pending tree pushes to the active tree, the pending twin
   // disappears.
   layer_impl->twin_layer_ = NULL;
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index 12bfb18..c0a10aa 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -648,6 +648,16 @@
   live_tiles_rect_ = new_live_tiles_rect;
 }
 
+void PictureLayerTiling::DidBecomeRecycled() {
+  // DidBecomeActive below will set the active priority for tiles that are
+  // still in the tree. Calling this first on an active tiling that is becoming
+  // recycled takes care of tiles that are no longer in the active tree (eg.
+  // due to a pending invalidation).
+  for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
+    it->second->SetPriority(ACTIVE_TREE, TilePriority());
+  }
+}
+
 void PictureLayerTiling::DidBecomeActive() {
   for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
     it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE));
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index 973fa50..9be1d6d 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -147,6 +147,13 @@
   // also updates the pile on each tile to be the current client's pile.
   void DidBecomeActive();
 
+  // Resets the active priority for all tiles in a tiling, when an active
+  // tiling is becoming recycled. This may include some tiles which are
+  // not in the the pending tiling (due to invalidations). This must
+  // be called before DidBecomeActive, as it resets the active priority
+  // while DidBecomeActive promotes pending priority on a similar set of tiles.
+  void DidBecomeRecycled();
+
   void UpdateTilesToCurrentPile();
 
   bool NeedsUpdateForFrameAtTime(double frame_time_in_seconds) {
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
index 1b0cb5f..5f76052 100644
--- a/cc/resources/picture_layer_tiling_set.cc
+++ b/cc/resources/picture_layer_tiling_set.cc
@@ -334,6 +334,11 @@
     tilings_[i]->DidBecomeActive();
 }
 
+void PictureLayerTilingSet::DidBecomeRecycled() {
+  for (size_t i = 0; i < tilings_.size(); ++i)
+    tilings_[i]->DidBecomeRecycled();
+}
+
 scoped_ptr<base::Value> PictureLayerTilingSet::AsValue() const {
   scoped_ptr<base::ListValue> state(new base::ListValue());
   for (size_t i = 0; i < tilings_.size(); ++i)
diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h
index e498cb9..c43850a 100644
--- a/cc/resources/picture_layer_tiling_set.h
+++ b/cc/resources/picture_layer_tiling_set.h
@@ -68,6 +68,7 @@
       size_t max_tiles_for_interest_area);
 
   void DidBecomeActive();
+  void DidBecomeRecycled();
 
   // For a given rect, iterates through tiles that can fill it.  If no
   // set of tiles with resources can fill the rect, then it will iterate