Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions | 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.
 
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.
 
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.
 
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).
 
const FilterContentsAsFilter () const override
 Cast to a filter. Returns nullptr if this Contents is not a filter.
 
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 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.
 
bool IsLeaf () const
 Returns true if this filter does not have any FilterInput children.
 
void SetLeafInputs (const FilterInput::Vector &inputs)
 Replaces the set of all leaf FilterContents with a new set of FilterInputs.
 
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
 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.
 
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.
 
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.
 
void SetColorSourceSize (Size size)
 
virtual bool CanInheritOpacity (const Entity &entity) const
 Whether or not this contents can accept the opacity peephole optimization.
 
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 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
 

Private Member Functions

std::optional< EntityRenderFilter (const FilterInput::Vector &input_textures, const ContentContext &renderer, const Entity &entity, const Matrix &effect_transform, const Rect &coverage, const std::optional< Rect > &coverage_hint) const override
 Converts zero or more filter inputs into a render instruction.
 

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

303 : sigma_x_(sigma_x),
304 sigma_y_(sigma_y),
305 tile_mode_(tile_mode),
306 mask_blur_style_(mask_blur_style),
307 mask_geometry_(mask_geometry) {
308 // This is supposed to be enforced at a higher level.
309 FML_DCHECK(mask_blur_style == BlurStyle::kNormal || mask_geometry);
310}
@ 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 563 of file gaussian_blur_filter_contents.cc.

563 {
564 return static_cast<Radius>(Sigma(sigma)).radius;
565}

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

315 {
316 if (sigma <= 4) {
317 return 1.0;
318 }
319 Scalar raw_result = 4.0 / sigma;
320 // Round to the nearest 1/(2^n) to get the best quality down scaling.
321 Scalar exponent = round(log2f(raw_result));
322 // Don't scale down below 1/16th to preserve signal.
323 exponent = std::max(-4.0f, exponent);
324 Scalar rounded = powf(2.0f, exponent);
325 Scalar result = rounded;
326 // Extend the range of the 1/8th downsample based on the effective kernel size
327 // for the blur.
328 if (rounded < 0.125f) {
329 Scalar rounded_plus = powf(2.0f, exponent + 1);
330 Scalar blur_radius = CalculateBlurRadius(sigma);
331 int kernel_size_plus = (ScaleBlurRadius(blur_radius, rounded_plus) * 2) + 1;
332 // This constant was picked by looking at the results to make sure no
333 // shimmering was introduced at the highest sigma values that downscale to
334 // 1/16th.
335 static constexpr int32_t kEighthDownsampleKernalWidthMax = 41;
336 result = kernel_size_plus <= kEighthDownsampleKernalWidthMax ? rounded_plus
337 : rounded;
338 }
339 return result;
340};
static void round(SkPoint *p)
GAsyncResult * result
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 567 of file gaussian_blur_filter_contents.cc.

571 {
572 Matrix input_transform = filter_input->GetLocalTransform(entity);
573 Quad coverage_quad = source_rect.GetTransformedPoints(input_transform);
574
575 Matrix uv_transform = Matrix::MakeScale(
576 {1.0f / texture_size.width, 1.0f / texture_size.height, 1.0f});
577 return uv_transform.Transform(coverage_quad);
578}
std::array< Point, 4 > Quad
Definition point.h:321
constexpr Quad Transform(const Quad &quad) const
Definition matrix.h:485
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 353 of file gaussian_blur_filter_contents.cc.

356 {
357 if (inputs.empty()) {
358 return {};
359 }
360
361 std::optional<Rect> input_coverage = inputs[0]->GetCoverage(entity);
362 if (!input_coverage.has_value()) {
363 return {};
364 }
365
366 Vector2 scaled_sigma = (effect_transform.Basis() *
367 Vector2(ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)))
368 .Abs();
369 Vector2 blur_radius = Vector2(CalculateBlurRadius(scaled_sigma.x),
370 CalculateBlurRadius(scaled_sigma.y));
371 Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y));
372 Vector2 local_padding = (entity.GetTransform().Basis() * padding).Abs();
373 return input_coverage.value().Expand(Point(local_padding.x, local_padding.y));
374}
Point Vector2
Definition point.h:320
TPoint< Scalar > Point
Definition point.h:316
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 342 of file gaussian_blur_filter_contents.cc.

344 {
345 Vector2 scaled_sigma = {ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)};
346 Vector2 blur_radius = {CalculateBlurRadius(scaled_sigma.x),
347 CalculateBlurRadius(scaled_sigma.y)};
348 Vector3 blur_radii =
349 effect_transform.Basis() * Vector3{blur_radius.x, blur_radius.y, 0.0};
350 return output_limit.Expand(Point(blur_radii.x, blur_radii.y));
351}

◆ 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_; }

◆ RenderFilter()

std::optional< Entity > impeller::GaussianBlurFilterContents::RenderFilter ( const FilterInput::Vector inputs,
const ContentContext renderer,
const Entity entity,
const Matrix effect_transform,
const Rect coverage,
const std::optional< Rect > &  coverage_hint 
) const
overrideprivatevirtual

Converts zero or more filter inputs into a render instruction.

Implements impeller::FilterContents.

Definition at line 376 of file gaussian_blur_filter_contents.cc.

382 {
383 if (inputs.empty()) {
384 return std::nullopt;
385 }
386
387 Vector2 scaled_sigma = (effect_transform.Basis() *
388 Vector2(ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)))
389 .Abs();
390 Vector2 blur_radius = Vector2(CalculateBlurRadius(scaled_sigma.x),
391 CalculateBlurRadius(scaled_sigma.y));
392 Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y));
393 Vector2 local_padding = (entity.GetTransform().Basis() * padding).Abs();
394
395 // Apply as much of the desired padding as possible from the source. This may
396 // be ignored so must be accounted for in the downsample pass by adding a
397 // transparent gutter.
398 std::optional<Rect> expanded_coverage_hint;
399 if (coverage_hint.has_value()) {
400 expanded_coverage_hint = coverage_hint->Expand(local_padding);
401 }
402
403 int32_t mip_count = kBlurFilterRequiredMipCount;
404 if (renderer.GetContext()->GetBackendType() ==
406 // TODO(https://github.com/flutter/flutter/issues/141732): Implement mip map
407 // generation on opengles.
408 mip_count = 1;
409 }
410
411 std::optional<Snapshot> input_snapshot =
412 inputs[0]->GetSnapshot("GaussianBlur", renderer, entity,
413 /*coverage_limit=*/expanded_coverage_hint,
414 /*mip_count=*/mip_count);
415 if (!input_snapshot.has_value()) {
416 return std::nullopt;
417 }
418
419 if (scaled_sigma.x < kEhCloseEnough && scaled_sigma.y < kEhCloseEnough) {
420 return Entity::FromSnapshot(input_snapshot.value(),
421 entity.GetBlendMode()); // No blur to render.
422 }
423
424 // In order to avoid shimmering in downsampling step, we should have mips.
425 if (input_snapshot->texture->GetMipCount() <= 1) {
427 }
428 FML_DCHECK(!input_snapshot->texture->NeedsMipmapGeneration());
429
430 Scalar desired_scalar =
431 std::min(CalculateScale(scaled_sigma.x), CalculateScale(scaled_sigma.y));
432 // TODO(jonahwilliams): If desired_scalar is 1.0 and we fully acquired the
433 // gutter from the expanded_coverage_hint, we can skip the downsample pass.
434 // pass.
435 Vector2 downsample_scalar(desired_scalar, desired_scalar);
436 Rect source_rect = Rect::MakeSize(input_snapshot->texture->GetSize());
437 Rect source_rect_padded = source_rect.Expand(padding);
438 Matrix padding_snapshot_adjustment = Matrix::MakeTranslation(-padding);
439 // TODO(gaaclarke): The padding could be removed if we know it's not needed or
440 // resized to account for the expanded_clip_coverage. There doesn't appear
441 // to be the math to make those calculations though. The following
442 // optimization works, but causes a shimmer as a result of
443 // https://github.com/flutter/flutter/issues/140193 so it isn't applied.
444 //
445 // !input_snapshot->GetCoverage()->Expand(-local_padding)
446 // .Contains(coverage_hint.value()))
447 Vector2 downsampled_size = source_rect_padded.GetSize() * downsample_scalar;
448 ISize subpass_size =
449 ISize(round(downsampled_size.x), round(downsampled_size.y));
450 Vector2 effective_scalar =
451 Vector2(subpass_size) / source_rect_padded.GetSize();
452
453 Quad uvs = CalculateUVs(inputs[0], entity, source_rect_padded,
454 input_snapshot->texture->GetSize());
455
456 std::shared_ptr<CommandBuffer> command_buffer =
457 renderer.GetContext()->CreateCommandBuffer();
458 if (!command_buffer) {
459 return std::nullopt;
460 }
461
462 fml::StatusOr<RenderTarget> pass1_out = MakeDownsampleSubpass(
463 renderer, command_buffer, input_snapshot->texture,
464 input_snapshot->sampler_descriptor, uvs, subpass_size, tile_mode_);
465
466 if (!pass1_out.ok()) {
467 return std::nullopt;
468 }
469
470 Vector2 pass1_pixel_size =
471 1.0 / Vector2(pass1_out.value().GetRenderTargetTexture()->GetSize());
472
473 std::optional<Rect> input_snapshot_coverage = input_snapshot->GetCoverage();
474 Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)};
475 if (expanded_coverage_hint.has_value() &&
476 input_snapshot_coverage.has_value() &&
477 // TODO(https://github.com/flutter/flutter/issues/140890): Remove this
478 // condition. There is some flaw in coverage stopping us from using this
479 // today. I attempted to use source coordinates to calculate the uvs,
480 // but that didn't work either.
481 input_snapshot.has_value() &&
482 input_snapshot.value().transform.IsTranslationScaleOnly()) {
483 // Only process the uvs where the blur is happening, not the whole texture.
484 std::optional<Rect> uvs = MakeReferenceUVs(input_snapshot_coverage.value(),
485 expanded_coverage_hint.value())
486 .Intersection(Rect::MakeSize(Size(1, 1)));
487 FML_DCHECK(uvs.has_value());
488 if (uvs.has_value()) {
489 blur_uvs[0] = uvs->GetLeftTop();
490 blur_uvs[1] = uvs->GetRightTop();
491 blur_uvs[2] = uvs->GetLeftBottom();
492 blur_uvs[3] = uvs->GetRightBottom();
493 }
494 }
495
496 fml::StatusOr<RenderTarget> pass2_out = MakeBlurSubpass(
497 renderer, command_buffer, /*input_pass=*/pass1_out.value(),
498 input_snapshot->sampler_descriptor, tile_mode_,
499 BlurParameters{
500 .blur_uv_offset = Point(0.0, pass1_pixel_size.y),
501 .blur_sigma = scaled_sigma.y * effective_scalar.y,
502 .blur_radius = ScaleBlurRadius(blur_radius.y, effective_scalar.y),
503 .step_size = 1,
504 },
505 /*destination_target=*/std::nullopt, blur_uvs);
506
507 if (!pass2_out.ok()) {
508 return std::nullopt;
509 }
510
511 // Only ping pong if the first pass actually created a render target.
512 auto pass3_destination = pass2_out.value().GetRenderTargetTexture() !=
513 pass1_out.value().GetRenderTargetTexture()
514 ? std::optional<RenderTarget>(pass1_out.value())
515 : std::optional<RenderTarget>(std::nullopt);
516
517 fml::StatusOr<RenderTarget> pass3_out = MakeBlurSubpass(
518 renderer, command_buffer, /*input_pass=*/pass2_out.value(),
519 input_snapshot->sampler_descriptor, tile_mode_,
520 BlurParameters{
521 .blur_uv_offset = Point(pass1_pixel_size.x, 0.0),
522 .blur_sigma = scaled_sigma.x * effective_scalar.x,
523 .blur_radius = ScaleBlurRadius(blur_radius.x, effective_scalar.x),
524 .step_size = 1,
525 },
526 pass3_destination, blur_uvs);
527
528 if (!pass3_out.ok()) {
529 return std::nullopt;
530 }
531
532 if (!renderer.GetContext()
533 ->GetCommandQueue()
534 ->Submit(/*buffers=*/{command_buffer})
535 .ok()) {
536 return std::nullopt;
537 }
538
539 // The ping-pong approach requires that each render pass output has the same
540 // size.
541 FML_DCHECK((pass1_out.value().GetRenderTargetSize() ==
542 pass2_out.value().GetRenderTargetSize()) &&
543 (pass2_out.value().GetRenderTargetSize() ==
544 pass3_out.value().GetRenderTargetSize()));
545
546 SamplerDescriptor sampler_desc = MakeSamplerDescriptor(
548
549 Entity blur_output_entity = Entity::FromSnapshot(
550 Snapshot{.texture = pass3_out.value().GetRenderTargetTexture(),
551 .transform = input_snapshot->transform *
552 padding_snapshot_adjustment *
553 Matrix::MakeScale(1 / effective_scalar),
554 .sampler_descriptor = sampler_desc,
555 .opacity = input_snapshot->opacity},
556 entity.GetBlendMode());
557
558 return ApplyBlurStyle(mask_blur_style_, entity, inputs[0],
559 input_snapshot.value(), std::move(blur_output_entity),
560 mask_geometry_);
561}
const T & value() const
Definition status_or.h:77
bool ok() const
Definition status_or.h:75
static Entity FromSnapshot(const Snapshot &snapshot, BlendMode blend_mode=BlendMode::kSourceOver)
Create an entity that can be used to render a given snapshot.
Definition entity.cc:22
static Quad CalculateUVs(const std::shared_ptr< FilterInput > &filter_input, const Entity &entity, const Rect &source_rect, const ISize &texture_size)
#define FML_DLOG(severity)
Definition logging.h:102
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
constexpr float kEhCloseEnough
Definition constants.h:56
TRect< Scalar > Rect
Definition rect.h:746
TSize< int64_t > ISize
Definition size.h:138
TSize< Scalar > Size
Definition size.h:137
Definition ref_ptr.h:256
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition p3.cpp:47
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:146
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
Definition rect.h:582
#define ERROR(message)

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

583 {
584 // Limit the kernel size to 1000x1000 pixels, like Skia does.
585 Scalar clamped = std::min(sigma, 500.0f);
586 constexpr Scalar a = 3.4e-06;
587 constexpr Scalar b = -3.4e-3;
588 constexpr Scalar c = 1.f;
589 Scalar scalar = c + b * clamped + a * clamped * clamped;
590 return clamped * scalar;
591}
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: