Commit 4c2554aa authored by Robert Flack's avatar Robert Flack Committed by Commit Bot

Preserve raster scale when animations run on will-change: transform.

When authors add will-change: transform hints, we expect the transform
to change and should attempt to not change the raster scale unless
higher resolution tilings are needed.

Bug: 1074055
Change-Id: Ica3daff2a093617602aff8785568e5c29d5b6210
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2164152Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#763533}
parent 5578402d
......@@ -1209,8 +1209,14 @@ bool PictureLayerImpl::ShouldAdjustRasterScale() const {
}
if (was_screen_space_transform_animating_ !=
draw_properties().screen_space_transform_is_animating)
return true;
draw_properties().screen_space_transform_is_animating) {
// Skip adjusting raster scale when animations finish if we have a
// will-change: transform hint to preserve maximum resolution tiles
// needed.
if (draw_properties().screen_space_transform_is_animating ||
!has_will_change_transform_hint())
return true;
}
bool is_pinching = layer_tree_impl()->PinchGestureActive();
if (is_pinching && raster_page_scale_) {
......@@ -1319,6 +1325,9 @@ void PictureLayerImpl::RecalculateRasterScales() {
float old_raster_contents_scale = raster_contents_scale_;
float old_raster_page_scale = raster_page_scale_;
// The raster scale if previous tilings should be preserved.
float preserved_raster_contents_scale = old_raster_contents_scale;
raster_device_scale_ = ideal_device_scale_;
raster_page_scale_ = ideal_page_scale_;
raster_source_scale_ = ideal_source_scale_;
......@@ -1340,8 +1349,9 @@ void PictureLayerImpl::RecalculateRasterScales() {
while (desired_contents_scale < ideal_contents_scale_)
desired_contents_scale *= kMaxScaleRatioDuringPinch;
}
raster_contents_scale_ = tilings_->GetSnappedContentsScaleKey(
desired_contents_scale, kSnapToExistingTilingRatio);
raster_contents_scale_ = preserved_raster_contents_scale =
tilings_->GetSnappedContentsScaleKey(desired_contents_scale,
kSnapToExistingTilingRatio);
raster_page_scale_ =
raster_contents_scale_ / raster_device_scale_ / raster_source_scale_;
}
......@@ -1391,15 +1401,27 @@ void PictureLayerImpl::RecalculateRasterScales() {
if (start_area <= viewport_area)
should_raster_at_starting_scale = true;
}
// Use the computed scales for the raster scale directly, do not try to use
// the ideal scale here. The current ideal scale may be way too large in the
// case of an animation with scale, and will be constantly changing.
float animation_desired_scale;
if (should_raster_at_starting_scale)
raster_contents_scale_ = starting_scale;
animation_desired_scale = starting_scale;
else if (can_raster_at_maximum_scale)
raster_contents_scale_ = maximum_scale;
animation_desired_scale = maximum_scale;
else
raster_contents_scale_ = 1.f * ideal_page_scale_ * ideal_device_scale_;
animation_desired_scale = 1.f * ideal_page_scale_ * ideal_device_scale_;
if (has_will_change_transform_hint()) {
// If we have a will-change: transform hint, do not shrink the content
// raster scale, otherwise we will end up throwing away larger tiles we
// may need again.
raster_contents_scale_ =
std::max(preserved_raster_contents_scale, animation_desired_scale);
} else {
raster_contents_scale_ = animation_desired_scale;
}
}
// Clamp will-change: transform layers to be at least the native scale.
......
......@@ -2880,6 +2880,66 @@ TEST_F(LegacySWPictureLayerImplTest, HighResTilingDuringAnimation) {
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 11.f);
}
TEST_F(LegacySWPictureLayerImplTest,
AnimationTilingChangesWithWillChangeTransformHint) {
gfx::Size viewport_size(1000, 1000);
host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size));
gfx::Size layer_bounds(100, 100);
SetupDefaultTrees(layer_bounds);
float contents_scale = 1.f;
float device_scale = 1.f;
float page_scale = 1.f;
float maximum_animation_scale = 1.f;
float starting_animation_scale = 0.f;
bool animating_transform = false;
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f);
active_layer()->SetHasWillChangeTransformHint(true);
pending_layer()->SetHasWillChangeTransformHint(true);
// Starting an animation should cause tiling resolution to get set to the
// maximum animation scale factor.
animating_transform = true;
maximum_animation_scale = 2.f;
contents_scale = 1.f;
SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
maximum_animation_scale,
starting_animation_scale, animating_transform);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f);
// Once we stop animating, because we have a will-change: transform hint
// we should not reset the scale factor.
animating_transform = false;
SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
maximum_animation_scale,
starting_animation_scale, animating_transform);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f);
// Starting an animation with a different maximum animation scale should
// not cause a change either.
animating_transform = true;
maximum_animation_scale = 1.5f;
SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
maximum_animation_scale,
starting_animation_scale, animating_transform);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f);
// Again, stop animating, because we have a will-change: transform hint
// we should not reset the scale factor.
animating_transform = false;
SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
maximum_animation_scale,
starting_animation_scale, animating_transform);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f);
}
TEST_F(LegacySWPictureLayerImplTest, HighResTilingDuringAnimationAspectRatio) {
gfx::Size viewport_size(2000, 1000);
host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size));
......@@ -3441,6 +3501,9 @@ TEST_F(LegacySWPictureLayerImplTest, RasterScaleChangeWithoutAnimation) {
EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f);
}
TEST_F(LegacySWPictureLayerImplTest,
AnimationChangeRespectsWillChangeTransformHint) {}
TEST_F(LegacySWPictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) {
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment