diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-01 17:43:37 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-01 17:43:37 +0000 |
commit | bac6ddbb41a551655b8802c2253ed21a0ab9a992 (patch) | |
tree | eab78a7667a312c089e356a57eb695e0f6b5a5c1 /cc | |
parent | 1343a880d6aebf73a384e89d0e3d0e0fb7d2e78a (diff) | |
download | chromium_src-bac6ddbb41a551655b8802c2253ed21a0ab9a992.zip chromium_src-bac6ddbb41a551655b8802c2253ed21a0ab9a992.tar.gz chromium_src-bac6ddbb41a551655b8802c2253ed21a0ab9a992.tar.bz2 |
cc: Reraster and fix the raster source scale factor when it changes.
When a web page changes the scale of elements in the page outside of an
animation, we should have that cause us to make a new tiling at the new
scale.
However, we don't want to do this every main thread frame. So when the
first change happens, we set raster_source_scale_is_fixed_ to true
and change the source scale to 1, ignoring any css transform scales
when rastering the layer from then on.
R=enne
BUG=368201
Review URL: https://codereview.chromium.org/262613005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267570 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 69 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.h | 3 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl_unittest.cc | 146 |
3 files changed, 135 insertions, 83 deletions
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 1475232..15dc02e 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -50,13 +50,15 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id) raster_source_scale_(0.f), raster_contents_scale_(0.f), low_res_raster_contents_scale_(0.f), - raster_source_scale_was_animating_(false), + raster_source_scale_is_fixed_(false), + was_animating_transform_to_screen_(false), is_using_lcd_text_(tree_impl->settings().can_use_lcd_text), needs_post_commit_initialization_(true), should_update_tile_priorities_(false), should_use_low_res_tiling_(tree_impl->settings().create_low_res_tiling), use_gpu_rasterization_(false), - layer_needs_to_register_itself_(true) {} + layer_needs_to_register_itself_(true) { +} PictureLayerImpl::~PictureLayerImpl() { if (!layer_needs_to_register_itself_) @@ -965,15 +967,16 @@ void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen, << "A layer with no tilings shouldn't have valid raster scales"; } - // Store the value for the next time ShouldAdjustRasterScale is called. - raster_source_scale_was_animating_ = animating_transform_to_screen; + if (change_target_tiling) { + RecalculateRasterScales(animating_transform_to_screen, + maximum_animation_contents_scale); + } + + was_animating_transform_to_screen_ = animating_transform_to_screen; if (!change_target_tiling) return; - RecalculateRasterScales(animating_transform_to_screen, - maximum_animation_contents_scale); - PictureLayerTiling* high_res = NULL; PictureLayerTiling* low_res = NULL; @@ -1020,12 +1023,7 @@ void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen, bool PictureLayerImpl::ShouldAdjustRasterScale( bool animating_transform_to_screen) const { - // TODO(danakj): Adjust raster source scale closer to ideal source scale at - // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending - // tree. This will allow CSS scale changes to get re-rastered at an - // appropriate rate. - - if (raster_source_scale_was_animating_ != animating_transform_to_screen) + if (was_animating_transform_to_screen_ != animating_transform_to_screen) return true; if (animating_transform_to_screen && @@ -1054,6 +1052,12 @@ bool PictureLayerImpl::ShouldAdjustRasterScale( if (raster_device_scale_ != ideal_device_scale_) return true; + // When the source scale changes we want to match it, but not when animating + // or when we've fixed the scale in place. + if (!animating_transform_to_screen && !raster_source_scale_is_fixed_ && + raster_source_scale_ != ideal_source_scale_) + return true; + return false; } @@ -1075,22 +1079,44 @@ float PictureLayerImpl::SnappedContentsScale(float scale) { void PictureLayerImpl::RecalculateRasterScales( bool animating_transform_to_screen, float maximum_animation_contents_scale) { + float old_raster_contents_scale = raster_contents_scale_; + float old_raster_page_scale = raster_page_scale_; + float old_raster_source_scale = raster_source_scale_; + raster_device_scale_ = ideal_device_scale_; + raster_page_scale_ = ideal_page_scale_; raster_source_scale_ = ideal_source_scale_; + raster_contents_scale_ = ideal_contents_scale_; + + // If we're not animating, or leaving an animation, and the + // ideal_source_scale_ changes, then things are unpredictable, and we fix + // the raster_source_scale_ in place. + if (old_raster_source_scale && !animating_transform_to_screen && + !was_animating_transform_to_screen_ && + old_raster_source_scale != ideal_source_scale_) + raster_source_scale_is_fixed_ = true; + + // TODO(danakj): Adjust raster source scale closer to ideal source scale at + // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending + // tree. This will allow CSS scale changes to get re-rastered at an + // appropriate rate. + if (raster_source_scale_is_fixed_) { + raster_contents_scale_ /= raster_source_scale_; + raster_source_scale_ = 1.f; + } + // During pinch we completely ignore the current ideal scale, and just use + // a multiple of the previous scale. + // TODO(danakj): This seems crazy, we should use the current ideal, no? bool is_pinching = layer_tree_impl()->PinchGestureActive(); - if (!is_pinching || raster_contents_scale_ == 0.f) { - // When not pinching or when we have no previous scale, we use ideal scale: - raster_page_scale_ = ideal_page_scale_; - raster_contents_scale_ = ideal_contents_scale_; - } else { + if (is_pinching && old_raster_contents_scale) { // 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_; + bool zooming_out = old_raster_page_scale > ideal_page_scale_; float desired_contents_scale = - zooming_out ? raster_contents_scale_ / kMaxScaleRatioDuringPinch - : raster_contents_scale_ * kMaxScaleRatioDuringPinch; + zooming_out ? old_raster_contents_scale / kMaxScaleRatioDuringPinch + : old_raster_contents_scale * kMaxScaleRatioDuringPinch; raster_contents_scale_ = SnappedContentsScale(desired_contents_scale); raster_page_scale_ = raster_contents_scale_ / raster_device_scale_; } @@ -1220,6 +1246,7 @@ void PictureLayerImpl::ResetRasterScale() { raster_source_scale_ = 0.f; raster_contents_scale_ = 0.f; low_res_raster_contents_scale_ = 0.f; + raster_source_scale_is_fixed_ = false; // When raster scales aren't valid, don't update tile priorities until // this layer has been updated via UpdateDrawProperties. diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index bf24251..b559e3d 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h @@ -204,7 +204,8 @@ class CC_EXPORT PictureLayerImpl float raster_contents_scale_; float low_res_raster_contents_scale_; - bool raster_source_scale_was_animating_; + bool raster_source_scale_is_fixed_; + bool was_animating_transform_to_screen_; bool is_using_lcd_text_; bool needs_post_commit_initialization_; // A sanity state check to make sure UpdateTilePriorities only gets called diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 9af89af..6c5b2c7 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -100,6 +100,8 @@ class PictureLayerImplTest : public testing::Test { SetupPendingTree(active_pile); ActivateTree(); SetupPendingTree(pending_pile); + host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f); + host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f); } void CreateHighLowResAndSetAllTilesVisible() { @@ -695,43 +697,23 @@ TEST_F(PictureLayerImplTest, ManageTilingsCreatesTilings) { float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; EXPECT_LT(low_res_factor, 1.f); - pending_layer_->CalculateContentsScale(1.3f, // ideal contents scale - 1.7f, // device scale - 3.2f, // page scale - 1.f, // maximum animation scale - false, - &result_scale_x, - &result_scale_y, - &result_bounds); - ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings()); - EXPECT_FLOAT_EQ( - 1.3f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ( - 1.3f * low_res_factor, - pending_layer_->tilings()->tiling_at(1)->contents_scale()); - - // If we change the layer's CSS scale factor, then we should not get new - // tilings. - pending_layer_->CalculateContentsScale(1.8f, // ideal contents scale - 1.7f, // device scale - 3.2f, // page scale - 1.f, // maximum animation scale + pending_layer_->CalculateContentsScale(6.f, // ideal contents scale + 3.f, // device scale + 2.f, // page scale + 1.f, // maximum animation scale false, &result_scale_x, &result_scale_y, &result_bounds); ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings()); - EXPECT_FLOAT_EQ( - 1.3f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ( - 1.3f * low_res_factor, - pending_layer_->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ(6.f, + pending_layer_->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ(6.f * low_res_factor, + pending_layer_->tilings()->tiling_at(1)->contents_scale()); // If we change the page scale factor, then we should get new tilings. - pending_layer_->CalculateContentsScale(1.8f, // ideal contents scale - 1.7f, // device scale + pending_layer_->CalculateContentsScale(6.6f, // ideal contents scale + 3.f, // device scale 2.2f, // page scale 1.f, // maximum animation scale false, @@ -739,47 +721,41 @@ TEST_F(PictureLayerImplTest, ManageTilingsCreatesTilings) { &result_scale_y, &result_bounds); ASSERT_EQ(4u, pending_layer_->tilings()->num_tilings()); - EXPECT_FLOAT_EQ( - 1.8f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ( - 1.8f * low_res_factor, - pending_layer_->tilings()->tiling_at(2)->contents_scale()); + EXPECT_FLOAT_EQ(6.6f, + pending_layer_->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ(6.6f * low_res_factor, + pending_layer_->tilings()->tiling_at(2)->contents_scale()); // If we change the device scale factor, then we should get new tilings. - pending_layer_->CalculateContentsScale(1.9f, // ideal contents scale - 1.4f, // device scale - 2.2f, // page scale - 1.f, // maximum animation scale + pending_layer_->CalculateContentsScale(7.26f, // ideal contents scale + 3.3f, // device scale + 2.2f, // page scale + 1.f, // maximum animation scale false, &result_scale_x, &result_scale_y, &result_bounds); ASSERT_EQ(6u, pending_layer_->tilings()->num_tilings()); - EXPECT_FLOAT_EQ( - 1.9f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ( - 1.9f * low_res_factor, - pending_layer_->tilings()->tiling_at(3)->contents_scale()); + EXPECT_FLOAT_EQ(7.26f, + pending_layer_->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ(7.26f * low_res_factor, + pending_layer_->tilings()->tiling_at(3)->contents_scale()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. - pending_layer_->CalculateContentsScale(1.9f, // ideal contents scale - 2.2f, // device scale - 1.4f, // page scale - 1.f, // maximum animation scale + pending_layer_->CalculateContentsScale(7.26f, // ideal contents scale + 2.2f, // device scale + 3.3f, // page scale + 1.f, // maximum animation scale false, &result_scale_x, &result_scale_y, &result_bounds); ASSERT_EQ(6u, pending_layer_->tilings()->num_tilings()); - EXPECT_FLOAT_EQ( - 1.9f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ( - 1.9f * low_res_factor, - pending_layer_->tilings()->tiling_at(3)->contents_scale()); + EXPECT_FLOAT_EQ(7.26f, + pending_layer_->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ(7.26f * low_res_factor, + pending_layer_->tilings()->tiling_at(3)->contents_scale()); } TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) { @@ -960,8 +936,9 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { float device_scale = 1.7f; float page_scale = 3.2f; + float scale = 1.f; - SetContentsScaleOnBothLayers(1.f, device_scale, page_scale, 1.f, false); + SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, false); ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); // We only have ideal tilings, so they aren't removed. @@ -969,8 +946,12 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + host_impl_.PinchGestureBegin(); + // Changing the ideal but not creating new tilings. - SetContentsScaleOnBothLayers(1.5f, device_scale, page_scale, 1.f, false); + scale *= 1.5f; + page_scale *= 1.5f; + SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, false); ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); // The tilings are still our target scale, so they aren't removed. @@ -978,8 +959,11 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + host_impl_.PinchGestureEnd(); + // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2. - page_scale = 1.2f; + scale /= 4.f; + page_scale /= 4.f; SetContentsScaleOnBothLayers(1.2f, device_scale, page_scale, 1.f, false); ASSERT_EQ(4u, active_layer_->tilings()->num_tilings()); EXPECT_FLOAT_EQ( @@ -1058,8 +1042,8 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { #define EXPECT_BOTH_EQ(expression, x) \ do { \ - EXPECT_EQ(pending_layer_->expression, x); \ - EXPECT_EQ(active_layer_->expression, x); \ + EXPECT_EQ(x, pending_layer_->expression); \ + EXPECT_EQ(x, active_layer_->expression); \ } while (false) TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { @@ -2279,5 +2263,45 @@ TEST_F(PictureLayerImplTest, Occlusion) { } } +TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { + gfx::Size tile_size(host_impl_.settings().default_tile_size); + SetupDefaultTrees(tile_size); + + float contents_scale = 2.f; + float device_scale = 1.f; + float page_scale = 1.f; + float maximum_animation_scale = 1.f; + bool animating_transform = false; + + SetContentsScaleOnBothLayers(contents_scale, + device_scale, + page_scale, + maximum_animation_scale, + animating_transform); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f); + + // Changing the source scale without being in an animation will cause + // the layer to reset its source scale to 1.f. + contents_scale = 3.f; + + SetContentsScaleOnBothLayers(contents_scale, + device_scale, + page_scale, + maximum_animation_scale, + animating_transform); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f); + + // Further changes to the source scale will no longer be reflected in the + // contents scale. + contents_scale = 0.5f; + + SetContentsScaleOnBothLayers(contents_scale, + device_scale, + page_scale, + maximum_animation_scale, + animating_transform); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f); +} + } // namespace } // namespace cc |