diff options
author | epenner@chromium.org <epenner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-25 23:35:53 +0000 |
---|---|---|
committer | epenner@chromium.org <epenner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-25 23:35:53 +0000 |
commit | 9318345aa982a45e264ec9682f056323e117e9c0 (patch) | |
tree | f6506c9a0acfbc0c123096820c45a60ceed191ce /cc/layers/picture_layer_impl.cc | |
parent | 007c1194fe848b3483e3acbbed56b986166cf2f1 (diff) | |
download | chromium_src-9318345aa982a45e264ec9682f056323e117e9c0.zip chromium_src-9318345aa982a45e264ec9682f056323e117e9c0.tar.gz chromium_src-9318345aa982a45e264ec9682f056323e117e9c0.tar.bz2 |
Reland: CC: Adjust tiling creation triggers during pinch-zoom.
We used to create tilings only when exceeding a certain scale
difference from the ideal scale. This meant that in the worst
case our only available high-res tiling was 2X the required
resolution.
This patch adjusts the creation of new tilings, to ensure we
always have a tiling option that is less-than-or-equal-to
the current ideal scale.
BUG=307206
Review URL: https://codereview.chromium.org/81453002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@237179 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/layers/picture_layer_impl.cc')
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 81 |
1 files changed, 58 insertions, 23 deletions
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 29f5110..a8fecb9 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -5,6 +5,7 @@ #include "cc/layers/picture_layer_impl.h" #include <algorithm> +#include <limits> #include "base/time/time.h" #include "cc/base/math_util.h" @@ -27,6 +28,10 @@ namespace { const float kMaxScaleRatioDuringPinch = 2.0f; + +// When creating a new tiling during pinch, snap to an existing +// tiling's scale if the desired scale is within this ratio. +const float kSnapToExistingTilingRatio = 0.2f; } namespace cc { @@ -828,13 +833,7 @@ void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen) { if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) return; - raster_page_scale_ = ideal_page_scale_; - raster_device_scale_ = ideal_device_scale_; - raster_source_scale_ = ideal_source_scale_; - - CalculateRasterContentsScale(animating_transform_to_screen, - &raster_contents_scale_, - &low_res_raster_contents_scale_); + RecalculateRasterScales(animating_transform_to_screen); PictureLayerTiling* high_res = NULL; PictureLayerTiling* low_res = NULL; @@ -867,12 +866,15 @@ void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen) { low_res != high_res) low_res = AddTiling(low_res_raster_contents_scale_); - high_res->set_resolution(HIGH_RESOLUTION); + // Set low-res if we have one. if (!low_res) low_res = previous_low_res; if (low_res && low_res != high_res) low_res->set_resolution(LOW_RESOLUTION); + // Make sure we always have one high-res (even if high == low). + high_res->set_resolution(HIGH_RESOLUTION); + SanityCheckTilingState(); } @@ -888,10 +890,12 @@ bool PictureLayerImpl::ShouldAdjustRasterScale( bool is_pinching = layer_tree_impl()->PinchGestureActive(); if (is_pinching && raster_page_scale_) { - // If the page scale diverges too far during pinch, change raster target to - // the current page scale. - float ratio = PositiveRatio(ideal_page_scale_, raster_page_scale_); - if (ratio >= kMaxScaleRatioDuringPinch) + // We change our raster scale when it is: + // - Higher than ideal (need a lower-res tiling available) + // - Too far from ideal (need a higher-res tiling available) + float ratio = ideal_page_scale_ / raster_page_scale_; + if (raster_page_scale_ > ideal_page_scale_ || + ratio > kMaxScaleRatioDuringPinch) return true; } @@ -908,35 +912,66 @@ bool PictureLayerImpl::ShouldAdjustRasterScale( return false; } -void PictureLayerImpl::CalculateRasterContentsScale( - bool animating_transform_to_screen, - float* raster_contents_scale, - float* low_res_raster_contents_scale) const { - *raster_contents_scale = ideal_contents_scale_; +float PictureLayerImpl::SnappedContentsScale(float scale) { + // If a tiling exists within the max snapping ratio, snap to its scale. + float snapped_contents_scale = scale; + float snapped_ratio = kSnapToExistingTilingRatio; + for (size_t i = 0; i < tilings_->num_tilings(); ++i) { + float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale(); + float ratio = PositiveRatio(tiling_contents_scale, scale); + if (ratio < snapped_ratio) { + snapped_contents_scale = tiling_contents_scale; + snapped_ratio = ratio; + } + } + return snapped_contents_scale; +} + +void PictureLayerImpl::RecalculateRasterScales( + bool animating_transform_to_screen) { + raster_device_scale_ = ideal_device_scale_; + raster_source_scale_ = ideal_source_scale_; + + bool is_pinching = layer_tree_impl()->PinchGestureActive(); + if (!is_pinching) { + // When not pinching, we use ideal scale: + raster_page_scale_ = ideal_page_scale_; + raster_contents_scale_ = ideal_contents_scale_; + } else { + // See ShouldAdjustRasterScale: + // - When zooming out, preemptively create new tiling at lower resolution. + // - When zooming in, approximate ideal using multiple of kMaxScaleRatio. + bool zooming_out = raster_page_scale_ > ideal_page_scale_; + float desired_contents_scale = + zooming_out ? raster_contents_scale_ / kMaxScaleRatioDuringPinch + : raster_contents_scale_ * kMaxScaleRatioDuringPinch; + raster_contents_scale_ = SnappedContentsScale(desired_contents_scale); + raster_page_scale_ = raster_contents_scale_ / raster_device_scale_; + } // Don't allow animating CSS scales to drop below 1. This is needed because // changes in raster source scale aren't handled. See the comment in // ShouldAdjustRasterScale. if (animating_transform_to_screen) { - *raster_contents_scale = std::max( - *raster_contents_scale, 1.f * ideal_page_scale_ * ideal_device_scale_); + raster_contents_scale_ = std::max( + raster_contents_scale_, 1.f * ideal_page_scale_ * ideal_device_scale_); } // If this layer would only create one tile at this content scale, // don't create a low res tiling. gfx::Size content_bounds = - gfx::ToCeiledSize(gfx::ScaleSize(bounds(), *raster_contents_scale)); + gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_)); gfx::Size tile_size = CalculateTileSize(content_bounds); if (tile_size.width() >= content_bounds.width() && tile_size.height() >= content_bounds.height()) { - *low_res_raster_contents_scale = *raster_contents_scale; + low_res_raster_contents_scale_ = raster_contents_scale_; return; } float low_res_factor = layer_tree_impl()->settings().low_res_contents_scale_factor; - *low_res_raster_contents_scale = std::max( - *raster_contents_scale * low_res_factor, + low_res_raster_contents_scale_ = std::max( + raster_contents_scale_ * low_res_factor, MinimumContentsScale()); } |