Merge "Cherry pick "Fix strict mode violations in Android."" into lmp-dev
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index f08a564..a736218 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -711,6 +711,9 @@
         FROM_HERE,
         fallback_tick_fired_.callback(),
         base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds));
+  } else {
+    // Pretend we just composited to unblock further invalidates.
+    DidComposite();
   }
 }
 
@@ -723,8 +726,12 @@
   // This should only be called if OnDraw or DrawGL did not come in time, which
   // means block_invalidates_ must still be true.
   DCHECK(block_invalidates_);
-  if (compositor_needs_continuous_invalidate_ && compositor_)
+  if (compositor_needs_continuous_invalidate_ && compositor_) {
     ForceFakeCompositeSW();
+  } else {
+    // Pretend we just composited to unblock further invalidates.
+    DidComposite();
+  }
 }
 
 void BrowserViewRenderer::ForceFakeCompositeSW() {
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 1c945f6..0e7b089 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -1389,6 +1389,9 @@
       parent_->RemoveDependentNeedsPushProperties();
 }
 
+void LayerImpl::GetAllTilesForTracing(std::set<const Tile*>* tiles) const {
+}
+
 void LayerImpl::AsValueInto(base::DictionaryValue* state) const {
   TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
       TRACE_DISABLED_BY_DEFAULT("cc.debug"),
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index cb18604..ff09e30 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -508,6 +508,7 @@
   virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl);
   virtual void PushPropertiesTo(LayerImpl* layer);
 
+  virtual void GetAllTilesForTracing(std::set<const Tile*>* tiles) const;
   scoped_ptr<base::Value> AsValue() const;
   virtual size_t GPUMemoryUsageInBytes() const;
 
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index fad8137..4a43c71 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <limits>
+#include <set>
 
 #include "base/time/time.h"
 #include "cc/base/math_util.h"
@@ -40,8 +41,6 @@
 // TileManager::BinFromTilePriority).
 const float kGpuSkewportTargetTimeInFrames = 0.0f;
 
-// Minimum width/height of a layer that would require analysis for tiles.
-const int kMinDimensionsForAnalysis = 256;
 }  // namespace
 
 namespace cc {
@@ -557,25 +556,12 @@
   if (!pile_->CanRaster(tiling->contents_scale(), content_rect))
     return scoped_refptr<Tile>();
 
-  int flags = 0;
-  // We analyze picture before rasterization to detect solid-color tiles.
-  // If the tile is detected as such there is no need to raster or upload.
-  // It is drawn directly as a solid-color quad saving memory, raster and upload
-  // cost. The analysis step is however expensive and may not be justified when
-  // doing gpu rasterization which runs on the compositor thread and where there
-  // is no upload.
-  // TODO(alokp): Revisit the decision to avoid analysis for gpu rasterization
-  // becuase it too can potentially benefit from memory savings.
-  if (!layer_tree_impl()->use_gpu_rasterization()) {
-    // Additionally, we do not want to do the analysis if the layer is too
-    // narrow, since more likely than not the tile would not be solid. Note that
-    // this last optimization is a heuristic that ensures that we don't spend
-    // too much time analyzing tiles on a multitude of small layers, as it is
-    // likely that these layers have some non-solid content.
-    int min_dimension = std::min(bounds().width(), bounds().height());
-    if (min_dimension >= kMinDimensionsForAnalysis)
-      flags |= Tile::USE_PICTURE_ANALYSIS;
-  }
+  // TODO(vmpstr): Revisit this. For now, enabling analysis means that we get as
+  // much savings on memory as we can. However, for some cases like ganesh or
+  // small layers, the amount of time we spend analyzing might not justify
+  // memory savings that we can get.
+  // Bugs: crbug.com/397198, crbug.com/396908
+  int flags = Tile::USE_PICTURE_ANALYSIS;
 
   return layer_tree_impl()->tile_manager()->CreateTile(
       pile_.get(),
@@ -1372,6 +1358,15 @@
   *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
 }
 
+void PictureLayerImpl::GetAllTilesForTracing(
+    std::set<const Tile*>* tiles) const {
+  if (!tilings_)
+    return;
+
+  for (size_t i = 0; i < tilings_->num_tilings(); ++i)
+    tilings_->tiling_at(i)->GetAllTilesForTracing(tiles);
+}
+
 void PictureLayerImpl::AsValueInto(base::DictionaryValue* state) const {
   const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
   LayerImpl::AsValueInto(state);
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index df94b4b..7908148 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -5,6 +5,7 @@
 #ifndef CC_LAYERS_PICTURE_LAYER_IMPL_H_
 #define CC_LAYERS_PICTURE_LAYER_IMPL_H_
 
+#include <set>
 #include <string>
 #include <vector>
 
@@ -171,6 +172,8 @@
 
   virtual void GetDebugBorderProperties(
       SkColor* color, float* width) const OVERRIDE;
+  virtual void GetAllTilesForTracing(
+      std::set<const Tile*>* tiles) const OVERRIDE;
   virtual void AsValueInto(base::DictionaryValue* dict) const OVERRIDE;
 
   virtual void UpdateIdealScales();
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index 9a7777d..f8f5443 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <cmath>
 #include <limits>
+#include <set>
 
 #include "base/debug/trace_event.h"
 #include "cc/base/math_util.h"
@@ -622,6 +623,12 @@
   }
 }
 
+void PictureLayerTiling::GetAllTilesForTracing(
+    std::set<const Tile*>* tiles) const {
+  for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
+    tiles->insert(it->second.get());
+}
+
 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const {
   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
   state->SetInteger("num_tiles", tiles_.size());
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index 9c85a0e..5b1201d 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -5,6 +5,7 @@
 #ifndef CC_RESOURCES_PICTURE_LAYER_TILING_H_
 #define CC_RESOURCES_PICTURE_LAYER_TILING_H_
 
+#include <set>
 #include <utility>
 #include <vector>
 
@@ -235,6 +236,7 @@
     return frame_time_in_seconds != last_impl_frame_time_in_seconds_;
   }
 
+  void GetAllTilesForTracing(std::set<const Tile*>* tiles) const;
   scoped_ptr<base::Value> AsValue() const;
   size_t GPUMemoryUsageInBytes() const;
 
diff --git a/cc/resources/tile.cc b/cc/resources/tile.cc
index d59dc02..aa78242 100644
--- a/cc/resources/tile.cc
+++ b/cc/resources/tile.cc
@@ -72,6 +72,7 @@
   res->Set("pending_priority", priority_[PENDING_TREE].AsValue().release());
   res->Set("managed_state", managed_state_.AsValue().release());
   res->SetBoolean("use_picture_analysis", use_picture_analysis());
+  res->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes());
   return res.PassAs<base::Value>();
 }
 
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index d508f6a..9b10d0b 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -701,14 +701,6 @@
   return state.PassAs<base::Value>();
 }
 
-scoped_ptr<base::Value> TileManager::AllTilesAsValue() const {
-  scoped_ptr<base::ListValue> state(new base::ListValue());
-  for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
-    state->Append(it->second->AsValue().release());
-
-  return state.PassAs<base::Value>();
-}
-
 void TileManager::AssignGpuMemoryToTiles(
     PrioritizedTileSet* tiles,
     TileVector* tiles_that_need_to_be_rasterized) {
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index 5ad8091..9792b91 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -186,7 +186,6 @@
                                  int flags);
 
   scoped_ptr<base::Value> BasicStateAsValue() const;
-  scoped_ptr<base::Value> AllTilesAsValue() const;
   const MemoryHistory::Entry& memory_stats_from_last_assign() const {
     return memory_stats_from_last_assign_;
   }
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 420c311..48184e5 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -3027,8 +3027,21 @@
       state->Set("activation_state", ActivationStateAsValue().release());
   state->Set("device_viewport_size",
              MathUtil::AsValue(device_viewport_size_).release());
-  if (tile_manager_)
-    state->Set("tiles", tile_manager_->AllTilesAsValue().release());
+
+  std::set<const Tile*> tiles;
+  active_tree_->GetAllTilesForTracing(&tiles);
+  if (pending_tree_)
+    pending_tree_->GetAllTilesForTracing(&tiles);
+ 
+  scoped_ptr<base::ListValue> tile_state(new base::ListValue());
+  for (std::set<const Tile*>::const_iterator it = tiles.begin(); it != tiles.end(); ++it)
+    tile_state->Append((*it)->AsValue().release());
+
+  state->Set("active_tiles", tile_state.release());
+ 
+  if (tile_manager_) {
+    state->Set("tile_manager_basic_state", tile_manager_->BasicStateAsValue().release());
+  }
   state->Set("active_tree", active_tree_->AsValue().release());
   if (pending_tree_)
     state->Set("pending_tree", pending_tree_->AsValue().release());
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 6bcc9fc..e625360 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -790,10 +790,25 @@
   return layer_tree_host_impl_->animation_registrar();
 }
 
+void LayerTreeImpl::GetAllTilesForTracing(std::set<const Tile*>* tiles) const {
+  typedef LayerIterator<LayerImpl> LayerIteratorType;
+  LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
+  for (LayerIteratorType it =
+           LayerIteratorType::Begin(&render_surface_layer_list_);
+       it != end;
+       ++it) {
+    if (!it.represents_itself())
+      continue;
+    LayerImpl* layer_impl = *it;
+    layer_impl->GetAllTilesForTracing(tiles);
+  }
+}
+
 scoped_ptr<base::Value> LayerTreeImpl::AsValue() const {
   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
   TracedValue::MakeDictIntoImplicitSnapshot(
       state.get(), "cc::LayerTreeImpl", this);
+  state->SetInteger("source_frame_number", source_frame_number_);
 
   state->Set("root_layer", root_layer_->AsValue().release());
 
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 55e6fb1..0dd57cf 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -6,6 +6,7 @@
 #define CC_TREES_LAYER_TREE_IMPL_H_
 
 #include <list>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -104,6 +105,7 @@
   const LayerTreeDebugState& debug_state() const;
   float device_scale_factor() const;
   DebugRectHistory* debug_rect_history() const;
+  void GetAllTilesForTracing(std::set<const Tile*>* tiles) const;
   scoped_ptr<base::Value> AsValue() const;
 
   // Other public methods