Flutter Engine
The Flutter Engine
solid_rrect_blur_contents.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6#include <optional>
7
14
15namespace impeller {
16
17namespace {
18// Generous padding to make sure blurs with large sigmas are fully visible. Used
19// to expand the geometry around the rrect. Larger sigmas have more subtle
20// gradients so they need larger padding to avoid hard cutoffs. Sigma is
21// maximized to 3.5 since that should cover 99.95% of all samples. 3.0 should
22// cover 99.7% but that was seen to be not enough for large sigmas.
23Scalar PadForSigma(Scalar sigma) {
24 Scalar scalar = std::min((1.0f / 47.6f) * sigma + 2.5f, 3.5f);
25 return sigma * scalar;
26}
27} // namespace
28
30
32
33void SolidRRectBlurContents::SetRRect(std::optional<Rect> rect,
34 Size corner_radii) {
35 rect_ = rect;
36 corner_radii_ = corner_radii;
37}
38
40 sigma_ = sigma;
41}
42
44 color_ = color.Premultiply();
45}
46
48 return color_;
49}
50
52 const Entity& entity) const {
53 if (!rect_.has_value()) {
54 return std::nullopt;
55 }
56
57 Scalar radius = PadForSigma(sigma_.sigma);
58
59 return rect_->Expand(radius).TransformBounds(entity.GetTransform());
60}
61
63 const Entity& entity,
64 RenderPass& pass) const {
65 if (!rect_.has_value()) {
66 return true;
67 }
68
71
73
74 // Clamp the max kernel width/height to 1000 to limit the extent
75 // of the blur and to kEhCloseEnough to prevent NaN calculations
76 // trying to evaluate a Guassian distribution with a sigma of 0.
77 auto blur_sigma = std::clamp(sigma_.sigma, kEhCloseEnough, 250.0f);
78 // Increase quality by making the radius a bit bigger than the typical
79 // sigma->radius conversion we use for slower blurs.
80 auto blur_radius = PadForSigma(blur_sigma);
81 auto positive_rect = rect_->GetPositive();
82 {
83 auto left = -blur_radius;
84 auto top = -blur_radius;
85 auto right = positive_rect.GetWidth() + blur_radius;
86 auto bottom = positive_rect.GetHeight() + blur_radius;
87
88 vtx_builder.AddVertices({
89 {Point(left, top)},
90 {Point(right, top)},
91 {Point(left, bottom)},
92 {Point(right, bottom)},
93 });
94 }
95
98 Color color = color_;
99 if (entity.GetBlendMode() == BlendMode::kClear) {
100 opts.is_for_rrect_blur_clear = true;
102 }
103
104 VS::FrameInfo frame_info;
105 frame_info.mvp = Entity::GetShaderTransform(
106 entity.GetShaderClipDepth(), pass,
107 entity.GetTransform() *
108 Matrix::MakeTranslation(positive_rect.GetOrigin()));
109
110 FS::FragInfo frag_info;
111 frag_info.color = color;
112 frag_info.blur_sigma = blur_sigma;
113 frag_info.rect_size = Point(positive_rect.GetSize());
114 frag_info.corner_radii = {std::clamp(corner_radii_.width, kEhCloseEnough,
115 positive_rect.GetWidth() * 0.5f),
116 std::clamp(corner_radii_.width, kEhCloseEnough,
117 positive_rect.GetHeight() * 0.5f)};
118
119 pass.SetCommandLabel("RRect Shadow");
120 pass.SetPipeline(renderer.GetRRectBlurPipeline(opts));
121 pass.SetVertexBuffer(
122 vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()));
123 VS::BindFrameInfo(pass,
124 renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
125 FS::BindFragInfo(pass,
126 renderer.GetTransientsBuffer().EmplaceUniform(frag_info));
127
128 if (!pass.Draw().ok()) {
129 return false;
130 }
131
132 return true;
133}
134
136 const ColorFilterProc& color_filter_proc) {
137 color_ = color_filter_proc(color_);
138 return true;
139}
140
141} // namespace impeller
static unsigned clamp(SkFixed fx, int max)
bool ok() const
Definition: status.h:71
std::function< Color(Color)> ColorFilterProc
Definition: contents.h:35
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:50
BlendMode GetBlendMode() const
Definition: entity.cc:119
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:46
float GetShaderClipDepth() const
Definition: entity.cc:106
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:33
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
Definition: render_pass.cc:123
virtual void SetPipeline(const std::shared_ptr< Pipeline< PipelineDescriptor > > &pipeline)
The pipeline to use for this command.
Definition: render_pass.cc:92
virtual fml::Status Draw()
Record the currently pending command.
Definition: render_pass.cc:127
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
Definition: render_pass.cc:97
FragmentShader_ FragmentShader
Definition: pipeline.h:107
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.
bool ApplyColorFilter(const ColorFilterProc &color_filter_proc) override
If possible, applies a color filter to this contents inputs on the CPU.
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
void SetRRect(std::optional< Rect > rect, Size corner_radii={})
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
DlColor color
static float min(float r, float g, float b)
Definition: hsl.cpp:48
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
float Scalar
Definition: scalar.h:18
constexpr float kEhCloseEnough
Definition: constants.h:56
SolidFillVertexShader VS
TPoint< Scalar > Point
Definition: point.h:322
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:34
static constexpr Color White()
Definition: color.h:266
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
Scalar sigma
Definition: sigma.h:33
Type width
Definition: size.h:22