Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -909,8 +909,8 @@ void Canvas::DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
// needs to be reworked in order to interact correctly with
// mask filters.
// https://github.com/flutter/flutter/issues/133297
entity.SetContents(
paint.WithFilters(paint.WithMaskBlur(std::move(text_contents), true)));
entity.SetContents(paint.WithFilters(paint.WithMaskBlur(
std::move(text_contents), true, GetCurrentTransform())));

AddRenderEntityToCurrentPass(std::move(entity));
}
Expand Down
4 changes: 2 additions & 2 deletions impeller/aiks/experimental_canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,8 @@ void ExperimentalCanvas::DrawTextFrame(
// needs to be reworked in order to interact correctly with
// mask filters.
// https://github.com/flutter/flutter/issues/133297
entity.SetContents(
paint.WithFilters(paint.WithMaskBlur(std::move(text_contents), true)));
entity.SetContents(paint.WithFilters(paint.WithMaskBlur(
std::move(text_contents), true, GetCurrentTransform())));

AddRenderEntityToCurrentPass(std::move(entity), false);
}
Expand Down
18 changes: 13 additions & 5 deletions impeller/aiks/paint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ std::shared_ptr<Contents> Paint::WithFiltersForSubpassTarget(
}

std::shared_ptr<Contents> Paint::WithMaskBlur(std::shared_ptr<Contents> input,
bool is_solid_color) const {
bool is_solid_color,
const Matrix& ctm) const {
if (mask_blur_descriptor.has_value()) {
input = mask_blur_descriptor->CreateMaskBlur(FilterInput::Make(input),
is_solid_color);
is_solid_color, ctm);
}
return input;
}
Expand Down Expand Up @@ -203,12 +204,19 @@ std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(

std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
const FilterInput::Ref& input,
bool is_solid_color) const {
bool is_solid_color,
const Matrix& ctm) const {
Vector2 blur_sigma(sigma.sigma, sigma.sigma);
if (!respect_ctm) {
blur_sigma /= Vector2(ctm.GetBasisX().Length(), ctm.GetBasisY().Length());
}
if (is_solid_color) {
return FilterContents::MakeGaussianBlur(input, sigma, sigma,
return FilterContents::MakeGaussianBlur(input, Sigma(blur_sigma.x),
Sigma(blur_sigma.y),
Entity::TileMode::kDecal, style);
}
return FilterContents::MakeBorderMaskBlur(input, sigma, sigma, style);
return FilterContents::MakeBorderMaskBlur(input, Sigma(blur_sigma.x),
Sigma(blur_sigma.y), style);
}

std::shared_ptr<ColorFilter> Paint::GetColorFilter() const {
Expand Down
9 changes: 7 additions & 2 deletions impeller/aiks/paint.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ struct Paint {
struct MaskBlurDescriptor {
FilterContents::BlurStyle style;
Sigma sigma;
/// Text mask blurs need to not apply the CTM to the blur kernel.
/// See: https://github.com/flutter/flutter/issues/115112
bool respect_ctm = true;

std::shared_ptr<FilterContents> CreateMaskBlur(
std::shared_ptr<ColorSourceContents> color_source_contents,
Expand All @@ -58,7 +61,8 @@ struct Paint {

std::shared_ptr<FilterContents> CreateMaskBlur(
const FilterInput::Ref& input,
bool is_solid_color) const;
bool is_solid_color,
const Matrix& ctm) const;
};

Color color = Color::Black();
Expand Down Expand Up @@ -105,7 +109,8 @@ struct Paint {
bool HasColorFilter() const;

std::shared_ptr<Contents> WithMaskBlur(std::shared_ptr<Contents> input,
bool is_solid_color) const;
bool is_solid_color,
const Matrix& ctm) const;

std::shared_ptr<FilterContents> WithImageFilter(
const FilterInput::Variant& input,
Expand Down
1 change: 1 addition & 0 deletions impeller/display_list/dl_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ void DlDispatcherBase::setMaskFilter(const flutter::DlMaskFilter* filter) {
paint_.mask_blur_descriptor = {
.style = ToBlurStyle(blur->style()),
.sigma = Sigma(blur->sigma()),
.respect_ctm = blur->respectCTM(),
};
break;
}
Expand Down
44 changes: 34 additions & 10 deletions impeller/entity/contents/filters/gaussian_blur_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,14 @@ std::optional<Rect> GaussianBlurFilterContents::GetFilterCoverage(
return expanded_source_coverage.TransformBounds(entity.GetTransform());
}

namespace {
Vector2 ExtractScale(const Matrix& matrix) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use Matrix::Decompose for this

Vector2 entity_scale_x = matrix * Vector2(1.0, 0.0);
Vector2 entity_scale_y = matrix * Vector2(0.0, 1.0);
return Vector2(entity_scale_x.GetLength(), entity_scale_y.GetLength());
}
} // namespace

std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
const FilterInput::Vector& inputs,
const ContentContext& renderer,
Expand All @@ -390,7 +398,14 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
return std::nullopt;
}

const Vector2 source_space_scalar =
ExtractScale(entity.GetTransform().Basis());

Vector2 scaled_sigma = (effect_transform.Basis() *
// Uncomment the following line to break the text
// shadows, but fix GaussianVsRRectBlur tests.
Matrix::MakeScale({source_space_scalar.x,
source_space_scalar.y, 1}) * //
Vector2(ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)))
.Abs();
scaled_sigma.x = std::min(scaled_sigma.x, kMaxSigma);
Expand All @@ -417,11 +432,13 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
}

Entity snapshot_entity = entity.Clone();
snapshot_entity.SetTransform(Matrix());
snapshot_entity.SetTransform(
Matrix::MakeScale({source_space_scalar.x, source_space_scalar.y, 1}));
std::optional<Rect> source_expanded_coverage_hint;
if (expanded_coverage_hint.has_value()) {
source_expanded_coverage_hint =
expanded_coverage_hint->TransformBounds(entity.GetTransform().Invert());
source_expanded_coverage_hint = expanded_coverage_hint->TransformBounds(
Matrix::MakeScale({source_space_scalar.x, source_space_scalar.y, 1}) *
entity.GetTransform().Invert());
}

std::optional<Snapshot> input_snapshot =
Expand All @@ -436,7 +453,10 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
Entity result =
Entity::FromSnapshot(input_snapshot.value(),
entity.GetBlendMode()); // No blur to render.
result.SetTransform(entity.GetTransform() * input_snapshot->transform);
result.SetTransform(entity.GetTransform() *
Matrix::MakeScale({1.f / source_space_scalar.x,
1.f / source_space_scalar.y, 1}) *
input_snapshot->transform);
return result;
}

Expand Down Expand Up @@ -562,12 +582,16 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
MinMagFilter::kLinear, SamplerAddressMode::kClampToEdge);

Entity blur_output_entity = Entity::FromSnapshot(
Snapshot{.texture = pass3_out.value().GetRenderTargetTexture(),
.transform = entity.GetTransform() * input_snapshot->transform *
padding_snapshot_adjustment *
Matrix::MakeScale(1 / effective_scalar),
.sampler_descriptor = sampler_desc,
.opacity = input_snapshot->opacity},
Snapshot{
.texture = pass3_out.value().GetRenderTargetTexture(),
.transform = entity.GetTransform() * //
Matrix::MakeScale({1.f / source_space_scalar.x,
1.f / source_space_scalar.y, 1}) * //
input_snapshot->transform * //
padding_snapshot_adjustment * //
Matrix::MakeScale(1 / effective_scalar),
.sampler_descriptor = sampler_desc,
.opacity = input_snapshot->opacity},
entity.GetBlendMode());

return ApplyBlurStyle(mask_blur_style_, entity, inputs[0],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ TEST_P(GaussianBlurFilterContentsTest,
if (result_coverage.has_value() && contents_coverage.has_value()) {
EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
EXPECT_TRUE(RectNear(contents_coverage.value(),
Rect::MakeXYWH(98.f, 78.f, 204.0f, 204.f)));
Rect::MakeXYWH(94.f, 74.f, 212.0f, 212.f)));
}
}
}
Expand Down Expand Up @@ -438,7 +438,7 @@ TEST_P(GaussianBlurFilterContentsTest, TextureContentsWithEffectTransform) {
if (result_coverage.has_value() && contents_coverage.has_value()) {
EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
EXPECT_TRUE(RectNear(contents_coverage.value(),
Rect::MakeXYWH(49.f, 39.f, 102.f, 102.f)));
Rect::MakeXYWH(94.f, 74.f, 212.f, 212.f)));
}
}
}
Expand Down