Home | History | Annotate | Download | only in layers
      1 // Copyright 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/layers/picture_layer_impl.h"
      6 
      7 #include <algorithm>
      8 #include <limits>
      9 #include <set>
     10 
     11 #include "base/debug/trace_event_argument.h"
     12 #include "base/time/time.h"
     13 #include "cc/base/math_util.h"
     14 #include "cc/base/util.h"
     15 #include "cc/debug/debug_colors.h"
     16 #include "cc/debug/micro_benchmark_impl.h"
     17 #include "cc/debug/traced_value.h"
     18 #include "cc/layers/append_quads_data.h"
     19 #include "cc/layers/solid_color_layer_impl.h"
     20 #include "cc/output/begin_frame_args.h"
     21 #include "cc/quads/checkerboard_draw_quad.h"
     22 #include "cc/quads/debug_border_draw_quad.h"
     23 #include "cc/quads/picture_draw_quad.h"
     24 #include "cc/quads/solid_color_draw_quad.h"
     25 #include "cc/quads/tile_draw_quad.h"
     26 #include "cc/resources/tile_manager.h"
     27 #include "cc/trees/layer_tree_impl.h"
     28 #include "cc/trees/occlusion_tracker.h"
     29 #include "ui/gfx/quad_f.h"
     30 #include "ui/gfx/rect_conversions.h"
     31 #include "ui/gfx/size_conversions.h"
     32 
     33 namespace {
     34 const float kMaxScaleRatioDuringPinch = 2.0f;
     35 
     36 // When creating a new tiling during pinch, snap to an existing
     37 // tiling's scale if the desired scale is within this ratio.
     38 const float kSnapToExistingTilingRatio = 1.2f;
     39 
     40 // Estimate skewport 60 frames ahead for pre-rasterization on the CPU.
     41 const float kCpuSkewportTargetTimeInFrames = 60.0f;
     42 
     43 // Don't pre-rasterize on the GPU (except for kBackflingGuardDistancePixels in
     44 // TileManager::BinFromTilePriority).
     45 const float kGpuSkewportTargetTimeInFrames = 0.0f;
     46 
     47 }  // namespace
     48 
     49 namespace cc {
     50 
     51 PictureLayerImpl::Pair::Pair() : active(NULL), pending(NULL) {
     52 }
     53 
     54 PictureLayerImpl::Pair::Pair(PictureLayerImpl* active_layer,
     55                              PictureLayerImpl* pending_layer)
     56     : active(active_layer), pending(pending_layer) {
     57 }
     58 
     59 PictureLayerImpl::Pair::~Pair() {
     60 }
     61 
     62 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
     63     : LayerImpl(tree_impl, id),
     64       twin_layer_(NULL),
     65       pile_(PicturePileImpl::Create()),
     66       ideal_page_scale_(0.f),
     67       ideal_device_scale_(0.f),
     68       ideal_source_scale_(0.f),
     69       ideal_contents_scale_(0.f),
     70       raster_page_scale_(0.f),
     71       raster_device_scale_(0.f),
     72       raster_source_scale_(0.f),
     73       raster_contents_scale_(0.f),
     74       low_res_raster_contents_scale_(0.f),
     75       raster_source_scale_is_fixed_(false),
     76       was_screen_space_transform_animating_(false),
     77       needs_post_commit_initialization_(true),
     78       should_update_tile_priorities_(false) {
     79   layer_tree_impl()->RegisterPictureLayerImpl(this);
     80 }
     81 
     82 PictureLayerImpl::~PictureLayerImpl() {
     83   layer_tree_impl()->UnregisterPictureLayerImpl(this);
     84 }
     85 
     86 const char* PictureLayerImpl::LayerTypeAsString() const {
     87   return "cc::PictureLayerImpl";
     88 }
     89 
     90 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
     91     LayerTreeImpl* tree_impl) {
     92   return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
     93 }
     94 
     95 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
     96   // It's possible this layer was never drawn or updated (e.g. because it was
     97   // a descendant of an opacity 0 layer).
     98   DoPostCommitInitializationIfNeeded();
     99   PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
    100 
    101   // We have already synced the important bits from the the active layer, and
    102   // we will soon swap out its tilings and use them for recycling. However,
    103   // there are now tiles in this layer's tilings that were unref'd and replaced
    104   // with new tiles (due to invalidation). This resets all active priorities on
    105   // the to-be-recycled tiling to ensure replaced tiles don't linger and take
    106   // memory (due to a stale 'active' priority).
    107   if (layer_impl->tilings_)
    108     layer_impl->tilings_->DidBecomeRecycled();
    109 
    110   LayerImpl::PushPropertiesTo(base_layer);
    111 
    112   // When the pending tree pushes to the active tree, the pending twin
    113   // becomes recycled.
    114   layer_impl->twin_layer_ = NULL;
    115   twin_layer_ = NULL;
    116 
    117   layer_impl->UpdatePile(pile_);
    118 
    119   DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings());
    120   // Tilings would be expensive to push, so we swap.
    121   layer_impl->tilings_.swap(tilings_);
    122   layer_impl->tilings_->SetClient(layer_impl);
    123   if (tilings_)
    124     tilings_->SetClient(this);
    125 
    126   // Ensure that the recycle tree doesn't have any unshared tiles.
    127   if (tilings_ && pile_->is_solid_color())
    128     tilings_->RemoveAllTilings();
    129 
    130   // Remove invalidated tiles from what will become a recycle tree.
    131   if (tilings_)
    132     tilings_->RemoveTilesInRegion(invalidation_);
    133 
    134   layer_impl->raster_page_scale_ = raster_page_scale_;
    135   layer_impl->raster_device_scale_ = raster_device_scale_;
    136   layer_impl->raster_source_scale_ = raster_source_scale_;
    137   layer_impl->raster_contents_scale_ = raster_contents_scale_;
    138   layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
    139   layer_impl->needs_post_commit_initialization_ = false;
    140 
    141   // The invalidation on this soon-to-be-recycled layer must be cleared to
    142   // mirror clearing the invalidation in PictureLayer's version of this function
    143   // in case push properties is skipped.
    144   layer_impl->invalidation_.Swap(&invalidation_);
    145   invalidation_.Clear();
    146   needs_post_commit_initialization_ = true;
    147 
    148   // We always need to push properties.
    149   // See http://crbug.com/303943
    150   needs_push_properties_ = true;
    151 }
    152 
    153 void PictureLayerImpl::UpdatePile(scoped_refptr<PicturePileImpl> pile) {
    154   bool could_have_tilings = CanHaveTilings();
    155   pile_.swap(pile);
    156 
    157   // Need to call UpdateTiles again if CanHaveTilings changed.
    158   if (could_have_tilings != CanHaveTilings()) {
    159     layer_tree_impl()->set_needs_update_draw_properties();
    160   }
    161 }
    162 
    163 void PictureLayerImpl::AppendQuads(
    164     RenderPass* render_pass,
    165     const OcclusionTracker<LayerImpl>& occlusion_tracker,
    166     AppendQuadsData* append_quads_data) {
    167   DCHECK(!needs_post_commit_initialization_);
    168 
    169   SharedQuadState* shared_quad_state =
    170       render_pass->CreateAndAppendSharedQuadState();
    171 
    172   if (pile_->is_solid_color()) {
    173     PopulateSharedQuadState(shared_quad_state);
    174 
    175     AppendDebugBorderQuad(
    176         render_pass, content_bounds(), shared_quad_state, append_quads_data);
    177 
    178     SolidColorLayerImpl::AppendSolidQuads(
    179         render_pass,
    180         occlusion_tracker,
    181         shared_quad_state,
    182         visible_content_rect(),
    183         draw_properties().target_space_transform,
    184         pile_->solid_color());
    185     return;
    186   }
    187 
    188   float max_contents_scale = MaximumTilingContentsScale();
    189   gfx::Transform scaled_draw_transform = draw_transform();
    190   scaled_draw_transform.Scale(SK_MScalar1 / max_contents_scale,
    191                               SK_MScalar1 / max_contents_scale);
    192   gfx::Size scaled_content_bounds =
    193       gfx::ToCeiledSize(gfx::ScaleSize(content_bounds(), max_contents_scale));
    194 
    195   gfx::Rect scaled_visible_content_rect =
    196       gfx::ScaleToEnclosingRect(visible_content_rect(), max_contents_scale);
    197   scaled_visible_content_rect.Intersect(gfx::Rect(scaled_content_bounds));
    198 
    199   Occlusion occlusion =
    200       occlusion_tracker.GetCurrentOcclusionForLayer(scaled_draw_transform);
    201 
    202   shared_quad_state->SetAll(scaled_draw_transform,
    203                             scaled_content_bounds,
    204                             scaled_visible_content_rect,
    205                             draw_properties().clip_rect,
    206                             draw_properties().is_clipped,
    207                             draw_properties().opacity,
    208                             blend_mode(),
    209                             sorting_context_id_);
    210 
    211   if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
    212     AppendDebugBorderQuad(
    213         render_pass,
    214         scaled_content_bounds,
    215         shared_quad_state,
    216         append_quads_data,
    217         DebugColors::DirectPictureBorderColor(),
    218         DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
    219 
    220     gfx::Rect geometry_rect = scaled_visible_content_rect;
    221     gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
    222     gfx::Rect visible_geometry_rect =
    223         occlusion.GetUnoccludedContentRect(geometry_rect);
    224     if (visible_geometry_rect.IsEmpty())
    225       return;
    226 
    227     gfx::Size texture_size = scaled_visible_content_rect.size();
    228     gfx::RectF texture_rect = gfx::RectF(texture_size);
    229     gfx::Rect quad_content_rect = scaled_visible_content_rect;
    230 
    231     PictureDrawQuad* quad =
    232         render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
    233     quad->SetNew(shared_quad_state,
    234                  geometry_rect,
    235                  opaque_rect,
    236                  visible_geometry_rect,
    237                  texture_rect,
    238                  texture_size,
    239                  RGBA_8888,
    240                  quad_content_rect,
    241                  max_contents_scale,
    242                  pile_);
    243     return;
    244   }
    245 
    246   AppendDebugBorderQuad(
    247       render_pass, scaled_content_bounds, shared_quad_state, append_quads_data);
    248 
    249   if (ShowDebugBorders()) {
    250     for (PictureLayerTilingSet::CoverageIterator iter(
    251              tilings_.get(),
    252              max_contents_scale,
    253              scaled_visible_content_rect,
    254              ideal_contents_scale_);
    255          iter;
    256          ++iter) {
    257       SkColor color;
    258       float width;
    259       if (*iter && iter->IsReadyToDraw()) {
    260         ManagedTileState::TileVersion::Mode mode =
    261             iter->GetTileVersionForDrawing().mode();
    262         if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
    263           color = DebugColors::SolidColorTileBorderColor();
    264           width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
    265         } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
    266           color = DebugColors::PictureTileBorderColor();
    267           width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
    268         } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) {
    269           color = DebugColors::HighResTileBorderColor();
    270           width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
    271         } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) {
    272           color = DebugColors::LowResTileBorderColor();
    273           width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
    274         } else if (iter->contents_scale() > max_contents_scale) {
    275           color = DebugColors::ExtraHighResTileBorderColor();
    276           width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
    277         } else {
    278           color = DebugColors::ExtraLowResTileBorderColor();
    279           width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
    280         }
    281       } else {
    282         color = DebugColors::MissingTileBorderColor();
    283         width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
    284       }
    285 
    286       DebugBorderDrawQuad* debug_border_quad =
    287           render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
    288       gfx::Rect geometry_rect = iter.geometry_rect();
    289       gfx::Rect visible_geometry_rect = geometry_rect;
    290       debug_border_quad->SetNew(shared_quad_state,
    291                                 geometry_rect,
    292                                 visible_geometry_rect,
    293                                 color,
    294                                 width);
    295     }
    296   }
    297 
    298   // Keep track of the tilings that were used so that tilings that are
    299   // unused can be considered for removal.
    300   std::vector<PictureLayerTiling*> seen_tilings;
    301 
    302   // Ignore missing tiles outside of viewport for tile priority. This is
    303   // normally the same as draw viewport but can be independently overridden by
    304   // embedders like Android WebView with SetExternalDrawConstraints.
    305   gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect(
    306       GetViewportForTilePriorityInContentSpace(), max_contents_scale);
    307 
    308   size_t missing_tile_count = 0u;
    309   size_t on_demand_missing_tile_count = 0u;
    310   for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
    311                                                     max_contents_scale,
    312                                                     scaled_visible_content_rect,
    313                                                     ideal_contents_scale_);
    314        iter;
    315        ++iter) {
    316     gfx::Rect geometry_rect = iter.geometry_rect();
    317     gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
    318     gfx::Rect visible_geometry_rect =
    319         occlusion.GetUnoccludedContentRect(geometry_rect);
    320     if (visible_geometry_rect.IsEmpty())
    321       continue;
    322 
    323     append_quads_data->visible_content_area +=
    324         visible_geometry_rect.width() * visible_geometry_rect.height();
    325 
    326     bool has_draw_quad = false;
    327     if (*iter && iter->IsReadyToDraw()) {
    328       const ManagedTileState::TileVersion& tile_version =
    329           iter->GetTileVersionForDrawing();
    330       switch (tile_version.mode()) {
    331         case ManagedTileState::TileVersion::RESOURCE_MODE: {
    332           gfx::RectF texture_rect = iter.texture_rect();
    333 
    334           // The raster_contents_scale_ is the best scale that the layer is
    335           // trying to produce, even though it may not be ideal. Since that's
    336           // the best the layer can promise in the future, consider those as
    337           // complete. But if a tile is ideal scale, we don't want to consider
    338           // it incomplete and trying to replace it with a tile at a worse
    339           // scale.
    340           if (iter->contents_scale() != raster_contents_scale_ &&
    341               iter->contents_scale() != ideal_contents_scale_ &&
    342               geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
    343             append_quads_data->num_incomplete_tiles++;
    344           }
    345 
    346           TileDrawQuad* quad =
    347               render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
    348           quad->SetNew(shared_quad_state,
    349                        geometry_rect,
    350                        opaque_rect,
    351                        visible_geometry_rect,
    352                        tile_version.get_resource_id(),
    353                        texture_rect,
    354                        iter.texture_size(),
    355                        tile_version.contents_swizzled());
    356           has_draw_quad = true;
    357           break;
    358         }
    359         case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
    360           if (!layer_tree_impl()
    361                    ->GetRendererCapabilities()
    362                    .allow_rasterize_on_demand) {
    363             ++on_demand_missing_tile_count;
    364             break;
    365           }
    366 
    367           gfx::RectF texture_rect = iter.texture_rect();
    368 
    369           ResourceProvider* resource_provider =
    370               layer_tree_impl()->resource_provider();
    371           ResourceFormat format =
    372               resource_provider->memory_efficient_texture_format();
    373           PictureDrawQuad* quad =
    374               render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
    375           quad->SetNew(shared_quad_state,
    376                        geometry_rect,
    377                        opaque_rect,
    378                        visible_geometry_rect,
    379                        texture_rect,
    380                        iter.texture_size(),
    381                        format,
    382                        iter->content_rect(),
    383                        iter->contents_scale(),
    384                        pile_);
    385           has_draw_quad = true;
    386           break;
    387         }
    388         case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
    389           SolidColorDrawQuad* quad =
    390               render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    391           quad->SetNew(shared_quad_state,
    392                        geometry_rect,
    393                        visible_geometry_rect,
    394                        tile_version.get_solid_color(),
    395                        false);
    396           has_draw_quad = true;
    397           break;
    398         }
    399       }
    400     }
    401 
    402     if (!has_draw_quad) {
    403       if (draw_checkerboard_for_missing_tiles()) {
    404         CheckerboardDrawQuad* quad =
    405             render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
    406         SkColor color = DebugColors::DefaultCheckerboardColor();
    407         quad->SetNew(
    408             shared_quad_state, geometry_rect, visible_geometry_rect, color);
    409       } else {
    410         SkColor color = SafeOpaqueBackgroundColor();
    411         SolidColorDrawQuad* quad =
    412             render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    413         quad->SetNew(shared_quad_state,
    414                      geometry_rect,
    415                      visible_geometry_rect,
    416                      color,
    417                      false);
    418       }
    419 
    420       if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
    421         append_quads_data->num_missing_tiles++;
    422         ++missing_tile_count;
    423       }
    424       append_quads_data->approximated_visible_content_area +=
    425           visible_geometry_rect.width() * visible_geometry_rect.height();
    426       continue;
    427     }
    428 
    429     if (iter->priority(ACTIVE_TREE).resolution != HIGH_RESOLUTION) {
    430       append_quads_data->approximated_visible_content_area +=
    431           visible_geometry_rect.width() * visible_geometry_rect.height();
    432     }
    433 
    434     if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling())
    435       seen_tilings.push_back(iter.CurrentTiling());
    436   }
    437 
    438   if (missing_tile_count) {
    439     TRACE_EVENT_INSTANT2("cc",
    440                          "PictureLayerImpl::AppendQuads checkerboard",
    441                          TRACE_EVENT_SCOPE_THREAD,
    442                          "missing_tile_count",
    443                          missing_tile_count,
    444                          "on_demand_missing_tile_count",
    445                          on_demand_missing_tile_count);
    446   }
    447 
    448   // Aggressively remove any tilings that are not seen to save memory. Note
    449   // that this is at the expense of doing cause more frequent re-painting. A
    450   // better scheme would be to maintain a tighter visible_content_rect for the
    451   // finer tilings.
    452   CleanUpTilingsOnActiveLayer(seen_tilings);
    453 }
    454 
    455 void PictureLayerImpl::UpdateTiles(const Occlusion& occlusion_in_content_space,
    456                                    bool resourceless_software_draw) {
    457   TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTiles");
    458   DCHECK_EQ(1.f, contents_scale_x());
    459   DCHECK_EQ(1.f, contents_scale_y());
    460 
    461   DoPostCommitInitializationIfNeeded();
    462 
    463   // Any draw properties derived from |transform|, |viewport|, and |clip|
    464   // parameters in LayerTreeHostImpl::SetExternalDrawConstraints are not valid
    465   // for prioritizing tiles during resourceless software draws. This is because
    466   // resourceless software draws can have wildly different transforms/viewports
    467   // from regular draws.
    468   if (!resourceless_software_draw) {
    469     visible_rect_for_tile_priority_ = visible_content_rect();
    470   }
    471   viewport_rect_for_tile_priority_ =
    472       layer_tree_impl()->ViewportRectForTilePriority();
    473   screen_space_transform_for_tile_priority_ = screen_space_transform();
    474 
    475   if (!CanHaveTilings()) {
    476     ideal_page_scale_ = 0.f;
    477     ideal_device_scale_ = 0.f;
    478     ideal_contents_scale_ = 0.f;
    479     ideal_source_scale_ = 0.f;
    480     SanityCheckTilingState();
    481     return;
    482   }
    483 
    484   UpdateIdealScales();
    485 
    486   DCHECK(tilings_->num_tilings() > 0 || raster_contents_scale_ == 0.f)
    487       << "A layer with no tilings shouldn't have valid raster scales";
    488   if (!raster_contents_scale_ || ShouldAdjustRasterScale()) {
    489     RecalculateRasterScales();
    490     AddTilingsForRasterScale();
    491   }
    492 
    493   DCHECK(raster_page_scale_);
    494   DCHECK(raster_device_scale_);
    495   DCHECK(raster_source_scale_);
    496   DCHECK(raster_contents_scale_);
    497   DCHECK(low_res_raster_contents_scale_);
    498 
    499   was_screen_space_transform_animating_ =
    500       draw_properties().screen_space_transform_is_animating;
    501 
    502   should_update_tile_priorities_ = true;
    503 
    504   UpdateTilePriorities(occlusion_in_content_space);
    505 
    506   if (layer_tree_impl()->IsPendingTree())
    507     MarkVisibleResourcesAsRequired();
    508 }
    509 
    510 void PictureLayerImpl::UpdateTilePriorities(
    511     const Occlusion& occlusion_in_content_space) {
    512   DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings());
    513 
    514   TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities");
    515 
    516   double current_frame_time_in_seconds =
    517       (layer_tree_impl()->CurrentBeginFrameArgs().frame_time -
    518        base::TimeTicks()).InSecondsF();
    519 
    520   gfx::Rect viewport_rect_in_layer_space =
    521       GetViewportForTilePriorityInContentSpace();
    522   bool tiling_needs_update = false;
    523   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    524     if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTimeAndViewport(
    525             current_frame_time_in_seconds, viewport_rect_in_layer_space)) {
    526       tiling_needs_update = true;
    527       break;
    528     }
    529   }
    530   if (!tiling_needs_update)
    531     return;
    532 
    533   WhichTree tree =
    534       layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
    535   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    536     // Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since
    537     // they are the same space in picture lbayer, as contents scale is always 1.
    538     tilings_->tiling_at(i)->UpdateTilePriorities(tree,
    539                                                  viewport_rect_in_layer_space,
    540                                                  ideal_contents_scale_,
    541                                                  current_frame_time_in_seconds,
    542                                                  occlusion_in_content_space);
    543   }
    544 
    545   // Tile priorities were modified.
    546   layer_tree_impl()->DidModifyTilePriorities();
    547 }
    548 
    549 gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const {
    550   // If visible_rect_for_tile_priority_ is empty or
    551   // viewport_rect_for_tile_priority_ is set to be different from the device
    552   // viewport, try to inverse project the viewport into layer space and use
    553   // that. Otherwise just use visible_rect_for_tile_priority_
    554   gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_;
    555 
    556   if (visible_rect_in_content_space.IsEmpty() ||
    557       layer_tree_impl()->DeviceViewport() != viewport_rect_for_tile_priority_) {
    558     gfx::Transform view_to_layer(gfx::Transform::kSkipInitialization);
    559 
    560     if (screen_space_transform_for_tile_priority_.GetInverse(&view_to_layer)) {
    561       // Transform from view space to content space.
    562       visible_rect_in_content_space =
    563           gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
    564               view_to_layer, viewport_rect_for_tile_priority_));
    565     }
    566   }
    567   return visible_rect_in_content_space;
    568 }
    569 
    570 PictureLayerImpl* PictureLayerImpl::GetRecycledTwinLayer() {
    571   // TODO(vmpstr): Maintain recycled twin as a member. crbug.com/407418
    572   return static_cast<PictureLayerImpl*>(
    573       layer_tree_impl()->FindRecycleTreeLayerById(id()));
    574 }
    575 
    576 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
    577   if (layer_tree_impl()->IsActiveTree()) {
    578     gfx::RectF layer_damage_rect =
    579         gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale());
    580     AddDamageRect(layer_damage_rect);
    581   }
    582 }
    583 
    584 void PictureLayerImpl::DidBecomeActive() {
    585   LayerImpl::DidBecomeActive();
    586   tilings_->DidBecomeActive();
    587   layer_tree_impl()->DidModifyTilePriorities();
    588 }
    589 
    590 void PictureLayerImpl::DidBeginTracing() {
    591   pile_->DidBeginTracing();
    592 }
    593 
    594 void PictureLayerImpl::ReleaseResources() {
    595   if (tilings_)
    596     RemoveAllTilings();
    597 
    598   ResetRasterScale();
    599 
    600   // To avoid an edge case after lost context where the tree is up to date but
    601   // the tilings have not been managed, request an update draw properties
    602   // to force tilings to get managed.
    603   layer_tree_impl()->set_needs_update_draw_properties();
    604 }
    605 
    606 skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() {
    607   return pile_->GetFlattenedPicture();
    608 }
    609 
    610 scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
    611                                                const gfx::Rect& content_rect) {
    612   DCHECK(!pile_->is_solid_color());
    613   if (!pile_->CanRaster(tiling->contents_scale(), content_rect))
    614     return scoped_refptr<Tile>();
    615 
    616   int flags = 0;
    617 
    618   // TODO(vmpstr): Revisit this. For now, enabling analysis means that we get as
    619   // much savings on memory as we can. However, for some cases like ganesh or
    620   // small layers, the amount of time we spend analyzing might not justify
    621   // memory savings that we can get. Note that we don't handle solid color
    622   // masks, so we shouldn't bother analyzing those.
    623   // Bugs: crbug.com/397198, crbug.com/396908
    624   if (!pile_->is_mask())
    625     flags = Tile::USE_PICTURE_ANALYSIS;
    626 
    627   return layer_tree_impl()->tile_manager()->CreateTile(
    628       pile_.get(),
    629       content_rect.size(),
    630       content_rect,
    631       tiling->contents_scale(),
    632       id(),
    633       layer_tree_impl()->source_frame_number(),
    634       flags);
    635 }
    636 
    637 PicturePileImpl* PictureLayerImpl::GetPile() {
    638   return pile_.get();
    639 }
    640 
    641 const Region* PictureLayerImpl::GetInvalidation() {
    642   return &invalidation_;
    643 }
    644 
    645 const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
    646     const PictureLayerTiling* tiling) const {
    647   if (!twin_layer_)
    648     return NULL;
    649   return twin_layer_->tilings_->TilingAtScale(tiling->contents_scale());
    650 }
    651 
    652 PictureLayerTiling* PictureLayerImpl::GetRecycledTwinTiling(
    653     const PictureLayerTiling* tiling) {
    654   PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
    655   if (!recycled_twin || !recycled_twin->tilings_)
    656     return NULL;
    657   return recycled_twin->tilings_->TilingAtScale(tiling->contents_scale());
    658 }
    659 
    660 size_t PictureLayerImpl::GetMaxTilesForInterestArea() const {
    661   return layer_tree_impl()->settings().max_tiles_for_interest_area;
    662 }
    663 
    664 float PictureLayerImpl::GetSkewportTargetTimeInSeconds() const {
    665   float skewport_target_time_in_frames =
    666       layer_tree_impl()->use_gpu_rasterization()
    667           ? kGpuSkewportTargetTimeInFrames
    668           : kCpuSkewportTargetTimeInFrames;
    669   return skewport_target_time_in_frames *
    670          layer_tree_impl()->begin_impl_frame_interval().InSecondsF() *
    671          layer_tree_impl()->settings().skewport_target_time_multiplier;
    672 }
    673 
    674 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
    675   return layer_tree_impl()
    676       ->settings()
    677       .skewport_extrapolation_limit_in_content_pixels;
    678 }
    679 
    680 gfx::Size PictureLayerImpl::CalculateTileSize(
    681     const gfx::Size& content_bounds) const {
    682   int max_texture_size =
    683       layer_tree_impl()->resource_provider()->max_texture_size();
    684 
    685   if (pile_->is_mask()) {
    686     // Masks are not tiled, so if we can't cover the whole mask with one tile,
    687     // don't make any tiles at all. Returning an empty size signals this.
    688     if (content_bounds.width() > max_texture_size ||
    689         content_bounds.height() > max_texture_size)
    690       return gfx::Size();
    691     return content_bounds;
    692   }
    693 
    694   gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size;
    695   if (layer_tree_impl()->use_gpu_rasterization()) {
    696     // TODO(ernstm) crbug.com/365877: We need a unified way to override the
    697     // default-tile-size.
    698     default_tile_size =
    699         gfx::Size(layer_tree_impl()->device_viewport_size().width(),
    700                   layer_tree_impl()->device_viewport_size().height() / 4);
    701   }
    702   default_tile_size.SetToMin(gfx::Size(max_texture_size, max_texture_size));
    703 
    704   gfx::Size max_untiled_content_size =
    705       layer_tree_impl()->settings().max_untiled_layer_size;
    706   max_untiled_content_size.SetToMin(
    707       gfx::Size(max_texture_size, max_texture_size));
    708 
    709   bool any_dimension_too_large =
    710       content_bounds.width() > max_untiled_content_size.width() ||
    711       content_bounds.height() > max_untiled_content_size.height();
    712 
    713   bool any_dimension_one_tile =
    714       content_bounds.width() <= default_tile_size.width() ||
    715       content_bounds.height() <= default_tile_size.height();
    716 
    717   // If long and skinny, tile at the max untiled content size, and clamp
    718   // the smaller dimension to the content size, e.g. 1000x12 layer with
    719   // 500x500 max untiled size would get 500x12 tiles.  Also do this
    720   // if the layer is small.
    721   if (any_dimension_one_tile || !any_dimension_too_large) {
    722     int width = std::min(
    723         std::max(max_untiled_content_size.width(), default_tile_size.width()),
    724         content_bounds.width());
    725     int height = std::min(
    726         std::max(max_untiled_content_size.height(), default_tile_size.height()),
    727         content_bounds.height());
    728     // Round up to the closest multiple of 64. This improves recycling and
    729     // avoids odd texture sizes.
    730     width = RoundUp(width, 64);
    731     height = RoundUp(height, 64);
    732     return gfx::Size(width, height);
    733   }
    734 
    735   return default_tile_size;
    736 }
    737 
    738 void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
    739   TRACE_EVENT0("cc", "SyncFromActiveLayer");
    740   DCHECK(!other->needs_post_commit_initialization_);
    741   DCHECK(other->tilings_);
    742 
    743   if (!DrawsContent()) {
    744     RemoveAllTilings();
    745     return;
    746   }
    747 
    748   raster_page_scale_ = other->raster_page_scale_;
    749   raster_device_scale_ = other->raster_device_scale_;
    750   raster_source_scale_ = other->raster_source_scale_;
    751   raster_contents_scale_ = other->raster_contents_scale_;
    752   low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
    753 
    754   bool synced_high_res_tiling = false;
    755   if (CanHaveTilings()) {
    756     synced_high_res_tiling = tilings_->SyncTilings(
    757         *other->tilings_, bounds(), invalidation_, MinimumContentsScale());
    758   } else {
    759     RemoveAllTilings();
    760   }
    761 
    762   // If our MinimumContentsScale has changed to prevent the twin's high res
    763   // tiling from being synced, we should reset the raster scale and let it be
    764   // recalculated (1) again. This can happen if our bounds shrink to the point
    765   // where min contents scale grows.
    766   // (1) - TODO(vmpstr) Instead of hoping that this will be recalculated, we
    767   // should refactor this code a little bit and actually recalculate this.
    768   // However, this is a larger undertaking, so this will work for now.
    769   if (!synced_high_res_tiling)
    770     ResetRasterScale();
    771   else
    772     SanityCheckTilingState();
    773 }
    774 
    775 void PictureLayerImpl::SyncTiling(
    776     const PictureLayerTiling* tiling) {
    777   if (!CanHaveTilingWithScale(tiling->contents_scale()))
    778     return;
    779   tilings_->AddTiling(tiling->contents_scale());
    780 
    781   // If this tree needs update draw properties, then the tiling will
    782   // get updated prior to drawing or activation.  If this tree does not
    783   // need update draw properties, then its transforms are up to date and
    784   // we can create tiles for this tiling immediately.
    785   if (!layer_tree_impl()->needs_update_draw_properties() &&
    786       should_update_tile_priorities_) {
    787     // TODO(danakj): Add a DCHECK() that we are not using occlusion tracking
    788     // when we stop using the pending tree in the browser compositor. If we want
    789     // to support occlusion tracking here, we need to dirty the draw properties
    790     // or save occlusion as a draw property.
    791     UpdateTilePriorities(Occlusion());
    792   }
    793 }
    794 
    795 ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {
    796   gfx::Rect content_rect(content_bounds());
    797   PictureLayerTilingSet::CoverageIterator iter(
    798       tilings_.get(), 1.f, content_rect, ideal_contents_scale_);
    799 
    800   // Mask resource not ready yet.
    801   if (!iter || !*iter)
    802     return 0;
    803 
    804   // Masks only supported if they fit on exactly one tile.
    805   DCHECK(iter.geometry_rect() == content_rect)
    806       << "iter rect " << iter.geometry_rect().ToString() << " content rect "
    807       << content_rect.ToString();
    808 
    809   const ManagedTileState::TileVersion& tile_version =
    810       iter->GetTileVersionForDrawing();
    811   if (!tile_version.IsReadyToDraw() ||
    812       tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE)
    813     return 0;
    814 
    815   return tile_version.get_resource_id();
    816 }
    817 
    818 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
    819   DCHECK(layer_tree_impl()->IsPendingTree());
    820   DCHECK(ideal_contents_scale_);
    821   DCHECK_GT(tilings_->num_tilings(), 0u);
    822 
    823   // The goal of this function is to find the minimum set of tiles that need to
    824   // be ready to draw in order to activate without flashing content from a
    825   // higher res on the active tree to a lower res on the pending tree.
    826 
    827   // First, early out for layers with no visible content.
    828   if (visible_rect_for_tile_priority_.IsEmpty())
    829     return;
    830 
    831   // Only mark tiles inside the viewport for tile priority as required for
    832   // activation. This viewport is normally the same as the draw viewport but
    833   // can be independently overridden by embedders like Android WebView with
    834   // SetExternalDrawConstraints.
    835   gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
    836   rect.Intersect(visible_rect_for_tile_priority_);
    837 
    838   float min_acceptable_scale =
    839       std::min(raster_contents_scale_, ideal_contents_scale_);
    840 
    841   if (PictureLayerImpl* twin = twin_layer_) {
    842     float twin_min_acceptable_scale =
    843         std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
    844     // Ignore 0 scale in case CalculateContentsScale() has never been
    845     // called for active twin.
    846     if (twin_min_acceptable_scale != 0.0f) {
    847       min_acceptable_scale =
    848           std::min(min_acceptable_scale, twin_min_acceptable_scale);
    849     }
    850   }
    851 
    852   PictureLayerTiling* high_res = NULL;
    853   PictureLayerTiling* low_res = NULL;
    854 
    855   // First pass: ready to draw tiles in acceptable but non-ideal tilings are
    856   // marked as required for activation so that their textures are not thrown
    857   // away; any non-ready tiles are not marked as required.
    858   Region missing_region = rect;
    859   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    860     PictureLayerTiling* tiling = tilings_->tiling_at(i);
    861     DCHECK(tiling->has_ever_been_updated());
    862 
    863     if (tiling->resolution() == LOW_RESOLUTION) {
    864       DCHECK(!low_res) << "There can only be one low res tiling";
    865       low_res = tiling;
    866     }
    867     if (tiling->contents_scale() < min_acceptable_scale)
    868       continue;
    869     if (tiling->resolution() == HIGH_RESOLUTION) {
    870       DCHECK(!high_res) << "There can only be one high res tiling";
    871       high_res = tiling;
    872       continue;
    873     }
    874     for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
    875          ++iter) {
    876       if (!*iter || !iter->IsReadyToDraw())
    877         continue;
    878 
    879       missing_region.Subtract(iter.geometry_rect());
    880       iter->MarkRequiredForActivation();
    881     }
    882   }
    883   DCHECK(high_res) << "There must be one high res tiling";
    884 
    885   // If these pointers are null (because no twin, no matching tiling, or the
    886   // simpification just below), then high res tiles will be required to fill any
    887   // holes left by the first pass above.  If the pointers are valid, then this
    888   // layer is allowed to skip any tiles that are not ready on its twin.
    889   const PictureLayerTiling* twin_high_res = NULL;
    890   const PictureLayerTiling* twin_low_res = NULL;
    891 
    892   if (twin_layer_) {
    893     // As a simplification, only allow activating to skip twin tiles that the
    894     // active layer is also missing when both this layer and its twin have
    895     // "simple" sets of tilings: only 2 tilings (high and low) or only 1 high
    896     // res tiling. This avoids having to iterate/track coverage of non-ideal
    897     // tilings during the last draw call on the active layer.
    898     if (tilings_->num_tilings() <= 2 &&
    899         twin_layer_->tilings_->num_tilings() <= tilings_->num_tilings()) {
    900       twin_low_res = low_res ? GetTwinTiling(low_res) : NULL;
    901       twin_high_res = high_res ? GetTwinTiling(high_res) : NULL;
    902     }
    903 
    904     // If this layer and its twin have different transforms, then don't compare
    905     // them and only allow activating to high res tiles, since tiles on each
    906     // layer will be in different places on screen.
    907     if (twin_layer_->layer_tree_impl()->RequiresHighResToDraw() ||
    908         bounds() != twin_layer_->bounds() ||
    909         draw_properties().screen_space_transform !=
    910             twin_layer_->draw_properties().screen_space_transform) {
    911       twin_high_res = NULL;
    912       twin_low_res = NULL;
    913     }
    914   }
    915 
    916   // As a second pass, mark as required any visible high res tiles not filled in
    917   // by acceptable non-ideal tiles from the first pass.
    918   if (MarkVisibleTilesAsRequired(
    919           high_res, twin_high_res, rect, missing_region)) {
    920     // As an optional third pass, if a high res tile was skipped because its
    921     // twin was also missing, then fall back to mark low res tiles as required
    922     // in case the active twin is substituting those for missing high res
    923     // content. Only suitable, when low res is enabled.
    924     if (low_res) {
    925       MarkVisibleTilesAsRequired(low_res, twin_low_res, rect, missing_region);
    926     }
    927   }
    928 }
    929 
    930 bool PictureLayerImpl::MarkVisibleTilesAsRequired(
    931     PictureLayerTiling* tiling,
    932     const PictureLayerTiling* optional_twin_tiling,
    933     const gfx::Rect& rect,
    934     const Region& missing_region) const {
    935   bool twin_had_missing_tile = false;
    936   for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
    937        ++iter) {
    938     Tile* tile = *iter;
    939     // A null tile (i.e. missing recording) can just be skipped.
    940     if (!tile)
    941       continue;
    942 
    943     // If the tile is occluded, don't mark it as required for activation.
    944     if (tile->is_occluded(PENDING_TREE))
    945       continue;
    946 
    947     // If the missing region doesn't cover it, this tile is fully
    948     // covered by acceptable tiles at other scales.
    949     if (!missing_region.Intersects(iter.geometry_rect()))
    950       continue;
    951 
    952     // If the twin tile doesn't exist (i.e. missing recording or so far away
    953     // that it is outside the visible tile rect) or this tile is shared between
    954     // with the twin, then this tile isn't required to prevent flashing.
    955     if (optional_twin_tiling) {
    956       Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j());
    957       if (!twin_tile || twin_tile == tile) {
    958         // However if the shared tile is being used on the active tree, then
    959         // there's no missing content in this place, and low res is not needed.
    960         if (!twin_tile || !twin_tile->IsReadyToDraw())
    961           twin_had_missing_tile = true;
    962         continue;
    963       }
    964     }
    965 
    966     tile->MarkRequiredForActivation();
    967   }
    968   return twin_had_missing_tile;
    969 }
    970 
    971 void PictureLayerImpl::DoPostCommitInitialization() {
    972   DCHECK(needs_post_commit_initialization_);
    973   DCHECK(layer_tree_impl()->IsPendingTree());
    974 
    975   if (!tilings_)
    976     tilings_.reset(new PictureLayerTilingSet(this, bounds()));
    977 
    978   DCHECK(!twin_layer_);
    979   twin_layer_ = static_cast<PictureLayerImpl*>(
    980       layer_tree_impl()->FindActiveTreeLayerById(id()));
    981   if (twin_layer_) {
    982     DCHECK(!twin_layer_->twin_layer_);
    983     twin_layer_->twin_layer_ = this;
    984     // If the twin has never been pushed to, do not sync from it.
    985     // This can happen if this function is called during activation.
    986     if (!twin_layer_->needs_post_commit_initialization_)
    987       SyncFromActiveLayer(twin_layer_);
    988   }
    989 
    990   needs_post_commit_initialization_ = false;
    991 }
    992 
    993 PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
    994   DCHECK(CanHaveTilingWithScale(contents_scale)) <<
    995       "contents_scale: " << contents_scale;
    996 
    997   PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
    998 
    999   DCHECK(pile_->HasRecordings());
   1000 
   1001   if (twin_layer_)
   1002     twin_layer_->SyncTiling(tiling);
   1003 
   1004   return tiling;
   1005 }
   1006 
   1007 void PictureLayerImpl::RemoveTiling(float contents_scale) {
   1008   if (!tilings_ || tilings_->num_tilings() == 0)
   1009     return;
   1010 
   1011   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
   1012     PictureLayerTiling* tiling = tilings_->tiling_at(i);
   1013     if (tiling->contents_scale() == contents_scale) {
   1014       tilings_->Remove(tiling);
   1015       break;
   1016     }
   1017   }
   1018   if (tilings_->num_tilings() == 0)
   1019     ResetRasterScale();
   1020   SanityCheckTilingState();
   1021 }
   1022 
   1023 void PictureLayerImpl::RemoveAllTilings() {
   1024   if (tilings_)
   1025     tilings_->RemoveAllTilings();
   1026   // If there are no tilings, then raster scales are no longer meaningful.
   1027   ResetRasterScale();
   1028 }
   1029 
   1030 namespace {
   1031 
   1032 inline float PositiveRatio(float float1, float float2) {
   1033   DCHECK_GT(float1, 0);
   1034   DCHECK_GT(float2, 0);
   1035   return float1 > float2 ? float1 / float2 : float2 / float1;
   1036 }
   1037 
   1038 }  // namespace
   1039 
   1040 void PictureLayerImpl::AddTilingsForRasterScale() {
   1041   PictureLayerTiling* high_res = NULL;
   1042   PictureLayerTiling* low_res = NULL;
   1043 
   1044   PictureLayerTiling* previous_low_res = NULL;
   1045   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
   1046     PictureLayerTiling* tiling = tilings_->tiling_at(i);
   1047     if (tiling->contents_scale() == raster_contents_scale_)
   1048       high_res = tiling;
   1049     if (tiling->contents_scale() == low_res_raster_contents_scale_)
   1050       low_res = tiling;
   1051     if (tiling->resolution() == LOW_RESOLUTION)
   1052       previous_low_res = tiling;
   1053 
   1054     // Reset all tilings to non-ideal until the end of this function.
   1055     tiling->set_resolution(NON_IDEAL_RESOLUTION);
   1056   }
   1057 
   1058   if (!high_res) {
   1059     high_res = AddTiling(raster_contents_scale_);
   1060     if (raster_contents_scale_ == low_res_raster_contents_scale_)
   1061       low_res = high_res;
   1062   }
   1063 
   1064   // Only create new low res tilings when the transform is static.  This
   1065   // prevents wastefully creating a paired low res tiling for every new high res
   1066   // tiling during a pinch or a CSS animation.
   1067   bool is_pinching = layer_tree_impl()->PinchGestureActive();
   1068   if (layer_tree_impl()->create_low_res_tiling() && !is_pinching &&
   1069       !draw_properties().screen_space_transform_is_animating && !low_res &&
   1070       low_res != high_res)
   1071     low_res = AddTiling(low_res_raster_contents_scale_);
   1072 
   1073   // Set low-res if we have one.
   1074   if (!low_res)
   1075     low_res = previous_low_res;
   1076   if (low_res && low_res != high_res)
   1077     low_res->set_resolution(LOW_RESOLUTION);
   1078 
   1079   // Make sure we always have one high-res (even if high == low).
   1080   high_res->set_resolution(HIGH_RESOLUTION);
   1081 
   1082   SanityCheckTilingState();
   1083 }
   1084 
   1085 bool PictureLayerImpl::ShouldAdjustRasterScale() const {
   1086   if (was_screen_space_transform_animating_ !=
   1087       draw_properties().screen_space_transform_is_animating)
   1088     return true;
   1089 
   1090   if (draw_properties().screen_space_transform_is_animating &&
   1091       raster_contents_scale_ != ideal_contents_scale_ &&
   1092       ShouldAdjustRasterScaleDuringScaleAnimations())
   1093     return true;
   1094 
   1095   bool is_pinching = layer_tree_impl()->PinchGestureActive();
   1096   if (is_pinching && raster_page_scale_) {
   1097     // We change our raster scale when it is:
   1098     // - Higher than ideal (need a lower-res tiling available)
   1099     // - Too far from ideal (need a higher-res tiling available)
   1100     float ratio = ideal_page_scale_ / raster_page_scale_;
   1101     if (raster_page_scale_ > ideal_page_scale_ ||
   1102         ratio > kMaxScaleRatioDuringPinch)
   1103       return true;
   1104   }
   1105 
   1106   if (!is_pinching) {
   1107     // When not pinching, match the ideal page scale factor.
   1108     if (raster_page_scale_ != ideal_page_scale_)
   1109       return true;
   1110   }
   1111 
   1112   // Always match the ideal device scale factor.
   1113   if (raster_device_scale_ != ideal_device_scale_)
   1114     return true;
   1115 
   1116   // When the source scale changes we want to match it, but not when animating
   1117   // or when we've fixed the scale in place.
   1118   if (!draw_properties().screen_space_transform_is_animating &&
   1119       !raster_source_scale_is_fixed_ &&
   1120       raster_source_scale_ != ideal_source_scale_)
   1121     return true;
   1122 
   1123   return false;
   1124 }
   1125 
   1126 float PictureLayerImpl::SnappedContentsScale(float scale) {
   1127   // If a tiling exists within the max snapping ratio, snap to its scale.
   1128   float snapped_contents_scale = scale;
   1129   float snapped_ratio = kSnapToExistingTilingRatio;
   1130   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
   1131     float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale();
   1132     float ratio = PositiveRatio(tiling_contents_scale, scale);
   1133     if (ratio < snapped_ratio) {
   1134       snapped_contents_scale = tiling_contents_scale;
   1135       snapped_ratio = ratio;
   1136     }
   1137   }
   1138   return snapped_contents_scale;
   1139 }
   1140 
   1141 void PictureLayerImpl::RecalculateRasterScales() {
   1142   float old_raster_contents_scale = raster_contents_scale_;
   1143   float old_raster_page_scale = raster_page_scale_;
   1144   float old_raster_source_scale = raster_source_scale_;
   1145 
   1146   raster_device_scale_ = ideal_device_scale_;
   1147   raster_page_scale_ = ideal_page_scale_;
   1148   raster_source_scale_ = ideal_source_scale_;
   1149   raster_contents_scale_ = ideal_contents_scale_;
   1150 
   1151   // If we're not animating, or leaving an animation, and the
   1152   // ideal_source_scale_ changes, then things are unpredictable, and we fix
   1153   // the raster_source_scale_ in place.
   1154   if (old_raster_source_scale &&
   1155       !draw_properties().screen_space_transform_is_animating &&
   1156       !was_screen_space_transform_animating_ &&
   1157       old_raster_source_scale != ideal_source_scale_)
   1158     raster_source_scale_is_fixed_ = true;
   1159 
   1160   // TODO(danakj): Adjust raster source scale closer to ideal source scale at
   1161   // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
   1162   // tree. This will allow CSS scale changes to get re-rastered at an
   1163   // appropriate rate. (crbug.com/413636)
   1164   if (raster_source_scale_is_fixed_) {
   1165     raster_contents_scale_ /= raster_source_scale_;
   1166     raster_source_scale_ = 1.f;
   1167   }
   1168 
   1169   // During pinch we completely ignore the current ideal scale, and just use
   1170   // a multiple of the previous scale.
   1171   // TODO(danakj): This seems crazy, we should use the current ideal, no?
   1172   bool is_pinching = layer_tree_impl()->PinchGestureActive();
   1173   if (is_pinching && old_raster_contents_scale) {
   1174     // See ShouldAdjustRasterScale:
   1175     // - When zooming out, preemptively create new tiling at lower resolution.
   1176     // - When zooming in, approximate ideal using multiple of kMaxScaleRatio.
   1177     bool zooming_out = old_raster_page_scale > ideal_page_scale_;
   1178     float desired_contents_scale =
   1179         zooming_out ? old_raster_contents_scale / kMaxScaleRatioDuringPinch
   1180                     : old_raster_contents_scale * kMaxScaleRatioDuringPinch;
   1181     raster_contents_scale_ = SnappedContentsScale(desired_contents_scale);
   1182     raster_page_scale_ =
   1183         raster_contents_scale_ / raster_device_scale_ / raster_source_scale_;
   1184   }
   1185 
   1186   raster_contents_scale_ =
   1187       std::max(raster_contents_scale_, MinimumContentsScale());
   1188 
   1189   // If we're not re-rasterizing during animation, rasterize at the maximum
   1190   // scale that will occur during the animation, if the maximum scale is
   1191   // known. However we want to avoid excessive memory use. If the scale is
   1192   // smaller than what we would choose otherwise, then it's always better off
   1193   // for us memory-wise. But otherwise, we don't choose a scale at which this
   1194   // layer's rastered content would become larger than the viewport.
   1195   if (draw_properties().screen_space_transform_is_animating &&
   1196       !ShouldAdjustRasterScaleDuringScaleAnimations()) {
   1197     bool can_raster_at_maximum_scale = false;
   1198     // TODO(ajuma): If we need to deal with scale-down animations starting right
   1199     // as a layer gets promoted, then we'd want to have the
   1200     // |starting_animation_contents_scale| passed in here as a separate draw
   1201     // property so we could try use that when the max is too large.
   1202     // See crbug.com/422341.
   1203     float maximum_scale = draw_properties().maximum_animation_contents_scale;
   1204     if (maximum_scale) {
   1205       gfx::Size bounds_at_maximum_scale =
   1206           gfx::ToCeiledSize(gfx::ScaleSize(bounds(), maximum_scale));
   1207       if (bounds_at_maximum_scale.GetArea() <=
   1208           layer_tree_impl()->device_viewport_size().GetArea())
   1209         can_raster_at_maximum_scale = true;
   1210     }
   1211     // Use the computed scales for the raster scale directly, do not try to use
   1212     // the ideal scale here. The current ideal scale may be way too large in the
   1213     // case of an animation with scale, and will be constantly changing.
   1214     if (can_raster_at_maximum_scale)
   1215       raster_contents_scale_ = maximum_scale;
   1216     else
   1217       raster_contents_scale_ = 1.f * ideal_page_scale_ * ideal_device_scale_;
   1218   }
   1219 
   1220   // If this layer would create zero or one tiles at this content scale,
   1221   // don't create a low res tiling.
   1222   gfx::Size content_bounds =
   1223       gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_));
   1224   gfx::Size tile_size = CalculateTileSize(content_bounds);
   1225   bool tile_covers_bounds = tile_size.width() >= content_bounds.width() &&
   1226                             tile_size.height() >= content_bounds.height();
   1227   if (tile_size.IsEmpty() || tile_covers_bounds) {
   1228     low_res_raster_contents_scale_ = raster_contents_scale_;
   1229     return;
   1230   }
   1231 
   1232   float low_res_factor =
   1233       layer_tree_impl()->settings().low_res_contents_scale_factor;
   1234   low_res_raster_contents_scale_ = std::max(
   1235       raster_contents_scale_ * low_res_factor,
   1236       MinimumContentsScale());
   1237 }
   1238 
   1239 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
   1240     std::vector<PictureLayerTiling*> used_tilings) {
   1241   DCHECK(layer_tree_impl()->IsActiveTree());
   1242   if (tilings_->num_tilings() == 0)
   1243     return;
   1244 
   1245   float min_acceptable_high_res_scale = std::min(
   1246       raster_contents_scale_, ideal_contents_scale_);
   1247   float max_acceptable_high_res_scale = std::max(
   1248       raster_contents_scale_, ideal_contents_scale_);
   1249   float twin_low_res_scale = 0.f;
   1250 
   1251   PictureLayerImpl* twin = twin_layer_;
   1252   if (twin && twin->CanHaveTilings()) {
   1253     min_acceptable_high_res_scale = std::min(
   1254         min_acceptable_high_res_scale,
   1255         std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_));
   1256     max_acceptable_high_res_scale = std::max(
   1257         max_acceptable_high_res_scale,
   1258         std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
   1259 
   1260     for (size_t i = 0; i < twin->tilings_->num_tilings(); ++i) {
   1261       PictureLayerTiling* tiling = twin->tilings_->tiling_at(i);
   1262       if (tiling->resolution() == LOW_RESOLUTION)
   1263         twin_low_res_scale = tiling->contents_scale();
   1264     }
   1265   }
   1266 
   1267   std::vector<PictureLayerTiling*> to_remove;
   1268   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
   1269     PictureLayerTiling* tiling = tilings_->tiling_at(i);
   1270 
   1271     // Keep multiple high resolution tilings even if not used to help
   1272     // activate earlier at non-ideal resolutions.
   1273     if (tiling->contents_scale() >= min_acceptable_high_res_scale &&
   1274         tiling->contents_scale() <= max_acceptable_high_res_scale)
   1275       continue;
   1276 
   1277     // Keep low resolution tilings, if the layer should have them.
   1278     if (layer_tree_impl()->create_low_res_tiling()) {
   1279       if (tiling->resolution() == LOW_RESOLUTION ||
   1280           tiling->contents_scale() == twin_low_res_scale)
   1281         continue;
   1282     }
   1283 
   1284     // Don't remove tilings that are being used (and thus would cause a flash.)
   1285     if (std::find(used_tilings.begin(), used_tilings.end(), tiling) !=
   1286         used_tilings.end())
   1287       continue;
   1288 
   1289     to_remove.push_back(tiling);
   1290   }
   1291 
   1292   if (to_remove.empty())
   1293     return;
   1294 
   1295   PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
   1296   // Remove tilings on this tree and the twin tree.
   1297   for (size_t i = 0; i < to_remove.size(); ++i) {
   1298     const PictureLayerTiling* twin_tiling = GetTwinTiling(to_remove[i]);
   1299     // Only remove tilings from the twin layer if they have
   1300     // NON_IDEAL_RESOLUTION.
   1301     if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
   1302       twin->RemoveTiling(to_remove[i]->contents_scale());
   1303     // Remove the tiling from the recycle tree. Note that we ignore resolution,
   1304     // since we don't need to maintain high/low res on the recycle tree.
   1305     if (recycled_twin)
   1306       recycled_twin->RemoveTiling(to_remove[i]->contents_scale());
   1307     // TODO(enne): temporary sanity CHECK for http://crbug.com/358350
   1308     CHECK_NE(HIGH_RESOLUTION, to_remove[i]->resolution());
   1309     tilings_->Remove(to_remove[i]);
   1310   }
   1311 
   1312   DCHECK_GT(tilings_->num_tilings(), 0u);
   1313   SanityCheckTilingState();
   1314 }
   1315 
   1316 float PictureLayerImpl::MinimumContentsScale() const {
   1317   float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
   1318 
   1319   // If the contents scale is less than 1 / width (also for height),
   1320   // then it will end up having less than one pixel of content in that
   1321   // dimension.  Bump the minimum contents scale up in this case to prevent
   1322   // this from happening.
   1323   int min_dimension = std::min(bounds().width(), bounds().height());
   1324   if (!min_dimension)
   1325     return setting_min;
   1326 
   1327   return std::max(1.f / min_dimension, setting_min);
   1328 }
   1329 
   1330 void PictureLayerImpl::ResetRasterScale() {
   1331   raster_page_scale_ = 0.f;
   1332   raster_device_scale_ = 0.f;
   1333   raster_source_scale_ = 0.f;
   1334   raster_contents_scale_ = 0.f;
   1335   low_res_raster_contents_scale_ = 0.f;
   1336   raster_source_scale_is_fixed_ = false;
   1337 
   1338   // When raster scales aren't valid, don't update tile priorities until
   1339   // this layer has been updated via UpdateDrawProperties.
   1340   should_update_tile_priorities_ = false;
   1341 }
   1342 
   1343 bool PictureLayerImpl::CanHaveTilings() const {
   1344   if (pile_->is_solid_color())
   1345     return false;
   1346   if (!DrawsContent())
   1347     return false;
   1348   if (!pile_->HasRecordings())
   1349     return false;
   1350   return true;
   1351 }
   1352 
   1353 bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale) const {
   1354   if (!CanHaveTilings())
   1355     return false;
   1356   if (contents_scale < MinimumContentsScale())
   1357     return false;
   1358   return true;
   1359 }
   1360 
   1361 void PictureLayerImpl::SanityCheckTilingState() const {
   1362 #if DCHECK_IS_ON
   1363   // Recycle tree doesn't have any restrictions.
   1364   if (layer_tree_impl()->IsRecycleTree())
   1365     return;
   1366 
   1367   if (!CanHaveTilings()) {
   1368     DCHECK_EQ(0u, tilings_->num_tilings());
   1369     return;
   1370   }
   1371   if (tilings_->num_tilings() == 0)
   1372     return;
   1373 
   1374   // MarkVisibleResourcesAsRequired depends on having exactly 1 high res
   1375   // tiling to mark its tiles as being required for activation.
   1376   DCHECK_EQ(1, tilings_->NumHighResTilings());
   1377 #endif
   1378 }
   1379 
   1380 bool PictureLayerImpl::ShouldAdjustRasterScaleDuringScaleAnimations() const {
   1381   if (!layer_tree_impl()->use_gpu_rasterization())
   1382     return false;
   1383 
   1384   // Re-rastering text at different scales using GPU rasterization causes
   1385   // texture uploads for glyphs at each scale (see crbug.com/366225). To
   1386   // workaround this performance issue, we don't re-rasterize layers with
   1387   // text during scale animations.
   1388   // TODO(ajuma): Remove this workaround once text can be efficiently
   1389   // re-rastered at different scales (e.g. by using distance-field fonts).
   1390   if (pile_->has_text())
   1391     return false;
   1392 
   1393   return true;
   1394 }
   1395 
   1396 float PictureLayerImpl::MaximumTilingContentsScale() const {
   1397   float max_contents_scale = MinimumContentsScale();
   1398   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
   1399     const PictureLayerTiling* tiling = tilings_->tiling_at(i);
   1400     max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
   1401   }
   1402   return max_contents_scale;
   1403 }
   1404 
   1405 void PictureLayerImpl::UpdateIdealScales() {
   1406   DCHECK(CanHaveTilings());
   1407 
   1408   float min_contents_scale = MinimumContentsScale();
   1409   DCHECK_GT(min_contents_scale, 0.f);
   1410   float min_page_scale = layer_tree_impl()->min_page_scale_factor();
   1411   DCHECK_GT(min_page_scale, 0.f);
   1412   float min_device_scale = 1.f;
   1413   float min_source_scale =
   1414       min_contents_scale / min_page_scale / min_device_scale;
   1415 
   1416   float ideal_page_scale = draw_properties().page_scale_factor;
   1417   float ideal_device_scale = draw_properties().device_scale_factor;
   1418   float ideal_source_scale = draw_properties().ideal_contents_scale /
   1419                              ideal_page_scale / ideal_device_scale;
   1420   ideal_contents_scale_ =
   1421       std::max(draw_properties().ideal_contents_scale, min_contents_scale);
   1422   ideal_page_scale_ = draw_properties().page_scale_factor;
   1423   ideal_device_scale_ = draw_properties().device_scale_factor;
   1424   ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
   1425 }
   1426 
   1427 void PictureLayerImpl::GetDebugBorderProperties(
   1428     SkColor* color,
   1429     float* width) const {
   1430   *color = DebugColors::TiledContentLayerBorderColor();
   1431   *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
   1432 }
   1433 
   1434 void PictureLayerImpl::GetAllTilesForTracing(
   1435     std::set<const Tile*>* tiles) const {
   1436   if (!tilings_)
   1437     return;
   1438 
   1439   for (size_t i = 0; i < tilings_->num_tilings(); ++i)
   1440     tilings_->tiling_at(i)->GetAllTilesForTracing(tiles);
   1441 }
   1442 
   1443 void PictureLayerImpl::AsValueInto(base::debug::TracedValue* state) const {
   1444   const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
   1445   LayerImpl::AsValueInto(state);
   1446   state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
   1447   state->SetDouble("geometry_contents_scale", MaximumTilingContentsScale());
   1448   state->BeginArray("tilings");
   1449   tilings_->AsValueInto(state);
   1450   state->EndArray();
   1451 
   1452   state->BeginArray("tile_priority_rect");
   1453   MathUtil::AddToTracedValue(GetViewportForTilePriorityInContentSpace(), state);
   1454   state->EndArray();
   1455 
   1456   state->BeginArray("visible_rect");
   1457   MathUtil::AddToTracedValue(visible_content_rect(), state);
   1458   state->EndArray();
   1459 
   1460   state->BeginArray("pictures");
   1461   pile_->AsValueInto(state);
   1462   state->EndArray();
   1463 
   1464   state->BeginArray("invalidation");
   1465   invalidation_.AsValueInto(state);
   1466   state->EndArray();
   1467 
   1468   state->BeginArray("coverage_tiles");
   1469   for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
   1470                                                     1.f,
   1471                                                     gfx::Rect(content_bounds()),
   1472                                                     ideal_contents_scale_);
   1473        iter;
   1474        ++iter) {
   1475     state->BeginDictionary();
   1476 
   1477     state->BeginArray("geometry_rect");
   1478     MathUtil::AddToTracedValue(iter.geometry_rect(), state);
   1479     state->EndArray();
   1480 
   1481     if (*iter)
   1482       TracedValue::SetIDRef(*iter, state, "tile");
   1483 
   1484     state->EndDictionary();
   1485   }
   1486   state->EndArray();
   1487 }
   1488 
   1489 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
   1490   const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
   1491   return tilings_->GPUMemoryUsageInBytes();
   1492 }
   1493 
   1494 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
   1495   benchmark->RunOnLayer(this);
   1496 }
   1497 
   1498 WhichTree PictureLayerImpl::GetTree() const {
   1499   return layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
   1500 }
   1501 
   1502 bool PictureLayerImpl::IsOnActiveOrPendingTree() const {
   1503   return !layer_tree_impl()->IsRecycleTree();
   1504 }
   1505 
   1506 bool PictureLayerImpl::HasValidTilePriorities() const {
   1507   return IsOnActiveOrPendingTree() && IsDrawnRenderSurfaceLayerListMember();
   1508 }
   1509 
   1510 bool PictureLayerImpl::AllTilesRequiredForActivationAreReadyToDraw() const {
   1511   if (!layer_tree_impl()->IsPendingTree())
   1512     return true;
   1513 
   1514   if (!HasValidTilePriorities())
   1515     return true;
   1516 
   1517   if (!tilings_)
   1518     return true;
   1519 
   1520   if (visible_rect_for_tile_priority_.IsEmpty())
   1521     return true;
   1522 
   1523   gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
   1524   rect.Intersect(visible_rect_for_tile_priority_);
   1525 
   1526   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
   1527     PictureLayerTiling* tiling = tilings_->tiling_at(i);
   1528     if (tiling->resolution() != HIGH_RESOLUTION &&
   1529         tiling->resolution() != LOW_RESOLUTION)
   1530       continue;
   1531 
   1532     for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
   1533          ++iter) {
   1534       const Tile* tile = *iter;
   1535       // A null tile (i.e. missing recording) can just be skipped.
   1536       if (!tile)
   1537         continue;
   1538 
   1539       if (tile->required_for_activation() && !tile->IsReadyToDraw())
   1540         return false;
   1541     }
   1542   }
   1543 
   1544   return true;
   1545 }
   1546 
   1547 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator()
   1548     : layer_(NULL), current_stage_(arraysize(stages_)) {
   1549 }
   1550 
   1551 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator(
   1552     PictureLayerImpl* layer,
   1553     bool prioritize_low_res)
   1554     : layer_(layer), current_stage_(0) {
   1555   DCHECK(layer_);
   1556 
   1557   // Early out if the layer has no tilings.
   1558   if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) {
   1559     current_stage_ = arraysize(stages_);
   1560     return;
   1561   }
   1562 
   1563   // Tiles without valid priority are treated as having lowest priority and
   1564   // never considered for raster.
   1565   if (!layer_->HasValidTilePriorities()) {
   1566     current_stage_ = arraysize(stages_);
   1567     return;
   1568   }
   1569 
   1570   WhichTree tree = layer_->GetTree();
   1571 
   1572   // Find high and low res tilings and initialize the iterators.
   1573   for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) {
   1574     PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i);
   1575     if (tiling->resolution() == HIGH_RESOLUTION) {
   1576       iterators_[HIGH_RES] =
   1577           PictureLayerTiling::TilingRasterTileIterator(tiling, tree);
   1578     }
   1579 
   1580     if (tiling->resolution() == LOW_RESOLUTION) {
   1581       iterators_[LOW_RES] =
   1582           PictureLayerTiling::TilingRasterTileIterator(tiling, tree);
   1583     }
   1584   }
   1585 
   1586   if (prioritize_low_res) {
   1587     stages_[0].iterator_type = LOW_RES;
   1588     stages_[0].tile_type = TilePriority::NOW;
   1589 
   1590     stages_[1].iterator_type = HIGH_RES;
   1591     stages_[1].tile_type = TilePriority::NOW;
   1592   } else {
   1593     stages_[0].iterator_type = HIGH_RES;
   1594     stages_[0].tile_type = TilePriority::NOW;
   1595 
   1596     stages_[1].iterator_type = LOW_RES;
   1597     stages_[1].tile_type = TilePriority::NOW;
   1598   }
   1599 
   1600   stages_[2].iterator_type = HIGH_RES;
   1601   stages_[2].tile_type = TilePriority::SOON;
   1602 
   1603   stages_[3].iterator_type = HIGH_RES;
   1604   stages_[3].tile_type = TilePriority::EVENTUALLY;
   1605 
   1606   IteratorType index = stages_[current_stage_].iterator_type;
   1607   TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
   1608   if (!iterators_[index] || iterators_[index].get_type() != tile_type)
   1609     AdvanceToNextStage();
   1610 }
   1611 
   1612 PictureLayerImpl::LayerRasterTileIterator::~LayerRasterTileIterator() {}
   1613 
   1614 PictureLayerImpl::LayerRasterTileIterator::operator bool() const {
   1615   return current_stage_ < arraysize(stages_);
   1616 }
   1617 
   1618 PictureLayerImpl::LayerRasterTileIterator&
   1619 PictureLayerImpl::LayerRasterTileIterator::
   1620 operator++() {
   1621   IteratorType index = stages_[current_stage_].iterator_type;
   1622   TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
   1623 
   1624   // First advance the iterator.
   1625   DCHECK(iterators_[index]);
   1626   DCHECK(iterators_[index].get_type() == tile_type);
   1627   ++iterators_[index];
   1628 
   1629   if (!iterators_[index] || iterators_[index].get_type() != tile_type)
   1630     AdvanceToNextStage();
   1631 
   1632   return *this;
   1633 }
   1634 
   1635 Tile* PictureLayerImpl::LayerRasterTileIterator::operator*() {
   1636   DCHECK(*this);
   1637 
   1638   IteratorType index = stages_[current_stage_].iterator_type;
   1639   DCHECK(iterators_[index]);
   1640   DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type);
   1641 
   1642   return *iterators_[index];
   1643 }
   1644 
   1645 const Tile* PictureLayerImpl::LayerRasterTileIterator::operator*() const {
   1646   DCHECK(*this);
   1647 
   1648   IteratorType index = stages_[current_stage_].iterator_type;
   1649   DCHECK(iterators_[index]);
   1650   DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type);
   1651 
   1652   return *iterators_[index];
   1653 }
   1654 
   1655 void PictureLayerImpl::LayerRasterTileIterator::AdvanceToNextStage() {
   1656   DCHECK_LT(current_stage_, arraysize(stages_));
   1657   ++current_stage_;
   1658   while (current_stage_ < arraysize(stages_)) {
   1659     IteratorType index = stages_[current_stage_].iterator_type;
   1660     TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
   1661 
   1662     if (iterators_[index] && iterators_[index].get_type() == tile_type)
   1663       break;
   1664     ++current_stage_;
   1665   }
   1666 }
   1667 
   1668 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator()
   1669     : layer_(NULL),
   1670       tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES),
   1671       current_category_(PictureLayerTiling::EVENTUALLY),
   1672       current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
   1673       current_tiling_(0u) {
   1674 }
   1675 
   1676 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator(
   1677     PictureLayerImpl* layer,
   1678     TreePriority tree_priority)
   1679     : layer_(layer),
   1680       tree_priority_(tree_priority),
   1681       current_category_(PictureLayerTiling::EVENTUALLY),
   1682       current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
   1683       current_tiling_(CurrentTilingRange().start - 1u) {
   1684   // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure
   1685   // that layers that don't have valid tile priorities have lowest priorities so
   1686   // they evict their tiles first (crbug.com/381704)
   1687   DCHECK(layer_->tilings_);
   1688   do {
   1689     if (!AdvanceToNextTiling())
   1690       break;
   1691 
   1692     current_iterator_ = PictureLayerTiling::TilingEvictionTileIterator(
   1693         layer_->tilings_->tiling_at(CurrentTilingIndex()),
   1694         tree_priority,
   1695         current_category_);
   1696   } while (!current_iterator_);
   1697 }
   1698 
   1699 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {
   1700 }
   1701 
   1702 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() {
   1703   DCHECK(*this);
   1704   return *current_iterator_;
   1705 }
   1706 
   1707 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const {
   1708   DCHECK(*this);
   1709   return *current_iterator_;
   1710 }
   1711 
   1712 PictureLayerImpl::LayerEvictionTileIterator&
   1713 PictureLayerImpl::LayerEvictionTileIterator::
   1714 operator++() {
   1715   DCHECK(*this);
   1716   ++current_iterator_;
   1717   while (!current_iterator_) {
   1718     if (!AdvanceToNextTiling())
   1719       break;
   1720 
   1721     current_iterator_ = PictureLayerTiling::TilingEvictionTileIterator(
   1722         layer_->tilings_->tiling_at(CurrentTilingIndex()),
   1723         tree_priority_,
   1724         current_category_);
   1725   }
   1726   return *this;
   1727 }
   1728 
   1729 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const {
   1730   return !!current_iterator_;
   1731 }
   1732 
   1733 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextCategory() {
   1734   switch (current_category_) {
   1735     case PictureLayerTiling::EVENTUALLY:
   1736       current_category_ =
   1737           PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION;
   1738       return true;
   1739     case PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
   1740       current_category_ = PictureLayerTiling::SOON;
   1741       return true;
   1742     case PictureLayerTiling::SOON:
   1743       current_category_ = PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION;
   1744       return true;
   1745     case PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION:
   1746       current_category_ = PictureLayerTiling::NOW;
   1747       return true;
   1748     case PictureLayerTiling::NOW:
   1749       current_category_ = PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION;
   1750       return true;
   1751     case PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION:
   1752       return false;
   1753   }
   1754   NOTREACHED();
   1755   return false;
   1756 }
   1757 
   1758 bool
   1759 PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextTilingRangeType() {
   1760   switch (current_tiling_range_type_) {
   1761     case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
   1762       current_tiling_range_type_ = PictureLayerTilingSet::LOWER_THAN_LOW_RES;
   1763       return true;
   1764     case PictureLayerTilingSet::LOWER_THAN_LOW_RES:
   1765       current_tiling_range_type_ =
   1766           PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES;
   1767       return true;
   1768     case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
   1769       current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES;
   1770       return true;
   1771     case PictureLayerTilingSet::LOW_RES:
   1772       current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES;
   1773       return true;
   1774     case PictureLayerTilingSet::HIGH_RES:
   1775       if (!AdvanceToNextCategory())
   1776         return false;
   1777 
   1778       current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES;
   1779       return true;
   1780   }
   1781   NOTREACHED();
   1782   return false;
   1783 }
   1784 
   1785 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextTiling() {
   1786   DCHECK_NE(current_tiling_, CurrentTilingRange().end);
   1787   ++current_tiling_;
   1788   while (current_tiling_ == CurrentTilingRange().end) {
   1789     if (!AdvanceToNextTilingRangeType())
   1790       return false;
   1791 
   1792     current_tiling_ = CurrentTilingRange().start;
   1793   }
   1794   return true;
   1795 }
   1796 
   1797 PictureLayerTilingSet::TilingRange
   1798 PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingRange() const {
   1799   return layer_->tilings_->GetTilingRange(current_tiling_range_type_);
   1800 }
   1801 
   1802 size_t PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingIndex() const {
   1803   DCHECK_NE(current_tiling_, CurrentTilingRange().end);
   1804   switch (current_tiling_range_type_) {
   1805     case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
   1806     case PictureLayerTilingSet::LOW_RES:
   1807     case PictureLayerTilingSet::HIGH_RES:
   1808       return current_tiling_;
   1809     // Tilings in the following ranges are accessed in reverse order.
   1810     case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
   1811     case PictureLayerTilingSet::LOWER_THAN_LOW_RES: {
   1812       PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange();
   1813       size_t current_tiling_range_offset = current_tiling_ - tiling_range.start;
   1814       return tiling_range.end - 1 - current_tiling_range_offset;
   1815     }
   1816   }
   1817   NOTREACHED();
   1818   return 0;
   1819 }
   1820 
   1821 }  // namespace cc
   1822