| Flutter Impeller |

filter_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/filters/filter_contents.h"
6
7 #include <algorithm>
8 #include <cmath>
9 #include <cstddef>
10 #include <memory>
11 #include <optional>
12 #include <tuple>
13 #include <utility>
14
15 #include "flutter/fml/logging.h"
16 #include "impeller/core/formats.h"
17 #include "impeller/entity/contents/content_context.h"
18 #include "impeller/entity/contents/filters/border_mask_blur_filter_contents.h"
19 #include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h"
20 #include "impeller/entity/contents/filters/inputs/filter_input.h"
21 #include "impeller/entity/contents/filters/local_matrix_filter_contents.h"
22 #include "impeller/entity/contents/filters/matrix_filter_contents.h"
23 #include "impeller/entity/contents/filters/morphology_filter_contents.h"
24 #include "impeller/entity/contents/filters/runtime_effect_filter_contents.h"
25 #include "impeller/entity/contents/filters/yuv_to_rgb_filter_contents.h"
26 #include "impeller/entity/contents/texture_contents.h"
27 #include "impeller/entity/entity.h"
28 #include "impeller/renderer/command_buffer.h"
29 #include "impeller/renderer/render_pass.h"
30 #include "impeller/runtime_stage/runtime_stage.h"
31
32 namespace impeller {
33
34 const int32_t FilterContents::kBlurFilterRequiredMipCount =
35 GaussianBlurFilterContents::kBlurFilterRequiredMipCount;
36
37 std::shared_ptr<FilterContents> FilterContents::MakeGaussianBlur(
38 const FilterInput::Ref& input,
39 Sigma sigma_x,
40 Sigma sigma_y,
41 Entity::TileMode tile_mode,
42 std::optional<Rect> bounds,
43 FilterContents::BlurStyle mask_blur_style,
44 const Geometry* mask_geometry) {
45 auto blur = std::make_shared<GaussianBlurFilterContents>(
46 sigma_x.sigma, sigma_y.sigma, tile_mode, bounds, mask_blur_style,
47 mask_geometry);
48 blur->SetInputs({input});
49 return blur;
50 }
51
52 std::shared_ptr<FilterContents> FilterContents::MakeBorderMaskBlur(
53 FilterInput::Ref input,
54 Sigma sigma_x,
55 Sigma sigma_y,
56 BlurStyle blur_style) {
57 auto filter = std::make_shared<BorderMaskBlurFilterContents>();
58 filter->SetInputs({std::move(input)});
59 filter->SetSigma(sigma_x, sigma_y);
60 filter->SetBlurStyle(blur_style);
61 return filter;
62 }
63
64 std::shared_ptr<FilterContents> FilterContents::MakeDirectionalMorphology(
65 FilterInput::Ref input,
66 Radius radius,
67 Vector2 direction,
68 MorphType morph_type) {
69 auto filter = std::make_shared<DirectionalMorphologyFilterContents>();
70 filter->SetInputs({std::move(input)});
71 filter->SetRadius(radius);
72 filter->SetDirection(direction);
73 filter->SetMorphType(morph_type);
74 return filter;
75 }
76
77 std::shared_ptr<FilterContents> FilterContents::MakeMorphology(
78 FilterInput::Ref input,
79 Radius radius_x,
80 Radius radius_y,
81 MorphType morph_type) {
82 auto x_morphology = MakeDirectionalMorphology(std::move(input), radius_x,
83 Point(1, 0), morph_type);
84 auto y_morphology = MakeDirectionalMorphology(
85 FilterInput::Make(x_morphology), radius_y, Point(0, 1), morph_type);
86 return y_morphology;
87 }
88
89 std::shared_ptr<FilterContents> FilterContents::MakeMatrixFilter(
90 FilterInput::Ref input,
91 const Matrix& matrix,
92 const SamplerDescriptor& desc) {
93 auto filter = std::make_shared<MatrixFilterContents>();
94 filter->SetInputs({std::move(input)});
95 filter->SetMatrix(matrix);
96 filter->SetSamplerDescriptor(desc);
97 return filter;
98 }
99
100 std::shared_ptr<FilterContents> FilterContents::MakeLocalMatrixFilter(
101 FilterInput::Ref input,
102 const Matrix& matrix) {
103 auto filter = std::make_shared<LocalMatrixFilterContents>();
104 filter->SetInputs({std::move(input)});
105 filter->SetMatrix(matrix);
106 return filter;
107 }
108
109 std::shared_ptr<FilterContents> FilterContents::MakeYUVToRGBFilter(
110 std::shared_ptr<Texture> y_texture,
111 std::shared_ptr<Texture> uv_texture,
112 YUVColorSpace yuv_color_space) {
113 auto filter = std::make_shared<impeller::YUVToRGBFilterContents>();
114 filter->SetInputs({impeller::FilterInput::Make(y_texture),
115 impeller::FilterInput::Make(uv_texture)});
116 filter->SetYUVColorSpace(yuv_color_space);
117 return filter;
118 }
119
120 std::shared_ptr<FilterContents> FilterContents::MakeRuntimeEffect(
121 FilterInput::Ref input,
122 std::shared_ptr<RuntimeStage> runtime_stage,
123 std::shared_ptr<std::vector<uint8_t>> uniforms,
124 std::vector<RuntimeEffectContents::TextureInput> texture_inputs) {
125 auto filter = std::make_shared<impeller::RuntimeEffectFilterContents>();
126 filter->SetInputs({std::move(input)});
127 filter->SetRuntimeStage(std::move(runtime_stage));
128 filter->SetUniforms(std::move(uniforms));
129 filter->SetTextureInputs(std::move(texture_inputs));
130 return filter;
131 }
132
133 FilterContents::FilterContents() = default;
134
135 FilterContents::~FilterContents() = default;
136
137 void FilterContents::SetInputs(FilterInput::Vector inputs) {
138 inputs_ = std::move(inputs);
139 }
140
141 void FilterContents::SetEffectTransform(const Matrix& effect_transform) {
142 effect_transform_ = effect_transform;
143
144 for (auto& input : inputs_) {
145 input->SetEffectTransform(effect_transform);
146 }
147 }
148
149 bool FilterContents::Render(const ContentContext& renderer,
150 const Entity& entity,
151 RenderPass& pass) const {
152 auto filter_coverage = GetCoverage(entity);
153 if (!filter_coverage.has_value()) {
154 return true;
155 }
156
157 // Run the filter.
158
159 auto maybe_entity = GetEntity(renderer, entity, GetCoverageHint());
160 if (!maybe_entity.has_value()) {
161 return true;
162 }
163 maybe_entity->SetClipDepth(entity.GetClipDepth());
164 return maybe_entity->Render(renderer, pass);
165 }
166
167 std::optional<Rect> FilterContents::GetLocalCoverage(
168 const Entity& local_entity) const {
169 auto coverage = GetFilterCoverage(inputs_, local_entity, effect_transform_);
170 auto coverage_hint = GetCoverageHint();
171 if (coverage_hint.has_value() && coverage.has_value()) {
172 coverage = coverage->Intersection(coverage_hint.value());
173 }
174
175 return coverage;
176 }
177
178 std::optional<Rect> FilterContents::GetCoverage(const Entity& entity) const {
179 Entity entity_with_local_transform = entity.Clone();
180 entity_with_local_transform.SetTransform(GetTransform(entity.GetTransform()));
181
182 return GetLocalCoverage(entity_with_local_transform);
183 }
184
185 std::optional<Rect> FilterContents::GetFilterCoverage(
186 const FilterInput::Vector& inputs,
187 const Entity& entity,
188 const Matrix& effect_transform) const {
189 // The default coverage of FilterContents is just the union of its inputs'
190 // coverage. FilterContents implementations may choose to adjust this
191 // coverage depending on the use case.
192
193 if (inputs_.empty()) {
194 return std::nullopt;
195 }
196
197 std::optional<Rect> result;
198 for (const auto& input : inputs) {
199 auto coverage = input->GetCoverage(entity);
200 if (!coverage.has_value()) {
201 continue;
202 }
203 if (!result.has_value()) {
204 result = coverage;
205 continue;
206 }
207 result = result->Union(coverage.value());
208 }
209 return result;
210 }
211
212 std::optional<Rect> FilterContents::GetSourceCoverage(
213 const Matrix& effect_transform,
214 const Rect& output_limit) const {
215 auto filter_input_coverage =
216 GetFilterSourceCoverage(effect_transform_, output_limit);
217
218 if (!filter_input_coverage.has_value()) {
219 return std::nullopt;
220 }
221
222 std::optional<Rect> inputs_coverage;
223 for (const auto& input : inputs_) {
224 auto input_coverage = input->GetSourceCoverage(
225 effect_transform, filter_input_coverage.value());
226 if (!input_coverage.has_value()) {
227 return std::nullopt;
228 }
229 inputs_coverage = Rect::Union(inputs_coverage, input_coverage.value());
230 }
231 return inputs_coverage;
232 }
233
234 std::optional<Entity> FilterContents::GetEntity(
235 const ContentContext& renderer,
236 const Entity& entity,
237 const std::optional<Rect>& coverage_hint) const {
238 Entity entity_with_local_transform = entity.Clone();
239 entity_with_local_transform.SetTransform(GetTransform(entity.GetTransform()));
240
241 std::optional<Rect> coverage = GetLocalCoverage(entity_with_local_transform);
242 if (!coverage.has_value() || coverage->IsEmpty()) {
243 return std::nullopt;
244 }
245
246 return RenderFilter(inputs_, //
247 renderer, //
248 entity_with_local_transform, //
249 effect_transform_, //
250 coverage.value(), //
251 coverage_hint //
252 );
253 }
254
255 std::optional<Snapshot> FilterContents::RenderToSnapshot(
256 const ContentContext& renderer,
257 const Entity& entity,
258 const SnapshotOptions& options) const {
259 // Resolve the render instruction (entity) from the filter and render it to a
260 // snapshot.
261 if (std::optional<Entity> result =
262 GetEntity(renderer, entity, options.coverage_limit);
263 result.has_value()) {
264 return result->GetContents()->RenderToSnapshot(
265 renderer, result.value(),
266 {.coverage_limit = options.coverage_limit,
267 .sampler_descriptor = std::nullopt,
268 .msaa_enabled = true,
269 .mip_count = options.mip_count,
270 .label = options.label});
271 }
272
273 return std::nullopt;
274 }
275
276 Matrix FilterContents::GetLocalTransform(const Matrix& parent_transform) const {
277 return Matrix();
278 }
279
280 Matrix FilterContents::GetTransform(const Matrix& parent_transform) const {
281 return parent_transform * GetLocalTransform(parent_transform);
282 }
283
284 void FilterContents::SetRenderingMode(Entity::RenderingMode rendering_mode) {
285 for (auto& input : inputs_) {
286 input->SetRenderingMode(rendering_mode);
287 }
288 }
289
290 } // namespace impeller
border_mask_blur_filter_contents.h
impeller::ContentContext
Definition: content_context.h:122
impeller::Contents::GetCoverageHint
const std::optional< Rect > & GetCoverageHint() const
Definition: contents.cc:137
impeller::Entity
Definition: entity.h:26
impeller::Entity::SetTransform
void SetTransform(const Matrix &transform)
Set the global transform matrix for this Entity.
Definition: entity.cc:62
impeller::Entity::TileMode
TileMode
Definition: entity.h:48
impeller::Entity::RenderingMode
RenderingMode
Definition: entity.h:33
impeller::Entity::Clone
Entity Clone() const
Definition: entity.cc:159
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:46
impeller::Entity::GetClipDepth
uint32_t GetClipDepth() const
Definition: entity.cc:86
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, std::optional< Rect > bounds=std::nullopt, BlurStyle mask_blur_style=BlurStyle::kNormal, const Geometry *mask_geometry=nullptr)
Definition: filter_contents.cc:37
impeller::FilterContents::kBlurFilterRequiredMipCount
static const int32_t kBlurFilterRequiredMipCount
Definition: filter_contents.h:26
impeller::FilterContents::BlurStyle
BlurStyle
Definition: filter_contents.h:28
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:234
impeller::FilterContents::MakeDirectionalMorphology
static std::shared_ptr< FilterContents > MakeDirectionalMorphology(FilterInput::Ref input, Radius radius, Vector2 direction, MorphType morph_type)
Definition: filter_contents.cc:64
impeller::FilterContents::FilterContents
FilterContents()
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:178
impeller::FilterContents::~FilterContents
~FilterContents() override
impeller::FilterContents::GetTransform
Matrix GetTransform(const Matrix &parent_transform) const
Definition: filter_contents.cc:280
impeller::FilterContents::MorphType
MorphType
Definition: filter_contents.h:39
impeller::FilterContents::Render
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Definition: filter_contents.cc:149
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:77
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:52
impeller::FilterContents::MakeLocalMatrixFilter
static std::shared_ptr< FilterContents > MakeLocalMatrixFilter(FilterInput::Ref input, const Matrix &matrix)
Definition: filter_contents.cc:100
impeller::FilterContents::RenderToSnapshot
std::optional< Snapshot > RenderToSnapshot(const ContentContext &renderer, const Entity &entity, const SnapshotOptions &options) const override
Render this contents to a snapshot, respecting the entity's transform, path, clip depth,...
Definition: filter_contents.cc:255
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:137
impeller::FilterContents::SetRenderingMode
virtual void SetRenderingMode(Entity::RenderingMode rendering_mode)
Marks this filter chain as applying in a subpass scenario.
Definition: filter_contents.cc:284
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:212
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:141
impeller::FilterContents::MakeMatrixFilter
static std::shared_ptr< FilterContents > MakeMatrixFilter(FilterInput::Ref input, const Matrix &matrix, const SamplerDescriptor &desc)
Definition: filter_contents.cc:89
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:109
impeller::FilterContents::MakeRuntimeEffect
static std::shared_ptr< FilterContents > MakeRuntimeEffect(FilterInput::Ref input, std::shared_ptr< RuntimeStage > runtime_stage, std::shared_ptr< std::vector< uint8_t >> uniforms, std::vector< RuntimeEffectContents::TextureInput > texture_inputs)
Definition: filter_contents.cc:120
impeller::FilterContents::GetLocalTransform
virtual Matrix GetLocalTransform(const Matrix &parent_transform) const
Definition: filter_contents.cc:276
impeller::FilterInput::Ref
std::shared_ptr< FilterInput > Ref
Definition: filter_input.h:32
impeller::FilterInput::Make
static FilterInput::Ref Make(Variant input, bool msaa_enabled=true)
Definition: filter_input.cc:19
impeller::FilterInput::Vector
std::vector< FilterInput::Ref > Vector
Definition: filter_input.h:33
impeller::Geometry
Definition: geometry.h:50
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:30
command_buffer.h
content_context.h
formats.h
entity.h
filter_contents.h
filter_input.h
gaussian_blur_filter_contents.h
local_matrix_filter_contents.h
matrix_filter_contents.h
morphology_filter_contents.h
impeller
Definition: allocation.cc:12
impeller::YUVColorSpace
YUVColorSpace
Definition: color.h:54
impeller::Point
TPoint< Scalar > Point
Definition: point.h:425
render_pass.h
runtime_effect_filter_contents.h
runtime_stage.h
impeller::Contents::SnapshotOptions
Definition: contents.h:85
impeller::Contents::SnapshotOptions::coverage_limit
std::optional< Rect > coverage_limit
Definition: contents.h:86
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
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::SamplerDescriptor
Definition: sampler_descriptor.h:14
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::Sigma::sigma
Scalar sigma
Definition: sigma.h:33
impeller::TPoint< Scalar >
impeller::TRect< Scalar >
impeller::TRect< Scalar >::Union
constexpr TRect Union(const TRect &o) const
Definition: rect.h:513
texture_contents.h
yuv_to_rgb_filter_contents.h