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