Skip to content

Commit

Permalink
[cc] Support 2D scales in raster transforms
Browse files Browse the repository at this point in the history
Before this patch, AxisTransform2d used to store the transform scale as
a single float, and then all the logic was 1D. This produced suboptimal
results for things like 'transform: scale3d(1, 5, 1)'.

This patch changes AxisTransform2d to store the scale as a Vector2dF,
and updates PictureLayerImpl to use 2D logic. Most of the tiling logic
is kept unchanged, using the maximum component of the scale.

Note that the ideal scale continues clamping the maximum scale component
to not be greater than 5 times the minimum one.

Bug: 1119996

TEST=third_party/blink/web_tests/compositing/transform-3d-scales-different-x-y.html

Change-Id: I13fb3605455393d4a65c788103ba28b923e1cb4a
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2642377
Reviewed-by: danakj <danakj@chromium.org>
Reviewed-by: Victor Miura <vmiura@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: vmpstr <vmpstr@chromium.org>
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Oriol Brufau <obrufau@igalia.com>
Cr-Commit-Position: refs/heads/master@{#872117}
  • Loading branch information
Loirooriol authored and Chromium LUCI CQ committed Apr 13, 2021
1 parent 09d0a87 commit a8c344f
Show file tree
Hide file tree
Showing 48 changed files with 369 additions and 245 deletions.
9 changes: 5 additions & 4 deletions cc/benchmarks/rasterize_and_record_benchmark_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <algorithm>
#include <limits>
#include <memory>

#include "base/timer/lap_timer.h"
#include "base/values.h"
Expand All @@ -31,7 +32,7 @@ const int kDefaultRasterizeRepeatCount = 100;
void RunBenchmark(RasterSource* raster_source,
ImageDecodeCache* image_decode_cache,
const gfx::Rect& content_rect,
float contents_scale,
const gfx::Vector2dF& contents_scale,
size_t repeat_count,
base::TimeDelta* min_time,
bool* is_solid_color) {
Expand All @@ -48,8 +49,8 @@ void RunBenchmark(RasterSource* raster_source,
base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
kTimeCheckInterval);
SkColor color = SK_ColorTRANSPARENT;
gfx::Rect layer_rect =
gfx::ScaleToEnclosingRect(content_rect, 1.f / contents_scale);
gfx::Rect layer_rect = gfx::ScaleToEnclosingRect(
content_rect, 1.f / contents_scale.x(), 1.f / contents_scale.y());
*is_solid_color =
raster_source->PerformSolidColorAnalysis(layer_rect, &color);

Expand Down Expand Up @@ -230,7 +231,7 @@ void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
DCHECK(*it);

gfx::Rect content_rect = (*it)->content_rect();
float contents_scale = (*it)->raster_transform().scale();
const gfx::Vector2dF& contents_scale = (*it)->raster_transform().scale();

base::TimeDelta min_time;
bool is_solid_color = false;
Expand Down
6 changes: 4 additions & 2 deletions cc/layers/heads_up_display_layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ bool HeadsUpDisplayLayerImpl::WillDraw(
}

int max_texture_size = layer_tree_impl()->max_texture_size();
internal_contents_scale_ = GetIdealContentsScale();
// TODO(crbug.com/1196414): Support 2D scales in heads up layers.
internal_contents_scale_ = GetIdealContentsScaleKey();
internal_content_bounds_ =
gfx::ScaleToCeiledSize(bounds(), internal_contents_scale_);
internal_content_bounds_.SetToMin(
Expand Down Expand Up @@ -379,12 +380,13 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
can_use_lcd_text, gfx::ColorSpace::CreateSRGB(),
backing->mailbox.name);
gfx::Vector2dF post_translate(0.f, 0.f);
gfx::Vector2dF post_scale(1.f, 1.f);
DummyImageProvider image_provider;
size_t max_op_size_limit =
gpu::raster::RasterInterface::kDefaultMaxOpSizeHint;
ri->RasterCHROMIUM(display_item_list.get(), &image_provider, size,
gfx::Rect(size), gfx::Rect(size), post_translate,
1.f /* post_scale */, false /* requires_clear */,
post_scale, false /* requires_clear */,
&max_op_size_limit);
ri->EndRasterCHROMIUM();
backing->mailbox_sync_token =
Expand Down
15 changes: 12 additions & 3 deletions cc/layers/layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ const RenderSurfaceImpl* LayerImpl::render_target() const {
return GetEffectTree().GetRenderSurface(render_target_effect_tree_index());
}

float LayerImpl::GetIdealContentsScale() const {
gfx::Vector2dF LayerImpl::GetIdealContentsScale() const {
float page_scale = IsAffectedByPageScale()
? layer_tree_impl()->current_page_scale_factor()
: 1.f;
Expand All @@ -801,6 +801,7 @@ float LayerImpl::GetIdealContentsScale() const {

const auto& transform = ScreenSpaceTransform();
if (transform.HasPerspective()) {
// TODO(crbug.com/1196414): This function should return a 2D scale.
float scale = gfx::ComputeApproximateMaxScale(transform);

const int kMaxTilesToCoverLayerDimension = 5;
Expand All @@ -827,13 +828,21 @@ float LayerImpl::GetIdealContentsScale() const {
scale = std::round(scale);

// Don't let the scale fall below the default scale.
return std::max(scale, default_scale);
scale = std::max(scale, default_scale);
return gfx::Vector2dF(scale, scale);
}

gfx::Vector2dF transform_scales =
gfx::ComputeTransform2dScaleComponents(transform, default_scale);

return GetPreferredRasterScale(transform_scales);
// TODO(crbug.com/1196414): Remove this scale cap.
float scale_cap = GetPreferredRasterScale(transform_scales);
transform_scales.SetToMin(gfx::Vector2dF(scale_cap, scale_cap));
return transform_scales;
}

float LayerImpl::GetIdealContentsScaleKey() const {
return GetPreferredRasterScale(GetIdealContentsScale());
}

float LayerImpl::GetPreferredRasterScale(
Expand Down
9 changes: 8 additions & 1 deletion cc/layers/layer_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,14 @@ class CC_EXPORT LayerImpl {
// PopulateScaledSharedQuadStateQuadState() for more details.
gfx::Rect GetScaledEnclosingRectInTargetSpace(float scale) const;

float GetIdealContentsScale() const;
// GetIdealContentsScale() returns the ideal 2D scale, clamped to not exceed
// GetPreferredRasterScale().
// GetIdealContentsScaleKey() returns the maximum component, a fallback to
// uniform scale for callers that don't support 2d scales yet.
// TODO(crbug.com/1196414): Remove uses of GetIdealContentsScaleKey() outside
// tests, and rename it to GetIdealContentsScaleKeyForTest().
gfx::Vector2dF GetIdealContentsScale() const;
float GetIdealContentsScaleKey() const;

void NoteLayerPropertyChanged();
void NoteLayerPropertyChangedFromPropertyTrees();
Expand Down
10 changes: 6 additions & 4 deletions cc/layers/layer_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "cc/layers/layer_impl.h"

#include <algorithm>

#include "base/stl_util.h"
#include "cc/layers/painted_scrollbar_layer_impl.h"
#include "cc/layers/solid_color_scrollbar_layer_impl.h"
Expand Down Expand Up @@ -263,7 +265,7 @@ TEST_F(LayerImplTest, PerspectiveTransformHasReasonableScale) {
layer->draw_properties().screen_space_transform = transform;

ASSERT_TRUE(layer->ScreenSpaceTransform().HasPerspective());
EXPECT_FLOAT_EQ(15.f, layer->GetIdealContentsScale());
EXPECT_FLOAT_EQ(15.f, layer->GetIdealContentsScaleKey());
}
// Ensure that we don't fall below the device scale factor.
{
Expand All @@ -273,7 +275,7 @@ TEST_F(LayerImplTest, PerspectiveTransformHasReasonableScale) {
layer->draw_properties().screen_space_transform = transform;

ASSERT_TRUE(layer->ScreenSpaceTransform().HasPerspective());
EXPECT_FLOAT_EQ(1.f, layer->GetIdealContentsScale());
EXPECT_FLOAT_EQ(1.f, layer->GetIdealContentsScaleKey());
}
// Ensure that large scales don't end up extremely large.
{
Expand All @@ -283,7 +285,7 @@ TEST_F(LayerImplTest, PerspectiveTransformHasReasonableScale) {
layer->draw_properties().screen_space_transform = transform;

ASSERT_TRUE(layer->ScreenSpaceTransform().HasPerspective());
EXPECT_FLOAT_EQ(127.f, layer->GetIdealContentsScale());
EXPECT_FLOAT_EQ(127.f, layer->GetIdealContentsScaleKey());
}
// Test case from crbug.com/766021.
{
Expand All @@ -294,7 +296,7 @@ TEST_F(LayerImplTest, PerspectiveTransformHasReasonableScale) {
layer->draw_properties().screen_space_transform = transform;

ASSERT_TRUE(layer->ScreenSpaceTransform().HasPerspective());
EXPECT_FLOAT_EQ(1.f, layer->GetIdealContentsScale());
EXPECT_FLOAT_EQ(1.f, layer->GetIdealContentsScaleKey());
}
}

Expand Down
8 changes: 5 additions & 3 deletions cc/layers/mirror_layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ void MirrorLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
const bool contents_opaque = false;
viz::SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
// TODO(crbug.com/1196414): Support 2D scales in mirror layers.
PopulateScaledSharedQuadStateWithContentRects(
shared_quad_state, mirrored_layer->GetIdealContentsScale(), content_rect,
content_rect, contents_opaque);
shared_quad_state, mirrored_layer->GetIdealContentsScaleKey(),
content_rect, content_rect, contents_opaque);

AppendDebugBorderQuad(render_pass, content_rect, shared_quad_state,
append_quads_data);
Expand Down Expand Up @@ -77,8 +78,9 @@ gfx::Rect MirrorLayerImpl::GetDamageRect() const {
gfx::Rect MirrorLayerImpl::GetEnclosingRectInTargetSpace() const {
const LayerImpl* mirrored_layer =
layer_tree_impl()->LayerById(mirrored_layer_id_);
// TODO(crbug.com/1196414): Support 2D scales in mirror layers.
return GetScaledEnclosingRectInTargetSpace(
mirrored_layer->GetIdealContentsScale());
mirrored_layer->GetIdealContentsScaleKey());
}

const char* MirrorLayerImpl::LayerTypeAsString() const {
Expand Down
Loading

0 comments on commit a8c344f

Please sign in to comment.