| Flutter Impeller |

filter_contents.h
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 #ifndef FLUTTER_IMPELLER_ENTITY_CONTENTS_FILTERS_FILTER_CONTENTS_H_
6 #define FLUTTER_IMPELLER_ENTITY_CONTENTS_FILTERS_FILTER_CONTENTS_H_
7
8 #include <memory>
9 #include <optional>
10 #include <variant>
11 #include <vector>
12
13 #include "impeller/core/formats.h"
14 #include "impeller/entity/contents/filters/inputs/filter_input.h"
15 #include "impeller/entity/entity.h"
16 #include "impeller/geometry/matrix.h"
17 #include "impeller/geometry/sigma.h"
18
19 namespace impeller {
20
21 class FilterContents : public Contents {
22 public:
23 enum class BlurStyle {
24 /// Blurred inside and outside.
25 kNormal,
26 /// Solid inside, blurred outside.
27 kSolid,
28 /// Nothing inside, blurred outside.
29 kOuter,
30 /// Blurred inside, nothing outside.
31 kInner,
32 };
33
34 enum class MorphType { kDilate, kErode };
35
36 /// Creates a gaussian blur that operates in one direction.
37 /// See also: `MakeGaussianBlur`
38 static std::shared_ptr<FilterContents> MakeDirectionalGaussianBlur(
39 FilterInput::Ref input,
40 Sigma sigma,
41 Vector2 direction,
42 BlurStyle blur_style = BlurStyle::kNormal,
43 Entity::TileMode tile_mode = Entity::TileMode::kDecal,
44 bool is_second_pass = false,
45 Sigma secondary_sigma = {});
46
47 /// Creates a gaussian blur that operates in 2 dimensions.
48 /// See also: `MakeDirectionalGaussianBlur`
49 static std::shared_ptr<FilterContents> MakeGaussianBlur(
50 const FilterInput::Ref& input,
51 Sigma sigma_x,
52 Sigma sigma_y,
53 BlurStyle blur_style = BlurStyle::kNormal,
54 Entity::TileMode tile_mode = Entity::TileMode::kDecal);
55
56 static std::shared_ptr<FilterContents> MakeBorderMaskBlur(
57 FilterInput::Ref input,
58 Sigma sigma_x,
59 Sigma sigma_y,
60 BlurStyle blur_style = BlurStyle::kNormal);
61
62 static std::shared_ptr<FilterContents> MakeDirectionalMorphology(
63 FilterInput::Ref input,
64 Radius radius,
65 Vector2 direction,
66 MorphType morph_type);
67
68 static std::shared_ptr<FilterContents> MakeMorphology(FilterInput::Ref input,
69 Radius radius_x,
70 Radius radius_y,
71 MorphType morph_type);
72
73 static std::shared_ptr<FilterContents> MakeMatrixFilter(
74 FilterInput::Ref input,
75 const Matrix& matrix,
76 const SamplerDescriptor& desc);
77
78 static std::shared_ptr<FilterContents> MakeLocalMatrixFilter(
79 FilterInput::Ref input,
80 const Matrix& matrix);
81
82 static std::shared_ptr<FilterContents> MakeYUVToRGBFilter(
83 std::shared_ptr<Texture> y_texture,
84 std::shared_ptr<Texture> uv_texture,
85 YUVColorSpace yuv_color_space);
86
87 FilterContents();
88
89 ~FilterContents() override;
90
91 /// @brief The input texture sources for this filter. Each input's emitted
92 /// texture is expected to have premultiplied alpha colors.
93 ///
94 /// The number of required or optional textures depends on the
95 /// particular filter's implementation.
96 void SetInputs(FilterInput::Vector inputs);
97
98 /// @brief Sets the transform which gets appended to the effect of this
99 /// filter. Note that this is in addition to the entity's transform.
100 ///
101 /// This is useful for subpass rendering scenarios where it's
102 /// difficult to encode the current transform of the layer into the
103 /// Entity being rendered.
104 void SetEffectTransform(const Matrix& effect_transform);
105
106 /// @brief Create an Entity that renders this filter's output.
107 std::optional<Entity> GetEntity(
108 const ContentContext& renderer,
109 const Entity& entity,
110 const std::optional<Rect>& coverage_hint) const;
111
112 // |Contents|
113 bool Render(const ContentContext& renderer,
114 const Entity& entity,
115 RenderPass& pass) const override;
116
117 // |Contents|
118 std::optional<Rect> GetCoverage(const Entity& entity) const override;
119
120 // |Contents|
121 void PopulateGlyphAtlas(
122 const std::shared_ptr<LazyGlyphAtlas>& lazy_glyph_atlas,
123 Scalar scale) override;
124
125 // |Contents|
126 std::optional<Snapshot> RenderToSnapshot(
127 const ContentContext& renderer,
128 const Entity& entity,
129 std::optional<Rect> coverage_limit = std::nullopt,
130 const std::optional<SamplerDescriptor>& sampler_descriptor = std::nullopt,
131 bool msaa_enabled = true,
132 const std::string& label = "Filter Snapshot") const override;
133
134 // |Contents|
135 const FilterContents* AsFilter() const override;
136
137 /// @brief Determines the coverage of source pixels that will be needed
138 /// to produce results for the specified |output_limit| under the
139 /// specified |effect_transform|. This is essentially a reverse of
140 /// the |GetCoverage| method computing a source coverage from
141 /// an intended |output_limit| coverage.
142 ///
143 /// Both the |output_limit| and the return value are in the
144 /// transformed coordinate space, and so do not need to be
145 /// transformed or inverse transformed by the |effect_transform|
146 /// but individual parameters on the filter might be in the
147 /// untransformed space and should be transformed by the
148 /// |effect_transform| before applying them to the coverages.
149 ///
150 /// The method computes a result such that if the filter is applied
151 /// to a set of pixels filling the computed source coverage, it
152 /// should produce an output that covers the entire specified
153 /// |output_limit|.
154 ///
155 /// This is useful for subpass rendering scenarios where a filter
156 /// will be applied to the output of the subpass and we need to
157 /// determine how large of a render target to allocate in order
158 /// to collect all pixels that might affect the supplied output
159 /// coverage limit. While we might end up clipping the rendering
160 /// of the subpass to its destination, we want to avoid clipping
161 /// out any pixels that contribute to the output limit via the
162 /// filtering operation.
163 ///
164 /// @return The coverage bounds in the transformed space of any source pixel
165 /// that may be needed to produce output for the indicated filter
166 /// that covers the indicated |output_limit|.
167 std::optional<Rect> GetSourceCoverage(const Matrix& effect_transform,
168 const Rect& output_limit) const;
169
170 virtual Matrix GetLocalTransform(const Matrix& parent_transform) const;
171
172 Matrix GetTransform(const Matrix& parent_transform) const;
173
174 /// @brief Returns true if this filter graph doesn't perform any basis
175 /// transforms to the filtered content. For example: Rotating,
176 /// scaling, and skewing are all basis transforms, but
177 /// translating is not.
178 ///
179 /// This is useful for determining whether a filtered object's space
180 /// is compatible enough with the parent pass space to perform certain
181 /// subpass clipping optimizations.
182 virtual bool IsTranslationOnly() const;
183
184 /// @brief Returns `true` if this filter does not have any `FilterInput`
185 /// children.
186 bool IsLeaf() const;
187
188 /// @brief Replaces the set of all leaf `FilterContents` with a new set
189 /// of `FilterInput`s.
190 /// @see `FilterContents::IsLeaf`
191 void SetLeafInputs(const FilterInput::Vector& inputs);
192
193 /// @brief Marks this filter chain as applying in a subpass scenario.
194 ///
195 /// Subpasses render in screenspace, and this setting informs filters
196 /// that the current transform matrix of the entity is not stored
197 /// in the Entity transform matrix. Instead, the effect transform
198 /// is used in this case.
199 virtual void SetRenderingMode(Entity::RenderingMode rendering_mode);
200
201 private:
202 /// @brief Internal utility method for |GetLocalCoverage| that computes
203 /// the output coverage of this filter across the specified inputs,
204 /// ignoring the coverage hint.
205 virtual std::optional<Rect> GetFilterCoverage(
206 const FilterInput::Vector& inputs,
207 const Entity& entity,
208 const Matrix& effect_transform) const;
209
210 /// @brief Internal utility method for |GetSourceCoverage| that computes
211 /// the inverse effect of this transform on the specified output
212 /// coverage, ignoring the inputs which will be accommodated by
213 /// the caller.
214 virtual std::optional<Rect> GetFilterSourceCoverage(
215 const Matrix& effect_transform,
216 const Rect& output_limit) const = 0;
217
218 /// @brief Converts zero or more filter inputs into a render instruction.
219 virtual std::optional<Entity> RenderFilter(
220 const FilterInput::Vector& inputs,
221 const ContentContext& renderer,
222 const Entity& entity,
223 const Matrix& effect_transform,
224 const Rect& coverage,
225 const std::optional<Rect>& coverage_hint) const = 0;
226
227 /// @brief Internal utility method to compute the coverage of this
228 /// filter across its internally specified inputs and subject
229 /// to the coverage hint.
230 ///
231 /// Uses |GetFilterCoverage|.
232 std::optional<Rect> GetLocalCoverage(const Entity& local_entity) const;
233
234 FilterInput::Vector inputs_;
235 Matrix effect_transform_ = Matrix();
236
237 FilterContents(const FilterContents&) = delete;
238
239 FilterContents& operator=(const FilterContents&) = delete;
240 };
241
242 } // namespace impeller
243
244 #endif // FLUTTER_IMPELLER_ENTITY_CONTENTS_FILTERS_FILTER_CONTENTS_H_
impeller::FilterContents::PopulateGlyphAtlas
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 draw...
Definition: filter_contents.cc:212
impeller::FilterContents::IsLeaf
bool IsLeaf() const
Returns true if this filter does not have any FilterInput children.
Definition: filter_contents.cc:329
impeller::FilterContents::SetInputs
void SetInputs(FilterInput::Vector inputs)
The input texture sources for this filter. Each input's emitted texture is expected to have premultip...
Definition: filter_contents.cc:165
impeller::FilterContents::MorphType::kErode
@ kErode
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::FilterContents::FilterContents
FilterContents()
impeller::FilterContents::GetSourceCoverage
std::optional< Rect > GetSourceCoverage(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 |ou...
Definition: filter_contents.cc:247
entity.h
impeller::FilterContents::SetEffectTransform
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...
Definition: filter_contents.cc:169
impeller::FilterContents::BlurStyle
BlurStyle
Definition: filter_contents.h:23
impeller::Entity::TileMode::kDecal
@ kDecal
impeller::FilterContents::GetTransform
Matrix GetTransform(const Matrix &parent_transform) const
Definition: filter_contents.cc:317
impeller::FilterContents::RenderToSnapshot
std::optional< Snapshot > RenderToSnapshot(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, const std::string &label="Filter Snapshot") const override
Render this contents to a snapshot, respecting the entity's transform, path, clip depth,...
Definition: filter_contents.cc:285
formats.h
impeller::FilterInput::Ref
std::shared_ptr< FilterInput > Ref
Definition: filter_input.h:32
impeller::Vector2
Point Vector2
Definition: point.h:312
impeller::FilterContents::MakeDirectionalGaussianBlur
static std::shared_ptr< FilterContents > MakeDirectionalGaussianBlur(FilterInput::Ref input, Sigma sigma, Vector2 direction, BlurStyle blur_style=BlurStyle::kNormal, Entity::TileMode tile_mode=Entity::TileMode::kDecal, bool is_second_pass=false, Sigma secondary_sigma={})
Definition: filter_contents.cc:34
impeller::FilterContents::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.
matrix.h
impeller::FilterContents::MakeGaussianBlur
static std::shared_ptr< FilterContents > MakeGaussianBlur(const FilterInput::Ref &input, Sigma sigma_x, Sigma sigma_y, BlurStyle blur_style=BlurStyle::kNormal, Entity::TileMode tile_mode=Entity::TileMode::kDecal)
Definition: filter_contents.cc:53
impeller::FilterContents::Render
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Definition: filter_contents.cc:177
sigma.h
impeller::FilterContents::BlurStyle::kSolid
@ kSolid
Solid inside, blurred outside.
impeller::FilterContents::IsTranslationOnly
virtual bool IsTranslationOnly() const
Returns true if this filter graph doesn't perform any basis transforms to the filtered content....
Definition: filter_contents.cc:320
impeller::FilterContents::MakeDirectionalMorphology
static std::shared_ptr< FilterContents > MakeDirectionalMorphology(FilterInput::Ref input, Radius radius, Vector2 direction, MorphType morph_type)
Definition: filter_contents.cc:105
impeller::Sigma
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
filter_input.h
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:488
impeller::FilterContents::MakeBorderMaskBlur
static std::shared_ptr< FilterContents > MakeBorderMaskBlur(FilterInput::Ref input, Sigma sigma_x, Sigma sigma_y, BlurStyle blur_style=BlurStyle::kNormal)
Definition: filter_contents.cc:93
impeller::FilterContents::BlurStyle::kInner
@ kInner
Blurred inside, nothing outside.
impeller::Entity::TileMode
TileMode
Definition: entity.h:40
impeller::FilterContents::MakeYUVToRGBFilter
static std::shared_ptr< FilterContents > MakeYUVToRGBFilter(std::shared_ptr< Texture > y_texture, std::shared_ptr< Texture > uv_texture, YUVColorSpace yuv_color_space)
Definition: filter_contents.cc:150
impeller::FilterContents::MorphType
MorphType
Definition: filter_contents.h:34
impeller::FilterContents::BlurStyle::kOuter
@ kOuter
Nothing inside, blurred outside.
impeller::FilterContents::MakeMorphology
static std::shared_ptr< FilterContents > MakeMorphology(FilterInput::Ref input, Radius radius_x, Radius radius_y, MorphType morph_type)
Definition: filter_contents.cc:118
impeller::FilterContents::MorphType::kDilate
@ kDilate
impeller::FilterContents::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: filter_contents.cc:205
impeller::FilterContents::GetEntity
std::optional< Entity > GetEntity(const ContentContext &renderer, const Entity &entity, const std::optional< Rect > &coverage_hint) const
Create an Entity that renders this filter's output.
Definition: filter_contents.cc:269
impeller::FilterContents::SetLeafInputs
void SetLeafInputs(const FilterInput::Vector &inputs)
Replaces the set of all leaf FilterContents with a new set of FilterInputs.
Definition: filter_contents.cc:338
impeller::TPoint< Scalar >
impeller::FilterContents::MakeMatrixFilter
static std::shared_ptr< FilterContents > MakeMatrixFilter(FilterInput::Ref input, const Matrix &matrix, const SamplerDescriptor &desc)
Definition: filter_contents.cc:130
impeller::YUVColorSpace
YUVColorSpace
Definition: color.h:55
impeller::FilterContents::GetLocalTransform
virtual Matrix GetLocalTransform(const Matrix &parent_transform) const
Definition: filter_contents.cc:313
impeller::FilterContents::SetRenderingMode
virtual void SetRenderingMode(Entity::RenderingMode rendering_mode)
Marks this filter chain as applying in a subpass scenario.
Definition: filter_contents.cc:348
impeller::Entity::RenderingMode
RenderingMode
Definition: entity.h:26
impeller::FilterContents::MakeLocalMatrixFilter
static std::shared_ptr< FilterContents > MakeLocalMatrixFilter(FilterInput::Ref input, const Matrix &matrix)
Definition: filter_contents.cc:141
impeller::FilterInput::Vector
std::vector< FilterInput::Ref > Vector
Definition: filter_input.h:33
impeller::Contents
Definition: contents.h:34
impeller::FilterContents::~FilterContents
~FilterContents() override
impeller
Definition: aiks_context.cc:10
impeller::FilterContents::AsFilter
const FilterContents * AsFilter() const override
Cast to a filter. Returns nullptr if this Contents is not a filter.
Definition: filter_contents.cc:309
impeller::FilterContents
Definition: filter_contents.h:21