| Index: cc/layers/picture_layer_impl.cc | 
| diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc | 
| index c25bba5a98b6c108a84d64c486c7afe2c853c498..83f6ea416f23f145152fcc4352c918b39e041339 100644 | 
| --- a/cc/layers/picture_layer_impl.cc | 
| +++ b/cc/layers/picture_layer_impl.cc | 
| @@ -46,6 +46,13 @@ const int kMinDimensionsForAnalysis = 256; | 
|  | 
| namespace cc { | 
|  | 
| +PairedPictureLayer::PairedPictureLayer() | 
| +    : active_layer(NULL), pending_layer(NULL) { | 
| +} | 
| + | 
| +PairedPictureLayer::~PairedPictureLayer() { | 
| +} | 
| + | 
| PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id) | 
| : LayerImpl(tree_impl, id), | 
| twin_layer_(NULL), | 
| @@ -86,15 +93,6 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { | 
| DoPostCommitInitializationIfNeeded(); | 
| 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 | 
| @@ -217,10 +215,10 @@ void PictureLayerImpl::AppendQuads( | 
| } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) { | 
| color = DebugColors::PictureTileBorderColor(); | 
| width = DebugColors::PictureTileBorderWidth(layer_tree_impl()); | 
| -        } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) { | 
| +        } else if (iter.resolution() == HIGH_RESOLUTION) { | 
| color = DebugColors::HighResTileBorderColor(); | 
| width = DebugColors::HighResTileBorderWidth(layer_tree_impl()); | 
| -        } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) { | 
| +        } else if (iter.resolution() == LOW_RESOLUTION) { | 
| color = DebugColors::LowResTileBorderColor(); | 
| width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); | 
| } else if (iter->contents_scale() > max_contents_scale) { | 
| @@ -359,7 +357,7 @@ void PictureLayerImpl::AppendQuads( | 
| continue; | 
| } | 
|  | 
| -    if (iter->priority(ACTIVE_TREE).resolution != HIGH_RESOLUTION) { | 
| +    if (iter.resolution() != HIGH_RESOLUTION) { | 
| append_quads_data->approximated_visible_content_area += | 
| visible_geometry_rect.width() * visible_geometry_rect.height(); | 
| } | 
| @@ -435,9 +433,6 @@ void PictureLayerImpl::UpdateTiles( | 
| should_update_tile_priorities_ = true; | 
|  | 
| UpdateTilePriorities(occlusion_tracker); | 
| - | 
| -  if (layer_tree_impl()->IsPendingTree()) | 
| -    MarkVisibleResourcesAsRequired(); | 
| } | 
|  | 
| void PictureLayerImpl::UpdateTilePriorities( | 
| @@ -600,6 +595,16 @@ int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const { | 
| .skewport_extrapolation_limit_in_content_pixels; | 
| } | 
|  | 
| +bool PictureLayerImpl::RequiresHighResToDraw() const { | 
| +  const PictureLayerImpl* layer = this; | 
| +  if (GetTree() == PENDING_TREE) | 
| +    layer = twin_layer_; | 
| + | 
| +  if (layer) | 
| +    return layer->layer_tree_impl()->RequiresHighResToDraw(); | 
| +  return false; | 
| +} | 
| + | 
| gfx::Size PictureLayerImpl::CalculateTileSize( | 
| const gfx::Size& content_bounds) const { | 
| if (is_mask_) { | 
| @@ -754,159 +759,6 @@ ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const { | 
| return tile_version.get_resource_id(); | 
| } | 
|  | 
| -void PictureLayerImpl::MarkVisibleResourcesAsRequired() const { | 
| -  DCHECK(layer_tree_impl()->IsPendingTree()); | 
| -  DCHECK(ideal_contents_scale_); | 
| -  DCHECK_GT(tilings_->num_tilings(), 0u); | 
| - | 
| -  // The goal of this function is to find the minimum set of tiles that need to | 
| -  // be ready to draw in order to activate without flashing content from a | 
| -  // higher res on the active tree to a lower res on the pending tree. | 
| - | 
| -  // First, early out for layers with no visible content. | 
| -  if (visible_content_rect().IsEmpty()) | 
| -    return; | 
| - | 
| -  gfx::Rect rect(visible_content_rect()); | 
| - | 
| -  float min_acceptable_scale = | 
| -      std::min(raster_contents_scale_, ideal_contents_scale_); | 
| - | 
| -  if (PictureLayerImpl* twin = twin_layer_) { | 
| -    float twin_min_acceptable_scale = | 
| -        std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_); | 
| -    // Ignore 0 scale in case CalculateContentsScale() has never been | 
| -    // called for active twin. | 
| -    if (twin_min_acceptable_scale != 0.0f) { | 
| -      min_acceptable_scale = | 
| -          std::min(min_acceptable_scale, twin_min_acceptable_scale); | 
| -    } | 
| -  } | 
| - | 
| -  PictureLayerTiling* high_res = NULL; | 
| -  PictureLayerTiling* low_res = NULL; | 
| - | 
| -  // First pass: ready to draw tiles in acceptable but non-ideal tilings are | 
| -  // marked as required for activation so that their textures are not thrown | 
| -  // away; any non-ready tiles are not marked as required. | 
| -  Region missing_region = rect; | 
| -  for (size_t i = 0; i < tilings_->num_tilings(); ++i) { | 
| -    PictureLayerTiling* tiling = tilings_->tiling_at(i); | 
| -    DCHECK(tiling->has_ever_been_updated()); | 
| - | 
| -    if (tiling->resolution() == LOW_RESOLUTION) { | 
| -      DCHECK(!low_res) << "There can only be one low res tiling"; | 
| -      low_res = tiling; | 
| -    } | 
| -    if (tiling->contents_scale() < min_acceptable_scale) | 
| -      continue; | 
| -    if (tiling->resolution() == HIGH_RESOLUTION) { | 
| -      DCHECK(!high_res) << "There can only be one high res tiling"; | 
| -      high_res = tiling; | 
| -      continue; | 
| -    } | 
| -    for (PictureLayerTiling::CoverageIterator iter(tiling, | 
| -                                                   contents_scale_x(), | 
| -                                                   rect); | 
| -         iter; | 
| -         ++iter) { | 
| -      if (!*iter || !iter->IsReadyToDraw()) | 
| -        continue; | 
| - | 
| -      missing_region.Subtract(iter.geometry_rect()); | 
| -      iter->MarkRequiredForActivation(); | 
| -    } | 
| -  } | 
| -  DCHECK(high_res) << "There must be one high res tiling"; | 
| - | 
| -  // If these pointers are null (because no twin, no matching tiling, or the | 
| -  // simpification just below), then high res tiles will be required to fill any | 
| -  // holes left by the first pass above.  If the pointers are valid, then this | 
| -  // layer is allowed to skip any tiles that are not ready on its twin. | 
| -  const PictureLayerTiling* twin_high_res = NULL; | 
| -  const PictureLayerTiling* twin_low_res = NULL; | 
| - | 
| -  if (twin_layer_) { | 
| -    // As a simplification, only allow activating to skip twin tiles that the | 
| -    // active layer is also missing when both this layer and its twin have | 
| -    // "simple" sets of tilings: only 2 tilings (high and low) or only 1 high | 
| -    // res tiling. This avoids having to iterate/track coverage of non-ideal | 
| -    // tilings during the last draw call on the active layer. | 
| -    if (tilings_->num_tilings() <= 2 && | 
| -        twin_layer_->tilings_->num_tilings() <= tilings_->num_tilings()) { | 
| -      twin_low_res = low_res ? GetTwinTiling(low_res) : NULL; | 
| -      twin_high_res = high_res ? GetTwinTiling(high_res) : NULL; | 
| -    } | 
| - | 
| -    // If this layer and its twin have different transforms, then don't compare | 
| -    // them and only allow activating to high res tiles, since tiles on each | 
| -    // layer will be in different places on screen. | 
| -    if (twin_layer_->layer_tree_impl()->RequiresHighResToDraw() || | 
| -        bounds() != twin_layer_->bounds() || | 
| -        draw_properties().screen_space_transform != | 
| -            twin_layer_->draw_properties().screen_space_transform) { | 
| -      twin_high_res = NULL; | 
| -      twin_low_res = NULL; | 
| -    } | 
| -  } | 
| - | 
| -  // As a second pass, mark as required any visible high res tiles not filled in | 
| -  // by acceptable non-ideal tiles from the first pass. | 
| -  if (MarkVisibleTilesAsRequired( | 
| -      high_res, twin_high_res, contents_scale_x(), rect, missing_region)) { | 
| -    // As an optional third pass, if a high res tile was skipped because its | 
| -    // twin was also missing, then fall back to mark low res tiles as required | 
| -    // in case the active twin is substituting those for missing high res | 
| -    // content. Only suitable, when low res is enabled. | 
| -    if (low_res) { | 
| -      MarkVisibleTilesAsRequired( | 
| -          low_res, twin_low_res, contents_scale_x(), rect, missing_region); | 
| -    } | 
| -  } | 
| -} | 
| - | 
| -bool PictureLayerImpl::MarkVisibleTilesAsRequired( | 
| -    PictureLayerTiling* tiling, | 
| -    const PictureLayerTiling* optional_twin_tiling, | 
| -    float contents_scale, | 
| -    const gfx::Rect& rect, | 
| -    const Region& missing_region) const { | 
| -  bool twin_had_missing_tile = false; | 
| -  for (PictureLayerTiling::CoverageIterator iter(tiling, | 
| -                                                 contents_scale, | 
| -                                                 rect); | 
| -       iter; | 
| -       ++iter) { | 
| -    Tile* tile = *iter; | 
| -    // A null tile (i.e. missing recording) can just be skipped. | 
| -    if (!tile) | 
| -      continue; | 
| - | 
| -    // If the tile is occluded, don't mark it as required for activation. | 
| -    if (tile->is_occluded(PENDING_TREE)) | 
| -      continue; | 
| - | 
| -    // If the missing region doesn't cover it, this tile is fully | 
| -    // covered by acceptable tiles at other scales. | 
| -    if (!missing_region.Intersects(iter.geometry_rect())) | 
| -      continue; | 
| - | 
| -    // If the twin tile doesn't exist (i.e. missing recording or so far away | 
| -    // that it is outside the visible tile rect) or this tile is shared between | 
| -    // with the twin, then this tile isn't required to prevent flashing. | 
| -    if (optional_twin_tiling) { | 
| -      Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j()); | 
| -      if (!twin_tile || twin_tile == tile) { | 
| -        twin_had_missing_tile = true; | 
| -        continue; | 
| -      } | 
| -    } | 
| - | 
| -    tile->MarkRequiredForActivation(); | 
| -  } | 
| -  return twin_had_missing_tile; | 
| -} | 
| - | 
| void PictureLayerImpl::DoPostCommitInitialization() { | 
| DCHECK(needs_post_commit_initialization_); | 
| DCHECK(layer_tree_impl()->IsPendingTree()); | 
|  |