Chromium Code Reviews| Index: cc/layers/picture_layer_impl.cc |
| diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc |
| index 776507af0f83478662d77943cc4a4ba3af47e0ce..ebefd106161f0081cc2d8e2b0d52fb14fbd785cb 100644 |
| --- a/cc/layers/picture_layer_impl.cc |
| +++ b/cc/layers/picture_layer_impl.cc |
| @@ -16,6 +16,7 @@ |
| #include "base/time/time.h" |
| #include "base/trace_event/trace_event_argument.h" |
| #include "cc/base/math_util.h" |
| +#include "cc/base/scale_translate2d.h" |
| #include "cc/debug/debug_colors.h" |
| #include "cc/debug/micro_benchmark_impl.h" |
| #include "cc/debug/traced_value.h" |
| @@ -272,7 +273,8 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass, |
| } else if (iter.resolution() == LOW_RESOLUTION) { |
| color = DebugColors::LowResTileBorderColor(); |
| width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); |
| - } else if (iter->contents_scale() > max_contents_scale) { |
| + } else if (iter->contents_transform().pre_scale() > |
| + max_contents_scale) { |
| color = DebugColors::ExtraHighResTileBorderColor(); |
| width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl()); |
| } else { |
| @@ -340,8 +342,9 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass, |
| // complete. But if a tile is ideal scale, we don't want to consider |
| // it incomplete and trying to replace it with a tile at a worse |
| // scale. |
| - if (iter->contents_scale() != raster_contents_scale_ && |
| - iter->contents_scale() != ideal_contents_scale_ && |
| + if (iter->contents_transform().pre_scale() != |
| + raster_contents_scale_ && |
| + iter->contents_transform().pre_scale() != ideal_contents_scale_ && |
| geometry_rect.Intersects(scaled_viewport_for_tile_priority)) { |
| append_quads_data->num_incomplete_tiles++; |
| } |
| @@ -646,16 +649,16 @@ bool PictureLayerImpl::RasterSourceUsesLCDText() const { |
| } |
| void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) { |
| - if (layer_tree_impl()->IsActiveTree()) { |
| - gfx::Rect layer_damage_rect = gfx::ScaleToEnclosingRect( |
| - tile->content_rect(), 1.f / tile->contents_scale()); |
| - AddDamageRect(layer_damage_rect); |
| - } |
| + if (layer_tree_impl()->IsActiveTree()) |
| + AddDamageRect(tile->enclosing_layer_rect()); |
| if (tile->draw_info().NeedsRaster()) { |
| PictureLayerTiling* tiling = |
| - tilings_->FindTilingWithScale(tile->contents_scale()); |
| - if (tiling) |
| + tilings_->FindTilingWithScale(tile->contents_transform().pre_scale()); |
|
enne (OOO)
2016/08/29 20:21:19
This is also wrong and needs to take into account
|
| + if (tiling) { |
| + DCHECK_EQ(tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()), |
| + tile); |
| tiling->set_all_tiles_done(false); |
| + } |
| } |
| } |
| @@ -723,7 +726,14 @@ const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling( |
| PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer(); |
| if (!twin_layer) |
| return nullptr; |
| - return twin_layer->tilings_->FindTilingWithScale(tiling->contents_scale()); |
| + const PictureLayerTiling* twin_tiling = |
| + twin_layer->tilings_->FindTilingWithScale( |
|
enne (OOO)
2016/08/29 20:21:19
I think this you need to be more explicit here in
|
| + tiling->contents_transform().pre_scale()); |
| + return twin_tiling && |
| + twin_tiling->contents_transform() == |
| + tiling->contents_transform() |
| + ? twin_tiling |
| + : nullptr; |
| } |
| bool PictureLayerImpl::RequiresHighResToDraw() const { |
| @@ -869,12 +879,13 @@ void PictureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) { |
| NoteLayerPropertyChanged(); |
| } |
| -PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) { |
| +PictureLayerTiling* PictureLayerImpl::AddTiling( |
| + const ScaleTranslate2d& contents_transform) { |
| DCHECK(CanHaveTilings()); |
| - DCHECK_GE(contents_scale, MinimumContentsScale()); |
| - DCHECK_LE(contents_scale, MaximumContentsScale()); |
| + DCHECK_GE(contents_transform.pre_scale(), MinimumContentsScale()); |
| + DCHECK_LE(contents_transform.pre_scale(), MaximumContentsScale()); |
| DCHECK(raster_source_->HasRecordings()); |
| - return tilings_->AddTiling(contents_scale, raster_source_); |
| + return tilings_->AddTiling(contents_transform, raster_source_); |
| } |
| void PictureLayerImpl::RemoveAllTilings() { |
| @@ -891,8 +902,11 @@ void PictureLayerImpl::AddTilingsForRasterScale() { |
| PictureLayerTiling* high_res = |
| tilings_->FindTilingWithScale(raster_contents_scale_); |
|
enne (OOO)
2016/08/29 20:21:18
Here is another case where I think FindTilingWithS
|
| if (!high_res) { |
| + gfx::Vector2dF raster_translation = |
| + CalculateRasterTranslation(raster_contents_scale_); |
| // We always need a high res tiling, so create one if it doesn't exist. |
| - high_res = AddTiling(raster_contents_scale_); |
| + high_res = |
| + AddTiling(ScaleTranslate2d(raster_contents_scale_, raster_translation)); |
| } else if (high_res->may_contain_low_resolution_tiles()) { |
| // If the tiling we find here was LOW_RESOLUTION previously, it may not be |
| // fully rastered, so destroy the old tiles. |
| @@ -994,11 +1008,45 @@ void PictureLayerImpl::AddLowResolutionTilingIfNeeded() { |
| bool is_animating = draw_properties().screen_space_transform_is_animating; |
| if (!is_pinching && !is_animating) { |
| if (!low_res) |
| - low_res = AddTiling(low_res_raster_contents_scale_); |
| + low_res = AddTiling( |
| + ScaleTranslate2d(low_res_raster_contents_scale_, gfx::Vector2dF())); |
| low_res->set_resolution(LOW_RESOLUTION); |
| } |
| } |
| +gfx::Vector2dF PictureLayerImpl::CalculateRasterTranslation( |
| + float raster_scale) { |
| + // Do not align if the layer is animating, as we don't plan to re-raster |
| + // during animation. Aligning to the first frame will only introduce extra |
| + // aliasing error. |
| + if (draw_properties().screen_space_transform_is_animating) |
| + return gfx::Vector2dF(); |
| + |
| + // Can't align by just translation if the draw transform contains more than |
| + // scale and translation. e.g. rotation, perspective, etc... |
| + gfx::Transform draw_transform = DrawTransform(); |
| + if (!draw_transform.IsScaleOrTranslation()) |
| + return gfx::Vector2dF(); |
| + |
| + // It is only useful to align the content space to the target space if their |
| + // relative pixel ratio is some small rational number. Currently we only |
| + // align if the relative pixel ratio is 1:1. |
| + // Good match if the maximum alignment error on a layer of size 10000px |
| + // does not exceed 0.001px. |
| + static constexpr float kErrorThreshold = 0.0000001f; |
| + if (std::abs(draw_transform.matrix().getFloat(0, 0) - raster_scale) > |
| + kErrorThreshold || |
| + std::abs(draw_transform.matrix().getFloat(1, 1) - raster_scale) > |
| + kErrorThreshold) |
| + return gfx::Vector2dF(); |
| + |
| + // Extract the fractional part of layer origin in the target space. |
| + float origin_x = draw_transform.matrix().getFloat(0, 3); |
| + float origin_y = draw_transform.matrix().getFloat(1, 3); |
| + return gfx::Vector2dF(origin_x - floorf(origin_x), |
| + origin_y - floorf(origin_y)); |
| +} |
| + |
| void PictureLayerImpl::RecalculateRasterScales() { |
| if (is_directly_composited_image_) { |
| if (!raster_source_scale_) |