| Index: cc/resources/picture_layer_tiling_set.cc
 | 
| diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
 | 
| index 51896a5b5f7f29cfb287e970fb8b301aaa4b83a0..a3348bc72d350f608c21555cef7a60ed9da5c727 100644
 | 
| --- a/cc/resources/picture_layer_tiling_set.cc
 | 
| +++ b/cc/resources/picture_layer_tiling_set.cc
 | 
| @@ -29,26 +29,98 @@ inline float LargerRatio(float float1, float float2) {
 | 
|  
 | 
|  // static
 | 
|  scoped_ptr<PictureLayerTilingSet> PictureLayerTilingSet::Create(
 | 
| -    PictureLayerTilingClient* client) {
 | 
| -  return make_scoped_ptr(new PictureLayerTilingSet(client));
 | 
| -}
 | 
| -
 | 
| -PictureLayerTilingSet::PictureLayerTilingSet(PictureLayerTilingClient* client)
 | 
| -    : client_(client) {
 | 
| +    PictureLayerTilingClient* client,
 | 
| +    size_t max_tiles_for_interest_area,
 | 
| +    float skewport_target_time_in_seconds,
 | 
| +    int skewport_extrapolation_limit_in_content_pixels) {
 | 
| +  return make_scoped_ptr(new PictureLayerTilingSet(
 | 
| +      client, max_tiles_for_interest_area, skewport_target_time_in_seconds,
 | 
| +      skewport_extrapolation_limit_in_content_pixels));
 | 
| +}
 | 
| +
 | 
| +PictureLayerTilingSet::PictureLayerTilingSet(
 | 
| +    PictureLayerTilingClient* client,
 | 
| +    size_t max_tiles_for_interest_area,
 | 
| +    float skewport_target_time_in_seconds,
 | 
| +    int skewport_extrapolation_limit_in_content_pixels)
 | 
| +    : max_tiles_for_interest_area_(max_tiles_for_interest_area),
 | 
| +      skewport_target_time_in_seconds_(skewport_target_time_in_seconds),
 | 
| +      skewport_extrapolation_limit_in_content_pixels_(
 | 
| +          skewport_extrapolation_limit_in_content_pixels),
 | 
| +      client_(client) {
 | 
|  }
 | 
|  
 | 
|  PictureLayerTilingSet::~PictureLayerTilingSet() {
 | 
|  }
 | 
|  
 | 
| -void PictureLayerTilingSet::SetClient(PictureLayerTilingClient* client) {
 | 
| -  client_ = client;
 | 
| -  for (size_t i = 0; i < tilings_.size(); ++i)
 | 
| -    tilings_[i]->SetClient(client_);
 | 
| -}
 | 
| +void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSource(
 | 
| +    RasterSource* raster_source,
 | 
| +    const PictureLayerTilingSet* twin_set,
 | 
| +    const gfx::Size& layer_bounds,
 | 
| +    const Region& layer_invalidation,
 | 
| +    float minimum_contents_scale) {
 | 
| +  RemoveTilingsBelowScale(minimum_contents_scale);
 | 
|  
 | 
| -void PictureLayerTilingSet::RemoveTilesInRegion(const Region& region) {
 | 
| -  for (size_t i = 0; i < tilings_.size(); ++i)
 | 
| -    tilings_[i]->RemoveTilesInRegion(region);
 | 
| +  // Copy over tilings that are shared with the |twin_set| tiling set (if it
 | 
| +  // exists).
 | 
| +  if (twin_set) {
 | 
| +    for (PictureLayerTiling* twin_tiling : twin_set->tilings_) {
 | 
| +      float contents_scale = twin_tiling->contents_scale();
 | 
| +      DCHECK_GE(contents_scale, minimum_contents_scale);
 | 
| +
 | 
| +      PictureLayerTiling* this_tiling = FindTilingWithScale(contents_scale);
 | 
| +      if (!this_tiling) {
 | 
| +        scoped_ptr<PictureLayerTiling> new_tiling = PictureLayerTiling::Create(
 | 
| +            contents_scale, layer_bounds, client_, max_tiles_for_interest_area_,
 | 
| +            skewport_target_time_in_seconds_,
 | 
| +            skewport_extrapolation_limit_in_content_pixels_);
 | 
| +        tilings_.push_back(new_tiling.Pass());
 | 
| +        this_tiling = tilings_.back();
 | 
| +      }
 | 
| +      this_tiling->CloneTilesAndPropertiesFrom(*twin_tiling);
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  // For unshared tilings, invalidate tiles and update them to the new raster
 | 
| +  // source.
 | 
| +  for (PictureLayerTiling* tiling : tilings_) {
 | 
| +    if (twin_set && twin_set->FindTilingWithScale(tiling->contents_scale()))
 | 
| +      continue;
 | 
| +
 | 
| +    tiling->Resize(layer_bounds);
 | 
| +    tiling->Invalidate(layer_invalidation);
 | 
| +    tiling->SetRasterSource(raster_source);
 | 
| +    // This is needed for cases where the live tiles rect didn't change but
 | 
| +    // recordings exist in the raster source that did not exist on the last
 | 
| +    // raster source.
 | 
| +    tiling->CreateMissingTilesInLiveTilesRect();
 | 
| +
 | 
| +    // If |twin_set| is present, use the resolutions from there. Otherwise leave
 | 
| +    // all resolutions as they are.
 | 
| +    if (twin_set)
 | 
| +      tiling->set_resolution(NON_IDEAL_RESOLUTION);
 | 
| +  }
 | 
| +
 | 
| +  tilings_.sort(LargestToSmallestScaleFunctor());
 | 
| +
 | 
| +#if DCHECK_IS_ON
 | 
| +  for (PictureLayerTiling* tiling : tilings_) {
 | 
| +    DCHECK(tiling->tile_size() ==
 | 
| +           client_->CalculateTileSize(tiling->tiling_size()))
 | 
| +        << "tile_size: " << tiling->tile_size().ToString()
 | 
| +        << " tiling_size: " << tiling->tiling_size().ToString()
 | 
| +        << " CalculateTileSize: "
 | 
| +        << client_->CalculateTileSize(tiling->tiling_size()).ToString();
 | 
| +  }
 | 
| +
 | 
| +  if (!tilings_.empty()) {
 | 
| +    size_t num_high_res = std::count_if(tilings_.begin(), tilings_.end(),
 | 
| +                                        [](PictureLayerTiling* tiling) {
 | 
| +      return tiling->resolution() == HIGH_RESOLUTION;
 | 
| +    });
 | 
| +    DCHECK_EQ(1u, num_high_res);
 | 
| +  }
 | 
| +#endif
 | 
|  }
 | 
|  
 | 
|  void PictureLayerTilingSet::CleanUpTilings(
 | 
| @@ -91,14 +163,6 @@ void PictureLayerTilingSet::CleanUpTilings(
 | 
|    }
 | 
|  
 | 
|    for (auto* tiling : to_remove) {
 | 
| -    PictureLayerTiling* twin_tiling =
 | 
| -        twin_set ? twin_set->FindTilingWithScale(tiling->contents_scale())
 | 
| -                 : nullptr;
 | 
| -    // Only remove tilings from the twin layer if they have
 | 
| -    // NON_IDEAL_RESOLUTION.
 | 
| -    if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
 | 
| -      twin_set->Remove(twin_tiling);
 | 
| -
 | 
|      PictureLayerTiling* recycled_twin_tiling =
 | 
|          recycled_twin_set
 | 
|              ? recycled_twin_set->FindTilingWithScale(tiling->contents_scale())
 | 
| @@ -113,16 +177,24 @@ void PictureLayerTilingSet::CleanUpTilings(
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +void PictureLayerTilingSet::RemoveNonIdealTilings() {
 | 
| +  auto to_remove = tilings_.remove_if([](PictureLayerTiling* t) {
 | 
| +    return t->resolution() == NON_IDEAL_RESOLUTION;
 | 
| +  });
 | 
| +  tilings_.erase(to_remove, tilings_.end());
 | 
| +}
 | 
| +
 | 
|  void PictureLayerTilingSet::MarkAllTilingsNonIdeal() {
 | 
|    for (auto* tiling : tilings_)
 | 
|      tiling->set_resolution(NON_IDEAL_RESOLUTION);
 | 
|  }
 | 
|  
 | 
| -bool PictureLayerTilingSet::SyncTilings(const PictureLayerTilingSet& other,
 | 
| -                                        const gfx::Size& new_layer_bounds,
 | 
| -                                        const Region& layer_invalidation,
 | 
| -                                        float minimum_contents_scale,
 | 
| -                                        RasterSource* raster_source) {
 | 
| +bool PictureLayerTilingSet::SyncTilingsForTesting(
 | 
| +    const PictureLayerTilingSet& other,
 | 
| +    const gfx::Size& new_layer_bounds,
 | 
| +    const Region& layer_invalidation,
 | 
| +    float minimum_contents_scale,
 | 
| +    RasterSource* raster_source) {
 | 
|    if (new_layer_bounds.IsEmpty()) {
 | 
|      RemoveAllTilings();
 | 
|      return false;
 | 
| @@ -151,8 +223,9 @@ bool PictureLayerTilingSet::SyncTilings(const PictureLayerTilingSet& other,
 | 
|      if (PictureLayerTiling* this_tiling = FindTilingWithScale(contents_scale)) {
 | 
|        this_tiling->set_resolution(other.tilings_[i]->resolution());
 | 
|  
 | 
| -      this_tiling->UpdateTilesToCurrentRasterSource(
 | 
| -          raster_source, layer_invalidation, new_layer_bounds);
 | 
| +      this_tiling->Resize(new_layer_bounds);
 | 
| +      this_tiling->Invalidate(layer_invalidation);
 | 
| +      this_tiling->SetRasterSource(raster_source);
 | 
|        this_tiling->CreateMissingTilesInLiveTilesRect();
 | 
|        if (this_tiling->resolution() == HIGH_RESOLUTION)
 | 
|          have_high_res_tiling = true;
 | 
| @@ -166,9 +239,9 @@ bool PictureLayerTilingSet::SyncTilings(const PictureLayerTilingSet& other,
 | 
|        continue;
 | 
|      }
 | 
|      scoped_ptr<PictureLayerTiling> new_tiling = PictureLayerTiling::Create(
 | 
| -        contents_scale,
 | 
| -        new_layer_bounds,
 | 
| -        client_);
 | 
| +        contents_scale, new_layer_bounds, client_, max_tiles_for_interest_area_,
 | 
| +        skewport_target_time_in_seconds_,
 | 
| +        skewport_extrapolation_limit_in_content_pixels_);
 | 
|      new_tiling->set_resolution(other.tilings_[i]->resolution());
 | 
|      if (new_tiling->resolution() == HIGH_RESOLUTION)
 | 
|        have_high_res_tiling = true;
 | 
| @@ -185,8 +258,10 @@ PictureLayerTiling* PictureLayerTilingSet::AddTiling(
 | 
|    for (size_t i = 0; i < tilings_.size(); ++i)
 | 
|      DCHECK_NE(tilings_[i]->contents_scale(), contents_scale);
 | 
|  
 | 
| -  tilings_.push_back(
 | 
| -      PictureLayerTiling::Create(contents_scale, layer_bounds, client_));
 | 
| +  tilings_.push_back(PictureLayerTiling::Create(
 | 
| +      contents_scale, layer_bounds, client_, max_tiles_for_interest_area_,
 | 
| +      skewport_target_time_in_seconds_,
 | 
| +      skewport_extrapolation_limit_in_content_pixels_));
 | 
|    PictureLayerTiling* appended = tilings_.back();
 | 
|  
 | 
|    tilings_.sort(LargestToSmallestScaleFunctor());
 | 
| @@ -222,6 +297,14 @@ PictureLayerTiling* PictureLayerTilingSet::FindTilingWithResolution(
 | 
|    return *iter;
 | 
|  }
 | 
|  
 | 
| +void PictureLayerTilingSet::RemoveTilingsBelowScale(float minimum_scale) {
 | 
| +  auto to_remove =
 | 
| +      tilings_.remove_if([minimum_scale](PictureLayerTiling* tiling) {
 | 
| +        return tiling->contents_scale() < minimum_scale;
 | 
| +      });
 | 
| +  tilings_.erase(to_remove, tilings_.end());
 | 
| +}
 | 
| +
 | 
|  void PictureLayerTilingSet::RemoveAllTilings() {
 | 
|    tilings_.clear();
 | 
|  }
 | 
| 
 |