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 
      9 #include "base/time/time.h"
     10 #include "cc/base/math_util.h"
     11 #include "cc/base/util.h"
     12 #include "cc/debug/debug_colors.h"
     13 #include "cc/debug/traced_value.h"
     14 #include "cc/layers/append_quads_data.h"
     15 #include "cc/layers/quad_sink.h"
     16 #include "cc/quads/checkerboard_draw_quad.h"
     17 #include "cc/quads/debug_border_draw_quad.h"
     18 #include "cc/quads/picture_draw_quad.h"
     19 #include "cc/quads/solid_color_draw_quad.h"
     20 #include "cc/quads/tile_draw_quad.h"
     21 #include "cc/trees/layer_tree_impl.h"
     22 #include "ui/gfx/quad_f.h"
     23 #include "ui/gfx/rect_conversions.h"
     24 #include "ui/gfx/size_conversions.h"
     25 
     26 namespace {
     27 const float kMaxScaleRatioDuringPinch = 2.0f;
     28 }
     29 
     30 namespace cc {
     31 
     32 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
     33     : LayerImpl(tree_impl, id),
     34       twin_layer_(NULL),
     35       pile_(PicturePileImpl::Create()),
     36       last_content_scale_(0),
     37       is_mask_(false),
     38       ideal_page_scale_(0.f),
     39       ideal_device_scale_(0.f),
     40       ideal_source_scale_(0.f),
     41       ideal_contents_scale_(0.f),
     42       raster_page_scale_(0.f),
     43       raster_device_scale_(0.f),
     44       raster_source_scale_(0.f),
     45       raster_contents_scale_(0.f),
     46       low_res_raster_contents_scale_(0.f),
     47       raster_source_scale_was_animating_(false),
     48       is_using_lcd_text_(tree_impl->settings().can_use_lcd_text),
     49       should_update_tile_priorities_(false) {}
     50 
     51 PictureLayerImpl::~PictureLayerImpl() {}
     52 
     53 const char* PictureLayerImpl::LayerTypeAsString() const {
     54   return "cc::PictureLayerImpl";
     55 }
     56 
     57 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
     58     LayerTreeImpl* tree_impl) {
     59   return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
     60 }
     61 
     62 void PictureLayerImpl::CreateTilingSetIfNeeded() {
     63   DCHECK(layer_tree_impl()->IsPendingTree());
     64   if (!tilings_)
     65     tilings_.reset(new PictureLayerTilingSet(this, bounds()));
     66 }
     67 
     68 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
     69   LayerImpl::PushPropertiesTo(base_layer);
     70 
     71   PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
     72 
     73   // When the pending tree pushes to the active tree, the pending twin
     74   // disappears.
     75   layer_impl->twin_layer_ = NULL;
     76   twin_layer_ = NULL;
     77 
     78   layer_impl->SetIsMask(is_mask_);
     79   layer_impl->pile_ = pile_;
     80   pile_ = NULL;
     81 
     82   layer_impl->tilings_.swap(tilings_);
     83   layer_impl->tilings_->SetClient(layer_impl);
     84   if (tilings_)
     85     tilings_->SetClient(this);
     86 
     87   layer_impl->raster_page_scale_ = raster_page_scale_;
     88   layer_impl->raster_device_scale_ = raster_device_scale_;
     89   layer_impl->raster_source_scale_ = raster_source_scale_;
     90   layer_impl->raster_contents_scale_ = raster_contents_scale_;
     91   layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
     92 
     93   layer_impl->UpdateLCDTextStatus(is_using_lcd_text_);
     94 
     95   // As an optimization, don't make a copy of this potentially complex region,
     96   // and swap it directly from the pending to the active layer.  In general, any
     97   // property pushed to a LayerImpl continues to live on that LayerImpl.
     98   // However, invalidation is the difference between two main thread frames, so
     99   // it no longer makes sense once the pending tree gets recycled.  It will
    100   // always get pushed during PictureLayer::PushPropertiesTo.
    101   layer_impl->invalidation_.Swap(&invalidation_);
    102   invalidation_.Clear();
    103 }
    104 
    105 void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
    106                                    AppendQuadsData* append_quads_data) {
    107   gfx::Rect rect(visible_content_rect());
    108   gfx::Rect content_rect(content_bounds());
    109 
    110   SharedQuadState* shared_quad_state =
    111       quad_sink->UseSharedQuadState(CreateSharedQuadState());
    112 
    113   bool draw_direct_to_backbuffer =
    114       draw_properties().can_draw_directly_to_backbuffer &&
    115       layer_tree_impl()->settings().force_direct_layer_drawing;
    116 
    117   if (draw_direct_to_backbuffer ||
    118       current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
    119     AppendDebugBorderQuad(
    120         quad_sink,
    121         shared_quad_state,
    122         append_quads_data,
    123         DebugColors::DirectPictureBorderColor(),
    124         DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
    125 
    126     gfx::Rect geometry_rect = rect;
    127     gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
    128     gfx::Size texture_size = rect.size();
    129     gfx::RectF texture_rect = gfx::RectF(texture_size);
    130     gfx::Rect quad_content_rect = rect;
    131     float contents_scale = contents_scale_x();
    132 
    133     scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
    134     quad->SetNew(shared_quad_state,
    135                  geometry_rect,
    136                  opaque_rect,
    137                  texture_rect,
    138                  texture_size,
    139                  false,
    140                  quad_content_rect,
    141                  contents_scale,
    142                  draw_direct_to_backbuffer,
    143                  pile_);
    144     if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
    145       append_quads_data->num_missing_tiles++;
    146     return;
    147   }
    148 
    149   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
    150 
    151   bool clipped = false;
    152   gfx::QuadF target_quad = MathUtil::MapQuad(
    153       draw_transform(),
    154       gfx::QuadF(rect),
    155       &clipped);
    156   if (ShowDebugBorders()) {
    157     for (PictureLayerTilingSet::CoverageIterator iter(
    158         tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
    159          iter;
    160          ++iter) {
    161       SkColor color;
    162       float width;
    163       if (*iter && iter->IsReadyToDraw()) {
    164         ManagedTileState::TileVersion::Mode mode =
    165             iter->GetTileVersionForDrawing().mode();
    166         if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
    167           color = DebugColors::SolidColorTileBorderColor();
    168           width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
    169         } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
    170           color = DebugColors::PictureTileBorderColor();
    171           width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
    172         } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) {
    173           color = DebugColors::HighResTileBorderColor();
    174           width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
    175         } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) {
    176           color = DebugColors::LowResTileBorderColor();
    177           width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
    178         } else if (iter->contents_scale() > contents_scale_x()) {
    179           color = DebugColors::ExtraHighResTileBorderColor();
    180           width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
    181         } else {
    182           color = DebugColors::ExtraLowResTileBorderColor();
    183           width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
    184         }
    185       } else {
    186         color = DebugColors::MissingTileBorderColor();
    187         width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
    188       }
    189 
    190       scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
    191           DebugBorderDrawQuad::Create();
    192       gfx::Rect geometry_rect = iter.geometry_rect();
    193       debug_border_quad->SetNew(shared_quad_state, geometry_rect, color, width);
    194       quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(),
    195                         append_quads_data);
    196     }
    197   }
    198 
    199   // Keep track of the tilings that were used so that tilings that are
    200   // unused can be considered for removal.
    201   std::vector<PictureLayerTiling*> seen_tilings;
    202 
    203   for (PictureLayerTilingSet::CoverageIterator iter(
    204       tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
    205        iter;
    206        ++iter) {
    207     gfx::Rect geometry_rect = iter.geometry_rect();
    208     if (!*iter || !iter->IsReadyToDraw()) {
    209       if (DrawCheckerboardForMissingTiles()) {
    210         // TODO(enne): Figure out how to show debug "invalidated checker" color
    211         scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create();
    212         SkColor color = DebugColors::DefaultCheckerboardColor();
    213         quad->SetNew(shared_quad_state, geometry_rect, color);
    214         if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
    215           append_quads_data->num_missing_tiles++;
    216       } else {
    217         SkColor color = SafeOpaqueBackgroundColor();
    218         scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
    219         quad->SetNew(shared_quad_state, geometry_rect, color, false);
    220         if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
    221           append_quads_data->num_missing_tiles++;
    222       }
    223 
    224       append_quads_data->had_incomplete_tile = true;
    225       continue;
    226     }
    227 
    228     const ManagedTileState::TileVersion& tile_version =
    229         iter->GetTileVersionForDrawing();
    230     switch (tile_version.mode()) {
    231       case ManagedTileState::TileVersion::RESOURCE_MODE: {
    232         gfx::RectF texture_rect = iter.texture_rect();
    233         gfx::Rect opaque_rect = iter->opaque_rect();
    234         opaque_rect.Intersect(content_rect);
    235 
    236         if (iter->contents_scale() != ideal_contents_scale_)
    237           append_quads_data->had_incomplete_tile = true;
    238 
    239         scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
    240         quad->SetNew(shared_quad_state,
    241                      geometry_rect,
    242                      opaque_rect,
    243                      tile_version.get_resource_id(),
    244                      texture_rect,
    245                      iter.texture_size(),
    246                      tile_version.contents_swizzled());
    247         quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
    248         break;
    249       }
    250       case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
    251         gfx::RectF texture_rect = iter.texture_rect();
    252         gfx::Rect opaque_rect = iter->opaque_rect();
    253         opaque_rect.Intersect(content_rect);
    254 
    255         scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
    256         quad->SetNew(shared_quad_state,
    257                      geometry_rect,
    258                      opaque_rect,
    259                      texture_rect,
    260                      iter.texture_size(),
    261                      // TODO(reveman): This assumes the renderer will use
    262                      // GL_RGBA as format of temporary resource. The need
    263                      // to swizzle should instead be determined by the
    264                      // renderer.
    265                      !PlatformColor::SameComponentOrder(GL_RGBA),
    266                      iter->content_rect(),
    267                      iter->contents_scale(),
    268                      draw_direct_to_backbuffer,
    269                      pile_);
    270         quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
    271         break;
    272       }
    273       case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
    274         scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
    275         quad->SetNew(shared_quad_state,
    276                      geometry_rect,
    277                      tile_version.get_solid_color(),
    278                      false);
    279         quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
    280         break;
    281       }
    282       default:
    283         NOTREACHED();
    284     }
    285 
    286     if (!seen_tilings.size() || seen_tilings.back() != iter.CurrentTiling())
    287       seen_tilings.push_back(iter.CurrentTiling());
    288   }
    289 
    290   // Aggressively remove any tilings that are not seen to save memory. Note
    291   // that this is at the expense of doing cause more frequent re-painting. A
    292   // better scheme would be to maintain a tighter visible_content_rect for the
    293   // finer tilings.
    294   CleanUpTilingsOnActiveLayer(seen_tilings);
    295 }
    296 
    297 void PictureLayerImpl::UpdateTilePriorities() {
    298   CHECK(should_update_tile_priorities_);
    299 
    300   if (!tilings_->num_tilings())
    301     return;
    302 
    303   if (!layer_tree_impl()->DeviceViewportValidForTileManagement())
    304     return;
    305 
    306   double current_frame_time_in_seconds =
    307       (layer_tree_impl()->CurrentFrameTimeTicks() -
    308        base::TimeTicks()).InSecondsF();
    309 
    310   bool tiling_needs_update = false;
    311   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    312     if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime(
    313             current_frame_time_in_seconds)) {
    314       tiling_needs_update = true;
    315       break;
    316     }
    317   }
    318   if (!tiling_needs_update)
    319     return;
    320 
    321   // At this point, tile priorities are going to be modified.
    322   layer_tree_impl()->WillModifyTilePriorities();
    323 
    324   UpdateLCDTextStatus(can_use_lcd_text());
    325 
    326   gfx::Transform current_screen_space_transform = screen_space_transform();
    327 
    328   gfx::Size device_viewport_size = layer_tree_impl()->DeviceViewport().size();
    329   gfx::Rect viewport_in_content_space;
    330   gfx::Transform screen_to_layer(gfx::Transform::kSkipInitialization);
    331   if (screen_space_transform().GetInverse(&screen_to_layer)) {
    332     viewport_in_content_space =
    333         gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
    334             screen_to_layer, gfx::Rect(device_viewport_size)));
    335   }
    336 
    337   WhichTree tree =
    338       layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
    339   size_t max_tiles_for_interest_area =
    340       layer_tree_impl()->settings().max_tiles_for_interest_area;
    341   tilings_->UpdateTilePriorities(
    342       tree,
    343       device_viewport_size,
    344       viewport_in_content_space,
    345       visible_content_rect(),
    346       last_bounds_,
    347       bounds(),
    348       last_content_scale_,
    349       contents_scale_x(),
    350       last_screen_space_transform_,
    351       current_screen_space_transform,
    352       current_frame_time_in_seconds,
    353       max_tiles_for_interest_area);
    354 
    355   if (layer_tree_impl()->IsPendingTree())
    356     MarkVisibleResourcesAsRequired();
    357 
    358   last_screen_space_transform_ = current_screen_space_transform;
    359   last_bounds_ = bounds();
    360   last_content_scale_ = contents_scale_x();
    361 }
    362 
    363 void PictureLayerImpl::DidBecomeActive() {
    364   LayerImpl::DidBecomeActive();
    365   tilings_->DidBecomeActive();
    366   layer_tree_impl()->WillModifyTilePriorities();
    367 }
    368 
    369 void PictureLayerImpl::DidBeginTracing() {
    370   pile_->DidBeginTracing();
    371 }
    372 
    373 void PictureLayerImpl::DidLoseOutputSurface() {
    374   if (tilings_)
    375     tilings_->RemoveAllTilings();
    376 
    377   ResetRasterScale();
    378 }
    379 
    380 void PictureLayerImpl::CalculateContentsScale(
    381     float ideal_contents_scale,
    382     float device_scale_factor,
    383     float page_scale_factor,
    384     bool animating_transform_to_screen,
    385     float* contents_scale_x,
    386     float* contents_scale_y,
    387     gfx::Size* content_bounds) {
    388   // This function sets valid raster scales and manages tilings, so tile
    389   // priorities can now be updated.
    390   should_update_tile_priorities_ = true;
    391 
    392   if (!CanHaveTilings()) {
    393     ideal_page_scale_ = page_scale_factor;
    394     ideal_device_scale_ = device_scale_factor;
    395     ideal_contents_scale_ = ideal_contents_scale;
    396     ideal_source_scale_ =
    397         ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_;
    398     *contents_scale_x = ideal_contents_scale_;
    399     *contents_scale_y = ideal_contents_scale_;
    400     *content_bounds = gfx::ToCeiledSize(gfx::ScaleSize(bounds(),
    401                                                        ideal_contents_scale_,
    402                                                        ideal_contents_scale_));
    403     return;
    404   }
    405 
    406   float min_contents_scale = MinimumContentsScale();
    407   DCHECK_GT(min_contents_scale, 0.f);
    408   float min_page_scale = layer_tree_impl()->min_page_scale_factor();
    409   DCHECK_GT(min_page_scale, 0.f);
    410   float min_device_scale = 1.f;
    411   float min_source_scale =
    412       min_contents_scale / min_page_scale / min_device_scale;
    413 
    414   float ideal_page_scale = page_scale_factor;
    415   float ideal_device_scale = device_scale_factor;
    416   float ideal_source_scale =
    417       ideal_contents_scale / ideal_page_scale / ideal_device_scale;
    418 
    419   ideal_contents_scale_ = std::max(ideal_contents_scale, min_contents_scale);
    420   ideal_page_scale_ = ideal_page_scale;
    421   ideal_device_scale_ = ideal_device_scale;
    422   ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
    423 
    424   ManageTilings(animating_transform_to_screen);
    425 
    426   // The content scale and bounds for a PictureLayerImpl is somewhat fictitious.
    427   // There are (usually) several tilings at different scales.  However, the
    428   // content bounds is the (integer!) space in which quads are generated.
    429   // In order to guarantee that we can fill this integer space with any set of
    430   // tilings (and then map back to floating point texture coordinates), the
    431   // contents scale must be at least as large as the largest of the tilings.
    432   float max_contents_scale = min_contents_scale;
    433   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    434     const PictureLayerTiling* tiling = tilings_->tiling_at(i);
    435     max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
    436   }
    437 
    438   *contents_scale_x = max_contents_scale;
    439   *contents_scale_y = max_contents_scale;
    440   *content_bounds = gfx::ToCeiledSize(
    441       gfx::ScaleSize(bounds(), max_contents_scale, max_contents_scale));
    442 }
    443 
    444 skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() {
    445   return pile_->GetFlattenedPicture();
    446 }
    447 
    448 scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
    449                                                  gfx::Rect content_rect) {
    450   if (!pile_->CanRaster(tiling->contents_scale(), content_rect))
    451     return scoped_refptr<Tile>();
    452 
    453   return make_scoped_refptr(new Tile(
    454       layer_tree_impl()->tile_manager(),
    455       pile_.get(),
    456       content_rect.size(),
    457       content_rect,
    458       contents_opaque() ? content_rect : gfx::Rect(),
    459       tiling->contents_scale(),
    460       id(),
    461       layer_tree_impl()->source_frame_number(),
    462       is_using_lcd_text_));
    463 }
    464 
    465 void PictureLayerImpl::UpdatePile(Tile* tile) {
    466   tile->set_picture_pile(pile_);
    467 }
    468 
    469 const Region* PictureLayerImpl::GetInvalidation() {
    470   return &invalidation_;
    471 }
    472 
    473 const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
    474     const PictureLayerTiling* tiling) {
    475 
    476   if (!twin_layer_)
    477     return NULL;
    478   for (size_t i = 0; i < twin_layer_->tilings_->num_tilings(); ++i)
    479     if (twin_layer_->tilings_->tiling_at(i)->contents_scale() ==
    480         tiling->contents_scale())
    481       return twin_layer_->tilings_->tiling_at(i);
    482   return NULL;
    483 }
    484 
    485 gfx::Size PictureLayerImpl::CalculateTileSize(
    486     gfx::Size content_bounds) const {
    487   if (is_mask_) {
    488     int max_size = layer_tree_impl()->MaxTextureSize();
    489     return gfx::Size(
    490         std::min(max_size, content_bounds.width()),
    491         std::min(max_size, content_bounds.height()));
    492   }
    493 
    494   int max_texture_size =
    495       layer_tree_impl()->resource_provider()->max_texture_size();
    496 
    497   gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size;
    498   default_tile_size.SetToMin(gfx::Size(max_texture_size, max_texture_size));
    499 
    500   gfx::Size max_untiled_content_size =
    501       layer_tree_impl()->settings().max_untiled_layer_size;
    502   max_untiled_content_size.SetToMin(
    503       gfx::Size(max_texture_size, max_texture_size));
    504 
    505   bool any_dimension_too_large =
    506       content_bounds.width() > max_untiled_content_size.width() ||
    507       content_bounds.height() > max_untiled_content_size.height();
    508 
    509   bool any_dimension_one_tile =
    510       content_bounds.width() <= default_tile_size.width() ||
    511       content_bounds.height() <= default_tile_size.height();
    512 
    513   // If long and skinny, tile at the max untiled content size, and clamp
    514   // the smaller dimension to the content size, e.g. 1000x12 layer with
    515   // 500x500 max untiled size would get 500x12 tiles.  Also do this
    516   // if the layer is small.
    517   if (any_dimension_one_tile || !any_dimension_too_large) {
    518     int width =
    519         std::min(max_untiled_content_size.width(), content_bounds.width());
    520     int height =
    521         std::min(max_untiled_content_size.height(), content_bounds.height());
    522     // Round width and height up to the closest multiple of 64, or 56 if
    523     // we should avoid power-of-two textures. This helps reduce the number
    524     // of different textures sizes to help recycling, and also keeps all
    525     // textures multiple-of-eight, which is preferred on some drivers (IMG).
    526     bool avoid_pow2 =
    527         layer_tree_impl()->GetRendererCapabilities().avoid_pow2_textures;
    528     int round_up_to = avoid_pow2 ? 56 : 64;
    529     width = RoundUp(width, round_up_to);
    530     height = RoundUp(height, round_up_to);
    531     return gfx::Size(width, height);
    532   }
    533 
    534   return default_tile_size;
    535 }
    536 
    537 void PictureLayerImpl::SyncFromActiveLayer() {
    538   DCHECK(layer_tree_impl()->IsPendingTree());
    539 
    540   if (twin_layer_)
    541     SyncFromActiveLayer(twin_layer_);
    542 }
    543 
    544 void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
    545   UpdateLCDTextStatus(other->is_using_lcd_text_);
    546 
    547   if (!DrawsContent()) {
    548     ResetRasterScale();
    549     return;
    550   }
    551 
    552   raster_page_scale_ = other->raster_page_scale_;
    553   raster_device_scale_ = other->raster_device_scale_;
    554   raster_source_scale_ = other->raster_source_scale_;
    555   raster_contents_scale_ = other->raster_contents_scale_;
    556   low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
    557 
    558   // Add synthetic invalidations for any recordings that were dropped.  As
    559   // tiles are updated to point to this new pile, this will force the dropping
    560   // of tiles that can no longer be rastered.  This is not ideal, but is a
    561   // trade-off for memory (use the same pile as much as possible, by switching
    562   // during DidBecomeActive) and for time (don't bother checking every tile
    563   // during activation to see if the new pile can still raster it).
    564   for (int x = 0; x < pile_->num_tiles_x(); ++x) {
    565     for (int y = 0; y < pile_->num_tiles_y(); ++y) {
    566       bool previously_had = other->pile_->HasRecordingAt(x, y);
    567       bool now_has = pile_->HasRecordingAt(x, y);
    568       if (now_has || !previously_had)
    569         continue;
    570       gfx::Rect layer_rect = pile_->tile_bounds(x, y);
    571       invalidation_.Union(layer_rect);
    572     }
    573   }
    574 
    575   // Union in the other newly exposed regions as invalid.
    576   Region difference_region = Region(gfx::Rect(bounds()));
    577   difference_region.Subtract(gfx::Rect(other->bounds()));
    578   invalidation_.Union(difference_region);
    579 
    580   if (CanHaveTilings()) {
    581     // The recycle tree's tiling set is two frames out of date, so it needs to
    582     // have both this frame's invalidation and the previous frame's invalidation
    583     // (stored on the active layer).
    584     Region tiling_invalidation = other->invalidation_;
    585     tiling_invalidation.Union(invalidation_);
    586     tilings_->SyncTilings(*other->tilings_,
    587                           bounds(),
    588                           tiling_invalidation,
    589                           MinimumContentsScale());
    590   } else {
    591     tilings_->RemoveAllTilings();
    592   }
    593 }
    594 
    595 void PictureLayerImpl::SyncTiling(
    596     const PictureLayerTiling* tiling) {
    597   if (!CanHaveTilingWithScale(tiling->contents_scale()))
    598     return;
    599   tilings_->AddTiling(tiling->contents_scale());
    600 
    601   // If this tree needs update draw properties, then the tiling will
    602   // get updated prior to drawing or activation.  If this tree does not
    603   // need update draw properties, then its transforms are up to date and
    604   // we can create tiles for this tiling immediately.
    605   if (!layer_tree_impl()->needs_update_draw_properties())
    606     UpdateTilePriorities();
    607 }
    608 
    609 void PictureLayerImpl::UpdateTwinLayer() {
    610   DCHECK(layer_tree_impl()->IsPendingTree());
    611 
    612   twin_layer_ = static_cast<PictureLayerImpl*>(
    613       layer_tree_impl()->FindActiveTreeLayerById(id()));
    614   if (twin_layer_)
    615     twin_layer_->twin_layer_ = this;
    616 }
    617 
    618 void PictureLayerImpl::SetIsMask(bool is_mask) {
    619   if (is_mask_ == is_mask)
    620     return;
    621   is_mask_ = is_mask;
    622   if (tilings_)
    623     tilings_->RemoveAllTiles();
    624 }
    625 
    626 ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {
    627   gfx::Rect content_rect(content_bounds());
    628   float scale = contents_scale_x();
    629   for (PictureLayerTilingSet::CoverageIterator
    630            iter(tilings_.get(), scale, content_rect, ideal_contents_scale_);
    631        iter;
    632        ++iter) {
    633     // Mask resource not ready yet.
    634     if (!*iter)
    635       return 0;
    636 
    637     const ManagedTileState::TileVersion& tile_version =
    638         iter->GetTileVersionForDrawing();
    639     if (!tile_version.IsReadyToDraw() ||
    640         tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE)
    641       return 0;
    642 
    643     // Masks only supported if they fit on exactly one tile.
    644     if (iter.geometry_rect() != content_rect)
    645       return 0;
    646 
    647     return tile_version.get_resource_id();
    648   }
    649   return 0;
    650 }
    651 
    652 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
    653   DCHECK(layer_tree_impl()->IsPendingTree());
    654   DCHECK(!layer_tree_impl()->needs_update_draw_properties());
    655   DCHECK(ideal_contents_scale_);
    656   DCHECK_GT(tilings_->num_tilings(), 0u);
    657 
    658   gfx::Rect rect(visible_content_rect());
    659 
    660   float min_acceptable_scale =
    661       std::min(raster_contents_scale_, ideal_contents_scale_);
    662 
    663   if (PictureLayerImpl* twin = twin_layer_) {
    664     float twin_min_acceptable_scale =
    665         std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
    666     // Ignore 0 scale in case CalculateContentsScale() has never been
    667     // called for active twin.
    668     if (twin_min_acceptable_scale != 0.0f) {
    669       min_acceptable_scale =
    670           std::min(min_acceptable_scale, twin_min_acceptable_scale);
    671     }
    672   }
    673 
    674   // Mark tiles for activation in two passes.  Ready to draw tiles in acceptable
    675   // but non-ideal tilings are marked as required for activation, but any
    676   // non-ready tiles are not marked as required.  From there, any missing holes
    677   // will need to be filled in from the high res tiling.
    678 
    679   PictureLayerTiling* high_res = NULL;
    680   Region missing_region = rect;
    681   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    682     PictureLayerTiling* tiling = tilings_->tiling_at(i);
    683     DCHECK(tiling->has_ever_been_updated());
    684 
    685     if (tiling->contents_scale() < min_acceptable_scale)
    686       continue;
    687     if (tiling->resolution() == HIGH_RESOLUTION) {
    688       DCHECK(!high_res) << "There can only be one high res tiling";
    689       high_res = tiling;
    690       continue;
    691     }
    692     for (PictureLayerTiling::CoverageIterator iter(tiling,
    693                                                    contents_scale_x(),
    694                                                    rect);
    695          iter;
    696          ++iter) {
    697       if (!*iter || !iter->IsReadyToDraw())
    698         continue;
    699 
    700       // This iteration is over the visible content rect which is potentially
    701       // less conservative than projecting the viewport into the layer.
    702       // Ignore tiles that are know to be outside the viewport.
    703       if (iter->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
    704         continue;
    705 
    706       missing_region.Subtract(iter.geometry_rect());
    707       iter->mark_required_for_activation();
    708     }
    709   }
    710 
    711   DCHECK(high_res) << "There must be one high res tiling";
    712   for (PictureLayerTiling::CoverageIterator iter(high_res,
    713                                                  contents_scale_x(),
    714                                                  rect);
    715        iter;
    716        ++iter) {
    717     // A null tile (i.e. missing recording) can just be skipped.
    718     if (!*iter)
    719       continue;
    720 
    721     // This iteration is over the visible content rect which is potentially
    722     // less conservative than projecting the viewport into the layer.
    723     // Ignore tiles that are know to be outside the viewport.
    724     if (iter->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
    725       continue;
    726 
    727     // If the missing region doesn't cover it, this tile is fully
    728     // covered by acceptable tiles at other scales.
    729     if (!missing_region.Intersects(iter.geometry_rect()))
    730       continue;
    731 
    732     iter->mark_required_for_activation();
    733   }
    734 }
    735 
    736 PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
    737   DCHECK(CanHaveTilingWithScale(contents_scale)) <<
    738       "contents_scale: " << contents_scale;
    739 
    740   PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
    741 
    742   const Region& recorded = pile_->recorded_region();
    743   DCHECK(!recorded.IsEmpty());
    744 
    745   if (twin_layer_)
    746     twin_layer_->SyncTiling(tiling);
    747 
    748   return tiling;
    749 }
    750 
    751 void PictureLayerImpl::RemoveTiling(float contents_scale) {
    752   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    753     PictureLayerTiling* tiling = tilings_->tiling_at(i);
    754     if (tiling->contents_scale() == contents_scale) {
    755       tilings_->Remove(tiling);
    756       break;
    757     }
    758   }
    759 }
    760 
    761 namespace {
    762 
    763 inline float PositiveRatio(float float1, float float2) {
    764   DCHECK_GT(float1, 0);
    765   DCHECK_GT(float2, 0);
    766   return float1 > float2 ? float1 / float2 : float2 / float1;
    767 }
    768 
    769 inline bool IsCloserToThan(
    770     PictureLayerTiling* layer1,
    771     PictureLayerTiling* layer2,
    772     float contents_scale) {
    773   // Absolute value for ratios.
    774   float ratio1 = PositiveRatio(layer1->contents_scale(), contents_scale);
    775   float ratio2 = PositiveRatio(layer2->contents_scale(), contents_scale);
    776   return ratio1 < ratio2;
    777 }
    778 
    779 }  // namespace
    780 
    781 void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen) {
    782   DCHECK(ideal_contents_scale_);
    783   DCHECK(ideal_page_scale_);
    784   DCHECK(ideal_device_scale_);
    785   DCHECK(ideal_source_scale_);
    786   DCHECK(CanHaveTilings());
    787 
    788   bool change_target_tiling =
    789       raster_page_scale_ == 0.f ||
    790       raster_device_scale_ == 0.f ||
    791       raster_source_scale_ == 0.f ||
    792       raster_contents_scale_ == 0.f ||
    793       low_res_raster_contents_scale_ == 0.f ||
    794       ShouldAdjustRasterScale(animating_transform_to_screen);
    795 
    796   // Store the value for the next time ShouldAdjustRasterScale is called.
    797   raster_source_scale_was_animating_ = animating_transform_to_screen;
    798 
    799   if (!change_target_tiling)
    800     return;
    801 
    802   raster_page_scale_ = ideal_page_scale_;
    803   raster_device_scale_ = ideal_device_scale_;
    804   raster_source_scale_ = ideal_source_scale_;
    805 
    806   CalculateRasterContentsScale(animating_transform_to_screen,
    807                                &raster_contents_scale_,
    808                                &low_res_raster_contents_scale_);
    809 
    810   PictureLayerTiling* high_res = NULL;
    811   PictureLayerTiling* low_res = NULL;
    812 
    813   PictureLayerTiling* previous_low_res = NULL;
    814   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    815     PictureLayerTiling* tiling = tilings_->tiling_at(i);
    816     if (tiling->contents_scale() == raster_contents_scale_)
    817       high_res = tiling;
    818     if (tiling->contents_scale() == low_res_raster_contents_scale_)
    819       low_res = tiling;
    820     if (tiling->resolution() == LOW_RESOLUTION)
    821       previous_low_res = tiling;
    822 
    823     // Reset all tilings to non-ideal until the end of this function.
    824     tiling->set_resolution(NON_IDEAL_RESOLUTION);
    825   }
    826 
    827   if (!high_res) {
    828     high_res = AddTiling(raster_contents_scale_);
    829     if (raster_contents_scale_ == low_res_raster_contents_scale_)
    830       low_res = high_res;
    831   }
    832 
    833   // Only create new low res tilings when the transform is static.  This
    834   // prevents wastefully creating a paired low res tiling for every new high res
    835   // tiling during a pinch or a CSS animation.
    836   bool is_pinching = layer_tree_impl()->PinchGestureActive();
    837   if (!is_pinching && !animating_transform_to_screen && !low_res &&
    838       low_res != high_res)
    839     low_res = AddTiling(low_res_raster_contents_scale_);
    840 
    841   if (high_res)
    842     high_res->set_resolution(HIGH_RESOLUTION);
    843   if (low_res && low_res != high_res)
    844     low_res->set_resolution(LOW_RESOLUTION);
    845   else if (!low_res && previous_low_res)
    846     previous_low_res->set_resolution(LOW_RESOLUTION);
    847 }
    848 
    849 bool PictureLayerImpl::ShouldAdjustRasterScale(
    850     bool animating_transform_to_screen) const {
    851   // TODO(danakj): Adjust raster source scale closer to ideal source scale at
    852   // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
    853   // tree. This will allow CSS scale changes to get re-rastered at an
    854   // appropriate rate.
    855 
    856   if (raster_source_scale_was_animating_ && !animating_transform_to_screen)
    857     return true;
    858 
    859   bool is_pinching = layer_tree_impl()->PinchGestureActive();
    860   if (is_pinching && raster_page_scale_) {
    861     // If the page scale diverges too far during pinch, change raster target to
    862     // the current page scale.
    863     float ratio = PositiveRatio(ideal_page_scale_, raster_page_scale_);
    864     if (ratio >= kMaxScaleRatioDuringPinch)
    865       return true;
    866   }
    867 
    868   if (!is_pinching) {
    869     // When not pinching, match the ideal page scale factor.
    870     if (raster_page_scale_ != ideal_page_scale_)
    871       return true;
    872   }
    873 
    874   // Always match the ideal device scale factor.
    875   if (raster_device_scale_ != ideal_device_scale_)
    876     return true;
    877 
    878   return false;
    879 }
    880 
    881 void PictureLayerImpl::CalculateRasterContentsScale(
    882     bool animating_transform_to_screen,
    883     float* raster_contents_scale,
    884     float* low_res_raster_contents_scale) const {
    885   *raster_contents_scale = ideal_contents_scale_;
    886 
    887   // Don't allow animating CSS scales to drop below 1.  This is needed because
    888   // changes in raster source scale aren't handled.  See the comment in
    889   // ShouldAdjustRasterScale.
    890   if (animating_transform_to_screen) {
    891     *raster_contents_scale = std::max(
    892         *raster_contents_scale, 1.f * ideal_page_scale_ * ideal_device_scale_);
    893   }
    894 
    895   // If this layer would only create one tile at this content scale,
    896   // don't create a low res tiling.
    897   gfx::Size content_bounds =
    898       gfx::ToCeiledSize(gfx::ScaleSize(bounds(), *raster_contents_scale));
    899   gfx::Size tile_size = CalculateTileSize(content_bounds);
    900   if (tile_size.width() >= content_bounds.width() &&
    901       tile_size.height() >= content_bounds.height()) {
    902     *low_res_raster_contents_scale = *raster_contents_scale;
    903     return;
    904   }
    905 
    906   float low_res_factor =
    907       layer_tree_impl()->settings().low_res_contents_scale_factor;
    908   *low_res_raster_contents_scale = std::max(
    909       *raster_contents_scale * low_res_factor,
    910       MinimumContentsScale());
    911 }
    912 
    913 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
    914     std::vector<PictureLayerTiling*> used_tilings) {
    915   DCHECK(layer_tree_impl()->IsActiveTree());
    916 
    917   float min_acceptable_high_res_scale = std::min(
    918       raster_contents_scale_, ideal_contents_scale_);
    919   float max_acceptable_high_res_scale = std::max(
    920       raster_contents_scale_, ideal_contents_scale_);
    921 
    922   PictureLayerImpl* twin = twin_layer_;
    923   if (twin) {
    924     min_acceptable_high_res_scale = std::min(
    925         min_acceptable_high_res_scale,
    926         std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_));
    927     max_acceptable_high_res_scale = std::max(
    928         max_acceptable_high_res_scale,
    929         std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
    930   }
    931 
    932   std::vector<PictureLayerTiling*> to_remove;
    933   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    934     PictureLayerTiling* tiling = tilings_->tiling_at(i);
    935 
    936     // Keep multiple high resolution tilings even if not used to help
    937     // activate earlier at non-ideal resolutions.
    938     if (tiling->contents_scale() >= min_acceptable_high_res_scale &&
    939         tiling->contents_scale() <= max_acceptable_high_res_scale)
    940       continue;
    941 
    942     // Low resolution can't activate, so only keep one around.
    943     if (tiling->resolution() == LOW_RESOLUTION)
    944       continue;
    945 
    946     // Don't remove tilings that are being used (and thus would cause a flash.)
    947     if (std::find(used_tilings.begin(), used_tilings.end(), tiling) !=
    948         used_tilings.end())
    949       continue;
    950 
    951     to_remove.push_back(tiling);
    952   }
    953 
    954   for (size_t i = 0; i < to_remove.size(); ++i) {
    955     if (twin)
    956       twin->RemoveTiling(to_remove[i]->contents_scale());
    957     tilings_->Remove(to_remove[i]);
    958   }
    959 }
    960 
    961 float PictureLayerImpl::MinimumContentsScale() const {
    962   float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
    963 
    964   // If the contents scale is less than 1 / width (also for height),
    965   // then it will end up having less than one pixel of content in that
    966   // dimension.  Bump the minimum contents scale up in this case to prevent
    967   // this from happening.
    968   int min_dimension = std::min(bounds().width(), bounds().height());
    969   if (!min_dimension)
    970     return setting_min;
    971 
    972   return std::max(1.f / min_dimension, setting_min);
    973 }
    974 
    975 void PictureLayerImpl::UpdateLCDTextStatus(bool new_status) {
    976   // Once this layer is not using lcd text, don't switch back.
    977   if (!is_using_lcd_text_)
    978     return;
    979 
    980   if (is_using_lcd_text_ == new_status)
    981     return;
    982 
    983   is_using_lcd_text_ = new_status;
    984   tilings_->SetCanUseLCDText(is_using_lcd_text_);
    985 }
    986 
    987 void PictureLayerImpl::ResetRasterScale() {
    988   raster_page_scale_ = 0.f;
    989   raster_device_scale_ = 0.f;
    990   raster_source_scale_ = 0.f;
    991   raster_contents_scale_ = 0.f;
    992   low_res_raster_contents_scale_ = 0.f;
    993 
    994   // When raster scales aren't valid, don't update tile priorities until
    995   // this layer has been updated via UpdateDrawProperties.
    996   should_update_tile_priorities_ = false;
    997 }
    998 
    999 bool PictureLayerImpl::CanHaveTilings() const {
   1000   if (!DrawsContent())
   1001     return false;
   1002   if (pile_->recorded_region().IsEmpty())
   1003     return false;
   1004   if (draw_properties().can_draw_directly_to_backbuffer &&
   1005       layer_tree_impl()->settings().force_direct_layer_drawing)
   1006     return false;
   1007   return true;
   1008 }
   1009 
   1010 bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale) const {
   1011   if (!CanHaveTilings())
   1012     return false;
   1013   if (contents_scale < MinimumContentsScale())
   1014     return false;
   1015   return true;
   1016 }
   1017 
   1018 void PictureLayerImpl::GetDebugBorderProperties(
   1019     SkColor* color,
   1020     float* width) const {
   1021   *color = DebugColors::TiledContentLayerBorderColor();
   1022   *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
   1023 }
   1024 
   1025 void PictureLayerImpl::AsValueInto(base::DictionaryValue* state) const {
   1026   LayerImpl::AsValueInto(state);
   1027   state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
   1028   state->Set("tilings", tilings_->AsValue().release());
   1029   state->Set("pictures", pile_->AsValue().release());
   1030   state->Set("invalidation", invalidation_.AsValue().release());
   1031 
   1032   scoped_ptr<base::ListValue> coverage_tiles(new base::ListValue);
   1033   for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
   1034                                                     contents_scale_x(),
   1035                                                     gfx::Rect(bounds()),
   1036                                                     ideal_contents_scale_);
   1037        iter;
   1038        ++iter) {
   1039     scoped_ptr<base::DictionaryValue> tile_data(new base::DictionaryValue);
   1040     tile_data->Set("geometry_rect",
   1041                    MathUtil::AsValue(iter.geometry_rect()).release());
   1042     if (*iter)
   1043       tile_data->Set("tile", TracedValue::CreateIDRef(*iter).release());
   1044 
   1045     coverage_tiles->Append(tile_data.release());
   1046   }
   1047   state->Set("coverage_tiles", coverage_tiles.release());
   1048 }
   1049 
   1050 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
   1051   return tilings_->GPUMemoryUsageInBytes();
   1052 }
   1053 
   1054 }  // namespace cc
   1055