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