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 
6 #include <optional>
7 
12 #include "impeller/geometry/path.h"
17 
18 namespace impeller {
19 
20 namespace {
21 // Generous padding to make sure blurs with large sigmas are fully visible.
22 // Used to expand the geometry around the rrect.
23 Scalar PadForSigma(Scalar sigma) {
24  return sigma * 4.0;
25 }
26 } // namespace
27 
29 
31 
32 void SolidRRectBlurContents::SetRRect(std::optional<Rect> rect,
33  Size corner_radii) {
34  rect_ = rect;
35  corner_radii_ = corner_radii;
36 }
37 
39  sigma_ = sigma;
40 }
41 
43  color_ = color.Premultiply();
44 }
45 
47  return color_;
48 }
49 
51  const Entity& entity) const {
52  if (!rect_.has_value()) {
53  return std::nullopt;
54  }
55 
56  Scalar radius = PadForSigma(sigma_.sigma);
57 
58  return rect_->Expand(radius).TransformBounds(entity.GetTransform());
59 }
60 
62  const Entity& entity,
63  RenderPass& pass) const {
64  if (!rect_.has_value()) {
65  return true;
66  }
67 
70 
72 
73  // Clamp the max kernel width/height to 1000 to limit the extent
74  // of the blur and to kEhCloseEnough to prevent NaN calculations
75  // trying to evaluate a Guassian distribution with a sigma of 0.
76  auto blur_sigma = std::clamp(sigma_.sigma, kEhCloseEnough, 250.0f);
77  // Increase quality by making the radius a bit bigger than the typical
78  // sigma->radius conversion we use for slower blurs.
79  auto blur_radius = PadForSigma(blur_sigma);
80  auto positive_rect = rect_->GetPositive();
81  {
82  auto left = -blur_radius;
83  auto top = -blur_radius;
84  auto right = positive_rect.GetWidth() + blur_radius;
85  auto bottom = positive_rect.GetHeight() + blur_radius;
86 
87  vtx_builder.AddVertices({
88  {Point(left, top)},
89  {Point(right, top)},
90  {Point(left, bottom)},
91  {Point(right, bottom)},
92  });
93  }
94 
95  Command cmd;
96  DEBUG_COMMAND_INFO(cmd, "RRect Shadow");
99  Color color = color_;
100  if (entity.GetBlendMode() == BlendMode::kClear) {
101  opts.is_for_rrect_blur_clear = true;
102  color = Color::White();
103  }
104  cmd.pipeline = renderer.GetRRectBlurPipeline(opts);
105  cmd.stencil_reference = entity.GetClipDepth();
106 
107  cmd.BindVertices(vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
108 
109  VS::FrameInfo frame_info;
110  frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform() *
111  Matrix::MakeTranslation(positive_rect.GetOrigin());
112  VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));
113 
114  FS::FragInfo frag_info;
115  frag_info.color = color;
116  frag_info.blur_sigma = blur_sigma;
117  frag_info.rect_size = Point(positive_rect.GetSize());
118  frag_info.corner_radii = {std::clamp(corner_radii_.width, kEhCloseEnough,
119  positive_rect.GetWidth() * 0.5f),
120  std::clamp(corner_radii_.width, kEhCloseEnough,
121  positive_rect.GetHeight() * 0.5f)};
122  FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
123 
124  if (!pass.AddCommand(std::move(cmd))) {
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
impeller::Sigma::sigma
Scalar sigma
Definition: sigma.h:33
path.h
impeller::Command
An object used to specify work to the GPU along with references to resources the GPU will used when d...
Definition: command.h:92
DEBUG_COMMAND_INFO
#define DEBUG_COMMAND_INFO(obj, arg)
Definition: command.h:28
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:46
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:56
impeller::SolidRRectBlurContents::SetSigma
void SetSigma(Sigma sigma)
Definition: solid_rrect_blur_contents.cc:38
impeller::SolidRRectBlurContents::SetColor
void SetColor(Color color)
Definition: solid_rrect_blur_contents.cc:42
impeller::RenderPipelineT::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:93
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::GetOrthographicTransform
const Matrix & GetOrthographicTransform() const
Definition: render_pass.cc:51
tessellator.h
path_builder.h
impeller::Entity
Definition: entity.h:21
impeller::OptionsFromPassAndEntity
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:28
impeller::TSize< Scalar >
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::Point
TPoint< Scalar > Point
Definition: point.h:308
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::Command::BindVertices
bool BindVertices(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
Definition: command.cc:15
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:395
impeller::ContentContextOptions::is_for_rrect_blur_clear
bool is_for_rrect_blur_clear
Definition: content_context.h:285
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:131
impeller::TSize::width
Type width
Definition: size.h:22
impeller::Entity::GetBlendMode
BlendMode GetBlendMode() const
Definition: entity.cc:105
impeller::ContentContextOptions::primitive_type
PrimitiveType primitive_type
Definition: content_context.h:281
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:29
impeller::Entity::GetClipDepth
uint32_t GetClipDepth() const
Definition: entity.cc:93
impeller::Command::stencil_reference
uint32_t stencil_reference
Definition: command.h:122
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:61
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:41
impeller::SolidRRectBlurContents::SetRRect
void SetRRect(std::optional< Rect > rect, Size corner_radii={})
Definition: solid_rrect_blur_contents.cc:32
color.h
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:50
impeller::Command::pipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > pipeline
Definition: command.h:96
impeller::RenderPipelineT::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:92
impeller::ContentContextOptions
Definition: content_context.h:276
impeller::RenderPass::AddCommand
bool AddCommand(Command &&command)
Record a command for subsequent encoding to the underlying command buffer. No work is encoded into th...
Definition: render_pass.cc:67
impeller
Definition: aiks_context.cc:10
solid_rrect_blur_contents.h
impeller::ContentContext
Definition: content_context.h:332
impeller::Color::Premultiply
constexpr Color Premultiply() const
Definition: color.h:214
impeller::RenderPass::GetTransientsBuffer
HostBuffer & GetTransientsBuffer()
Definition: render_pass.cc:55
vertex_buffer_builder.h
impeller::SolidRRectBlurContents::~SolidRRectBlurContents
~SolidRRectBlurContents() override