Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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.
19// Used to expand the geometry around the rrect.
20Scalar PadForSigma(Scalar sigma) {
21 return sigma * 4.0;
22}
23} // namespace
24
26
28
29void SolidRRectBlurContents::SetRRect(std::optional<Rect> rect,
30 Size corner_radii) {
31 rect_ = rect;
32 corner_radii_ = corner_radii;
33}
34
36 sigma_ = sigma;
37}
38
40 color_ = color.Premultiply();
41}
42
44 return color_;
45}
46
48 const Entity& entity) const {
49 if (!rect_.has_value()) {
50 return std::nullopt;
51 }
52
53 Scalar radius = PadForSigma(sigma_.sigma);
54
55 return rect_->Expand(radius).TransformBounds(entity.GetTransform());
56}
57
59 const Entity& entity,
60 RenderPass& pass) const {
61 if (!rect_.has_value()) {
62 return true;
63 }
64
67
69
70 // Clamp the max kernel width/height to 1000 to limit the extent
71 // of the blur and to kEhCloseEnough to prevent NaN calculations
72 // trying to evaluate a Guassian distribution with a sigma of 0.
73 auto blur_sigma = std::clamp(sigma_.sigma, kEhCloseEnough, 250.0f);
74 // Increase quality by making the radius a bit bigger than the typical
75 // sigma->radius conversion we use for slower blurs.
76 auto blur_radius = PadForSigma(blur_sigma);
77 auto positive_rect = rect_->GetPositive();
78 {
79 auto left = -blur_radius;
80 auto top = -blur_radius;
81 auto right = positive_rect.GetWidth() + blur_radius;
82 auto bottom = positive_rect.GetHeight() + blur_radius;
83
84 vtx_builder.AddVertices({
85 {Point(left, top)},
86 {Point(right, top)},
87 {Point(left, bottom)},
88 {Point(right, bottom)},
89 });
90 }
91
94 Color color = color_;
95 if (entity.GetBlendMode() == BlendMode::kClear) {
96 opts.is_for_rrect_blur_clear = true;
98 }
99
100 VS::FrameInfo frame_info;
101 frame_info.mvp = Entity::GetShaderTransform(
102 entity.GetShaderClipDepth(), pass,
103 entity.GetTransform() *
104 Matrix::MakeTranslation(positive_rect.GetOrigin()));
105
106 FS::FragInfo frag_info;
107 frag_info.color = color;
108 frag_info.blur_sigma = blur_sigma;
109 frag_info.rect_size = Point(positive_rect.GetSize());
110 frag_info.corner_radii = {std::clamp(corner_radii_.width, kEhCloseEnough,
111 positive_rect.GetWidth() * 0.5f),
112 std::clamp(corner_radii_.width, kEhCloseEnough,
113 positive_rect.GetHeight() * 0.5f)};
114
115 pass.SetCommandLabel("RRect Shadow");
116 pass.SetPipeline(renderer.GetRRectBlurPipeline(opts));
117 pass.SetVertexBuffer(
118 vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()));
119 VS::BindFrameInfo(pass,
120 renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
121 FS::BindFragInfo(pass,
122 renderer.GetTransientsBuffer().EmplaceUniform(frag_info));
123
124 if (!pass.Draw().ok()) {
125 return false;
126 }
127
128 return true;
129}
130
132 const ColorFilterProc& color_filter_proc) {
133 color_ = color_filter_proc(color_);
134 return true;
135}
136
137} // namespace impeller
SkColor4f color
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
bool ok() const
Definition status.h:71
std::function< Color(Color)> ColorFilterProc
Definition contents.h:38
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.
virtual void SetPipeline(const std::shared_ptr< Pipeline< PipelineDescriptor > > &pipeline)
The pipeline to use for this command.
virtual fml::Status Draw()
Record the currently pending command.
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
FragmentShader_ FragmentShader
Definition pipeline.h:106
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)
float Scalar
Definition scalar.h:18
constexpr float kEhCloseEnough
Definition constants.h:56
SolidFillVertexShader VS
TPoint< Scalar > Point
Definition point.h:316
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition contents.cc:35
static constexpr Color White()
Definition color.h:256
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