| OLD | NEW | 
|    1 // Copyright 2012 The Chromium Authors. All rights reserved. |    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 |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "cc/resources/picture_layer_tiling.h" |    5 #include "cc/resources/picture_layer_tiling.h" | 
|    6  |    6  | 
|    7 #include <algorithm> |    7 #include <algorithm> | 
|    8 #include <cmath> |    8 #include <cmath> | 
|    9 #include <limits> |    9 #include <limits> | 
|   10  |   10  | 
|   11 #include "base/debug/trace_event.h" |   11 #include "base/debug/trace_event.h" | 
|   12 #include "cc/base/math_util.h" |   12 #include "cc/base/math_util.h" | 
|   13 #include "ui/gfx/point_conversions.h" |   13 #include "ui/gfx/point_conversions.h" | 
|   14 #include "ui/gfx/rect_conversions.h" |   14 #include "ui/gfx/rect_conversions.h" | 
|   15 #include "ui/gfx/safe_integer_conversions.h" |   15 #include "ui/gfx/safe_integer_conversions.h" | 
|   16 #include "ui/gfx/size_conversions.h" |   16 #include "ui/gfx/size_conversions.h" | 
|   17  |   17  | 
|   18 namespace cc { |   18 namespace cc { | 
|   19  |   19  | 
 |   20 namespace { | 
 |   21  | 
 |   22 const int kTileBundleWidth = 2; | 
 |   23 const int kTileBundleHeight = 2; | 
 |   24  | 
 |   25 std::pair<int, int> ComputeTileBundleIndex(int i, int j) { | 
 |   26   return std::make_pair(i / kTileBundleWidth, j / kTileBundleHeight); | 
 |   27 } | 
 |   28  | 
 |   29 gfx::Size ComputeBundleTextureSize(gfx::Size tile_size, | 
 |   30                                    const TilingData& tiling_data) { | 
 |   31   int border_texels = tiling_data.border_texels(); | 
 |   32  | 
 |   33   int inner_tile_width = tile_size.width() - 2 * border_texels; | 
 |   34   int bundle_width = inner_tile_width * kTileBundleWidth + 2 * border_texels; | 
 |   35  | 
 |   36   int inner_tile_height = tile_size.height() - 2 * border_texels; | 
 |   37   int bundle_height = inner_tile_height * kTileBundleHeight + 2 * border_texels; | 
 |   38   return gfx::Size(bundle_width, bundle_height); | 
 |   39 } | 
 |   40  | 
 |   41 }  // namespace | 
 |   42  | 
|   20 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |   43 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( | 
|   21     float contents_scale, |   44     float contents_scale, | 
|   22     gfx::Size layer_bounds, |   45     gfx::Size layer_bounds, | 
|   23     PictureLayerTilingClient* client) { |   46     PictureLayerTilingClient* client) { | 
|   24   return make_scoped_ptr(new PictureLayerTiling(contents_scale, |   47   return make_scoped_ptr(new PictureLayerTiling(contents_scale, | 
|   25                                                 layer_bounds, |   48                                                 layer_bounds, | 
|   26                                                 client)); |   49                                                 client)); | 
|   27 } |   50 } | 
|   28  |   51  | 
|   29 PictureLayerTiling::PictureLayerTiling(float contents_scale, |   52 PictureLayerTiling::PictureLayerTiling(float contents_scale, | 
|   30                                        gfx::Size layer_bounds, |   53                                        gfx::Size layer_bounds, | 
|   31                                        PictureLayerTilingClient* client) |   54                                        PictureLayerTilingClient* client) | 
|   32     : contents_scale_(contents_scale), |   55     : contents_scale_(contents_scale), | 
|   33       layer_bounds_(layer_bounds), |   56       layer_bounds_(layer_bounds), | 
|   34       resolution_(NON_IDEAL_RESOLUTION), |   57       resolution_(NON_IDEAL_RESOLUTION), | 
|   35       client_(client), |   58       client_(client), | 
|   36       tiling_data_(gfx::Size(), gfx::Size(), true), |   59       tiling_data_(gfx::Size(), gfx::Size(), true), | 
 |   60       bundle_tiling_data_(gfx::Size(), gfx::Size(), true), | 
 |   61       current_tree_(PENDING_TREE), | 
|   37       last_impl_frame_time_in_seconds_(0.0) { |   62       last_impl_frame_time_in_seconds_(0.0) { | 
|   38   gfx::Size content_bounds = |   63   gfx::Size content_bounds = | 
|   39       gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); |   64       gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); | 
|   40   gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |   65   gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 
|   41  |   66  | 
|   42   DCHECK(!gfx::ToFlooredSize( |   67   DCHECK(!gfx::ToFlooredSize( | 
|   43       gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << |   68       gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << | 
|   44       "Tiling created with scale too small as contents become empty." << |   69       "Tiling created with scale too small as contents become empty." << | 
|   45       " Layer bounds: " << layer_bounds.ToString() << |   70       " Layer bounds: " << layer_bounds.ToString() << | 
|   46       " Contents scale: " << contents_scale; |   71       " Contents scale: " << contents_scale; | 
|   47  |   72  | 
|   48   tiling_data_.SetTotalSize(content_bounds); |   73   tiling_data_.SetTotalSize(content_bounds); | 
|   49   tiling_data_.SetMaxTextureSize(tile_size); |   74   tiling_data_.SetMaxTextureSize(tile_size); | 
 |   75   bundle_tiling_data_.SetTotalSize(content_bounds); | 
 |   76   bundle_tiling_data_.SetMaxTextureSize( | 
 |   77       ComputeBundleTextureSize(tile_size, tiling_data_)); | 
|   50 } |   78 } | 
|   51  |   79  | 
|   52 PictureLayerTiling::~PictureLayerTiling() { |   80 PictureLayerTiling::~PictureLayerTiling() { | 
|   53 } |   81 } | 
|   54  |   82  | 
|   55 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { |   83 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { | 
|   56   client_ = client; |   84   client_ = client; | 
|   57 } |   85 } | 
|   58  |   86  | 
|   59 gfx::Rect PictureLayerTiling::ContentRect() const { |   87 gfx::Rect PictureLayerTiling::ContentRect() const { | 
|   60   return gfx::Rect(tiling_data_.total_size()); |   88   return gfx::Rect(tiling_data_.total_size()); | 
|   61 } |   89 } | 
|   62  |   90  | 
|   63 gfx::SizeF PictureLayerTiling::ContentSizeF() const { |   91 gfx::SizeF PictureLayerTiling::ContentSizeF() const { | 
|   64   return gfx::ScaleSize(layer_bounds_, contents_scale_); |   92   return gfx::ScaleSize(layer_bounds_, contents_scale_); | 
|   65 } |   93 } | 
|   66  |   94  | 
|   67 Tile* PictureLayerTiling::TileAt(int i, int j) const { |   95 TileBundle* PictureLayerTiling::CreateBundleForTileAt( | 
|   68   TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); |   96     int i, | 
|   69   if (iter == tiles_.end()) |   97     int j, | 
|   70     return NULL; |   98     const PictureLayerTiling* twin_tiling) { | 
|   71   return iter->second.get(); |   99   TileBundleMapKey key = ComputeTileBundleIndex(i, j); | 
 |  100   DCHECK(tile_bundles_.find(key) == tile_bundles_.end()); | 
 |  101  | 
 |  102   scoped_refptr<TileBundle> candidate_bundle = NULL; | 
 |  103  | 
 |  104   // Always try to get the twin bundle first. TileBundles are always shared | 
 |  105   // between trees. | 
 |  106   if (twin_tiling && | 
 |  107       tiling_data_.max_texture_size() == | 
 |  108       twin_tiling->tiling_data_.max_texture_size()) { | 
 |  109     candidate_bundle = twin_tiling->TileBundleAt(key.first, key.second); | 
 |  110   } | 
 |  111  | 
 |  112   // If we couldn't get a tile bundle, create a new one. | 
 |  113   if (!candidate_bundle) { | 
 |  114     candidate_bundle = client_->CreateTileBundle(key.first * kTileBundleWidth, | 
 |  115                                                  key.second * kTileBundleHeight, | 
 |  116                                                  kTileBundleWidth, | 
 |  117                                                  kTileBundleHeight); | 
 |  118   } | 
 |  119   candidate_bundle->SwapTilesIfRequired(); | 
 |  120   tile_bundles_[key] = candidate_bundle; | 
 |  121   return candidate_bundle.get(); | 
|   72 } |  122 } | 
|   73  |  123  | 
|   74 void PictureLayerTiling::CreateTile(int i, |  124 TileBundle* PictureLayerTiling::TileBundleContainingTileAt(int i, int j) const { | 
 |  125   TileBundleMapKey key = ComputeTileBundleIndex(i, j); | 
 |  126   return TileBundleAt(key.first, key.second); | 
 |  127 } | 
 |  128  | 
 |  129 TileBundle* PictureLayerTiling::TileBundleAt(int i, int j) const { | 
 |  130   TileBundleMapKey key(i, j); | 
 |  131   TileBundleMap::const_iterator it = tile_bundles_.find(key); | 
 |  132   if (it == tile_bundles_.end()) | 
 |  133     return NULL; | 
 |  134   it->second->SwapTilesIfRequired(); | 
 |  135   return it->second.get(); | 
 |  136 } | 
 |  137  | 
 |  138 Tile* PictureLayerTiling::TileAt(WhichTree tree, int i, int j) const { | 
 |  139   TileBundle* bundle = TileBundleContainingTileAt(i, j); | 
 |  140   if (!bundle) | 
 |  141     return NULL; | 
 |  142   return bundle->TileAt(tree, i, j); | 
 |  143 } | 
 |  144  | 
 |  145 void PictureLayerTiling::CreateTile(WhichTree tree, | 
 |  146                                     int i, | 
|   75                                     int j, |  147                                     int j, | 
|   76                                     const PictureLayerTiling* twin_tiling) { |  148                                     const PictureLayerTiling* twin_tiling) { | 
|   77   TileMapKey key(i, j); |  149   TileBundle* bundle = TileBundleContainingTileAt(i, j); | 
|   78   DCHECK(tiles_.find(key) == tiles_.end()); |  150   if (!bundle) | 
 |  151     bundle = CreateBundleForTileAt(i, j, twin_tiling); | 
|   79  |  152  | 
|   80   gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); |  153   gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); | 
|   81   gfx::Rect tile_rect = paint_rect; |  154   gfx::Rect tile_rect = paint_rect; | 
|   82   tile_rect.set_size(tiling_data_.max_texture_size()); |  155   tile_rect.set_size(tiling_data_.max_texture_size()); | 
|   83  |  156  | 
|   84   // Check our twin for a valid tile. |  157   // Check our twin for a valid tile. | 
|   85   if (twin_tiling && |  158   WhichTree twin_tree = (tree == ACTIVE_TREE) ? PENDING_TREE : ACTIVE_TREE; | 
|   86       tiling_data_.max_texture_size() == |  159   if (Tile* candidate_tile = bundle->TileAt(twin_tree, i, j)) { | 
|   87       twin_tiling->tiling_data_.max_texture_size()) { |  160     gfx::Rect rect = | 
|   88     if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { |  161         gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); | 
|   89       gfx::Rect rect = |  162     if (!client_->GetInvalidation()->Intersects(rect)) { | 
|   90           gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); |  163       bundle->AddTileAt(tree, i, j, candidate_tile); | 
|   91       if (!client_->GetInvalidation()->Intersects(rect)) { |  164       return; | 
|   92         tiles_[key] = candidate_tile; |  | 
|   93         return; |  | 
|   94       } |  | 
|   95     } |  165     } | 
|   96   } |  166   } | 
|   97  |  167  | 
|   98   // Create a new tile because our twin didn't have a valid one. |  168   // Create a new tile because our twin didn't have a valid one. | 
|   99   scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |  169   scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 
|  100   if (tile.get()) |  170   if (tile.get()) | 
|  101     tiles_[key] = tile; |  171     bundle->AddTileAt(tree, i, j, tile); | 
 |  172 } | 
 |  173  | 
 |  174 bool PictureLayerTiling::RemoveTile(WhichTree tree, int i, int j) { | 
 |  175   TileBundleMapKey key = ComputeTileBundleIndex(i, j); | 
 |  176   TileBundleMap::iterator it = tile_bundles_.find(key); | 
 |  177   if (it == tile_bundles_.end()) | 
 |  178     return false; | 
 |  179  | 
 |  180   it->second->SwapTilesIfRequired(); | 
 |  181   return it->second->RemoveTileAt(tree, i, j); | 
 |  182 } | 
 |  183  | 
 |  184 void PictureLayerTiling::RemoveBundleContainingTileAtIfEmpty(int i, int j) { | 
 |  185   TileBundleMapKey key = ComputeTileBundleIndex(i, j); | 
 |  186   TileBundleMap::iterator it = tile_bundles_.find(key); | 
 |  187   if (it == tile_bundles_.end()) | 
 |  188     return; | 
 |  189  | 
 |  190   if (it->second->IsEmpty()) | 
 |  191     tile_bundles_.erase(it); | 
|  102 } |  192 } | 
|  103  |  193  | 
|  104 Region PictureLayerTiling::OpaqueRegionInContentRect( |  194 Region PictureLayerTiling::OpaqueRegionInContentRect( | 
|  105     gfx::Rect content_rect) const { |  195     gfx::Rect content_rect) const { | 
|  106   Region opaque_region; |  196   Region opaque_region; | 
|  107   // TODO(enne): implement me |  197   // TODO(enne): implement me | 
|  108   return opaque_region; |  198   return opaque_region; | 
|  109 } |  199 } | 
|  110  |  200  | 
|  111 void PictureLayerTiling::SetCanUseLCDText(bool can_use_lcd_text) { |  201 void PictureLayerTiling::SetCanUseLCDText(bool can_use_lcd_text) { | 
|  112   for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) |  202   // TODO(vmpstr): This can be done per bundle with results used | 
|  113     it->second->set_can_use_lcd_text(can_use_lcd_text); |  203   // in tile manager. | 
 |  204   for (TileBundleMap::iterator it = tile_bundles_.begin(); | 
 |  205        it != tile_bundles_.end(); | 
 |  206        ++it) { | 
 |  207     for (TileBundle::Iterator tile_it(it->second, current_tree_); | 
 |  208          tile_it; | 
 |  209          ++tile_it) | 
 |  210       tile_it->set_can_use_lcd_text(can_use_lcd_text); | 
 |  211   } | 
|  114 } |  212 } | 
|  115  |  213  | 
|  116 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |  214 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 
 |  215   DCHECK(current_tree_ == PENDING_TREE); | 
 |  216  | 
|  117   const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |  217   const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | 
|  118   for (TilingData::Iterator iter(&tiling_data_, live_tiles_rect_); iter; |  218   for (TilingData::Iterator iter(&tiling_data_, live_tiles_rect_); iter; | 
|  119        ++iter) { |  219        ++iter) { | 
|  120     TileMapKey key = iter.index(); |  220     int tile_x = iter.index_x(); | 
|  121     TileMap::iterator find = tiles_.find(key); |  221     int tile_y = iter.index_y(); | 
|  122     if (find != tiles_.end()) |  222     Tile* tile = TileAt(PENDING_TREE, tile_x, tile_y); | 
 |  223     if (tile) | 
|  123       continue; |  224       continue; | 
|  124     CreateTile(key.first, key.second, twin_tiling); |  225     CreateTile(PENDING_TREE, tile_x, tile_y, twin_tiling); | 
|  125   } |  226   } | 
|  126 } |  227 } | 
|  127  |  228  | 
|  128 void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) { |  229 void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) { | 
|  129   if (layer_bounds_ == layer_bounds) |  230   if (layer_bounds_ == layer_bounds) | 
|  130     return; |  231     return; | 
|  131  |  232  | 
 |  233   DCHECK(current_tree_ == PENDING_TREE); | 
|  132   DCHECK(!layer_bounds.IsEmpty()); |  234   DCHECK(!layer_bounds.IsEmpty()); | 
|  133  |  235  | 
|  134   gfx::Size old_layer_bounds = layer_bounds_; |  236   gfx::Size old_layer_bounds = layer_bounds_; | 
|  135   layer_bounds_ = layer_bounds; |  237   layer_bounds_ = layer_bounds; | 
|  136   gfx::Size old_content_bounds = tiling_data_.total_size(); |  238   gfx::Size old_content_bounds = tiling_data_.total_size(); | 
|  137   gfx::Size content_bounds = |  239   gfx::Size content_bounds = | 
|  138       gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds_, contents_scale_)); |  240       gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds_, contents_scale_)); | 
|  139  |  241  | 
|  140   gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |  242   gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 
|  141   if (tile_size != tiling_data_.max_texture_size()) { |  243   if (tile_size != tiling_data_.max_texture_size()) { | 
|  142     tiling_data_.SetTotalSize(content_bounds); |  244     tiling_data_.SetTotalSize(content_bounds); | 
|  143     tiling_data_.SetMaxTextureSize(tile_size); |  245     tiling_data_.SetMaxTextureSize(tile_size); | 
 |  246     bundle_tiling_data_.SetTotalSize(content_bounds); | 
 |  247     bundle_tiling_data_.SetMaxTextureSize( | 
 |  248         ComputeBundleTextureSize(tile_size, tiling_data_)); | 
|  144     Reset(); |  249     Reset(); | 
|  145     return; |  250     return; | 
|  146   } |  251   } | 
|  147  |  252  | 
|  148   // Any tiles outside our new bounds are invalid and should be dropped. |  253   // Any tiles outside our new bounds are invalid and should be dropped. | 
|  149   gfx::Rect bounded_live_tiles_rect(live_tiles_rect_); |  254   gfx::Rect bounded_live_tiles_rect(live_tiles_rect_); | 
|  150   bounded_live_tiles_rect.Intersect(gfx::Rect(content_bounds)); |  255   bounded_live_tiles_rect.Intersect(gfx::Rect(content_bounds)); | 
|  151   SetLiveTilesRect(bounded_live_tiles_rect); |  256   SetLiveTilesRect(bounded_live_tiles_rect); | 
|  152   tiling_data_.SetTotalSize(content_bounds); |  257   tiling_data_.SetTotalSize(content_bounds); | 
 |  258   bundle_tiling_data_.SetTotalSize(content_bounds); | 
|  153  |  259  | 
|  154   // Create tiles for newly exposed areas. |  260   // Create tiles for newly exposed areas. | 
|  155   Region layer_region((gfx::Rect(layer_bounds_))); |  261   Region layer_region((gfx::Rect(layer_bounds_))); | 
|  156   layer_region.Subtract(gfx::Rect(old_layer_bounds)); |  262   layer_region.Subtract(gfx::Rect(old_layer_bounds)); | 
|  157   Invalidate(layer_region); |  263   Invalidate(layer_region); | 
|  158 } |  264 } | 
|  159  |  265  | 
|  160 void PictureLayerTiling::Invalidate(const Region& layer_region) { |  266 void PictureLayerTiling::Invalidate(const Region& layer_region) { | 
|  161   std::vector<TileMapKey> new_tile_keys; |  267   DCHECK(current_tree_ == PENDING_TREE); | 
 |  268  | 
 |  269   std::vector<std::pair<int, int> > new_tile_keys; | 
|  162   for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) { |  270   for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) { | 
|  163     gfx::Rect layer_rect = iter.rect(); |  271     gfx::Rect layer_rect = iter.rect(); | 
|  164     gfx::Rect content_rect = |  272     gfx::Rect content_rect = | 
|  165         gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); |  273         gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); | 
|  166     content_rect.Intersect(live_tiles_rect_); |  274     content_rect.Intersect(live_tiles_rect_); | 
|  167     if (content_rect.IsEmpty()) |  275     if (content_rect.IsEmpty()) | 
|  168       continue; |  276       continue; | 
|  169     for (TilingData::Iterator iter(&tiling_data_, content_rect); iter; ++iter) { |  277     for (TilingData::Iterator iter(&tiling_data_, content_rect); iter; ++iter) { | 
|  170       TileMapKey key(iter.index()); |  278       int tile_x = iter.index_x(); | 
|  171       TileMap::iterator find = tiles_.find(key); |  279       int tile_y = iter.index_y(); | 
|  172       if (find == tiles_.end()) |  280  | 
|  173         continue; |  281       // If there is no bundle for the given tile, we can skip. | 
|  174       tiles_.erase(find); |  282       bool deleted = RemoveTile(PENDING_TREE, tile_x, tile_y); | 
|  175       new_tile_keys.push_back(key); |  283       if (deleted) | 
 |  284         new_tile_keys.push_back(std::make_pair(tile_x, tile_y)); | 
|  176     } |  285     } | 
|  177   } |  286   } | 
|  178  |  287  | 
|  179   const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |  288   const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | 
|  180   for (size_t i = 0; i < new_tile_keys.size(); ++i) |  289   for (size_t i = 0; i < new_tile_keys.size(); ++i) { | 
|  181     CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, twin_tiling); |  290     CreateTile(PENDING_TREE, | 
 |  291                new_tile_keys[i].first, | 
 |  292                new_tile_keys[i].second, | 
 |  293                twin_tiling); | 
 |  294   } | 
|  182 } |  295 } | 
|  183  |  296  | 
|  184 PictureLayerTiling::CoverageIterator::CoverageIterator() |  297 PictureLayerTiling::CoverageIterator::CoverageIterator() | 
|  185     : tiling_(NULL), |  298     : tiling_(NULL), | 
|  186       current_tile_(NULL), |  299       current_tile_(NULL), | 
|  187       tile_i_(0), |  300       tile_i_(0), | 
|  188       tile_j_(0), |  301       tile_j_(0), | 
|  189       left_(0), |  302       left_(0), | 
|  190       top_(0), |  303       top_(0), | 
|  191       right_(-1), |  304       right_(-1), | 
|  192       bottom_(-1) { |  305       bottom_(-1) { | 
|  193 } |  306 } | 
|  194  |  307  | 
|  195 PictureLayerTiling::CoverageIterator::CoverageIterator( |  308 PictureLayerTiling::CoverageIterator::CoverageIterator( | 
|  196     const PictureLayerTiling* tiling, |  309     const PictureLayerTiling* tiling, | 
|  197     float dest_scale, |  310     float dest_scale, | 
|  198     gfx::Rect dest_rect) |  311     gfx::Rect dest_rect) | 
|  199     : tiling_(tiling), |  312     : tiling_(tiling), | 
|  200       dest_rect_(dest_rect), |  313       dest_rect_(dest_rect), | 
|  201       dest_to_content_scale_(0), |  314       dest_to_content_scale_(0), | 
|  202       current_tile_(NULL), |  315       current_tile_(NULL), | 
|  203       tile_i_(0), |  316       tile_i_(0), | 
|  204       tile_j_(0), |  317       tile_j_(0), | 
|  205       left_(0), |  318       left_(0), | 
|  206       top_(0), |  319       top_(0), | 
|  207       right_(-1), |  320       right_(-1), | 
|  208       bottom_(-1) { |  321       bottom_(-1), | 
 |  322       tree_(tiling->current_tree_) { | 
|  209   DCHECK(tiling_); |  323   DCHECK(tiling_); | 
|  210   if (dest_rect_.IsEmpty()) |  324   if (dest_rect_.IsEmpty()) | 
|  211     return; |  325     return; | 
|  212  |  326  | 
|  213   dest_to_content_scale_ = tiling_->contents_scale_ / dest_scale; |  327   dest_to_content_scale_ = tiling_->contents_scale_ / dest_scale; | 
|  214   // This is the maximum size that the dest rect can be, given the content size. |  328   // This is the maximum size that the dest rect can be, given the content size. | 
|  215   gfx::Size dest_content_size = gfx::ToCeiledSize(gfx::ScaleSize( |  329   gfx::Size dest_content_size = gfx::ToCeiledSize(gfx::ScaleSize( | 
|  216       tiling_->ContentRect().size(), |  330       tiling_->ContentRect().size(), | 
|  217       1 / dest_to_content_scale_, |  331       1 / dest_to_content_scale_, | 
|  218       1 / dest_to_content_scale_)); |  332       1 / dest_to_content_scale_)); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  253   if (tile_i_ > right_) { |  367   if (tile_i_ > right_) { | 
|  254     tile_i_ = left_; |  368     tile_i_ = left_; | 
|  255     tile_j_++; |  369     tile_j_++; | 
|  256     new_row = true; |  370     new_row = true; | 
|  257     if (tile_j_ > bottom_) { |  371     if (tile_j_ > bottom_) { | 
|  258       current_tile_ = NULL; |  372       current_tile_ = NULL; | 
|  259       return *this; |  373       return *this; | 
|  260     } |  374     } | 
|  261   } |  375   } | 
|  262  |  376  | 
|  263   current_tile_ = tiling_->TileAt(tile_i_, tile_j_); |  377   current_tile_ = tiling_->TileAt(tree_, tile_i_, tile_j_); | 
|  264  |  378  | 
|  265   // Calculate the current geometry rect.  Due to floating point rounding |  379   // Calculate the current geometry rect.  Due to floating point rounding | 
|  266   // and ToEnclosingRect, tiles might overlap in destination space on the |  380   // and ToEnclosingRect, tiles might overlap in destination space on the | 
|  267   // edges. |  381   // edges. | 
|  268   gfx::Rect last_geometry_rect = current_geometry_rect_; |  382   gfx::Rect last_geometry_rect = current_geometry_rect_; | 
|  269  |  383  | 
|  270   gfx::Rect content_rect = tiling_->tiling_data_.TileBounds(tile_i_, tile_j_); |  384   gfx::Rect content_rect = tiling_->tiling_data_.TileBounds(tile_i_, tile_j_); | 
|  271  |  385  | 
|  272   current_geometry_rect_ = |  386   current_geometry_rect_ = | 
|  273       gfx::ScaleToEnclosingRect(content_rect, |  387       gfx::ScaleToEnclosingRect(content_rect, | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  309   return current_geometry_rect_; |  423   return current_geometry_rect_; | 
|  310 } |  424 } | 
|  311  |  425  | 
|  312 gfx::Rect |  426 gfx::Rect | 
|  313 PictureLayerTiling::CoverageIterator::full_tile_geometry_rect() const { |  427 PictureLayerTiling::CoverageIterator::full_tile_geometry_rect() const { | 
|  314   gfx::Rect rect = tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_); |  428   gfx::Rect rect = tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_); | 
|  315   rect.set_size(tiling_->tiling_data_.max_texture_size()); |  429   rect.set_size(tiling_->tiling_data_.max_texture_size()); | 
|  316   return rect; |  430   return rect; | 
|  317 } |  431 } | 
|  318  |  432  | 
 |  433 TilePriority PictureLayerTiling::CoverageIterator::priority() { | 
 |  434   TileBundle* bundle = tiling_->TileBundleContainingTileAt(tile_i_, tile_j_); | 
 |  435   if (bundle) | 
 |  436     return bundle->GetPriority(tree_); | 
 |  437   return TilePriority(); | 
 |  438 } | 
 |  439  | 
 |  440 void PictureLayerTiling::CoverageIterator::SetPriorityForTesting( | 
 |  441     const TilePriority& priority) { | 
 |  442   TileBundle* bundle = tiling_->TileBundleContainingTileAt(tile_i_, tile_j_); | 
 |  443   bundle->SetPriority(tree_, priority); | 
 |  444 } | 
 |  445  | 
|  319 gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const { |  446 gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const { | 
|  320   gfx::PointF tex_origin = |  447   gfx::PointF tex_origin = | 
|  321       tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin(); |  448       tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin(); | 
|  322  |  449  | 
|  323   // Convert from dest space => content space => texture space. |  450   // Convert from dest space => content space => texture space. | 
|  324   gfx::RectF texture_rect(current_geometry_rect_); |  451   gfx::RectF texture_rect(current_geometry_rect_); | 
|  325   texture_rect.Scale(dest_to_content_scale_, |  452   texture_rect.Scale(dest_to_content_scale_, | 
|  326                      dest_to_content_scale_); |  453                      dest_to_content_scale_); | 
|  327   texture_rect.Offset(-tex_origin.OffsetFromOrigin()); |  454   texture_rect.Offset(-tex_origin.OffsetFromOrigin()); | 
|  328   texture_rect.Intersect(tiling_->ContentRect()); |  455   texture_rect.Intersect(tiling_->ContentRect()); | 
|  329  |  456  | 
|  330   return texture_rect; |  457   return texture_rect; | 
|  331 } |  458 } | 
|  332  |  459  | 
|  333 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { |  460 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { | 
|  334   return tiling_->tiling_data_.max_texture_size(); |  461   return tiling_->tiling_data_.max_texture_size(); | 
|  335 } |  462 } | 
|  336  |  463  | 
|  337 void PictureLayerTiling::Reset() { |  464 void PictureLayerTiling::Reset() { | 
|  338   live_tiles_rect_ = gfx::Rect(); |  465   live_tiles_rect_ = gfx::Rect(); | 
|  339   tiles_.clear(); |  466   tile_bundles_.clear(); | 
|  340 } |  467 } | 
|  341  |  468  | 
|  342 void PictureLayerTiling::UpdateTilePriorities( |  469 void PictureLayerTiling::UpdateTilePriorities( | 
|  343     WhichTree tree, |  470     WhichTree tree, | 
|  344     gfx::Size device_viewport, |  471     gfx::Size device_viewport, | 
|  345     gfx::Rect viewport_in_layer_space, |  472     gfx::Rect viewport_in_layer_space, | 
|  346     gfx::Rect visible_layer_rect, |  473     gfx::Rect visible_layer_rect, | 
|  347     gfx::Size last_layer_bounds, |  474     gfx::Size last_layer_bounds, | 
|  348     gfx::Size current_layer_bounds, |  475     gfx::Size current_layer_bounds, | 
|  349     float last_layer_contents_scale, |  476     float last_layer_contents_scale, | 
|  350     float current_layer_contents_scale, |  477     float current_layer_contents_scale, | 
|  351     const gfx::Transform& last_screen_transform, |  478     const gfx::Transform& last_screen_transform, | 
|  352     const gfx::Transform& current_screen_transform, |  479     const gfx::Transform& current_screen_transform, | 
|  353     double current_frame_time_in_seconds, |  480     double current_frame_time_in_seconds, | 
|  354     size_t max_tiles_for_interest_area) { |  481     size_t max_tiles_for_interest_area) { | 
 |  482   if (!has_ever_been_updated()) | 
 |  483     current_tree_ = tree; | 
 |  484  | 
 |  485   DCHECK_EQ(tree, current_tree_); | 
|  355   if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) { |  486   if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) { | 
|  356     // This should never be zero for the purposes of has_ever_been_updated(). |  487     // This should never be zero for the purposes of has_ever_been_updated(). | 
|  357     DCHECK_NE(current_frame_time_in_seconds, 0.0); |  488     DCHECK_NE(current_frame_time_in_seconds, 0.0); | 
|  358     return; |  489     return; | 
|  359   } |  490   } | 
|  360   if (ContentRect().IsEmpty()) { |  491   if (ContentRect().IsEmpty()) { | 
|  361     last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |  492     last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 
|  362     return; |  493     return; | 
|  363   } |  494   } | 
|  364  |  495  | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  400           std::numeric_limits<float>::epsilon()) && |  531           std::numeric_limits<float>::epsilon()) && | 
|  401       current_screen_transform.IsApproximatelyIdentityOrTranslation( |  532       current_screen_transform.IsApproximatelyIdentityOrTranslation( | 
|  402           std::numeric_limits<float>::epsilon())) { |  533           std::numeric_limits<float>::epsilon())) { | 
|  403     gfx::Vector2dF current_offset( |  534     gfx::Vector2dF current_offset( | 
|  404         current_screen_transform.matrix().get(0, 3), |  535         current_screen_transform.matrix().get(0, 3), | 
|  405         current_screen_transform.matrix().get(1, 3)); |  536         current_screen_transform.matrix().get(1, 3)); | 
|  406     gfx::Vector2dF last_offset( |  537     gfx::Vector2dF last_offset( | 
|  407         last_screen_transform.matrix().get(0, 3), |  538         last_screen_transform.matrix().get(0, 3), | 
|  408         last_screen_transform.matrix().get(1, 3)); |  539         last_screen_transform.matrix().get(1, 3)); | 
|  409  |  540  | 
|  410     for (TilingData::Iterator iter(&tiling_data_, interest_rect); |  541     for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect); | 
|  411          iter; ++iter) { |  542          iter; ++iter) { | 
|  412       TileMap::iterator find = tiles_.find(iter.index()); |  543       int bundle_x = iter.index_x(); | 
|  413       if (find == tiles_.end()) |  544       int bundle_y = iter.index_y(); | 
 |  545       TileBundle* bundle = TileBundleAt(bundle_x, bundle_y); | 
 |  546       if (!bundle) | 
|  414         continue; |  547         continue; | 
|  415       Tile* tile = find->second.get(); |  | 
|  416  |  548  | 
|  417       gfx::Rect tile_bounds = |  549       gfx::Rect bundle_bounds = | 
|  418           tiling_data_.TileBounds(iter.index_x(), iter.index_y()); |  550           bundle_tiling_data_.TileBounds(bundle_x, bundle_y); | 
|  419       gfx::RectF current_screen_rect = gfx::ScaleRect( |  551       gfx::RectF current_screen_rect = | 
|  420           tile_bounds, |  552           gfx::ScaleRect(bundle_bounds, current_scale, current_scale) + | 
|  421           current_scale, |  553           current_offset; | 
|  422           current_scale) + current_offset; |  554       gfx::RectF last_screen_rect = | 
|  423       gfx::RectF last_screen_rect = gfx::ScaleRect( |  555           gfx::ScaleRect(bundle_bounds, last_scale, last_scale) + | 
|  424           tile_bounds, |  556           last_offset; | 
|  425           last_scale, |  | 
|  426           last_scale) + last_offset; |  | 
|  427  |  557  | 
|  428       float distance_to_visible_in_pixels = |  558       float distance_to_visible_in_pixels = | 
|  429           TilePriority::manhattanDistance(current_screen_rect, view_rect); |  559           TilePriority::manhattanDistance(current_screen_rect, view_rect); | 
|  430  |  560  | 
|  431       float time_to_visible_in_seconds = |  561       float time_to_visible_in_seconds = | 
|  432           TilePriority::TimeForBoundsToIntersect( |  562           TilePriority::TimeForBoundsToIntersect( | 
|  433               last_screen_rect, current_screen_rect, time_delta, view_rect); |  563               last_screen_rect, current_screen_rect, time_delta, view_rect); | 
|  434       TilePriority priority( |  564       TilePriority priority( | 
|  435           resolution_, |  565           resolution_, | 
|  436           time_to_visible_in_seconds, |  566           time_to_visible_in_seconds, | 
|  437           distance_to_visible_in_pixels); |  567           distance_to_visible_in_pixels); | 
|  438       tile->SetPriority(tree, priority); |  568  | 
 |  569       bundle->SetPriority(tree, priority); | 
|  439     } |  570     } | 
|  440   } else if (!last_screen_transform.HasPerspective() && |  571   } else if (!last_screen_transform.HasPerspective() && | 
|  441              !current_screen_transform.HasPerspective()) { |  572              !current_screen_transform.HasPerspective()) { | 
|  442     // Secondary fast path that can be applied for any affine transforms. |  573     // Secondary fast path that can be applied for any affine transforms. | 
|  443  |  574  | 
|  444     // Initialize the necessary geometry in screen space, so that we can |  575     // Initialize the necessary geometry in screen space, so that we can | 
|  445     // iterate over tiles in screen space without needing a costly transform |  576     // iterate over tiles in screen space without needing a costly transform | 
|  446     // mapping for each tile. |  577     // mapping for each tile. | 
|  447  |  578  | 
|  448     // Apply screen space transform to the local origin point (0, 0); only the |  579     // Apply screen space transform to the local origin point (0, 0); only the | 
|  449     // translation component is needed and can be initialized directly. |  580     // translation component is needed and can be initialized directly. | 
|  450     gfx::Point current_screen_space_origin( |  581     gfx::Point current_screen_space_origin( | 
|  451         current_screen_transform.matrix().get(0, 3), |  582         current_screen_transform.matrix().get(0, 3), | 
|  452         current_screen_transform.matrix().get(1, 3)); |  583         current_screen_transform.matrix().get(1, 3)); | 
|  453  |  584  | 
|  454     gfx::Point last_screen_space_origin( |  585     gfx::Point last_screen_space_origin( | 
|  455         last_screen_transform.matrix().get(0, 3), |  586         last_screen_transform.matrix().get(0, 3), | 
|  456         last_screen_transform.matrix().get(1, 3)); |  587         last_screen_transform.matrix().get(1, 3)); | 
|  457  |  588  | 
|  458     float current_tile_width = tiling_data_.TileSizeX(0) * current_scale; |  589     float current_bundle_width = | 
|  459     float last_tile_width = tiling_data_.TileSizeX(0) * last_scale; |  590         bundle_tiling_data_.TileSizeX(0) * current_scale; | 
|  460     float current_tile_height = tiling_data_.TileSizeY(0) * current_scale; |  591     float last_bundle_width = | 
|  461     float last_tile_height = tiling_data_.TileSizeY(0) * last_scale; |  592         bundle_tiling_data_.TileSizeX(0) * last_scale; | 
 |  593     float current_bundle_height = | 
 |  594         bundle_tiling_data_.TileSizeY(0) * current_scale; | 
 |  595     float last_bundle_height = | 
 |  596         bundle_tiling_data_.TileSizeY(0) * last_scale; | 
|  462  |  597  | 
|  463     // Apply screen space transform to local basis vectors (tile_width, 0) and |  598     // Apply screen space transform to local basis vectors (tile_width, 0) and | 
|  464     // (0, tile_height); the math simplifies and can be initialized directly. |  599     // (0, tile_height); the math simplifies and can be initialized directly. | 
|  465     gfx::Vector2dF current_horizontal( |  600     gfx::Vector2dF current_horizontal( | 
|  466         current_screen_transform.matrix().get(0, 0) * current_tile_width, |  601         current_screen_transform.matrix().get(0, 0) * current_bundle_width, | 
|  467         current_screen_transform.matrix().get(1, 0) * current_tile_width); |  602         current_screen_transform.matrix().get(1, 0) * current_bundle_width); | 
|  468     gfx::Vector2dF current_vertical( |  603     gfx::Vector2dF current_vertical( | 
|  469         current_screen_transform.matrix().get(0, 1) * current_tile_height, |  604         current_screen_transform.matrix().get(0, 1) * current_bundle_height, | 
|  470         current_screen_transform.matrix().get(1, 1) * current_tile_height); |  605         current_screen_transform.matrix().get(1, 1) * current_bundle_height); | 
|  471  |  606  | 
|  472     gfx::Vector2dF last_horizontal( |  607     gfx::Vector2dF last_horizontal( | 
|  473         last_screen_transform.matrix().get(0, 0) * last_tile_width, |  608         last_screen_transform.matrix().get(0, 0) * last_bundle_width, | 
|  474         last_screen_transform.matrix().get(1, 0) * last_tile_width); |  609         last_screen_transform.matrix().get(1, 0) * last_bundle_width); | 
|  475     gfx::Vector2dF last_vertical( |  610     gfx::Vector2dF last_vertical( | 
|  476         last_screen_transform.matrix().get(0, 1) * last_tile_height, |  611         last_screen_transform.matrix().get(0, 1) * last_bundle_height, | 
|  477         last_screen_transform.matrix().get(1, 1) * last_tile_height); |  612         last_screen_transform.matrix().get(1, 1) * last_bundle_height); | 
|  478  |  613  | 
|  479     for (TilingData::Iterator iter(&tiling_data_, interest_rect); |  614     for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect); | 
|  480          iter; ++iter) { |  615          iter; ++iter) { | 
|  481       TileMap::iterator find = tiles_.find(iter.index()); |  616       int bundle_x = iter.index_x(); | 
|  482       if (find == tiles_.end()) |  617       int bundle_y = iter.index_y(); | 
 |  618       TileBundle* bundle = TileBundleAt(bundle_x, bundle_y); | 
 |  619       if (!bundle) | 
|  483         continue; |  620         continue; | 
|  484  |  621  | 
|  485       Tile* tile = find->second.get(); |  622       gfx::PointF current_bundle_origin = current_screen_space_origin + | 
|  486  |  623               ScaleVector2d(current_horizontal, bundle_x) + | 
|  487       int i = iter.index_x(); |  624               ScaleVector2d(current_vertical, bundle_y); | 
|  488       int j = iter.index_y(); |  625       gfx::PointF last_bundle_origin = last_screen_space_origin + | 
|  489       gfx::PointF current_tile_origin = current_screen_space_origin + |  626               ScaleVector2d(last_horizontal, bundle_x) + | 
|  490               ScaleVector2d(current_horizontal, i) + |  627               ScaleVector2d(last_vertical, bundle_y); | 
|  491               ScaleVector2d(current_vertical, j); |  | 
|  492       gfx::PointF last_tile_origin = last_screen_space_origin + |  | 
|  493               ScaleVector2d(last_horizontal, i) + |  | 
|  494               ScaleVector2d(last_vertical, j); |  | 
|  495  |  628  | 
|  496       gfx::RectF current_screen_rect = gfx::QuadF( |  629       gfx::RectF current_screen_rect = gfx::QuadF( | 
|  497           current_tile_origin, |  630           current_bundle_origin, | 
|  498           current_tile_origin + current_horizontal, |  631           current_bundle_origin + current_horizontal, | 
|  499           current_tile_origin + current_horizontal + current_vertical, |  632           current_bundle_origin + current_horizontal + current_vertical, | 
|  500           current_tile_origin + current_vertical).BoundingBox(); |  633           current_bundle_origin + current_vertical).BoundingBox(); | 
|  501  |  634  | 
|  502       gfx::RectF last_screen_rect = gfx::QuadF( |  635       gfx::RectF last_screen_rect = gfx::QuadF( | 
|  503           last_tile_origin, |  636           last_bundle_origin, | 
|  504           last_tile_origin + last_horizontal, |  637           last_bundle_origin + last_horizontal, | 
|  505           last_tile_origin + last_horizontal + last_vertical, |  638           last_bundle_origin + last_horizontal + last_vertical, | 
|  506           last_tile_origin + last_vertical).BoundingBox(); |  639           last_bundle_origin + last_vertical).BoundingBox(); | 
|  507  |  640  | 
|  508       float distance_to_visible_in_pixels = |  641       float distance_to_visible_in_pixels = | 
|  509           TilePriority::manhattanDistance(current_screen_rect, view_rect); |  642           TilePriority::manhattanDistance(current_screen_rect, view_rect); | 
|  510  |  643  | 
|  511       float time_to_visible_in_seconds = |  644       float time_to_visible_in_seconds = | 
|  512           TilePriority::TimeForBoundsToIntersect( |  645           TilePriority::TimeForBoundsToIntersect( | 
|  513               last_screen_rect, current_screen_rect, time_delta, view_rect); |  646               last_screen_rect, current_screen_rect, time_delta, view_rect); | 
|  514       TilePriority priority( |  647       TilePriority priority( | 
|  515           resolution_, |  648           resolution_, | 
|  516           time_to_visible_in_seconds, |  649           time_to_visible_in_seconds, | 
|  517           distance_to_visible_in_pixels); |  650           distance_to_visible_in_pixels); | 
|  518       tile->SetPriority(tree, priority); |  651  | 
 |  652       bundle->SetPriority(tree, priority); | 
|  519     } |  653     } | 
|  520   } else { |  654   } else { | 
|  521     for (TilingData::Iterator iter(&tiling_data_, interest_rect); |  655     for (TilingData::Iterator iter(&bundle_tiling_data_, interest_rect); | 
|  522          iter; ++iter) { |  656          iter; ++iter) { | 
|  523       TileMap::iterator find = tiles_.find(iter.index()); |  657       int bundle_x = iter.index_x(); | 
|  524       if (find == tiles_.end()) |  658       int bundle_y = iter.index_y(); | 
 |  659       TileBundle* bundle = TileBundleAt(bundle_x, bundle_y); | 
 |  660       if (!bundle) | 
|  525         continue; |  661         continue; | 
|  526       Tile* tile = find->second.get(); |  | 
|  527  |  662  | 
|  528       gfx::Rect tile_bounds = |  663       gfx::Rect bundle_bounds = | 
|  529           tiling_data_.TileBounds(iter.index_x(), iter.index_y()); |  664           bundle_tiling_data_.TileBounds(bundle_x, bundle_y); | 
|  530       gfx::RectF current_layer_content_rect = gfx::ScaleRect( |  665       gfx::RectF current_layer_content_rect = gfx::ScaleRect( | 
|  531           tile_bounds, |  666           bundle_bounds, | 
|  532           current_scale, |  667           current_scale, | 
|  533           current_scale); |  668           current_scale); | 
|  534       gfx::RectF current_screen_rect = MathUtil::MapClippedRect( |  669       gfx::RectF current_screen_rect = MathUtil::MapClippedRect( | 
|  535           current_screen_transform, current_layer_content_rect); |  670           current_screen_transform, current_layer_content_rect); | 
|  536       gfx::RectF last_layer_content_rect = gfx::ScaleRect( |  671       gfx::RectF last_layer_content_rect = gfx::ScaleRect( | 
|  537           tile_bounds, |  672           bundle_bounds, | 
|  538           last_scale, |  673           last_scale, | 
|  539           last_scale); |  674           last_scale); | 
|  540       gfx::RectF last_screen_rect  = MathUtil::MapClippedRect( |  675       gfx::RectF last_screen_rect  = MathUtil::MapClippedRect( | 
|  541           last_screen_transform, last_layer_content_rect); |  676           last_screen_transform, last_layer_content_rect); | 
|  542  |  677  | 
|  543       float distance_to_visible_in_pixels = |  678       float distance_to_visible_in_pixels = | 
|  544           TilePriority::manhattanDistance(current_screen_rect, view_rect); |  679           TilePriority::manhattanDistance(current_screen_rect, view_rect); | 
|  545  |  680  | 
|  546       float time_to_visible_in_seconds = |  681       float time_to_visible_in_seconds = | 
|  547           TilePriority::TimeForBoundsToIntersect( |  682           TilePriority::TimeForBoundsToIntersect( | 
|  548               last_screen_rect, current_screen_rect, time_delta, view_rect); |  683               last_screen_rect, current_screen_rect, time_delta, view_rect); | 
|  549  |  684  | 
|  550       TilePriority priority( |  685       TilePriority priority( | 
|  551           resolution_, |  686           resolution_, | 
|  552           time_to_visible_in_seconds, |  687           time_to_visible_in_seconds, | 
|  553           distance_to_visible_in_pixels); |  688           distance_to_visible_in_pixels); | 
|  554       tile->SetPriority(tree, priority); |  689  | 
 |  690       bundle->SetPriority(tree, priority); | 
|  555     } |  691     } | 
|  556   } |  692   } | 
|  557  |  693  | 
|  558   last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |  694   last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 
|  559 } |  695 } | 
|  560  |  696  | 
|  561 void PictureLayerTiling::SetLiveTilesRect( |  697 void PictureLayerTiling::SetLiveTilesRect(gfx::Rect new_live_tiles_rect) { | 
|  562     gfx::Rect new_live_tiles_rect) { |  | 
|  563   DCHECK(new_live_tiles_rect.IsEmpty() || |  698   DCHECK(new_live_tiles_rect.IsEmpty() || | 
|  564          ContentRect().Contains(new_live_tiles_rect)); |  699          ContentRect().Contains(new_live_tiles_rect)); | 
|  565   if (live_tiles_rect_ == new_live_tiles_rect) |  700   if (live_tiles_rect_ == new_live_tiles_rect) | 
|  566     return; |  701     return; | 
|  567  |  702  | 
|  568   // Iterate to delete all tiles outside of our new live_tiles rect. |  703   // Iterate to delete all tiles outside of our new live_tiles rect. | 
|  569   for (TilingData::DifferenceIterator iter(&tiling_data_, |  704   for (TilingData::DifferenceIterator iter(&tiling_data_, | 
|  570                                            live_tiles_rect_, |  705                                            live_tiles_rect_, | 
|  571                                            new_live_tiles_rect); |  706                                            new_live_tiles_rect); | 
|  572        iter; |  707        iter; | 
|  573        ++iter) { |  708        ++iter) { | 
|  574     TileMapKey key(iter.index()); |  709     int tile_x = iter.index_x(); | 
|  575     TileMap::iterator found = tiles_.find(key); |  710     int tile_y = iter.index_y(); | 
 |  711  | 
|  576     // If the tile was outside of the recorded region, it won't exist even |  712     // If the tile was outside of the recorded region, it won't exist even | 
|  577     // though it was in the live rect. |  713     // though it was in the live rect. | 
|  578     if (found != tiles_.end()) |  714     RemoveTile(current_tree_, tile_x, tile_y); | 
|  579       tiles_.erase(found); |  715     RemoveBundleContainingTileAtIfEmpty(tile_x, tile_y); | 
|  580   } |  716   } | 
|  581  |  717  | 
|  582   const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |  718   const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | 
|  583  |  719  | 
|  584   // Iterate to allocate new tiles for all regions with newly exposed area. |  720   // Iterate to allocate new tiles for all regions with newly exposed area. | 
|  585   for (TilingData::DifferenceIterator iter(&tiling_data_, |  721   for (TilingData::DifferenceIterator iter(&tiling_data_, | 
|  586                                            new_live_tiles_rect, |  722                                            new_live_tiles_rect, | 
|  587                                            live_tiles_rect_); |  723                                            live_tiles_rect_); | 
|  588        iter; |  724        iter; | 
|  589        ++iter) { |  725        ++iter) { | 
|  590     TileMapKey key(iter.index()); |  726     CreateTile(current_tree_, iter.index_x(), iter.index_y(), twin_tiling); | 
|  591     CreateTile(key.first, key.second, twin_tiling); |  | 
|  592   } |  727   } | 
|  593  |  728  | 
|  594   live_tiles_rect_ = new_live_tiles_rect; |  729   live_tiles_rect_ = new_live_tiles_rect; | 
|  595 } |  730 } | 
|  596  |  731  | 
|  597 void PictureLayerTiling::DidBecomeRecycled() { |  732 void PictureLayerTiling::DidBecomeRecycled() { | 
|  598   // DidBecomeActive below will set the active priority for tiles that are |  733   // DidBecomeActive below will set the active priority for tiles that are | 
|  599   // still in the tree. Calling this first on an active tiling that is becoming |  734   // still in the tree. Calling this first on an active tiling that is becoming | 
|  600   // recycled takes care of tiles that are no longer in the active tree (eg. |  735   // recycled takes care of tiles that are no longer in the active tree (eg. | 
|  601   // due to a pending invalidation). |  736   // due to a pending invalidation). | 
|  602   for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |  737   for (TileBundleMap::const_iterator it = tile_bundles_.begin(); | 
|  603     it->second->SetPriority(ACTIVE_TREE, TilePriority()); |  738        it != tile_bundles_.end(); | 
 |  739        ++it) { | 
 |  740     it->second->DidBecomeRecycled(); | 
|  604   } |  741   } | 
 |  742   // Note that recycled tree would not be accessed, and the next tree | 
 |  743   // stage after recycled in pending, so we can just set the state to | 
 |  744   // pending here. | 
 |  745   current_tree_ = PENDING_TREE; | 
|  605 } |  746 } | 
|  606  |  747  | 
|  607 void PictureLayerTiling::DidBecomeActive() { |  748 void PictureLayerTiling::DidBecomeActive() { | 
|  608   for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |  749   for (TileBundleMap::const_iterator it = tile_bundles_.begin(); | 
|  609     it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE)); |  750        it != tile_bundles_.end(); | 
|  610     it->second->SetPriority(PENDING_TREE, TilePriority()); |  751        ++it) { | 
|  611  |  752     it->second->DidBecomeActive(); | 
|  612     // Tile holds a ref onto a picture pile. If the tile never gets invalidated |  753     for (TileBundle::Iterator tile_it(it->second.get(), ACTIVE_TREE); | 
|  613     // and recreated, then that picture pile ref could exist indefinitely.  To |  754          tile_it; | 
|  614     // prevent this, ask the client to update the pile to its own ref.  This |  755          ++tile_it) { | 
|  615     // will cause PicturePileImpls and their clones to get deleted once the |  756       // Tile holds a ref onto a picture pile. If the tile never gets | 
|  616     // corresponding PictureLayerImpl and any in flight raster jobs go out of |  757       // invalidated and recreated, then that picture pile ref could exist | 
|  617     // scope. |  758       // indefinitely.  To prevent this, ask the client to update the pile to | 
|  618     client_->UpdatePile(it->second.get()); |  759       // its own ref.  This will cause PicturePileImpls and their clones to get | 
 |  760       // deleted once the corresponding PictureLayerImpl and any in flight | 
 |  761       // raster jobs go out of scope. | 
 |  762       client_->UpdatePile(*tile_it); | 
 |  763     } | 
|  619   } |  764   } | 
 |  765   current_tree_ = ACTIVE_TREE; | 
|  620 } |  766 } | 
|  621  |  767  | 
|  622 void PictureLayerTiling::UpdateTilesToCurrentPile() { |  768 void PictureLayerTiling::UpdateTilesToCurrentPile() { | 
|  623   for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |  769   for (TileBundleMap::const_iterator it = tile_bundles_.begin(); | 
|  624     client_->UpdatePile(it->second.get()); |  770        it != tile_bundles_.end(); | 
 |  771        ++it) { | 
 |  772     for (TileBundle::Iterator tile_it(it->second.get(), PENDING_TREE); | 
 |  773          tile_it; | 
 |  774          ++tile_it) { | 
 |  775       client_->UpdatePile(*tile_it); | 
 |  776     } | 
|  625   } |  777   } | 
|  626 } |  778 } | 
|  627  |  779  | 
|  628 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { |  780 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { | 
|  629   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |  781   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 
|  630   state->SetInteger("num_tiles", tiles_.size()); |  782   state->SetInteger("num_tile_bundles", tile_bundles_.size()); | 
|  631   state->SetDouble("content_scale", contents_scale_); |  783   state->SetDouble("content_scale", contents_scale_); | 
|  632   state->Set("content_bounds", |  784   state->Set("content_bounds", | 
|  633              MathUtil::AsValue(ContentRect().size()).release()); |  785              MathUtil::AsValue(ContentRect().size()).release()); | 
|  634   return state.PassAs<base::Value>(); |  786   return state.PassAs<base::Value>(); | 
|  635 } |  787 } | 
|  636  |  788  | 
|  637 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { |  789 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { | 
|  638   size_t amount = 0; |  790   size_t amount = 0; | 
|  639   for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |  791   for (TileBundleMap::const_iterator it = tile_bundles_.begin(); | 
|  640     const Tile* tile = it->second.get(); |  792        it != tile_bundles_.end(); | 
|  641     amount += tile->GPUMemoryUsageInBytes(); |  793        ++it) { | 
 |  794     for (TileBundle::Iterator tile_it(it->second.get()); tile_it; ++tile_it) | 
 |  795       amount += tile_it->GPUMemoryUsageInBytes(); | 
|  642   } |  796   } | 
|  643   return amount; |  797   return amount; | 
|  644 } |  798 } | 
|  645  |  799  | 
|  646 PictureLayerTiling::RectExpansionCache::RectExpansionCache() |  800 PictureLayerTiling::RectExpansionCache::RectExpansionCache() | 
|  647   : previous_target(0) { |  801   : previous_target(0) { | 
|  648 } |  802 } | 
|  649  |  803  | 
|  650 namespace { |  804 namespace { | 
|  651  |  805  | 
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  786       break; |  940       break; | 
|  787   } |  941   } | 
|  788  |  942  | 
|  789   gfx::Rect result(origin_x, origin_y, width, height); |  943   gfx::Rect result(origin_x, origin_y, width, height); | 
|  790   if (cache) |  944   if (cache) | 
|  791     cache->previous_result = result; |  945     cache->previous_result = result; | 
|  792   return result; |  946   return result; | 
|  793 } |  947 } | 
|  794  |  948  | 
|  795 }  // namespace cc |  949 }  // namespace cc | 
| OLD | NEW |