Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Reland: [Impeller] Turned on new blur. (#48472) #49642

Merged
merged 11 commits into from
Jan 18, 2024
34 changes: 26 additions & 8 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3758,10 +3758,13 @@ TEST_P(AiksTest, GaussianBlurSetsMipCountOnPass) {
canvas.Restore();

Picture picture = canvas.EndRecordingAsPicture();
EXPECT_EQ(1, picture.pass->GetRequiredMipCount());
EXPECT_EQ(4, picture.pass->GetRequiredMipCount());
}

TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) {
size_t blur_required_mip_count =
GetParam() == PlaygroundBackend::kMetal ? 4 : 1;

Canvas canvas;
canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
canvas.SaveLayer({}, std::nullopt,
Expand All @@ -3782,11 +3785,14 @@ TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) {
max_mip_count =
std::max(it->texture->GetTextureDescriptor().mip_count, max_mip_count);
}
EXPECT_EQ(max_mip_count, 1lu);
EXPECT_EQ(max_mip_count, blur_required_mip_count);
}

TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) {
fml::testing::LogCapture log_capture;
size_t blur_required_mip_count =
GetParam() == PlaygroundBackend::kMetal ? 4 : 1;

Canvas canvas;
canvas.DrawPaint({.color = Color::Wheat()});
canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
Expand All @@ -3809,12 +3815,19 @@ TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) {
max_mip_count =
std::max(it->texture->GetTextureDescriptor().mip_count, max_mip_count);
}
EXPECT_EQ(max_mip_count, 1lu);
EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
EXPECT_EQ(max_mip_count, blur_required_mip_count);
if (GetParam() == PlaygroundBackend::kMetal) {
EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
} else {
EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
}
}

TEST_P(AiksTest, GaussianBlurMipMapImageFilter) {
size_t blur_required_mip_count =
GetParam() == PlaygroundBackend::kMetal ? 4 : 1;
fml::testing::LogCapture log_capture;
Canvas canvas;
canvas.SaveLayer(
Expand All @@ -3835,9 +3848,14 @@ TEST_P(AiksTest, GaussianBlurMipMapImageFilter) {
max_mip_count =
std::max(it->texture->GetTextureDescriptor().mip_count, max_mip_count);
}
EXPECT_EQ(max_mip_count, 1lu);
EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
EXPECT_EQ(max_mip_count, blur_required_mip_count);
if (GetParam() == PlaygroundBackend::kMetal) {
EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
} else {
EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
}
}

} // namespace testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ namespace impeller {
/// - `FilterContents::MakeGaussianBlur`
/// - //flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur.glsl
///
///\deprecated Previously 2 of these were chained to do 2D blurs, use
/// \ref GaussianBlurFilterContents instead since it has better
/// performance.
class DirectionalGaussianBlurFilterContents final : public FilterContents {
public:
DirectionalGaussianBlurFilterContents();
Expand Down
40 changes: 4 additions & 36 deletions impeller/entity/contents/filters/filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,50 +50,18 @@ std::shared_ptr<FilterContents> FilterContents::MakeDirectionalGaussianBlur(
return blur;
}

#ifdef IMPELLER_ENABLE_NEW_GAUSSIAN_FILTER
const int32_t FilterContents::kBlurFilterRequiredMipCount = 4;
#else
const int32_t FilterContents::kBlurFilterRequiredMipCount = 1;
#endif

std::shared_ptr<FilterContents> FilterContents::MakeGaussianBlur(
const FilterInput::Ref& input,
Sigma sigma_x,
Sigma sigma_y,
BlurStyle blur_style,
Entity::TileMode tile_mode) {
constexpr bool use_new_filter =
#ifdef IMPELLER_ENABLE_NEW_GAUSSIAN_FILTER
true;
#else
false;
#endif

// TODO(https://github.com/flutter/flutter/issues/131580): Remove once the new
// blur handles all cases.
if (use_new_filter) {
auto blur = std::make_shared<GaussianBlurFilterContents>(
sigma_x.sigma, sigma_y.sigma, tile_mode);
blur->SetInputs({input});
return blur;
}
std::shared_ptr<FilterContents> x_blur = MakeDirectionalGaussianBlur(
/*input=*/input,
/*sigma=*/sigma_x,
/*direction=*/Point(1, 0),
/*blur_style=*/BlurStyle::kNormal,
/*tile_mode=*/tile_mode,
/*is_second_pass=*/false,
/*secondary_sigma=*/{});
std::shared_ptr<FilterContents> y_blur = MakeDirectionalGaussianBlur(
/*input=*/FilterInput::Make(x_blur),
/*sigma=*/sigma_y,
/*direction=*/Point(0, 1),
/*blur_style=*/blur_style,
/*tile_mode=*/tile_mode,
/*is_second_pass=*/true,
/*secondary_sigma=*/sigma_x);
return y_blur;
auto blur = std::make_shared<GaussianBlurFilterContents>(
sigma_x.sigma, sigma_y.sigma, tile_mode);
blur->SetInputs({input});
return blur;
}

std::shared_ptr<FilterContents> FilterContents::MakeBorderMaskBlur(
Expand Down
8 changes: 8 additions & 0 deletions impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,14 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
/// What's important is the `StorageMode` of the textures, which cannot be
/// changed for the lifetime of the textures.

if (context->GetBackendType() != Context::BackendType::kMetal) {
// TODO(https://github.com/flutter/flutter/issues/141495): Implement mip map
// generation on vulkan.
// TODO(https://github.com/flutter/flutter/issues/141732): Implement mip map
// generation on opengles.
mip_count = 1;
}

RenderTarget target;
if (context->GetCapabilities()->SupportsOffscreenMSAA()) {
target = RenderTarget::CreateOffscreenMSAA(
Expand Down