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