Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
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 std::shared_ptr< Geometry > &mask_geometry)
 
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. More...
 
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. 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< EntityGetEntity (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< RectGetCoverage (const Entity &entity) const override
 Get the area of the render pass that will be affected when this contents is rendered. More...
 
void PopulateGlyphAtlas (const std::shared_ptr< LazyGlyphAtlas > &lazy_glyph_atlas, Scalar scale) override
 Add any text data to the specified lazy atlas. The scale parameter must be used again later when drawing the text. More...
 
std::optional< SnapshotRenderToSnapshot (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, const std::string &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...
 
const FilterContentsAsFilter () const override
 Cast to a filter. Returns nullptr if this Contents is not a filter. More...
 
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. More...
 
virtual Matrix GetLocalTransform (const Matrix &parent_transform) const
 
Matrix GetTransform (const Matrix &parent_transform) const
 
virtual bool IsTranslationOnly () const
 Returns true if this filter graph doesn't perform any basis transforms to the filtered content. For example: Rotating, scaling, and skewing are all basis transforms, but translating is not. More...
 
bool IsLeaf () const
 Returns true if this filter does not have any FilterInput children. More...
 
void SetLeafInputs (const FilterInput::Vector &inputs)
 Replaces the set of all leaf FilterContents with a new set of FilterInputs. More...
 
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 ()
 
virtual void PopulateGlyphAtlas (const std::shared_ptr< LazyGlyphAtlas > &lazy_glyph_atlas, Scalar scale)
 Add any text data to the specified lazy atlas. The scale parameter must be used again later when drawing the text. More...
 
virtual bool Render (const ContentContext &renderer, const Entity &entity, RenderPass &pass) const =0
 
virtual std::optional< RectGetCoverage (const Entity &entity) const =0
 Get the area of the render pass that will be affected when this contents is rendered. More...
 
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
 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...
 
virtual ClipCoverage GetClipCoverage (const Entity &entity, const std::optional< Rect > &current_clip_coverage) const
 Given the current pass space bounding rectangle of the clip buffer, return the expected clip coverage after this draw call. This should only be implemented for contents that may write to the clip buffer. More...
 
virtual std::optional< SnapshotRenderToSnapshot (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, const std::string &label="Snapshot") const
 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...
 
virtual bool ShouldRender (const Entity &entity, const std::optional< Rect > clip_coverage) const
 
std::optional< SizeGetColorSourceSize () const
 Return the color source's intrinsic size, if available. More...
 
void SetColorSourceSize (Size size)
 
virtual bool CanInheritOpacity (const Entity &entity) const
 Whether or not this contents can accept the opacity peephole optimization. More...
 
virtual void SetInheritedOpacity (Scalar opacity)
 Inherit the provided opacity. More...
 
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. More...
 
virtual const FilterContentsAsFilter () const
 Cast to a filter. Returns nullptr if this Contents is not a filter. 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< 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 std::shared_ptr< 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 Public Member Functions inherited from impeller::Contents
static std::shared_ptr< ContentsMakeAnonymous (RenderProc render_proc, CoverageProc coverage_proc)
 

Static Public Attributes

static std::string_view kNoMipsError
 
static const int32_t kBlurFilterRequiredMipCount = 4
 
- Static Public Attributes inherited from impeller::FilterContents
static const int32_t kBlurFilterRequiredMipCount
 

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)>
 

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 34 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 std::shared_ptr< Geometry > &  mask_geometry 
)
explicit

Definition at line 303 of file gaussian_blur_filter_contents.cc.

309 : sigma_x_(sigma_x),
310 sigma_y_(sigma_y),
311 tile_mode_(tile_mode),
312 mask_blur_style_(mask_blur_style),
313 mask_geometry_(mask_geometry) {
314 // This is supposed to be enforced at a higher level.
315 FML_DCHECK(mask_blur_style == BlurStyle::kNormal || mask_geometry);
316}
@ kNormal
Blurred inside and outside.
#define FML_DCHECK(condition)
Definition: logging.h:103

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

612 {
613 return static_cast<Radius>(Sigma(sigma)).radius;
614}

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

321 {
322 if (sigma <= 4) {
323 return 1.0;
324 }
325 Scalar raw_result = 4.0 / sigma;
326 // Round to the nearest 1/(2^n) to get the best quality down scaling.
327 Scalar exponent = round(log2f(raw_result));
328 // Don't scale down below 1/16th to preserve signal.
329 exponent = std::max(-4.0f, exponent);
330 Scalar rounded = powf(2.0f, exponent);
331 Scalar result = rounded;
332 // Extend the range of the 1/8th downsample based on the effective kernel size
333 // for the blur.
334 if (rounded < 0.125f) {
335 Scalar rounded_plus = powf(2.0f, exponent + 1);
336 Scalar blur_radius = CalculateBlurRadius(sigma);
337 int kernel_size_plus = (ScaleBlurRadius(blur_radius, rounded_plus) * 2) + 1;
338 // This constant was picked by looking at the results to make sure no
339 // shimmering was introduced at the highest sigma values that downscale to
340 // 1/16th.
341 static constexpr int32_t kEighthDownsampleKernalWidthMax = 41;
342 result = kernel_size_plus <= kEighthDownsampleKernalWidthMax ? rounded_plus
343 : rounded;
344 }
345 return result;
346};
static void round(SkPoint *p)
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49
float Scalar
Definition: scalar.h:18

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

620 {
621 Matrix input_transform = filter_input->GetLocalTransform(entity);
622 Quad coverage_quad = source_rect.GetTransformedPoints(input_transform);
623
624 Matrix uv_transform = Matrix::MakeScale(
625 {1.0f / texture_size.width, 1.0f / texture_size.height, 1.0f});
626 return uv_transform.Transform(coverage_quad);
627}
std::array< Point, 4 > Quad
Definition: point.h:327
SK_API sk_sp< PrecompileColorFilter > Matrix()
constexpr Quad Transform(const Quad &quad) const
Definition: matrix.h:487
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104

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

370 {
371 if (inputs.empty()) {
372 return {};
373 }
374 std::optional<Rect> input_coverage = inputs[0]->GetCoverage(entity);
375 if (!input_coverage.has_value()) {
376 return {};
377 }
378
379 const Vector2 source_space_scalar =
380 ExtractScale(entity.GetTransform().Basis());
381 Vector2 scaled_sigma = (Matrix::MakeScale(source_space_scalar) *
382 Vector2(ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)))
383 .Abs();
384 scaled_sigma.x = std::min(scaled_sigma.x, kMaxSigma);
385 scaled_sigma.y = std::min(scaled_sigma.y, kMaxSigma);
386 Vector2 blur_radius = Vector2(CalculateBlurRadius(scaled_sigma.x),
387 CalculateBlurRadius(scaled_sigma.y));
388 Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y));
389 Vector2 local_padding =
390 (Matrix::MakeScale(source_space_scalar) * padding).Abs();
391 return input_coverage.value().Expand(Point(local_padding.x, local_padding.y));
392}
static float min(float r, float g, float b)
Definition: hsl.cpp:48
Point Vector2
Definition: point.h:326
TPoint< Scalar > Point
Definition: point.h:322
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition: SkVx.h:702

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

350 {
351 Vector2 scaled_sigma = {ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)};
352 Vector2 blur_radius = {CalculateBlurRadius(scaled_sigma.x),
353 CalculateBlurRadius(scaled_sigma.y)};
354 Vector3 blur_radii =
355 effect_transform.Basis() * Vector3{blur_radius.x, blur_radius.y, 0.0};
356 return output_limit.Expand(Point(blur_radii.x, blur_radii.y));
357}

◆ GetSigmaX()

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

Definition at line 46 of file gaussian_blur_filter_contents.h.

46{ return sigma_x_; }

◆ GetSigmaY()

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

Definition at line 47 of file gaussian_blur_filter_contents.h.

47{ return sigma_y_; }

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

632 {
633 // Limit the kernel size to 1000x1000 pixels, like Skia does.
634 Scalar clamped = std::min(sigma, kMaxSigma);
635 constexpr Scalar a = 3.4e-06;
636 constexpr Scalar b = -3.4e-3;
637 constexpr Scalar c = 1.f;
638 Scalar scalar = c + b * clamped + a * clamped * clamped;
639 return clamped * scalar;
640}
static bool b
struct MyStruct a[10]

Member Data Documentation

◆ kBlurFilterRequiredMipCount

const int32_t impeller::GaussianBlurFilterContents::kBlurFilterRequiredMipCount = 4
static

Definition at line 37 of file gaussian_blur_filter_contents.h.

◆ kNoMipsError

std::string_view impeller::GaussianBlurFilterContents::kNoMipsError
static
Initial value:
=
"Applying gaussian blur without mipmap."

Definition at line 36 of file gaussian_blur_filter_contents.h.


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