| Index: cc/layers/picture_layer_impl.cc
|
| diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
|
| index 44b594f8a42db1ed7b372dd88d7454cc65eaecad..5cd14b3f6532ac463414485372914ed03ab4bfb2 100644
|
| --- a/cc/layers/picture_layer_impl.cc
|
| +++ b/cc/layers/picture_layer_impl.cc
|
| @@ -109,6 +109,7 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl,
|
| only_used_low_res_last_append_quads_(false),
|
| mask_type_(mask_type),
|
| nearest_neighbor_(false),
|
| + use_transformed_rasterization_(false),
|
| is_directly_composited_image_(false) {
|
| layer_tree_impl()->RegisterPictureLayerImpl(this);
|
| }
|
| @@ -145,6 +146,7 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
|
| layer_impl->twin_layer_ = this;
|
|
|
| layer_impl->SetNearestNeighbor(nearest_neighbor_);
|
| + layer_impl->SetUseTransformedRasterization(use_transformed_rasterization_);
|
|
|
| // Solid color layers have no tilings.
|
| DCHECK(!raster_source_->IsSolidColor() || tilings_->num_tilings() == 0);
|
| @@ -275,7 +277,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
|
| } else if (iter.resolution() == LOW_RESOLUTION) {
|
| color = DebugColors::LowResTileBorderColor();
|
| width = DebugColors::LowResTileBorderWidth(device_scale_factor);
|
| - } else if (iter->contents_scale() > max_contents_scale) {
|
| + } else if (iter->contents_scale_key() > max_contents_scale) {
|
| color = DebugColors::ExtraHighResTileBorderColor();
|
| width = DebugColors::ExtraHighResTileBorderWidth(device_scale_factor);
|
| } else {
|
| @@ -343,8 +345,8 @@ 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_scale_key() != raster_contents_scale_ &&
|
| + iter->contents_scale_key() != ideal_contents_scale_ &&
|
| geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
|
| append_quads_data->num_incomplete_tiles++;
|
| }
|
| @@ -644,19 +646,22 @@ 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_->FindTilingWithScaleKey(tile->contents_scale());
|
| + tilings_->FindTilingWithScaleKey(tile->contents_scale_key());
|
| if (tiling)
|
| tiling->set_all_tiles_done(false);
|
| }
|
| }
|
|
|
| +SimpleEnclosedRegion PictureLayerImpl::VisibleOpaqueRegion() const {
|
| + if (use_transformed_rasterization_)
|
| + return SimpleEnclosedRegion();
|
| + return LayerImpl::VisibleOpaqueRegion();
|
| +}
|
| +
|
| void PictureLayerImpl::DidBeginTracing() {
|
| raster_source_->DidBeginTracing();
|
| }
|
| @@ -724,7 +729,13 @@ const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling(
|
| PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer();
|
| if (!twin_layer)
|
| return nullptr;
|
| - return twin_layer->tilings_->FindTilingWithScaleKey(tiling->contents_scale());
|
| + const PictureLayerTiling* twin_tiling =
|
| + twin_layer->tilings_->FindTilingWithScaleKey(
|
| + tiling->contents_scale_key());
|
| + if (twin_tiling &&
|
| + twin_tiling->raster_transform() == tiling->raster_transform())
|
| + return twin_tiling;
|
| + return nullptr;
|
| }
|
|
|
| bool PictureLayerImpl::RequiresHighResToDraw() const {
|
| @@ -872,12 +883,21 @@ void PictureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) {
|
| NoteLayerPropertyChanged();
|
| }
|
|
|
| -PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
|
| +void PictureLayerImpl::SetUseTransformedRasterization(bool use) {
|
| + if (use_transformed_rasterization_ == use)
|
| + return;
|
| +
|
| + use_transformed_rasterization_ = use;
|
| + NoteLayerPropertyChanged();
|
| +}
|
| +
|
| +PictureLayerTiling* PictureLayerImpl::AddTiling(
|
| + const ScaleTranslate2d& contents_transform) {
|
| DCHECK(CanHaveTilings());
|
| - DCHECK_GE(contents_scale, MinimumContentsScale());
|
| - DCHECK_LE(contents_scale, MaximumContentsScale());
|
| + DCHECK_GE(contents_transform.scale(), MinimumContentsScale());
|
| + DCHECK_LE(contents_transform.scale(), MaximumContentsScale());
|
| DCHECK(raster_source_->HasRecordings());
|
| - return tilings_->AddTiling(contents_scale, raster_source_);
|
| + return tilings_->AddTiling(contents_transform, raster_source_);
|
| }
|
|
|
| void PictureLayerImpl::RemoveAllTilings() {
|
| @@ -893,9 +913,17 @@ void PictureLayerImpl::AddTilingsForRasterScale() {
|
|
|
| PictureLayerTiling* high_res =
|
| tilings_->FindTilingWithScaleKey(raster_contents_scale_);
|
| + gfx::Vector2dF raster_translation =
|
| + CalculateRasterTranslation(raster_contents_scale_);
|
| + if (high_res &&
|
| + high_res->raster_transform().translation() != raster_translation) {
|
| + tilings_->Remove(high_res);
|
| + high_res = nullptr;
|
| + }
|
| if (!high_res) {
|
| // 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.
|
| @@ -992,7 +1020,8 @@ 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);
|
| }
|
| }
|
| @@ -1158,6 +1187,34 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
|
| SanityCheckTilingState();
|
| }
|
|
|
| +gfx::Vector2dF PictureLayerImpl::CalculateRasterTranslation(
|
| + float raster_scale) {
|
| + if (!use_transformed_rasterization_)
|
| + return gfx::Vector2dF();
|
| +
|
| + DCHECK(!draw_properties().screen_space_transform_is_animating);
|
| + gfx::Transform draw_transform = DrawTransform();
|
| + DCHECK(draw_transform.IsScaleOrTranslation());
|
| +
|
| + // 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));
|
| +}
|
| +
|
| float PictureLayerImpl::MinimumContentsScale() const {
|
| float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
|
|
|
|
|