Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
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
82 changes: 81 additions & 1 deletion impeller/display_list/dl_golden_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace testing {
using impeller::PlaygroundBackend;
using impeller::PlaygroundTest;
using impeller::Point;
using impeller::Scalar;

INSTANTIATE_PLAYGROUND_SUITE(DlGoldenTest);

Expand Down Expand Up @@ -55,7 +56,7 @@ TEST_P(DlGoldenTest, Bug147807) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Transform2DAffine(content_scale.x, 0, 0, 0, content_scale.y, 0);
canvas->Scale(content_scale.x, content_scale.y);
DlPaint paint;
paint.setColor(DlColor(0xfffef7ff));
canvas->DrawRect(SkRect::MakeLTRB(0, 0, 375, 667), paint);
Expand Down Expand Up @@ -100,5 +101,84 @@ TEST_P(DlGoldenTest, Bug147807) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

namespace {
void DrawBlurGrid(DlCanvas* canvas) {
DlPaint paint;
paint.setColor(DlColor(0xfffef7ff));
Scalar width = 150;
Scalar height = 150;
Scalar gap = 80;
std::vector<Scalar> blur_radii = {10, 30, 50};
for (size_t i = 0; i < blur_radii.size(); ++i) {
Scalar blur_radius = blur_radii[i];
auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
flutter::DlBlurStyle::kNormal, blur_radius);
paint.setMaskFilter(blur_filter);
SkRRect rrect;
Scalar yval = gap + i * (gap + height);
rrect.setNinePatch(SkRect::MakeXYWH(gap, yval, width, height), 10, 10, 10,
10);
canvas->DrawRRect(rrect, paint);
rrect.setNinePatch(SkRect::MakeXYWH(2.0 * gap + width, yval, width, height),
9, 10, 10, 10);
canvas->DrawRRect(rrect, paint);
}
}
} // namespace

TEST_P(DlGoldenTest, GaussianVsRRectBlur) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
canvas->DrawPaint(DlPaint().setColor(DlColor(0xff112233)));
DrawBlurGrid(canvas);
};

DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
draw(&builder, images);

ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

TEST_P(DlGoldenTest, GaussianVsRRectBlurScaled) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
canvas->DrawPaint(DlPaint().setColor(DlColor(0xff112233)));
canvas->Scale(0.33, 0.33);
DrawBlurGrid(canvas);
};

DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
draw(&builder, images);

ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

TEST_P(DlGoldenTest, GaussianVsRRectBlurScaledRotated) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
canvas->Translate(200, 200);
canvas->DrawPaint(DlPaint().setColor(DlColor(0xff112233)));
canvas->Scale(0.33, 0.33);
canvas->Translate(300, 300);
canvas->Rotate(45);
canvas->Translate(-300, -300);
DrawBlurGrid(canvas);
};

DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
draw(&builder, images);

ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

} // namespace testing
} // namespace flutter
18 changes: 15 additions & 3 deletions impeller/entity/contents/filters/gaussian_blur_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const int32_t GaussianBlurFilterContents::kBlurFilterRequiredMipCount = 4;
namespace {

// 48 comes from gaussian.frag.
const int32_t kMaxKernelSize = 48;
const int32_t kMaxKernelSize = 50;
constexpr Scalar kMaxSigma = 500.0f;

SamplerDescriptor MakeSamplerDescriptor(MinMagFilter filter,
SamplerAddressMode address_mode) {
Expand Down Expand Up @@ -363,9 +364,14 @@ std::optional<Rect> GaussianBlurFilterContents::GetFilterCoverage(
return {};
}

Vector2 scaled_sigma = (effect_transform.Basis() *
Vector2 entity_scale_x = entity.GetTransform().Basis() * Vector2(1.0, 0.0);
Vector2 entity_scale_y = entity.GetTransform().Basis() * Vector2(0.0, 1.0);
Vector2 scaled_sigma = (Matrix::MakeScale({entity_scale_x.GetLength(),
entity_scale_y.GetLength(), 1.0}) *
Vector2(ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)))
.Abs();
scaled_sigma.x = std::min(scaled_sigma.x, kMaxSigma);
scaled_sigma.y = std::min(scaled_sigma.y, kMaxSigma);
Vector2 blur_radius = Vector2(CalculateBlurRadius(scaled_sigma.x),
CalculateBlurRadius(scaled_sigma.y));
Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y));
Expand All @@ -384,9 +390,15 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
return std::nullopt;
}

Vector2 entity_scale_x = entity.GetTransform().Basis() * Vector2(1.0, 0.0);
Vector2 entity_scale_y = entity.GetTransform().Basis() * Vector2(0.0, 1.0);
Vector2 scaled_sigma = (effect_transform.Basis() *
Matrix::MakeScale({entity_scale_x.GetLength(),
entity_scale_y.GetLength(), 1.0}) *
Vector2(ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)))
.Abs();
scaled_sigma.x = std::min(scaled_sigma.x, kMaxSigma);
scaled_sigma.y = std::min(scaled_sigma.y, kMaxSigma);
Vector2 blur_radius = Vector2(CalculateBlurRadius(scaled_sigma.x),
CalculateBlurRadius(scaled_sigma.y));
Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y));
Expand Down Expand Up @@ -582,7 +594,7 @@ Quad GaussianBlurFilterContents::CalculateUVs(
// that puts the minima there and a f(0)=1.
Scalar GaussianBlurFilterContents::ScaleSigma(Scalar sigma) {
// Limit the kernel size to 1000x1000 pixels, like Skia does.
Scalar clamped = std::min(sigma, 500.0f);
Scalar clamped = std::min(sigma, kMaxSigma);
constexpr Scalar a = 3.4e-06;
constexpr Scalar b = -3.4e-3;
constexpr Scalar c = 1.f;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,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::MakeLTRB(98.f, 78.f, 302.f, 282.f)));
Rect::MakeXYWH(94.f, 74.f, 212.f, 212.f)));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/shaders/filters/gaussian.frag
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct KernelSample {

uniform KernelSamples {
int sample_count;
KernelSample samples[48];
KernelSample samples[50];
}
blur_info;

Expand Down
9 changes: 9 additions & 0 deletions testing/impeller_golden_tests_output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -798,3 +798,12 @@ impeller_Play_DlGoldenTest_CanDrawPaint_Vulkan.png
impeller_Play_DlGoldenTest_CanRenderImage_Metal.png
impeller_Play_DlGoldenTest_CanRenderImage_OpenGLES.png
impeller_Play_DlGoldenTest_CanRenderImage_Vulkan.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlurScaledRotated_Metal.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlurScaledRotated_OpenGLES.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlurScaledRotated_Vulkan.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlurScaled_Metal.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlurScaled_OpenGLES.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlurScaled_Vulkan.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_Metal.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_OpenGLES.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_Vulkan.png