| Flutter Impeller |

Public Member Functions | Static Public Member Functions | List of all members
impeller::GaussianBlurFilterContents Class Referencefinal

`#include <gaussian_blur_filter_contents.h>`

Inheritance diagram for impeller::GaussianBlurFilterContents:

## Public Member Functions
| GaussianBlurFilterContents (Scalar sigma_x, Scalar sigma_y, Entity::TileMode tile_mode, BlurStyle mask_blur_style, const Geometry *mask_geometry=nullptr)
Scalar | GetSigmaX () const
Scalar | GetSigmaY () const
std::optional< Rect > | GetFilterSourceCoverage (const Matrix &effect_transform, const Rect &output_limit) const override
| Internal utility method for |GetSourceCoverage| that computes the inverse effect of this transform on the specified output coverage, ignoring the inputs which will be accommodated by the caller. More...
std::optional< Rect > | GetFilterCoverage (const FilterInput::Vector &inputs, const Entity &entity, const Matrix &effect_transform) const override
| Internal utility method for |GetLocalCoverage| that computes the output coverage of this filter across the specified inputs, ignoring the coverage hint. More...
Public Member Functions inherited from impeller::FilterContents
| FilterContents ()
| ~FilterContents () override
void | SetInputs (FilterInput::Vector inputs)
| The input texture sources for this filter. Each input's emitted texture is expected to have premultiplied alpha colors. More...
void | SetEffectTransform (const Matrix &effect_transform)
| Sets the transform which gets appended to the effect of this filter. Note that this is in addition to the entity's transform. More...
std::optional< Entity > | GetEntity (const ContentContext &renderer, const Entity &entity, const std::optional< Rect > &coverage_hint) const
| Create an Entity that renders this filter's output. More...
bool | Render (const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
std::optional< Rect > | GetCoverage (const Entity &entity) const override
| Get the area of the render pass that will be affected when this contents is rendered. More...
std::optional< Snapshot > | RenderToSnapshot (const ContentContext &renderer, const Entity &entity, std::optional< Rect > coverage_limit=std::nullopt, const std::optional< SamplerDescriptor > &sampler_descriptor=std::nullopt, bool msaa_enabled=true, int32_t mip_count=1, std::string_view label="Filter Snapshot") const override
| Render this contents to a snapshot, respecting the entity's transform, path, clip depth, and blend mode. The result texture size is always the size of `GetCoverage(entity)`. More...
std::optional< Rect > | GetSourceCoverage (const Matrix &effect_transform, const Rect &output_limit) const
| Determines the coverage of source pixels that will be needed to produce results for the specified |output_limit| under the specified |effect_transform|. This is essentially a reverse of the |GetCoverage| method computing a source coverage from an intended |output_limit| coverage. More...
virtual Matrix | GetLocalTransform (const Matrix &parent_transform) const
Matrix | GetTransform (const Matrix &parent_transform) const
virtual void | SetRenderingMode (Entity::RenderingMode rendering_mode)
| Marks this filter chain as applying in a subpass scenario. More...
Public Member Functions inherited from impeller::Contents
| Contents ()
virtual | ~Contents ()
void | SetCoverageHint (std::optional< Rect > coverage_hint)
| Hint that specifies the coverage area of this Contents that will actually be used during rendering. This is for optimization purposes only and can not be relied on as a clip. May optionally affect the result of `GetCoverage()`. More...
const std::optional< Rect > & | GetCoverageHint () const
virtual bool | IsOpaque (const Matrix &transform) const
| Whether this Contents only emits opaque source colors from the fragment stage. This value does not account for any entity properties (e.g. the blend mode), clips/visibility culling, or inherited opacity. More...
std::optional< Size > | GetColorSourceSize () const
| Return the color source's intrinsic size, if available. More...
void | SetColorSourceSize (Size size)
virtual void | SetInheritedOpacity (Scalar opacity)
| Inherit the provided opacity. More...
virtual std::optional< Color > | AsBackgroundColor (const Entity &entity, ISize target_size) const
| Returns a color if this Contents will flood the given `target_size` with a color. This output color is the "Source" color that will be used for the Entity's blend operation. More...
virtual bool | ApplyColorFilter (const ColorFilterProc &color_filter_proc)
| If possible, applies a color filter to this contents inputs on the CPU. More...

## Static Public Member Functions
static Scalar | CalculateBlurRadius (Scalar sigma)
static Quad | CalculateUVs (const std::shared_ptr< FilterInput > &filter_input, const Entity &entity, const Rect &source_rect, const ISize &texture_size)
static Scalar | CalculateScale (Scalar sigma)
static Scalar | ScaleSigma (Scalar sigma)
Static Public Member Functions inherited from impeller::FilterContents
static std::shared_ptr< FilterContents > | MakeGaussianBlur (const FilterInput::Ref &input, Sigma sigma_x, Sigma sigma_y, Entity::TileMode tile_mode=Entity::TileMode::kDecal, BlurStyle mask_blur_style=BlurStyle::kNormal, const Geometry *mask_geometry=nullptr)
static std::shared_ptr< FilterContents > | MakeBorderMaskBlur (FilterInput::Ref input, Sigma sigma_x, Sigma sigma_y, BlurStyle blur_style=BlurStyle::kNormal)
static std::shared_ptr< FilterContents > | MakeDirectionalMorphology (FilterInput::Ref input, Radius radius, Vector2 direction, MorphType morph_type)
static std::shared_ptr< FilterContents > | MakeMorphology (FilterInput::Ref input, Radius radius_x, Radius radius_y, MorphType morph_type)
static std::shared_ptr< FilterContents > | MakeMatrixFilter (FilterInput::Ref input, const Matrix &matrix, const SamplerDescriptor &desc)
static std::shared_ptr< FilterContents > | MakeLocalMatrixFilter (FilterInput::Ref input, const Matrix &matrix)
static std::shared_ptr< FilterContents > | MakeYUVToRGBFilter (std::shared_ptr< Texture > y_texture, std::shared_ptr< Texture > uv_texture, YUVColorSpace yuv_color_space)
static std::shared_ptr< FilterContents > | MakeRuntimeEffect (FilterInput::Ref input, std::shared_ptr< RuntimeStage > runtime_stage, std::shared_ptr< std::vector< uint8_t >> uniforms, std::vector< RuntimeEffectContents::TextureInput > texture_inputs)
Static Public Member Functions inherited from impeller::Contents
static std::shared_ptr< Contents > | MakeAnonymous (RenderProc render_proc, CoverageProc coverage_proc)

## Additional Inherited Members
Public Types inherited from impeller::FilterContents
enum class | BlurStyle { kNormal , kSolid , kOuter , kInner }
enum class | MorphType { kDilate , kErode }
Public Types inherited from impeller::Contents
using | ColorFilterProc = std::function< Color(Color)>
using | RenderProc = std::function< bool(const ContentContext &renderer, const Entity &entity, RenderPass &pass)>
using | CoverageProc = std::function< std::optional< Rect >(const Entity &entity)>
Static Public Attributes inherited from impeller::FilterContents
static const int32_t | kBlurFilterRequiredMipCount

## Detailed Description

Performs a bidirectional Gaussian blur.

This is accomplished by rendering multiple passes in multiple directions. Note: This will replace `DirectionalGaussianBlurFilterContents`.

Definition at line 56 of file gaussian_blur_filter_contents.h.

## Constructor & Destructor Documentation

## ◆ GaussianBlurFilterContents()

impeller::GaussianBlurFilterContents::GaussianBlurFilterContents | ( | Scalar | sigma_x,
|  | Scalar | sigma_y,
|  | Entity::TileMode | tile_mode,
|  | BlurStyle | mask_blur_style,
|  | const Geometry * | mask_geometry = `nullptr`
| ) |  |
| explicit

Definition at line 626 of file gaussian_blur_filter_contents.cc.

632 : sigma_(sigma_x, sigma_y),
633 tile_mode_(tile_mode),
634 mask_blur_style_(mask_blur_style),
635 mask_geometry_(mask_geometry) {
636 // This is supposed to be enforced at a higher level.
637 FML_DCHECK(mask_blur_style == BlurStyle::kNormal || mask_geometry);
638 }
impeller::FilterContents::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.

References impeller::FilterContents::kNormal.

## Member Function Documentation

## ◆ CalculateBlurRadius()

Scalar impeller::GaussianBlurFilterContents::CalculateBlurRadius | ( | Scalar | sigma | ) |
| static

Given a sigma (standard deviation) calculate the blur radius (1/2 the kernel size).

Definition at line 877 of file gaussian_blur_filter_contents.cc.

877 {
878 return static_cast<Radius>(Sigma(sigma)).radius;
879 }

Referenced by CalculateScale(), GetFilterSourceCoverage(), and impeller::testing::TEST().

## ◆ CalculateScale()

Scalar impeller::GaussianBlurFilterContents::CalculateScale | ( | Scalar | sigma | ) |
| static

Calculate the scale factor for the downsample pass given a sigma value.

Visible for testing.

Definition at line 643 of file gaussian_blur_filter_contents.cc.

643 {
644 if (sigma <= 4) {
645 return 1.0;
646 }
647 Scalar raw_result = 4.0 / sigma;
648 // Round to the nearest 1/(2^n) to get the best quality down scaling.
649 Scalar exponent = round(log2f(raw_result));
650 // Don't scale down below 1/16th to preserve signal.
651 exponent = std::max(-4.0f, exponent);
652 Scalar rounded = powf(2.0f, exponent);
653 Scalar result = rounded;
654 // Extend the range of the 1/8th downsample based on the effective kernel size
655 // for the blur.
656 if (rounded < 0.125f) {
657 Scalar rounded_plus = powf(2.0f, exponent + 1);
658 Scalar blur_radius = CalculateBlurRadius(sigma);
659 int kernel_size_plus = (ScaleBlurRadius(blur_radius, rounded_plus) * 2) + 1;
660 // This constant was picked by looking at the results to make sure no
661 // shimmering was introduced at the highest sigma values that downscale to
662 // 1/16th.
663 static constexpr int32_t kEighthDownsampleKernalWidthMax = 41;
664 result = kernel_size_plus <= kEighthDownsampleKernalWidthMax ? rounded_plus
665 : rounded;
666 }
667 return result;
668 };
impeller::GaussianBlurFilterContents::CalculateBlurRadius
static Scalar CalculateBlurRadius(Scalar sigma)
Definition: gaussian_blur_filter_contents.cc:877
blur_radius
Vector2 blur_radius
Blur radius in source pixels based on scaled_sigma.
Definition: gaussian_blur_filter_contents.cc:84
impeller::Scalar
float Scalar
Definition: scalar.h:18

References blur_radius, and CalculateBlurRadius().

Referenced by impeller::testing::TEST().

## ◆ CalculateUVs()

Quad impeller::GaussianBlurFilterContents::CalculateUVs | ( | const std::shared_ptr< FilterInput > & | filter_input,
|  | const Entity & | entity,
|  | const Rect & | source_rect,
|  | const ISize & | texture_size
| ) |  |
| static

Calculate the UV coordinates for rendering the filter_input.

Parameters

  filter_input | The FilterInput that should be rendered.
  entity | The associated entity for the filter_input.
  source_rect | The rect in source coordinates to convert to uvs.
  texture_size | The rect to convert in source coordinates.

Definition at line 881 of file gaussian_blur_filter_contents.cc.

885 {
886 Matrix input_transform = filter_input->GetLocalTransform(entity);
887 Quad coverage_quad = source_rect.GetTransformedPoints(input_transform);
888
889 Matrix uv_transform = Matrix::MakeScale(
890 {1.0f / texture_size.width, 1.0f / texture_size.height, 1.0f});
891 return uv_transform.Transform(coverage_quad);
892 }
impeller::Quad
std::array< Point, 4 > Quad
Definition: point.h:332
impeller::Matrix::Transform
constexpr Quad Transform(const Quad &quad) const
Definition: matrix.h:543
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104

References impeller::TRect< T >::GetTransformedPoints(), impeller::TSize< T >::height, impeller::Matrix::MakeScale(), impeller::Matrix::Transform(), and impeller::TSize< T >::width.

Referenced by impeller::testing::TEST_P().

## ◆ GetFilterCoverage()

std::optional< Rect > impeller::GaussianBlurFilterContents::GetFilterCoverage | ( | const FilterInput::Vector & | inputs,
|  | const Entity & | entity,
|  | const Matrix & | effect_transform
| ) |  | const
| override virtual

Internal utility method for |GetLocalCoverage| that computes the output coverage of this filter across the specified inputs, ignoring the coverage hint.

Reimplemented from impeller::FilterContents.

Definition at line 681 of file gaussian_blur_filter_contents.cc.

684 {
685 if (inputs.empty()) {
686 return {};
687 }
688 std::optional<Rect> input_coverage = inputs[0]->GetCoverage(entity);
689 if (!input_coverage.has_value()) {
690 return {};
691 }
692
693 BlurInfo blur_info = CalculateBlurInfo(entity, effect_transform, sigma_);
694 return input_coverage.value().Expand(
695 Point(blur_info.local_padding.x, blur_info.local_padding.y));
696 }
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327

Referenced by impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ GetFilterSourceCoverage()

std::optional< Rect > impeller::GaussianBlurFilterContents::GetFilterSourceCoverage | ( | const Matrix & | effect_transform,
|  | const Rect & | output_limit
| ) |  | const
| override virtual

Internal utility method for |GetSourceCoverage| that computes the inverse effect of this transform on the specified output coverage, ignoring the inputs which will be accommodated by the caller.

Implements impeller::FilterContents.

Definition at line 670 of file gaussian_blur_filter_contents.cc.

672 {
673 Vector2 scaled_sigma = {ScaleSigma(sigma_.x), ScaleSigma(sigma_.y)};
674 Vector2 blur_radius = {CalculateBlurRadius(scaled_sigma.x),
675 CalculateBlurRadius(scaled_sigma.y)};
676 Vector3 blur_radii =
677 effect_transform.Basis() * Vector3{blur_radius.x, blur_radius.y, 0.0};
678 return output_limit.Expand(Point(blur_radii.x, blur_radii.y));
679 }
impeller::GaussianBlurFilterContents::ScaleSigma
static Scalar ScaleSigma(Scalar sigma)
Definition: gaussian_blur_filter_contents.cc:897
scaled_sigma
Vector2 scaled_sigma
Sigma when considering an entity's scale and the effect transform.
Definition: gaussian_blur_filter_contents.cc:82
impeller::Vector2
Point Vector2
Definition: point.h:331
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::TPoint::x
Type x
Definition: point.h:30

References impeller::Matrix::Basis(), blur_radius, CalculateBlurRadius(), impeller::TRect< T >::Expand(), scaled_sigma, ScaleSigma(), impeller::TPoint< T >::x, impeller::Vector3::x, impeller::TPoint< T >::y, and impeller::Vector3::y.

## ◆ GetSigmaX()

Scalar impeller::GaussianBlurFilterContents::GetSigmaX | ( |  | ) | const
| inline

Definition at line 64 of file gaussian_blur_filter_contents.h.

64 { return sigma_.x; }

References impeller::TPoint< T >::x.

Referenced by impeller::testing::TEST().

## ◆ GetSigmaY()

Scalar impeller::GaussianBlurFilterContents::GetSigmaY | ( |  | ) | const
| inline

Definition at line 65 of file gaussian_blur_filter_contents.h.

65 { return sigma_.y; }

References impeller::TPoint< T >::y.

Referenced by impeller::testing::TEST().

## ◆ ScaleSigma()

Scalar impeller::GaussianBlurFilterContents::ScaleSigma | ( | Scalar | sigma | ) |
| static

Scales down the sigma value to match Skia's behavior.

effective_blur_radius = CalculateBlurRadius(ScaleSigma(sigma_));

This function was calculated by observing Skia's behavior. Its blur at 500 seemed to be 0.15. Since we clamp at 500 I solved the quadratic equation that puts the minima there and a f(0)=1.

Definition at line 897 of file gaussian_blur_filter_contents.cc.

897 {
898 // Limit the kernel size to 1000x1000 pixels, like Skia does.
899 Scalar clamped = std::min(sigma, kMaxSigma);
900 constexpr Scalar a = 3.4e-06;
901 constexpr Scalar b = -3.4e-3;
902 constexpr Scalar c = 1.f;
903 Scalar scalar = c + b * clamped + a * clamped * clamped;
904 return clamped * scalar;
905 }
impeller::saturated::b
SI b
Definition: saturated_math.h:87

References impeller::saturated::b.

Referenced by GetFilterSourceCoverage(), and impeller::testing::TEST().

The documentation for this class was generated from the following files:

- impeller/entity/contents/filters/gaussian_blur_filter_contents.h
- impeller/entity/contents/filters/gaussian_blur_filter_contents.cc