Chromium Code Reviews| Index: cc/tiles/picture_layer_tiling.cc | 
| diff --git a/cc/tiles/picture_layer_tiling.cc b/cc/tiles/picture_layer_tiling.cc | 
| index 74804dc511230809aba92b35d6b88ac201a98673..c71ba04053b26f890f81574c3b79aed9589acb85 100644 | 
| --- a/cc/tiles/picture_layer_tiling.cc | 
| +++ b/cc/tiles/picture_layer_tiling.cc | 
| @@ -29,51 +29,39 @@ | 
| #include "ui/gfx/geometry/size_conversions.h" | 
| namespace cc { | 
| -namespace { | 
| -// The math is similar to gfx::Rect::ManhattanInternalDistance except that each | 
| -// component is scaled by the specified |scale|. | 
| -float ComputeScaledManhattalInternalDistance(const gfx::Rect& a, | 
| - const gfx::Rect& b, | 
| - const gfx::SizeF& scale) { | 
| - gfx::Rect combined(a); | 
| - combined.Union(b); | 
| - | 
| - float x = | 
| - scale.width() * std::max(0, combined.width() - a.width() - b.width() + 1); | 
| - float y = scale.height() * | 
| - std::max(0, combined.height() - a.height() - b.height() + 1); | 
| - return x + y; | 
| -} | 
| -} // namespace | 
| PictureLayerTiling::PictureLayerTiling( | 
| WhichTree tree, | 
| - const gfx::SizeF& raster_scales, | 
| + const ScaleTranslate2d& raster_transform, | 
| scoped_refptr<RasterSource> raster_source, | 
| PictureLayerTilingClient* client, | 
| float min_preraster_distance, | 
| float max_preraster_distance) | 
| - : raster_scales_(raster_scales), | 
| + : raster_transform_(raster_transform), | 
| client_(client), | 
| tree_(tree), | 
| raster_source_(raster_source), | 
| min_preraster_distance_(min_preraster_distance), | 
| max_preraster_distance_(max_preraster_distance) { | 
| DCHECK(!raster_source->IsSolidColor()); | 
| - gfx::Size content_bounds = | 
| - gfx::ScaleToCeiledSize(raster_source_->GetSize(), raster_scales_.width(), | 
| - raster_scales_.height()); | 
| - gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 
| + DCHECK_GE(raster_transform.translation().x(), 0.f); | 
| + DCHECK_LT(raster_transform.translation().x(), 1.f); | 
| + DCHECK_GE(raster_transform.translation().y(), 0.f); | 
| + DCHECK_LT(raster_transform.translation().y(), 1.f); | 
| DCHECK(!gfx::ScaleToFlooredSize(raster_source_->GetSize(), | 
| - raster_scales_.width(), | 
| - raster_scales_.height()) | 
| + raster_transform.scale()) | 
| .IsEmpty()) | 
| << "Tiling created with scale too small as contents become empty." | 
| << " Layer bounds: " << raster_source_->GetSize().ToString() | 
| - << " Raster scales: " << raster_scales_.ToString(); | 
| - | 
| - tiling_data_.SetTilingSize(content_bounds); | 
| + << " Raster transform: " << raster_transform_.ToString(); | 
| + | 
| + gfx::Rect content_bounds_rect = | 
| + EnclosingContentsRectFromLayerRect(gfx::Rect(raster_source_->GetSize())); | 
| + gfx::Size tiling_size = gfx::Size(content_bounds_rect.bottom_right().x(), | 
| + content_bounds_rect.bottom_right().y()); | 
| + tiling_data_.SetTilingSize(tiling_size); | 
| + gfx::Size tile_size = client_->CalculateTileSize(tiling_size); | 
| tiling_data_.SetMaxTextureSize(tile_size); | 
| } | 
| @@ -126,8 +114,8 @@ void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 
| gfx::Rect invalidated; | 
| for (Region::Iterator iter(*invalidation); iter.has_rect(); | 
| iter.next()) { | 
| - gfx::Rect invalid_content_rect = gfx::ScaleToEnclosingRect( | 
| - iter.rect(), raster_scales_.width(), raster_scales_.height()); | 
| + gfx::Rect invalid_content_rect = | 
| + EnclosingContentsRectFromLayerRect(iter.rect()); | 
| invalid_content_rect.Intersect(tile_rect); | 
| invalidated.Union(invalid_content_rect); | 
| } | 
| @@ -189,12 +177,13 @@ void PictureLayerTiling::SetRasterSourceAndResize( | 
| gfx::Size old_layer_bounds = raster_source_->GetSize(); | 
| raster_source_ = std::move(raster_source); | 
| gfx::Size new_layer_bounds = raster_source_->GetSize(); | 
| - gfx::Size content_bounds = gfx::ScaleToCeiledSize( | 
| - new_layer_bounds, raster_scales_.width(), raster_scales_.height()); | 
| - gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 
| + gfx::Rect content_rect = | 
| + EnclosingContentsRectFromLayerRect(gfx::Rect(new_layer_bounds)); | 
| + DCHECK(content_rect.origin() == gfx::Point()); | 
| + gfx::Size tile_size = client_->CalculateTileSize(content_rect.size()); | 
| if (tile_size != tiling_data_.max_texture_size()) { | 
| - tiling_data_.SetTilingSize(content_bounds); | 
| + tiling_data_.SetTilingSize(content_rect.size()); | 
| tiling_data_.SetMaxTextureSize(tile_size); | 
| // When the tile size changes, the TilingData positions no longer work | 
| // as valid keys to the TileMap, so just drop all tiles and clear the live | 
| @@ -209,7 +198,6 @@ void PictureLayerTiling::SetRasterSourceAndResize( | 
| // The SetLiveTilesRect() method would drop tiles outside the new bounds, | 
| // but may do so incorrectly if resizing the tiling causes the number of | 
| // tiles in the tiling_data_ to change. | 
| - gfx::Rect content_rect(content_bounds); | 
| int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x()); | 
| int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y()); | 
| int before_right = | 
| @@ -220,7 +208,7 @@ void PictureLayerTiling::SetRasterSourceAndResize( | 
| // The live_tiles_rect_ is clamped to stay within the tiling size as we | 
| // change it. | 
| live_tiles_rect_.Intersect(content_rect); | 
| - tiling_data_.SetTilingSize(content_bounds); | 
| + tiling_data_.SetTilingSize(content_rect.size()); | 
| int after_right = -1; | 
| int after_bottom = -1; | 
| @@ -284,8 +272,8 @@ void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, | 
| iter.next()) { | 
| gfx::Rect layer_rect = iter.rect(); | 
| // The pixels which are invalid in content space. | 
| - gfx::Rect invalid_content_rect = gfx::ScaleToEnclosingRect( | 
| - layer_rect, raster_scales_.width(), raster_scales_.height()); | 
| + gfx::Rect invalid_content_rect = | 
| + EnclosingContentsRectFromLayerRect(layer_rect); | 
| gfx::Rect coverage_content_rect = invalid_content_rect; | 
| // Avoid needless work by not bothering to invalidate where there aren't | 
| // tiles. | 
| @@ -321,10 +309,10 @@ void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, | 
| Tile::CreateInfo PictureLayerTiling::CreateInfoForTile(int i, int j) const { | 
| gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); | 
| tile_rect.set_size(tiling_data_.max_texture_size()); | 
| - gfx::Rect enclosing_layer_rect = gfx::ScaleToEnclosingRect( | 
| - tile_rect, 1.f / raster_scales_.width(), 1.f / raster_scales_.height()); | 
| + gfx::Rect enclosing_layer_rect = | 
| + EnclosingLayerRectFromContentsRect(tile_rect); | 
| return Tile::CreateInfo(i, j, enclosing_layer_rect, tile_rect, | 
| - raster_scales_); | 
| + raster_transform_); | 
| } | 
| bool PictureLayerTiling::ShouldCreateTileAt( | 
| @@ -363,8 +351,8 @@ bool PictureLayerTiling::ShouldCreateTileAt( | 
| // on the active tree and avoid floating point inconsistencies. | 
| for (Region::Iterator iter(*layer_invalidation); iter.has_rect(); | 
| iter.next()) { | 
| - gfx::Rect invalid_content_rect = gfx::ScaleToEnclosingRect( | 
| - iter.rect(), raster_scales_.width(), raster_scales_.height()); | 
| + gfx::Rect invalid_content_rect = | 
| + EnclosingContentsRectFromLayerRect(iter.rect()); | 
| if (invalid_content_rect.Intersects(info.content_rect)) | 
| return true; | 
| } | 
| @@ -393,13 +381,14 @@ PictureLayerTiling::CoverageIterator::CoverageIterator( | 
| const PictureLayerTiling* tiling, | 
| float coverage_scale, | 
| const gfx::Rect& coverage_rect) | 
| - : tiling_(tiling), coverage_rect_(coverage_rect) { | 
| + : tiling_(tiling) | 
| + , coverage_rect_(coverage_rect) | 
| + , coverage_to_content_(ScaleTranslate2d::PreScale(tiling->raster_transform(), 1.f / coverage_scale)) { | 
| DCHECK(tiling_); | 
| // In order to avoid artifacts in geometry_rect scaling and clamping to ints, | 
| // the |coverage_scale| should always be at least as big as the tiling's | 
| // raster scales. | 
| - DCHECK_GE(coverage_scale, tiling_->raster_scales_.width()); | 
| - DCHECK_GE(coverage_scale, tiling_->raster_scales_.height()); | 
| + DCHECK_GE(coverage_scale, tiling_->raster_transform_.scale()); | 
| // Clamp |coverage_rect| to the bounds of this tiling's raster source. | 
| coverage_rect_max_bounds_ = | 
| @@ -408,10 +397,6 @@ PictureLayerTiling::CoverageIterator::CoverageIterator( | 
| if (coverage_rect_.IsEmpty()) | 
| return; | 
| - coverage_to_content_scale_ = | 
| - gfx::SizeF(tiling_->raster_scales_.width() / coverage_scale, | 
| - tiling_->raster_scales_.height() / coverage_scale); | 
| - | 
| // Find the indices of the texel samples that enclose the rect we want to | 
| // cover. | 
| // Because we don't know the target transform at this point, we have to be | 
| @@ -419,8 +404,8 @@ PictureLayerTiling::CoverageIterator::CoverageIterator( | 
| // snapped to a pixel sample) inside of the content rect may be sampled. | 
| // This code maps the boundary points into contents space, then find out the | 
| // enclosing texture samples. For example, assume we have: | 
| - // dest_scale : content_scale = 1.23 : 1 | 
| - // dest_rect = (l:123, t:234, r:345, b:456) | 
| + // coverage_scale : content_scale = 1.23 : 1 | 
| + // coverage_rect = (l:123, t:234, r:345, b:456) | 
| // Then it follows that: | 
| // content_rect = (l:100.00, t:190.24, r:280.49, b:370.73) | 
| // Without MSAA, the sample point of a texel is at the center of that texel, | 
| @@ -428,9 +413,7 @@ PictureLayerTiling::CoverageIterator::CoverageIterator( | 
| // wanted_texels(sample coordinates) = (l:99.5, t:189.5, r:280.5, b:371.5) | 
| // Or in integer index: | 
| // wanted_texels(integer index) = (l:99, t:189, r:280, b:371) | 
| - gfx::RectF content_rect = gfx::ScaleRect(gfx::RectF(coverage_rect_), | 
| - coverage_to_content_scale_.width(), | 
| - coverage_to_content_scale_.height()); | 
| + gfx::RectF content_rect = coverage_to_content_.TransformRect(gfx::RectF(coverage_rect_)); | 
| 
 
enne (OOO)
2017/01/03 22:53:53
Iterator changes definitely need unit tests.
 
trchen
2017/03/28 21:44:01
Done.
 
 | 
| content_rect.Offset(-0.5f, -0.5f); | 
| gfx::Rect wanted_texels = gfx::ToEnclosingRect(content_rect); | 
| @@ -492,8 +475,7 @@ PictureLayerTiling::CoverageIterator::operator++() { | 
| // Convert texel_extent to coverage scale, which is what we have to report | 
| // geometry_rect in. | 
| current_geometry_rect_ = gfx::ToEnclosedRect( | 
| - gfx::ScaleRect(texel_extent, 1.f / coverage_to_content_scale_.width(), | 
| - 1.f / coverage_to_content_scale_.height())); | 
| + coverage_to_content_.TransformRectReverse(texel_extent)); | 
| { | 
| // Adjust external edges to cover the whole layer in dest space. | 
| // | 
| @@ -556,10 +538,9 @@ gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const { | 
| auto tex_origin = gfx::PointF( | 
| tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin()); | 
| - // Convert from dest space => content space => texture space. | 
| + // Convert from coverage space => content space => texture space. | 
| gfx::RectF texture_rect(current_geometry_rect_); | 
| - texture_rect.Scale(coverage_to_content_scale_.width(), | 
| - coverage_to_content_scale_.height()); | 
| + texture_rect = coverage_to_content_.TransformRect(texture_rect); | 
| texture_rect.Intersect(gfx::RectF(gfx::SizeF(tiling_->tiling_size()))); | 
| if (texture_rect.IsEmpty()) | 
| return texture_rect; | 
| @@ -605,19 +586,15 @@ void PictureLayerTiling::ComputeTilePriorityRects( | 
| set_all_tiles_done(false); | 
| } | 
| - gfx::SizeF content_to_screen_scale( | 
| - ideal_contents_scale / raster_scales_.width(), | 
| - ideal_contents_scale / raster_scales_.height()); | 
| + const float content_to_screen_scale = | 
| + ideal_contents_scale / raster_transform_.scale(); | 
| const gfx::Rect* input_rects[] = { | 
| &visible_rect_in_layer_space, &skewport_in_layer_space, | 
| &soon_border_rect_in_layer_space, &eventually_rect_in_layer_space}; | 
| gfx::Rect output_rects[4]; | 
| - for (size_t i = 0; i < arraysize(input_rects); ++i) { | 
| - output_rects[i] = gfx::ToEnclosingRect( | 
| - gfx::ScaleRect(gfx::RectF(*input_rects[i]), raster_scales_.width(), | 
| - raster_scales_.height())); | 
| - } | 
| + for (size_t i = 0; i < arraysize(input_rects); ++i) | 
| + output_rects[i] = EnclosingContentsRectFromLayerRect(*input_rects[i]); | 
| // Make sure the eventually rect is aligned to tile bounds. | 
| output_rects[3] = | 
| tiling_data_.ExpandRectIgnoringBordersToTileBounds(output_rects[3]); | 
| @@ -629,7 +606,7 @@ void PictureLayerTiling::ComputeTilePriorityRects( | 
| } | 
| void PictureLayerTiling::SetTilePriorityRects( | 
| - const gfx::SizeF& content_to_screen_scale, | 
| + float content_to_screen_scale, | 
| const gfx::Rect& visible_rect_in_content_space, | 
| const gfx::Rect& skewport, | 
| const gfx::Rect& soon_border_rect, | 
| @@ -652,15 +629,14 @@ void PictureLayerTiling::SetTilePriorityRects( | 
| // Note that we use the largest skewport extent from the viewport as the | 
| // "skewport extent". Also note that this math can't produce negative numbers, | 
| // since skewport.Contains(visible_rect) is always true. | 
| - max_skewport_extent_in_screen_space_ = std::max( | 
| - current_content_to_screen_scale_.width() * | 
| - std::max( | 
| - current_visible_rect_.x() - current_skewport_rect_.x(), | 
| - current_skewport_rect_.right() - current_visible_rect_.right()), | 
| - current_content_to_screen_scale_.height() * | 
| - std::max(current_visible_rect_.y() - current_skewport_rect_.y(), | 
| - current_skewport_rect_.bottom() - | 
| - current_visible_rect_.bottom())); | 
| + max_skewport_extent_in_screen_space_ = | 
| + current_content_to_screen_scale_ * | 
| + std::max(std::max(current_visible_rect_.x() - current_skewport_rect_.x(), | 
| + current_skewport_rect_.right() - | 
| + current_visible_rect_.right()), | 
| + std::max(current_visible_rect_.y() - current_skewport_rect_.y(), | 
| + current_skewport_rect_.bottom() - | 
| + current_visible_rect_.bottom())); | 
| } | 
| void PictureLayerTiling::SetLiveTilesRect( | 
| @@ -761,11 +737,7 @@ bool PictureLayerTiling::IsTileOccludedOnCurrentTree(const Tile* tile) const { | 
| if (tile_query_rect.IsEmpty()) | 
| return false; | 
| - if (raster_scales_ != gfx::SizeF(1.f, 1.f)) { | 
| - tile_query_rect = | 
| - gfx::ScaleToEnclosingRect(tile_query_rect, 1.f / raster_scales_.width(), | 
| - 1.f / raster_scales_.height()); | 
| - } | 
| + tile_query_rect = EnclosingLayerRectFromContentsRect(tile_query_rect); | 
| return current_occlusion_in_layer_space_.IsOccluded(tile_query_rect); | 
| } | 
| @@ -847,10 +819,7 @@ PrioritizedTile PictureLayerTiling::MakePrioritizedTile( | 
| DCHECK(tile); | 
| DCHECK(raster_source()->CoversRect(tile->enclosing_layer_rect())) | 
| << "Recording rect: " | 
| - << gfx::ScaleToEnclosingRect(tile->content_rect(), | 
| - 1.f / tile->raster_scales().width(), | 
| - 1.f / tile->raster_scales().height()) | 
| - .ToString(); | 
| + << EnclosingLayerRectFromContentsRect(tile->content_rect()).ToString(); | 
| const auto& tile_priority = ComputePriorityForTile(tile, priority_rect_type); | 
| // Note that TileManager will consider this flag but may rasterize the tile | 
| @@ -904,10 +873,10 @@ TilePriority PictureLayerTiling::ComputePriorityForTile( | 
| gfx::Rect tile_bounds = | 
| tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index()); | 
| - DCHECK_GT(current_content_to_screen_scale_.width(), 0.f); | 
| - DCHECK_GT(current_content_to_screen_scale_.height(), 0.f); | 
| - float distance_to_visible = ComputeScaledManhattalInternalDistance( | 
| - current_visible_rect_, tile_bounds, current_content_to_screen_scale_); | 
| + DCHECK_GT(current_content_to_screen_scale_, 0.f); | 
| + float distance_to_visible = | 
| + current_visible_rect_.ManhattanInternalDistance(tile_bounds) * | 
| + current_content_to_screen_scale_; | 
| return TilePriority(resolution_, priority_bin, distance_to_visible); | 
| } | 
| @@ -949,9 +918,10 @@ void PictureLayerTiling::AsValueInto( | 
| // TODO(vmpstr): Change frameviewer to use raster scales. | 
| state->SetDouble("content_scale", contents_scale_key()); | 
| - state->BeginArray("raster_scales"); | 
| - state->AppendDouble(raster_scales_.width()); | 
| - state->AppendDouble(raster_scales_.height()); | 
| + state->BeginArray("raster_transform"); | 
| + state->AppendDouble(raster_transform_.scale()); | 
| + state->AppendDouble(raster_transform_.translation().x()); | 
| + state->AppendDouble(raster_transform_.translation().y()); | 
| state->EndArray(); | 
| MathUtil::AddToTracedValue("visible_rect", current_visible_rect_, state); | 
| @@ -971,4 +941,15 @@ size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { | 
| return amount; | 
| } | 
| +gfx::Rect PictureLayerTiling::EnclosingContentsRectFromLayerRect( | 
| + const gfx::Rect& layer_rect) const { | 
| + return ToEnclosingRect(raster_transform_.TransformRect(gfx::RectF(layer_rect))); | 
| +} | 
| + | 
| +gfx::Rect PictureLayerTiling::EnclosingLayerRectFromContentsRect( | 
| + const gfx::Rect& contents_rect) const { | 
| + return ToEnclosingRect( | 
| + raster_transform_.TransformRectReverse(gfx::RectF(contents_rect))); | 
| +} | 
| + | 
| } // namespace cc |