Flutter Engine
 
Loading...
Searching...
No Matches
impeller::GaussianBlurFilterContents Class Referencefinal

#include <gaussian_blur_filter_contents.h>

Inheritance diagram for impeller::GaussianBlurFilterContents:
impeller::FilterContents impeller::Contents

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< RectGetFilterSourceCoverage (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.
 
std::optional< RectGetFilterCoverage (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.
 
- 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.
 
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.
 
std::optional< EntityGetEntity (const ContentContext &renderer, const Entity &entity, const std::optional< Rect > &coverage_hint) const
 Create an Entity that renders this filter's output.
 
bool Render (const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
 
std::optional< RectGetCoverage (const Entity &entity) const override
 Get the area of the render pass that will be affected when this contents is rendered.
 
std::optional< SnapshotRenderToSnapshot (const ContentContext &renderer, const Entity &entity, const SnapshotOptions &options) 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).
 
std::optional< RectGetSourceCoverage (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.
 
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.
 
- 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().
 
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.
 
std::optional< SizeGetColorSourceSize () const
 Return the color source's intrinsic size, if available.
 
void SetColorSourceSize (Size size)
 
virtual void SetInheritedOpacity (Scalar opacity)
 Inherit the provided opacity.
 
virtual std::optional< ColorAsBackgroundColor (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.
 
virtual bool ApplyColorFilter (const ColorFilterProc &color_filter_proc)
 If possible, applies a color filter to this contents inputs on the CPU.
 

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< FilterContentsMakeGaussianBlur (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< FilterContentsMakeBorderMaskBlur (FilterInput::Ref input, Sigma sigma_x, Sigma sigma_y, BlurStyle blur_style=BlurStyle::kNormal)
 
static std::shared_ptr< FilterContentsMakeDirectionalMorphology (FilterInput::Ref input, Radius radius, Vector2 direction, MorphType morph_type)
 
static std::shared_ptr< FilterContentsMakeMorphology (FilterInput::Ref input, Radius radius_x, Radius radius_y, MorphType morph_type)
 
static std::shared_ptr< FilterContentsMakeMatrixFilter (FilterInput::Ref input, const Matrix &matrix, const SamplerDescriptor &desc)
 
static std::shared_ptr< FilterContentsMakeLocalMatrixFilter (FilterInput::Ref input, const Matrix &matrix)
 
static std::shared_ptr< FilterContentsMakeYUVToRGBFilter (std::shared_ptr< Texture > y_texture, std::shared_ptr< Texture > uv_texture, YUVColorSpace yuv_color_space)
 
static std::shared_ptr< FilterContentsMakeRuntimeEffect (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< ContentsMakeAnonymous (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 631 of file gaussian_blur_filter_contents.cc.

637 : sigma_(sigma_x, sigma_y),
638 tile_mode_(tile_mode),
639 mask_blur_style_(mask_blur_style),
640 mask_geometry_(mask_geometry) {
641 // This is supposed to be enforced at a higher level.
642 FML_DCHECK(mask_blur_style == BlurStyle::kNormal || mask_geometry);
643}
@ kNormal
Blurred inside and outside.
#define FML_DCHECK(condition)
Definition logging.h:122

References FML_DCHECK, and 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 882 of file gaussian_blur_filter_contents.cc.

882 {
883 return static_cast<Radius>(Sigma(sigma)).radius;
884}

Referenced by CalculateScale(), GetFilterSourceCoverage(), impeller::testing::TEST(), impeller::testing::TEST(), 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 648 of file gaussian_blur_filter_contents.cc.

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

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_inputThe FilterInput that should be rendered.
entityThe associated entity for the filter_input.
source_rectThe rect in source coordinates to convert to uvs.
texture_sizeThe rect to convert in source coordinates.

Definition at line 886 of file gaussian_blur_filter_contents.cc.

890 {
891 Matrix input_transform = filter_input->GetLocalTransform(entity);
892 Quad coverage_quad = source_rect.GetTransformedPoints(input_transform);
893
894 Matrix uv_transform = Matrix::MakeScale(
895 {1.0f / texture_size.width, 1.0f / texture_size.height, 1.0f});
896 return uv_transform.Transform(coverage_quad);
897}
std::array< Point, 4 > Quad
Definition point.h:332
constexpr Quad Transform(const Quad &quad) const
Definition matrix.h:623
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
overridevirtual

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 686 of file gaussian_blur_filter_contents.cc.

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

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

◆ GetFilterSourceCoverage()

std::optional< Rect > impeller::GaussianBlurFilterContents::GetFilterSourceCoverage ( const Matrix effect_transform,
const Rect output_limit 
) const
overridevirtual

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 675 of file gaussian_blur_filter_contents.cc.

677 {
678 Vector2 scaled_sigma = {ScaleSigma(sigma_.x), ScaleSigma(sigma_.y)};
681 Vector3 blur_radii =
682 effect_transform.Basis() * Vector3{blur_radius.x, blur_radius.y, 0.0};
683 return output_limit.Expand(Point(blur_radii.x, blur_radii.y));
684}
Vector2 scaled_sigma
Sigma when considering an entity's scale and the effect transform.
Point Vector2
Definition point.h:331

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 902 of file gaussian_blur_filter_contents.cc.

902 {
903 // Limit the kernel size to 1000x1000 pixels, like Skia does.
904 Scalar clamped = std::min(sigma, kMaxSigma);
905 constexpr Scalar a = 3.4e-06;
906 constexpr Scalar b = -3.4e-3;
907 constexpr Scalar c = 1.f;
908 Scalar scalar = c + b * clamped + a * clamped * clamped;
909 return clamped * scalar;
910}

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


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