summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-01 17:43:37 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-01 17:43:37 +0000
commitbac6ddbb41a551655b8802c2253ed21a0ab9a992 (patch)
treeeab78a7667a312c089e356a57eb695e0f6b5a5c1 /cc
parent1343a880d6aebf73a384e89d0e3d0e0fb7d2e78a (diff)
downloadchromium_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.cc69
-rw-r--r--cc/layers/picture_layer_impl.h3
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc146
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