| 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/tiles/picture_layer_tiling.h" |    5 #include "cc/tiles/picture_layer_tiling.h" | 
|    6  |    6  | 
|    7 #include <stddef.h> |    7 #include <stddef.h> | 
|    8  |    8  | 
|    9 #include <algorithm> |    9 #include <algorithm> | 
|   10 #include <cmath> |   10 #include <cmath> | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|   25 #include "ui/gfx/geometry/point_conversions.h" |   25 #include "ui/gfx/geometry/point_conversions.h" | 
|   26 #include "ui/gfx/geometry/rect_conversions.h" |   26 #include "ui/gfx/geometry/rect_conversions.h" | 
|   27 #include "ui/gfx/geometry/rect_f.h" |   27 #include "ui/gfx/geometry/rect_f.h" | 
|   28 #include "ui/gfx/geometry/safe_integer_conversions.h" |   28 #include "ui/gfx/geometry/safe_integer_conversions.h" | 
|   29 #include "ui/gfx/geometry/size_conversions.h" |   29 #include "ui/gfx/geometry/size_conversions.h" | 
|   30  |   30  | 
|   31 namespace cc { |   31 namespace cc { | 
|   32  |   32  | 
|   33 PictureLayerTiling::PictureLayerTiling( |   33 PictureLayerTiling::PictureLayerTiling( | 
|   34     WhichTree tree, |   34     WhichTree tree, | 
|   35     float contents_scale, |   35     const ScaleTranslate2d& raster_transform, | 
|   36     scoped_refptr<RasterSource> raster_source, |   36     scoped_refptr<RasterSource> raster_source, | 
|   37     PictureLayerTilingClient* client, |   37     PictureLayerTilingClient* client, | 
|   38     float min_preraster_distance, |   38     float min_preraster_distance, | 
|   39     float max_preraster_distance) |   39     float max_preraster_distance) | 
|   40     : contents_scale_(contents_scale), |   40     : raster_transform_(raster_transform), | 
|   41       client_(client), |   41       client_(client), | 
|   42       tree_(tree), |   42       tree_(tree), | 
|   43       raster_source_(raster_source), |   43       raster_source_(raster_source), | 
|   44       min_preraster_distance_(min_preraster_distance), |   44       min_preraster_distance_(min_preraster_distance), | 
|   45       max_preraster_distance_(max_preraster_distance) { |   45       max_preraster_distance_(max_preraster_distance) { | 
|   46   DCHECK(!raster_source->IsSolidColor()); |   46   DCHECK(!raster_source->IsSolidColor()); | 
|   47   gfx::Size content_bounds = |   47   DCHECK_GE(raster_transform.translation().x(), 0.f); | 
|   48       gfx::ScaleToCeiledSize(raster_source_->GetSize(), contents_scale_); |   48   DCHECK_LT(raster_transform.translation().x(), 1.f); | 
|   49   gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |   49   DCHECK_GE(raster_transform.translation().y(), 0.f); | 
 |   50   DCHECK_LT(raster_transform.translation().y(), 1.f); | 
|   50  |   51  | 
|   51   DCHECK(!gfx::ScaleToFlooredSize(raster_source_->GetSize(), contents_scale_) |   52   DCHECK(!gfx::ScaleToFlooredSize(raster_source_->GetSize(), | 
 |   53                                   raster_transform.scale()) | 
|   52               .IsEmpty()) |   54               .IsEmpty()) | 
|   53       << "Tiling created with scale too small as contents become empty." |   55       << "Tiling created with scale too small as contents become empty." | 
|   54       << " Layer bounds: " << raster_source_->GetSize().ToString() |   56       << " Layer bounds: " << raster_source_->GetSize().ToString() | 
|   55       << " Raster scale: " << contents_scale_; |   57       << " Raster transform: " << raster_transform_.ToString(); | 
|   56  |   58  | 
|   57   tiling_data_.SetTilingSize(content_bounds); |   59   gfx::Rect content_bounds_rect = | 
 |   60       EnclosingContentsRectFromLayerRect(gfx::Rect(raster_source_->GetSize())); | 
 |   61   gfx::Size tiling_size = gfx::Size(content_bounds_rect.bottom_right().x(), | 
 |   62                                     content_bounds_rect.bottom_right().y()); | 
 |   63   tiling_data_.SetTilingSize(tiling_size); | 
 |   64   gfx::Size tile_size = client_->CalculateTileSize(tiling_size); | 
|   58   tiling_data_.SetMaxTextureSize(tile_size); |   65   tiling_data_.SetMaxTextureSize(tile_size); | 
|   59 } |   66 } | 
|   60  |   67  | 
|   61 PictureLayerTiling::~PictureLayerTiling() { |   68 PictureLayerTiling::~PictureLayerTiling() { | 
|   62 } |   69 } | 
|   63  |   70  | 
|   64 Tile* PictureLayerTiling::CreateTile(const Tile::CreateInfo& info) { |   71 Tile* PictureLayerTiling::CreateTile(const Tile::CreateInfo& info) { | 
|   65   const int i = info.tiling_i_index; |   72   const int i = info.tiling_i_index; | 
|   66   const int j = info.tiling_j_index; |   73   const int j = info.tiling_j_index; | 
|   67   TileMapKey key(i, j); |   74   TileMapKey key(i, j); | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  101       // the previous content ID of these tiles. In that case, we need only |  108       // the previous content ID of these tiles. In that case, we need only | 
|  102       // partially raster the tile content. |  109       // partially raster the tile content. | 
|  103       if (tile && invalidation && TilingMatchesTileIndices(active_twin)) { |  110       if (tile && invalidation && TilingMatchesTileIndices(active_twin)) { | 
|  104         if (const Tile* old_tile = |  111         if (const Tile* old_tile = | 
|  105                 active_twin->TileAt(key.index_x, key.index_y)) { |  112                 active_twin->TileAt(key.index_x, key.index_y)) { | 
|  106           gfx::Rect tile_rect = tile->content_rect(); |  113           gfx::Rect tile_rect = tile->content_rect(); | 
|  107           gfx::Rect invalidated; |  114           gfx::Rect invalidated; | 
|  108           for (Region::Iterator iter(*invalidation); iter.has_rect(); |  115           for (Region::Iterator iter(*invalidation); iter.has_rect(); | 
|  109                iter.next()) { |  116                iter.next()) { | 
|  110             gfx::Rect invalid_content_rect = |  117             gfx::Rect invalid_content_rect = | 
|  111                 gfx::ScaleToEnclosingRect(iter.rect(), contents_scale_); |  118                 EnclosingContentsRectFromLayerRect(iter.rect()); | 
|  112             invalid_content_rect.Intersect(tile_rect); |  119             invalid_content_rect.Intersect(tile_rect); | 
|  113             invalidated.Union(invalid_content_rect); |  120             invalidated.Union(invalid_content_rect); | 
|  114           } |  121           } | 
|  115           tile->SetInvalidated(invalidated, old_tile->id()); |  122           tile->SetInvalidated(invalidated, old_tile->id()); | 
|  116         } |  123         } | 
|  117       } |  124       } | 
|  118     } |  125     } | 
|  119   } |  126   } | 
|  120   VerifyLiveTilesRect(false); |  127   VerifyLiveTilesRect(false); | 
|  121 } |  128 } | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  160                        pending_twin->current_eventually_rect_, |  167                        pending_twin->current_eventually_rect_, | 
|  161                        pending_twin->current_occlusion_in_layer_space_); |  168                        pending_twin->current_occlusion_in_layer_space_); | 
|  162 } |  169 } | 
|  163  |  170  | 
|  164 void PictureLayerTiling::SetRasterSourceAndResize( |  171 void PictureLayerTiling::SetRasterSourceAndResize( | 
|  165     scoped_refptr<RasterSource> raster_source) { |  172     scoped_refptr<RasterSource> raster_source) { | 
|  166   DCHECK(!raster_source->IsSolidColor()); |  173   DCHECK(!raster_source->IsSolidColor()); | 
|  167   gfx::Size old_layer_bounds = raster_source_->GetSize(); |  174   gfx::Size old_layer_bounds = raster_source_->GetSize(); | 
|  168   raster_source_ = std::move(raster_source); |  175   raster_source_ = std::move(raster_source); | 
|  169   gfx::Size new_layer_bounds = raster_source_->GetSize(); |  176   gfx::Size new_layer_bounds = raster_source_->GetSize(); | 
|  170   gfx::Size content_bounds = |  177   gfx::Rect content_rect = | 
|  171       gfx::ScaleToCeiledSize(new_layer_bounds, contents_scale_); |  178       EnclosingContentsRectFromLayerRect(gfx::Rect(new_layer_bounds)); | 
|  172   gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |  179   DCHECK(content_rect.origin() == gfx::Point()); | 
 |  180   gfx::Size tile_size = client_->CalculateTileSize(content_rect.size()); | 
|  173  |  181  | 
|  174   if (tile_size != tiling_data_.max_texture_size()) { |  182   if (tile_size != tiling_data_.max_texture_size()) { | 
|  175     tiling_data_.SetTilingSize(content_bounds); |  183     tiling_data_.SetTilingSize(content_rect.size()); | 
|  176     tiling_data_.SetMaxTextureSize(tile_size); |  184     tiling_data_.SetMaxTextureSize(tile_size); | 
|  177     // When the tile size changes, the TilingData positions no longer work |  185     // When the tile size changes, the TilingData positions no longer work | 
|  178     // as valid keys to the TileMap, so just drop all tiles and clear the live |  186     // as valid keys to the TileMap, so just drop all tiles and clear the live | 
|  179     // tiles rect. |  187     // tiles rect. | 
|  180     Reset(); |  188     Reset(); | 
|  181     return; |  189     return; | 
|  182   } |  190   } | 
|  183  |  191  | 
|  184   if (old_layer_bounds == new_layer_bounds) |  192   if (old_layer_bounds == new_layer_bounds) | 
|  185     return; |  193     return; | 
|  186  |  194  | 
|  187   // The SetLiveTilesRect() method would drop tiles outside the new bounds, |  195   // The SetLiveTilesRect() method would drop tiles outside the new bounds, | 
|  188   // but may do so incorrectly if resizing the tiling causes the number of |  196   // but may do so incorrectly if resizing the tiling causes the number of | 
|  189   // tiles in the tiling_data_ to change. |  197   // tiles in the tiling_data_ to change. | 
|  190   gfx::Rect content_rect(content_bounds); |  | 
|  191   int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x()); |  198   int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x()); | 
|  192   int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y()); |  199   int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y()); | 
|  193   int before_right = |  200   int before_right = | 
|  194       tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); |  201       tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); | 
|  195   int before_bottom = |  202   int before_bottom = | 
|  196       tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); |  203       tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); | 
|  197  |  204  | 
|  198   // The live_tiles_rect_ is clamped to stay within the tiling size as we |  205   // The live_tiles_rect_ is clamped to stay within the tiling size as we | 
|  199   // change it. |  206   // change it. | 
|  200   live_tiles_rect_.Intersect(content_rect); |  207   live_tiles_rect_.Intersect(content_rect); | 
|  201   tiling_data_.SetTilingSize(content_bounds); |  208   tiling_data_.SetTilingSize(content_rect.size()); | 
|  202  |  209  | 
|  203   int after_right = -1; |  210   int after_right = -1; | 
|  204   int after_bottom = -1; |  211   int after_bottom = -1; | 
|  205   if (!live_tiles_rect_.IsEmpty()) { |  212   if (!live_tiles_rect_.IsEmpty()) { | 
|  206     after_right = |  213     after_right = | 
|  207         tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); |  214         tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); | 
|  208     after_bottom = |  215     after_bottom = | 
|  209         tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); |  216         tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); | 
|  210   } |  217   } | 
|  211  |  218  | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  256   // unordered_map instead of a vector in the SmallMap. |  263   // unordered_map instead of a vector in the SmallMap. | 
|  257   base::SmallMap<std::unordered_map<TileMapKey, gfx::Rect, TileMapKeyHash>, 16> |  264   base::SmallMap<std::unordered_map<TileMapKey, gfx::Rect, TileMapKeyHash>, 16> | 
|  258       remove_tiles; |  265       remove_tiles; | 
|  259   gfx::Rect expanded_live_tiles_rect = |  266   gfx::Rect expanded_live_tiles_rect = | 
|  260       tiling_data_.ExpandRectToTileBounds(live_tiles_rect_); |  267       tiling_data_.ExpandRectToTileBounds(live_tiles_rect_); | 
|  261   for (Region::Iterator iter(layer_invalidation); iter.has_rect(); |  268   for (Region::Iterator iter(layer_invalidation); iter.has_rect(); | 
|  262        iter.next()) { |  269        iter.next()) { | 
|  263     gfx::Rect layer_rect = iter.rect(); |  270     gfx::Rect layer_rect = iter.rect(); | 
|  264     // The pixels which are invalid in content space. |  271     // The pixels which are invalid in content space. | 
|  265     gfx::Rect invalid_content_rect = |  272     gfx::Rect invalid_content_rect = | 
|  266         gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); |  273         EnclosingContentsRectFromLayerRect(layer_rect); | 
|  267     gfx::Rect coverage_content_rect = invalid_content_rect; |  274     gfx::Rect coverage_content_rect = invalid_content_rect; | 
|  268     // Avoid needless work by not bothering to invalidate where there aren't |  275     // Avoid needless work by not bothering to invalidate where there aren't | 
|  269     // tiles. |  276     // tiles. | 
|  270     coverage_content_rect.Intersect(expanded_live_tiles_rect); |  277     coverage_content_rect.Intersect(expanded_live_tiles_rect); | 
|  271     if (coverage_content_rect.IsEmpty()) |  278     if (coverage_content_rect.IsEmpty()) | 
|  272       continue; |  279       continue; | 
|  273     // Since the content_rect needs to invalidate things that only touch a |  280     // Since the content_rect needs to invalidate things that only touch a | 
|  274     // border of a tile, we need to include the borders while iterating. |  281     // border of a tile, we need to include the borders while iterating. | 
|  275     bool include_borders = true; |  282     bool include_borders = true; | 
|  276     for (TilingData::Iterator iter(&tiling_data_, coverage_content_rect, |  283     for (TilingData::Iterator iter(&tiling_data_, coverage_content_rect, | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  293       if (Tile* tile = CreateTile(info)) |  300       if (Tile* tile = CreateTile(info)) | 
|  294         tile->SetInvalidated(invalid_content_rect, old_tile->id()); |  301         tile->SetInvalidated(invalid_content_rect, old_tile->id()); | 
|  295     } |  302     } | 
|  296   } |  303   } | 
|  297 } |  304 } | 
|  298  |  305  | 
|  299 Tile::CreateInfo PictureLayerTiling::CreateInfoForTile(int i, int j) const { |  306 Tile::CreateInfo PictureLayerTiling::CreateInfoForTile(int i, int j) const { | 
|  300   gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); |  307   gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); | 
|  301   tile_rect.set_size(tiling_data_.max_texture_size()); |  308   tile_rect.set_size(tiling_data_.max_texture_size()); | 
|  302   gfx::Rect enclosing_layer_rect = |  309   gfx::Rect enclosing_layer_rect = | 
|  303       gfx::ScaleToEnclosingRect(tile_rect, 1.f / contents_scale_); |  310       EnclosingLayerRectFromContentsRect(tile_rect); | 
|  304   return Tile::CreateInfo(this, i, j, enclosing_layer_rect, tile_rect, |  311   return Tile::CreateInfo(this, i, j, enclosing_layer_rect, tile_rect, | 
|  305                           contents_scale_); |  312                           raster_transform_); | 
|  306 } |  313 } | 
|  307  |  314  | 
|  308 bool PictureLayerTiling::ShouldCreateTileAt( |  315 bool PictureLayerTiling::ShouldCreateTileAt( | 
|  309     const Tile::CreateInfo& info) const { |  316     const Tile::CreateInfo& info) const { | 
|  310   const int i = info.tiling_i_index; |  317   const int i = info.tiling_i_index; | 
|  311   const int j = info.tiling_j_index; |  318   const int j = info.tiling_j_index; | 
|  312   // Active tree should always create a tile. The reason for this is that active |  319   // Active tree should always create a tile. The reason for this is that active | 
|  313   // tree represents content that we draw on screen, which means that whenever |  320   // tree represents content that we draw on screen, which means that whenever | 
|  314   // we check whether a tile should exist somewhere, the answer is yes. This |  321   // we check whether a tile should exist somewhere, the answer is yes. This | 
|  315   // doesn't mean it will actually be created (if raster source doesn't cover |  322   // doesn't mean it will actually be created (if raster source doesn't cover | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  335     return true; |  342     return true; | 
|  336  |  343  | 
|  337   const Region* layer_invalidation = client_->GetPendingInvalidation(); |  344   const Region* layer_invalidation = client_->GetPendingInvalidation(); | 
|  338  |  345  | 
|  339   // If this tile is invalidated, then the pending tree should create one. |  346   // If this tile is invalidated, then the pending tree should create one. | 
|  340   // Do the intersection test in content space to match the corresponding check |  347   // Do the intersection test in content space to match the corresponding check | 
|  341   // on the active tree and avoid floating point inconsistencies. |  348   // on the active tree and avoid floating point inconsistencies. | 
|  342   for (Region::Iterator iter(*layer_invalidation); iter.has_rect(); |  349   for (Region::Iterator iter(*layer_invalidation); iter.has_rect(); | 
|  343        iter.next()) { |  350        iter.next()) { | 
|  344     gfx::Rect invalid_content_rect = |  351     gfx::Rect invalid_content_rect = | 
|  345         gfx::ScaleToEnclosingRect(iter.rect(), contents_scale_); |  352         EnclosingContentsRectFromLayerRect(iter.rect()); | 
|  346     if (invalid_content_rect.Intersects(info.content_rect)) |  353     if (invalid_content_rect.Intersects(info.content_rect)) | 
|  347       return true; |  354       return true; | 
|  348   } |  355   } | 
|  349   // If the active tree doesn't have a tile here, but it's in the pending tree's |  356   // If the active tree doesn't have a tile here, but it's in the pending tree's | 
|  350   // visible rect, then the pending tree should create a tile. This can happen |  357   // visible rect, then the pending tree should create a tile. This can happen | 
|  351   // if the pending visible rect is outside of the active tree's live tiles |  358   // if the pending visible rect is outside of the active tree's live tiles | 
|  352   // rect. In those situations, we need to block activation until we're ready to |  359   // rect. In those situations, we need to block activation until we're ready to | 
|  353   // display content, which will have to come from the pending tree. |  360   // display content, which will have to come from the pending tree. | 
|  354   if (!active_twin->TileAt(i, j) && |  361   if (!active_twin->TileAt(i, j) && | 
|  355       current_visible_rect_.Intersects(info.content_rect)) |  362       current_visible_rect_.Intersects(info.content_rect)) | 
|  356     return true; |  363     return true; | 
|  357  |  364  | 
|  358   // In all other cases, the pending tree doesn't need to create a tile. |  365   // In all other cases, the pending tree doesn't need to create a tile. | 
|  359   return false; |  366   return false; | 
|  360 } |  367 } | 
|  361  |  368  | 
|  362 bool PictureLayerTiling::TilingMatchesTileIndices( |  369 bool PictureLayerTiling::TilingMatchesTileIndices( | 
|  363     const PictureLayerTiling* twin) const { |  370     const PictureLayerTiling* twin) const { | 
|  364   return tiling_data_.max_texture_size() == |  371   return tiling_data_.max_texture_size() == | 
|  365          twin->tiling_data_.max_texture_size(); |  372          twin->tiling_data_.max_texture_size(); | 
|  366 } |  373 } | 
|  367  |  374  | 
|  368 PictureLayerTiling::CoverageIterator::CoverageIterator() = default; |  375 PictureLayerTiling::CoverageIterator::CoverageIterator() = default; | 
|  369  |  376  | 
|  370 PictureLayerTiling::CoverageIterator::CoverageIterator( |  377 PictureLayerTiling::CoverageIterator::CoverageIterator( | 
|  371     const PictureLayerTiling* tiling, |  378     const PictureLayerTiling* tiling, | 
|  372     float coverage_scale, |  379     float coverage_scale, | 
|  373     const gfx::Rect& coverage_rect) |  380     const gfx::Rect& coverage_rect) | 
|  374     : tiling_(tiling), coverage_rect_(coverage_rect) { |  381     : tiling_(tiling), | 
 |  382       coverage_rect_(coverage_rect), | 
 |  383       coverage_to_content_( | 
 |  384           ScaleTranslate2d::PreScale(tiling->raster_transform(), | 
 |  385                                      1.f / coverage_scale)) { | 
|  375   DCHECK(tiling_); |  386   DCHECK(tiling_); | 
|  376   // In order to avoid artifacts in geometry_rect scaling and clamping to ints, |  387   // In order to avoid artifacts in geometry_rect scaling and clamping to ints, | 
|  377   // the |coverage_scale| should always be at least as big as the tiling's |  388   // the |coverage_scale| should always be at least as big as the tiling's | 
|  378   // raster scales. |  389   // raster scales. | 
|  379   DCHECK_GE(coverage_scale, tiling_->contents_scale_); |  390   DCHECK_GE(coverage_scale, tiling_->raster_transform_.scale()); | 
|  380  |  391  | 
|  381   // Clamp |coverage_rect| to the bounds of this tiling's raster source. |  392   // Clamp |coverage_rect| to the bounds of this tiling's raster source. | 
|  382   coverage_rect_max_bounds_ = |  393   coverage_rect_max_bounds_ = | 
|  383       gfx::ScaleToCeiledSize(tiling->raster_source_->GetSize(), coverage_scale); |  394       gfx::ScaleToCeiledSize(tiling->raster_source_->GetSize(), coverage_scale); | 
|  384   coverage_rect_.Intersect(gfx::Rect(coverage_rect_max_bounds_)); |  395   coverage_rect_.Intersect(gfx::Rect(coverage_rect_max_bounds_)); | 
|  385   if (coverage_rect_.IsEmpty()) |  396   if (coverage_rect_.IsEmpty()) | 
|  386     return; |  397     return; | 
|  387  |  398  | 
|  388   coverage_to_content_scale_ = tiling_->contents_scale_ / coverage_scale; |  | 
|  389  |  | 
|  390   // Find the indices of the texel samples that enclose the rect we want to |  399   // Find the indices of the texel samples that enclose the rect we want to | 
|  391   // cover. |  400   // cover. | 
|  392   // Because we don't know the target transform at this point, we have to be |  401   // Because we don't know the target transform at this point, we have to be | 
|  393   // pessimistic, i.e. assume every point (a pair of real number, not necessary |  402   // pessimistic, i.e. assume every point (a pair of real number, not necessary | 
|  394   // snapped to a pixel sample) inside of the content rect may be sampled. |  403   // snapped to a pixel sample) inside of the content rect may be sampled. | 
|  395   // This code maps the boundary points into contents space, then find out the |  404   // This code maps the boundary points into contents space, then find out the | 
|  396   // enclosing texture samples. For example, assume we have: |  405   // enclosing texture samples. For example, assume we have: | 
|  397   // dest_scale : content_scale = 1.23 : 1 |  406   // coverage_scale : content_scale = 1.23 : 1 | 
|  398   // dest_rect = (l:123, t:234, r:345, b:456) |  407   // coverage_rect = (l:123, t:234, r:345, b:456) | 
|  399   // Then it follows that: |  408   // Then it follows that: | 
|  400   // content_rect = (l:100.00, t:190.24, r:280.49, b:370.73) |  409   // content_rect = (l:100.00, t:190.24, r:280.49, b:370.73) | 
|  401   // Without MSAA, the sample point of a texel is at the center of that texel, |  410   // Without MSAA, the sample point of a texel is at the center of that texel, | 
|  402   // thus the sample points we need to cover content_rect are: |  411   // thus the sample points we need to cover content_rect are: | 
|  403   // wanted_texels(sample coordinates) = (l:99.5, t:189.5, r:280.5, b:371.5) |  412   // wanted_texels(sample coordinates) = (l:99.5, t:189.5, r:280.5, b:371.5) | 
|  404   // Or in integer index: |  413   // Or in integer index: | 
|  405   // wanted_texels(integer index) = (l:99, t:189, r:280, b:371) |  414   // wanted_texels(integer index) = (l:99, t:189, r:280, b:371) | 
|  406   gfx::RectF content_rect = |  415   gfx::RectF content_rect = | 
|  407       gfx::ScaleRect(gfx::RectF(coverage_rect_), coverage_to_content_scale_); |  416       coverage_to_content_.TransformRect(gfx::RectF(coverage_rect_)); | 
|  408   content_rect.Offset(-0.5f, -0.5f); |  417   content_rect.Offset(-0.5f, -0.5f); | 
|  409   gfx::Rect wanted_texels = gfx::ToEnclosingRect(content_rect); |  418   gfx::Rect wanted_texels = gfx::ToEnclosingRect(content_rect); | 
|  410  |  419  | 
|  411   const TilingData& data = tiling_->tiling_data_; |  420   const TilingData& data = tiling_->tiling_data_; | 
|  412   left_ = data.LastBorderTileXIndexFromSrcCoord(wanted_texels.x()); |  421   left_ = data.LastBorderTileXIndexFromSrcCoord(wanted_texels.x()); | 
|  413   top_ = data.LastBorderTileYIndexFromSrcCoord(wanted_texels.y()); |  422   top_ = data.LastBorderTileYIndexFromSrcCoord(wanted_texels.y()); | 
|  414   right_ = std::max( |  423   right_ = std::max( | 
|  415       left_, data.FirstBorderTileXIndexFromSrcCoord(wanted_texels.right())); |  424       left_, data.FirstBorderTileXIndexFromSrcCoord(wanted_texels.right())); | 
|  416   bottom_ = std::max( |  425   bottom_ = std::max( | 
|  417       top_, data.FirstBorderTileYIndexFromSrcCoord(wanted_texels.bottom())); |  426       top_, data.FirstBorderTileYIndexFromSrcCoord(wanted_texels.bottom())); | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  459     // error in both u/v axis can't exceed |  468     // error in both u/v axis can't exceed | 
|  460     // 255 * (1 - (1 - 1/1024) * (1 - 1/1024)) ~= 0.498 |  469     // 255 * (1 - (1 - 1/1024) * (1 - 1/1024)) ~= 0.498 | 
|  461     // i.e. The color value can never flip over a rounding threshold. |  470     // i.e. The color value can never flip over a rounding threshold. | 
|  462     constexpr float epsilon = 1.f / 1024.f; |  471     constexpr float epsilon = 1.f / 1024.f; | 
|  463     texel_extent.Inset(-epsilon, -epsilon); |  472     texel_extent.Inset(-epsilon, -epsilon); | 
|  464   } |  473   } | 
|  465  |  474  | 
|  466   // Convert texel_extent to coverage scale, which is what we have to report |  475   // Convert texel_extent to coverage scale, which is what we have to report | 
|  467   // geometry_rect in. |  476   // geometry_rect in. | 
|  468   current_geometry_rect_ = gfx::ToEnclosedRect( |  477   current_geometry_rect_ = gfx::ToEnclosedRect( | 
|  469       gfx::ScaleRect(texel_extent, 1.f / coverage_to_content_scale_)); |  478       coverage_to_content_.TransformRectReverse(texel_extent)); | 
|  470   { |  479   { | 
|  471     // Adjust external edges to cover the whole layer in dest space. |  480     // Adjust external edges to cover the whole layer in dest space. | 
|  472     // |  481     // | 
|  473     // For external edges, extend the tile to scaled layer bounds. This is |  482     // For external edges, extend the tile to scaled layer bounds. This is | 
|  474     // needed to fully cover the coverage space because the sample extent |  483     // needed to fully cover the coverage space because the sample extent | 
|  475     // doesn't cover the last 0.5 texel to layer edge, and also the coverage |  484     // doesn't cover the last 0.5 texel to layer edge, and also the coverage | 
|  476     // space can be rounded up for up to 1 pixel. This overhang will never be |  485     // space can be rounded up for up to 1 pixel. This overhang will never be | 
|  477     // sampled as the AA fragment shader clamps sample coordinate and |  486     // sampled as the AA fragment shader clamps sample coordinate and | 
|  478     // antialiasing itself. |  487     // antialiasing itself. | 
|  479     const TilingData& data = tiling_->tiling_data_; |  488     const TilingData& data = tiling_->tiling_data_; | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  522 } |  531 } | 
|  523  |  532  | 
|  524 gfx::Rect PictureLayerTiling::CoverageIterator::geometry_rect() const { |  533 gfx::Rect PictureLayerTiling::CoverageIterator::geometry_rect() const { | 
|  525   return current_geometry_rect_; |  534   return current_geometry_rect_; | 
|  526 } |  535 } | 
|  527  |  536  | 
|  528 gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const { |  537 gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const { | 
|  529   auto tex_origin = gfx::PointF( |  538   auto tex_origin = gfx::PointF( | 
|  530       tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin()); |  539       tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin()); | 
|  531  |  540  | 
|  532   // Convert from dest space => content space => texture space. |  541   // Convert from coverage space => content space => texture space. | 
|  533   gfx::RectF texture_rect(current_geometry_rect_); |  542   gfx::RectF texture_rect(current_geometry_rect_); | 
|  534   texture_rect.Scale(coverage_to_content_scale_); |  543   texture_rect = coverage_to_content_.TransformRect(texture_rect); | 
|  535   texture_rect.Intersect(gfx::RectF(gfx::SizeF(tiling_->tiling_size()))); |  | 
|  536   if (texture_rect.IsEmpty()) |  | 
|  537     return texture_rect; |  | 
|  538   texture_rect.Offset(-tex_origin.OffsetFromOrigin()); |  544   texture_rect.Offset(-tex_origin.OffsetFromOrigin()); | 
|  539  |  545  | 
|  540   return texture_rect; |  546   return texture_rect; | 
|  541 } |  547 } | 
|  542  |  548  | 
|  543 std::unique_ptr<Tile> PictureLayerTiling::TakeTileAt(int i, int j) { |  549 std::unique_ptr<Tile> PictureLayerTiling::TakeTileAt(int i, int j) { | 
|  544   TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |  550   TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 
|  545   if (found == tiles_.end()) |  551   if (found == tiles_.end()) | 
|  546     return nullptr; |  552     return nullptr; | 
|  547   std::unique_ptr<Tile> result = std::move(found->second); |  553   std::unique_ptr<Tile> result = std::move(found->second); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  570     const gfx::Rect& eventually_rect_in_layer_space, |  576     const gfx::Rect& eventually_rect_in_layer_space, | 
|  571     float ideal_contents_scale, |  577     float ideal_contents_scale, | 
|  572     const Occlusion& occlusion_in_layer_space) { |  578     const Occlusion& occlusion_in_layer_space) { | 
|  573   // If we have, or had occlusions, mark the tiles as 'not done' to ensure that |  579   // If we have, or had occlusions, mark the tiles as 'not done' to ensure that | 
|  574   // we reiterate the tiles for rasterization. |  580   // we reiterate the tiles for rasterization. | 
|  575   if (occlusion_in_layer_space.HasOcclusion() || |  581   if (occlusion_in_layer_space.HasOcclusion() || | 
|  576       current_occlusion_in_layer_space_.HasOcclusion()) { |  582       current_occlusion_in_layer_space_.HasOcclusion()) { | 
|  577     set_all_tiles_done(false); |  583     set_all_tiles_done(false); | 
|  578   } |  584   } | 
|  579  |  585  | 
|  580   float content_to_screen_scale = ideal_contents_scale / contents_scale_; |  586   const float content_to_screen_scale = | 
 |  587       ideal_contents_scale / raster_transform_.scale(); | 
|  581  |  588  | 
|  582   const gfx::Rect* input_rects[] = { |  589   const gfx::Rect* input_rects[] = { | 
|  583       &visible_rect_in_layer_space, &skewport_in_layer_space, |  590       &visible_rect_in_layer_space, &skewport_in_layer_space, | 
|  584       &soon_border_rect_in_layer_space, &eventually_rect_in_layer_space}; |  591       &soon_border_rect_in_layer_space, &eventually_rect_in_layer_space}; | 
|  585   gfx::Rect output_rects[4]; |  592   gfx::Rect output_rects[4]; | 
|  586   for (size_t i = 0; i < arraysize(input_rects); ++i) { |  593   for (size_t i = 0; i < arraysize(input_rects); ++i) | 
|  587     output_rects[i] = gfx::ToEnclosingRect( |  594     output_rects[i] = EnclosingContentsRectFromLayerRect(*input_rects[i]); | 
|  588         gfx::ScaleRect(gfx::RectF(*input_rects[i]), contents_scale_)); |  | 
|  589   } |  | 
|  590   // Make sure the eventually rect is aligned to tile bounds. |  595   // Make sure the eventually rect is aligned to tile bounds. | 
|  591   output_rects[3] = |  596   output_rects[3] = | 
|  592       tiling_data_.ExpandRectIgnoringBordersToTileBounds(output_rects[3]); |  597       tiling_data_.ExpandRectIgnoringBordersToTileBounds(output_rects[3]); | 
|  593  |  598  | 
|  594   SetTilePriorityRects(content_to_screen_scale, output_rects[0], |  599   SetTilePriorityRects(content_to_screen_scale, output_rects[0], | 
|  595                        output_rects[1], output_rects[2], output_rects[3], |  600                        output_rects[1], output_rects[2], output_rects[3], | 
|  596                        occlusion_in_layer_space); |  601                        occlusion_in_layer_space); | 
|  597   SetLiveTilesRect(output_rects[3]); |  602   SetLiveTilesRect(output_rects[3]); | 
|  598 } |  603 } | 
|  599  |  604  | 
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  724     return false; |  729     return false; | 
|  725   gfx::Rect tile_bounds = |  730   gfx::Rect tile_bounds = | 
|  726       tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index()); |  731       tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index()); | 
|  727   gfx::Rect tile_query_rect = |  732   gfx::Rect tile_query_rect = | 
|  728       gfx::IntersectRects(tile_bounds, current_visible_rect_); |  733       gfx::IntersectRects(tile_bounds, current_visible_rect_); | 
|  729   // Explicitly check if the tile is outside the viewport. If so, we need to |  734   // Explicitly check if the tile is outside the viewport. If so, we need to | 
|  730   // return false, since occlusion for this tile is unknown. |  735   // return false, since occlusion for this tile is unknown. | 
|  731   if (tile_query_rect.IsEmpty()) |  736   if (tile_query_rect.IsEmpty()) | 
|  732     return false; |  737     return false; | 
|  733  |  738  | 
|  734   if (contents_scale_ != 1.f) { |  739   tile_query_rect = EnclosingLayerRectFromContentsRect(tile_query_rect); | 
|  735     tile_query_rect = |  | 
|  736         gfx::ScaleToEnclosingRect(tile_query_rect, 1.f / contents_scale_); |  | 
|  737   } |  | 
|  738   return current_occlusion_in_layer_space_.IsOccluded(tile_query_rect); |  740   return current_occlusion_in_layer_space_.IsOccluded(tile_query_rect); | 
|  739 } |  741 } | 
|  740  |  742  | 
|  741 bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const { |  743 bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const { | 
|  742   if (tree_ == PENDING_TREE) { |  744   if (tree_ == PENDING_TREE) { | 
|  743     if (!can_require_tiles_for_activation_) |  745     if (!can_require_tiles_for_activation_) | 
|  744       return false; |  746       return false; | 
|  745  |  747  | 
|  746     if (resolution_ != HIGH_RESOLUTION) |  748     if (resolution_ != HIGH_RESOLUTION) | 
|  747       return false; |  749       return false; | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  818 void PictureLayerTiling::UpdateRequiredStatesOnTile(Tile* tile) const { |  820 void PictureLayerTiling::UpdateRequiredStatesOnTile(Tile* tile) const { | 
|  819   tile->set_required_for_activation(IsTileRequiredForActivation(tile)); |  821   tile->set_required_for_activation(IsTileRequiredForActivation(tile)); | 
|  820   tile->set_required_for_draw(IsTileRequiredForDraw(tile)); |  822   tile->set_required_for_draw(IsTileRequiredForDraw(tile)); | 
|  821 } |  823 } | 
|  822  |  824  | 
|  823 PrioritizedTile PictureLayerTiling::MakePrioritizedTile( |  825 PrioritizedTile PictureLayerTiling::MakePrioritizedTile( | 
|  824     Tile* tile, |  826     Tile* tile, | 
|  825     PriorityRectType priority_rect_type) const { |  827     PriorityRectType priority_rect_type) const { | 
|  826   DCHECK(tile); |  828   DCHECK(tile); | 
|  827   DCHECK(raster_source()->CoversRect(tile->enclosing_layer_rect())) |  829   DCHECK(raster_source()->CoversRect(tile->enclosing_layer_rect())) | 
|  828       << "Tile layer rect: " << tile->enclosing_layer_rect().ToString(); |  830       << "Recording rect: " | 
 |  831       << EnclosingLayerRectFromContentsRect(tile->content_rect()).ToString(); | 
|  829  |  832  | 
|  830   UpdateRequiredStatesOnTile(tile); |  833   UpdateRequiredStatesOnTile(tile); | 
|  831   const auto& tile_priority = ComputePriorityForTile(tile, priority_rect_type); |  834   const auto& tile_priority = ComputePriorityForTile(tile, priority_rect_type); | 
|  832   DCHECK((!tile->required_for_activation() && !tile->required_for_draw()) || |  835   DCHECK((!tile->required_for_activation() && !tile->required_for_draw()) || | 
|  833          tile_priority.priority_bin == TilePriority::NOW || |  836          tile_priority.priority_bin == TilePriority::NOW || | 
|  834          !client_->HasValidTilePriorities()); |  837          !client_->HasValidTilePriorities()); | 
|  835  |  838  | 
|  836   // Note that TileManager will consider this flag but may rasterize the tile |  839   // Note that TileManager will consider this flag but may rasterize the tile | 
|  837   // anyway (if tile is required for activation for example). We should process |  840   // anyway (if tile is required for activation for example). We should process | 
|  838   // the tile for images only if it's further than half of the skewport extent. |  841   // the tile for images only if it's further than half of the skewport extent. | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  918   for (const auto& tile_pair : tiles_) { |  921   for (const auto& tile_pair : tiles_) { | 
|  919     Tile* tile = tile_pair.second.get(); |  922     Tile* tile = tile_pair.second.get(); | 
|  920     prioritized_tiles->push_back( |  923     prioritized_tiles->push_back( | 
|  921         MakePrioritizedTile(tile, ComputePriorityRectTypeForTile(tile))); |  924         MakePrioritizedTile(tile, ComputePriorityRectTypeForTile(tile))); | 
|  922   } |  925   } | 
|  923 } |  926 } | 
|  924  |  927  | 
|  925 void PictureLayerTiling::AsValueInto( |  928 void PictureLayerTiling::AsValueInto( | 
|  926     base::trace_event::TracedValue* state) const { |  929     base::trace_event::TracedValue* state) const { | 
|  927   state->SetInteger("num_tiles", base::saturated_cast<int>(tiles_.size())); |  930   state->SetInteger("num_tiles", base::saturated_cast<int>(tiles_.size())); | 
|  928   state->SetDouble("content_scale", contents_scale()); |  931   state->SetDouble("content_scale", contents_scale_key()); | 
 |  932  | 
 |  933   state->BeginArray("raster_transform"); | 
 |  934   state->AppendDouble(raster_transform_.scale()); | 
 |  935   state->AppendDouble(raster_transform_.translation().x()); | 
 |  936   state->AppendDouble(raster_transform_.translation().y()); | 
 |  937   state->EndArray(); | 
|  929  |  938  | 
|  930   MathUtil::AddToTracedValue("visible_rect", current_visible_rect_, state); |  939   MathUtil::AddToTracedValue("visible_rect", current_visible_rect_, state); | 
|  931   MathUtil::AddToTracedValue("skewport_rect", current_skewport_rect_, state); |  940   MathUtil::AddToTracedValue("skewport_rect", current_skewport_rect_, state); | 
|  932   MathUtil::AddToTracedValue("soon_rect", current_soon_border_rect_, state); |  941   MathUtil::AddToTracedValue("soon_rect", current_soon_border_rect_, state); | 
|  933   MathUtil::AddToTracedValue("eventually_rect", current_eventually_rect_, |  942   MathUtil::AddToTracedValue("eventually_rect", current_eventually_rect_, | 
|  934                              state); |  943                              state); | 
|  935   MathUtil::AddToTracedValue("tiling_size", tiling_size(), state); |  944   MathUtil::AddToTracedValue("tiling_size", tiling_size(), state); | 
|  936 } |  945 } | 
|  937  |  946  | 
|  938 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { |  947 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { | 
|  939   size_t amount = 0; |  948   size_t amount = 0; | 
|  940   for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |  949   for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 
|  941     const Tile* tile = it->second.get(); |  950     const Tile* tile = it->second.get(); | 
|  942     amount += tile->GPUMemoryUsageInBytes(); |  951     amount += tile->GPUMemoryUsageInBytes(); | 
|  943   } |  952   } | 
|  944   return amount; |  953   return amount; | 
|  945 } |  954 } | 
|  946  |  955  | 
 |  956 gfx::Rect PictureLayerTiling::EnclosingContentsRectFromLayerRect( | 
 |  957     const gfx::Rect& layer_rect) const { | 
 |  958   return ToEnclosingRect( | 
 |  959       raster_transform_.TransformRect(gfx::RectF(layer_rect))); | 
 |  960 } | 
 |  961  | 
 |  962 gfx::Rect PictureLayerTiling::EnclosingLayerRectFromContentsRect( | 
 |  963     const gfx::Rect& contents_rect) const { | 
 |  964   return ToEnclosingRect( | 
 |  965       raster_transform_.TransformRectReverse(gfx::RectF(contents_rect))); | 
 |  966 } | 
 |  967  | 
|  947 }  // namespace cc |  968 }  // namespace cc | 
| OLD | NEW |