| Flutter Impeller |

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
5 #include "impeller/entity/contents/solid_rrect_blur_contents.h"
6 #include <optional>
7
8 #include "impeller/entity/contents/content_context.h"
9 #include "impeller/entity/entity.h"
10 #include "impeller/geometry/color.h"
11 #include "impeller/geometry/constants.h"
12 #include "impeller/renderer/render_pass.h"
13 #include "impeller/renderer/vertex_buffer_builder.h"
14
15 namespace impeller {
16
17 namespace {
18 // Generous padding to make sure blurs with large sigmas are fully visible.
19 // Used to expand the geometry around the rrect.
20 Scalar PadForSigma(Scalar sigma) {
21 return sigma * 4.0;
22 }
23 } // namespace
24
25 SolidRRectBlurContents::SolidRRectBlurContents() = default;
26
27 SolidRRectBlurContents::~SolidRRectBlurContents() = default;
28
29 void SolidRRectBlurContents::SetRRect(std::optional<Rect> rect,
30 Size corner_radii) {
31 rect_ = rect;
32 corner_radii_ = corner_radii;
33 }
34
35 void SolidRRectBlurContents::SetSigma(Sigma sigma) {
36 sigma_ = sigma;
37 }
38
39 void SolidRRectBlurContents::SetColor(Color color) {
40 color_ = color.Premultiply();
41 }
42
43 Color SolidRRectBlurContents::GetColor() const {
44 return color_;
45 }
46
47 std::optional<Rect> SolidRRectBlurContents::GetCoverage(
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
58 bool SolidRRectBlurContents::Render(const ContentContext& renderer,
59 const Entity& entity,
60 RenderPass& pass) const {
61 if (!rect_.has_value()) {
62 return true;
63 }
64
65 using VS = RRectBlurPipeline::VertexShader;
66 using FS = RRectBlurPipeline::FragmentShader;
67
68 VertexBufferBuilder<VS::PerVertexData> vtx_builder;
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
92 ContentContextOptions opts = OptionsFromPassAndEntity(pass, entity);
93 opts.primitive_type = PrimitiveType::kTriangleStrip;
94 Color color = color_;
95 if (entity.GetBlendMode() == BlendMode::kClear) {
96 opts.is_for_rrect_blur_clear = true;
97 color = Color::White();
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.SetStencilReference(entity.GetClipDepth());
118 pass.SetVertexBuffer(
119 vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()));
120 VS::BindFrameInfo(pass,
121 renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
122 FS::BindFragInfo(pass,
123 renderer.GetTransientsBuffer().EmplaceUniform(frag_info));
124
125 if (!pass.Draw().ok()) {
126 return false;
127 }
128
129 return true;
130 }
131
132 bool SolidRRectBlurContents::ApplyColorFilter(
133 const ColorFilterProc& color_filter_proc) {
134 color_ = color_filter_proc(color_);
135 return true;
136 }
137
138 } // namespace impeller
impeller::Sigma::sigma
Scalar sigma
Definition: sigma.h:33
impeller::Entity::GetShaderTransform
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:53
impeller::Entity::GetShaderClipDepth
float GetShaderClipDepth() const
Definition: entity.cc:117
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:49
entity.h
impeller::Color
Definition: color.h:124
impeller::SolidRRectBlurContents::GetColor
Color GetColor() const
Definition: solid_rrect_blur_contents.cc:43
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:56
impeller::SolidRRectBlurContents::SetSigma
void SetSigma(Sigma sigma)
Definition: solid_rrect_blur_contents.cc:35
impeller::SolidRRectBlurContents::SetColor
void SetColor(Color color)
Definition: solid_rrect_blur_contents.cc:39
impeller::RenderPipelineT::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:94
impeller::RenderPass::SetVertexBuffer
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
Definition: render_pass.cc:123
impeller::VertexBufferBuilder::AddVertices
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
Definition: vertex_buffer_builder.h:70
impeller::SolidRRectBlurContents::SolidRRectBlurContents
SolidRRectBlurContents()
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::RenderPass::SetCommandLabel
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
Definition: render_pass.cc:97
impeller::RenderPass::Draw
virtual fml::Status Draw()
Record the currently pending command.
Definition: render_pass.cc:127
impeller::VS
SolidFillVertexShader VS
Definition: stroke_path_geometry.cc:15
impeller::Entity
Definition: entity.h:21
impeller::OptionsFromPassAndEntity
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:37
impeller::TSize< Scalar >
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::Point
TPoint< Scalar > Point
Definition: point.h:316
render_pass.h
impeller::BlendMode::kClear
@ kClear
impeller::VertexBufferBuilder
Definition: vertex_buffer_builder.h:24
impeller::Contents::ColorFilterProc
std::function< Color(Color)> ColorFilterProc
Definition: contents.h:38
impeller::Color::White
static constexpr Color White()
Definition: color.h:256
impeller::Sigma
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
impeller::ContentContext::GetRRectBlurPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetRRectBlurPipeline(ContentContextOptions opts) const
Definition: content_context.h:465
impeller::ContentContextOptions::is_for_rrect_blur_clear
bool is_for_rrect_blur_clear
Definition: content_context.h:342
impeller::SolidRRectBlurContents::ApplyColorFilter
bool ApplyColorFilter(const ColorFilterProc &color_filter_proc) override
If possible, applies a color filter to this contents inputs on the CPU.
Definition: solid_rrect_blur_contents.cc:132
impeller::RenderPass::SetStencilReference
virtual void SetStencilReference(uint32_t value)
Definition: render_pass.cc:103
impeller::TSize::width
Type width
Definition: size.h:22
impeller::Entity::GetBlendMode
BlendMode GetBlendMode() const
Definition: entity.cc:134
impeller::ContentContextOptions::primitive_type
PrimitiveType primitive_type
Definition: content_context.h:337
impeller::VertexBufferBuilder::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
Definition: vertex_buffer_builder.h:84
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:33
impeller::Entity::GetClipDepth
uint32_t GetClipDepth() const
Definition: entity.cc:105
content_context.h
constants.h
impeller::SolidRRectBlurContents::Render
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Definition: solid_rrect_blur_contents.cc:58
impeller::HostBuffer::EmplaceUniform
BufferView EmplaceUniform(const UniformType &uniform)
Emplace uniform data onto the host buffer. Ensure that backend specific uniform alignment requirement...
Definition: host_buffer.h:50
impeller::SolidRRectBlurContents::SetRRect
void SetRRect(std::optional< Rect > rect, Size corner_radii={})
Definition: solid_rrect_blur_contents.cc:29
color.h
impeller::RenderPass::SetPipeline
virtual void SetPipeline(const std::shared_ptr< Pipeline< PipelineDescriptor >> &pipeline)
The pipeline to use for this command.
Definition: render_pass.cc:92
impeller::SolidRRectBlurContents::GetCoverage
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.
Definition: solid_rrect_blur_contents.cc:47
impeller::RenderPipelineT::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:93
impeller::ContentContextOptions
Definition: content_context.h:288
impeller
Definition: aiks_blur_unittests.cc:20
solid_rrect_blur_contents.h
impeller::ContentContext
Definition: content_context.h:392
impeller::Color::Premultiply
constexpr Color Premultiply() const
Definition: color.h:214
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:833
vertex_buffer_builder.h
impeller::SolidRRectBlurContents::~SolidRRectBlurContents
~SolidRRectBlurContents() override