Skip to content

Commit 106a12d

Browse files
bdero0xZOne
authored andcommitted
[Impeller] Return entity from filters instead of a snapshot (flutter#39560)
1 parent 10ae6da commit 106a12d

24 files changed

+232
-176
lines changed

impeller/entity/contents/contents.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "fml/logging.h"
99
#include "impeller/entity/contents/content_context.h"
10+
#include "impeller/entity/contents/texture_contents.h"
1011
#include "impeller/renderer/command_buffer.h"
1112
#include "impeller/renderer/formats.h"
1213
#include "impeller/renderer/render_pass.h"
@@ -35,6 +36,30 @@ ContentContextOptions OptionsFromPassAndEntity(const RenderPass& pass,
3536
return opts;
3637
}
3738

39+
std::optional<Entity> Contents::EntityFromSnapshot(
40+
const std::optional<Snapshot>& snapshot,
41+
BlendMode blend_mode,
42+
uint32_t stencil_depth) {
43+
if (!snapshot.has_value()) {
44+
return std::nullopt;
45+
}
46+
47+
auto texture_rect = Rect::MakeSize(snapshot->texture->GetSize());
48+
49+
auto contents = TextureContents::MakeRect(texture_rect);
50+
contents->SetTexture(snapshot->texture);
51+
contents->SetSamplerDescriptor(snapshot->sampler_descriptor);
52+
contents->SetSourceRect(texture_rect);
53+
contents->SetOpacity(snapshot->opacity);
54+
55+
Entity entity;
56+
entity.SetBlendMode(blend_mode);
57+
entity.SetStencilDepth(stencil_depth);
58+
entity.SetTransformation(snapshot->transform);
59+
entity.SetContents(contents);
60+
return entity;
61+
}
62+
3863
Contents::Contents() = default;
3964

4065
Contents::~Contents() = default;

impeller/entity/contents/contents.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <vector>
1010

1111
#include "flutter/fml/macros.h"
12+
#include "impeller/geometry/color.h"
1213
#include "impeller/geometry/rect.h"
1314
#include "impeller/renderer/sampler_descriptor.h"
1415
#include "impeller/renderer/snapshot.h"
@@ -40,6 +41,12 @@ class Contents {
4041
std::optional<Rect> coverage = std::nullopt;
4142
};
4243

44+
/// @brief Create an entity that renders a given snapshot.
45+
static std::optional<Entity> EntityFromSnapshot(
46+
const std::optional<Snapshot>& snapshot,
47+
BlendMode blend_mode = BlendMode::kSourceOver,
48+
uint32_t stencil_depth = 0);
49+
4350
virtual bool Render(const ContentContext& renderer,
4451
const Entity& entity,
4552
RenderPass& pass) const = 0;

impeller/entity/contents/filters/blend_filter_contents.cc

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "impeller/renderer/formats.h"
1818
#include "impeller/renderer/render_pass.h"
1919
#include "impeller/renderer/sampler_library.h"
20+
#include "impeller/renderer/snapshot.h"
2021

2122
namespace impeller {
2223

@@ -30,7 +31,7 @@ using PipelineProc = std::shared_ptr<Pipeline<PipelineDescriptor>> (
3031
ContentContext::*)(ContentContextOptions) const;
3132

3233
template <typename TPipeline>
33-
static std::optional<Snapshot> AdvancedBlend(
34+
static std::optional<Entity> AdvancedBlend(
3435
const FilterInput::Vector& inputs,
3536
const ContentContext& renderer,
3637
const Entity& entity,
@@ -67,11 +68,19 @@ static std::optional<Snapshot> AdvancedBlend(
6768
if (!foreground_color.has_value()) {
6869
src_snapshot = inputs[1]->GetSnapshot(renderer, entity);
6970
if (!src_snapshot.has_value()) {
70-
return dst_snapshot;
71+
if (!dst_snapshot.has_value()) {
72+
return std::nullopt;
73+
}
74+
return Contents::EntityFromSnapshot(dst_snapshot, entity.GetBlendMode(),
75+
entity.GetStencilDepth());
7176
}
7277
auto maybe_src_uvs = src_snapshot->GetCoverageUVs(coverage);
7378
if (!maybe_src_uvs.has_value()) {
74-
return dst_snapshot;
79+
if (!dst_snapshot.has_value()) {
80+
return std::nullopt;
81+
}
82+
return Contents::EntityFromSnapshot(dst_snapshot, entity.GetBlendMode(),
83+
entity.GetStencilDepth());
7584
}
7685
src_uvs = maybe_src_uvs.value();
7786
}
@@ -147,17 +156,19 @@ static std::optional<Snapshot> AdvancedBlend(
147156
}
148157
out_texture->SetLabel("Advanced Blend Filter Texture");
149158

150-
return Snapshot{.texture = out_texture,
151-
.transform = Matrix::MakeTranslation(coverage.origin),
152-
// Since we absorbed the transform of the inputs and used the
153-
// respective snapshot sampling modes when blending, pass on
154-
// the default NN clamp sampler.
155-
.sampler_descriptor = {},
156-
.opacity = (absorb_opacity ? 1.0f : dst_snapshot->opacity) *
157-
alpha.value_or(1.0)};
159+
return Contents::EntityFromSnapshot(
160+
Snapshot{.texture = out_texture,
161+
.transform = Matrix::MakeTranslation(coverage.origin),
162+
// Since we absorbed the transform of the inputs and used the
163+
// respective snapshot sampling modes when blending, pass on
164+
// the default NN clamp sampler.
165+
.sampler_descriptor = {},
166+
.opacity = (absorb_opacity ? 1.0f : dst_snapshot->opacity) *
167+
alpha.value_or(1.0)},
168+
entity.GetBlendMode(), entity.GetStencilDepth());
158169
}
159170

160-
static std::optional<Snapshot> PipelineBlend(
171+
static std::optional<Entity> PipelineBlend(
161172
const FilterInput::Vector& inputs,
162173
const ContentContext& renderer,
163174
const Entity& entity,
@@ -269,28 +280,31 @@ static std::optional<Snapshot> PipelineBlend(
269280
}
270281
out_texture->SetLabel("Pipeline Blend Filter Texture");
271282

272-
return Snapshot{.texture = out_texture,
273-
.transform = Matrix::MakeTranslation(coverage.origin),
274-
// Since we absorbed the transform of the inputs and used the
275-
// respective snapshot sampling modes when blending, pass on
276-
// the default NN clamp sampler.
277-
.sampler_descriptor = {},
278-
.opacity = (absorb_opacity ? 1.0f : dst_snapshot->opacity) *
279-
alpha.value_or(1.0)};
283+
return Contents::EntityFromSnapshot(
284+
Snapshot{.texture = out_texture,
285+
.transform = Matrix::MakeTranslation(coverage.origin),
286+
// Since we absorbed the transform of the inputs and used the
287+
// respective snapshot sampling modes when blending, pass on
288+
// the default NN clamp sampler.
289+
.sampler_descriptor = {},
290+
.opacity = (absorb_opacity ? 1.0f : dst_snapshot->opacity) *
291+
alpha.value_or(1.0)},
292+
entity.GetBlendMode(), entity.GetStencilDepth());
280293
}
281294

282-
#define BLEND_CASE(mode) \
283-
case BlendMode::k##mode: \
284-
advanced_blend_proc_ = \
285-
[](const FilterInput::Vector& inputs, const ContentContext& renderer, \
286-
const Entity& entity, const Rect& coverage, \
287-
std::optional<Color> fg_color, bool absorb_opacity, \
288-
std::optional<Scalar> alpha) { \
289-
PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \
290-
return AdvancedBlend<BlendScreenPipeline>(inputs, renderer, entity, \
291-
coverage, fg_color, \
292-
absorb_opacity, p, alpha); \
293-
}; \
295+
#define BLEND_CASE(mode) \
296+
case BlendMode::k##mode: \
297+
advanced_blend_proc_ = [](const FilterInput::Vector& inputs, \
298+
const ContentContext& renderer, \
299+
const Entity& entity, const Rect& coverage, \
300+
std::optional<Color> fg_color, \
301+
bool absorb_opacity, \
302+
std::optional<Scalar> alpha) { \
303+
PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \
304+
return AdvancedBlend<Blend##mode##Pipeline>(inputs, renderer, entity, \
305+
coverage, fg_color, \
306+
absorb_opacity, p, alpha); \
307+
}; \
294308
break;
295309

296310
void BlendFilterContents::SetBlendMode(BlendMode blend_mode) {
@@ -328,7 +342,7 @@ void BlendFilterContents::SetForegroundColor(std::optional<Color> color) {
328342
foreground_color_ = color;
329343
}
330344

331-
std::optional<Snapshot> BlendFilterContents::RenderFilter(
345+
std::optional<Entity> BlendFilterContents::RenderFilter(
332346
const FilterInput::Vector& inputs,
333347
const ContentContext& renderer,
334348
const Entity& entity,

impeller/entity/contents/filters/blend_filter_contents.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ namespace impeller {
1111

1212
class BlendFilterContents : public ColorFilterContents {
1313
public:
14-
using AdvancedBlendProc = std::function<std::optional<Snapshot>(
15-
const FilterInput::Vector& inputs,
16-
const ContentContext& renderer,
17-
const Entity& entity,
18-
const Rect& coverage,
19-
std::optional<Color> foreground_color,
20-
bool absorb_opacity,
21-
std::optional<Scalar> alpha)>;
14+
using AdvancedBlendProc =
15+
std::function<std::optional<Entity>(const FilterInput::Vector& inputs,
16+
const ContentContext& renderer,
17+
const Entity& entity,
18+
const Rect& coverage,
19+
std::optional<Color> foreground_color,
20+
bool absorb_opacity,
21+
std::optional<Scalar> alpha)>;
2222

2323
BlendFilterContents();
2424

@@ -32,11 +32,11 @@ class BlendFilterContents : public ColorFilterContents {
3232

3333
private:
3434
// |FilterContents|
35-
std::optional<Snapshot> RenderFilter(const FilterInput::Vector& inputs,
36-
const ContentContext& renderer,
37-
const Entity& entity,
38-
const Matrix& effect_transform,
39-
const Rect& coverage) const override;
35+
std::optional<Entity> RenderFilter(const FilterInput::Vector& inputs,
36+
const ContentContext& renderer,
37+
const Entity& entity,
38+
const Matrix& effect_transform,
39+
const Rect& coverage) const override;
4040

4141
BlendMode blend_mode_ = BlendMode::kSourceOver;
4242
AdvancedBlendProc advanced_blend_proc_;

impeller/entity/contents/filters/border_mask_blur_filter_contents.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void BorderMaskBlurFilterContents::SetBlurStyle(BlurStyle blur_style) {
4747
}
4848
}
4949

50-
std::optional<Snapshot> BorderMaskBlurFilterContents::RenderFilter(
50+
std::optional<Entity> BorderMaskBlurFilterContents::RenderFilter(
5151
const FilterInput::Vector& inputs,
5252
const ContentContext& renderer,
5353
const Entity& entity,
@@ -126,9 +126,11 @@ std::optional<Snapshot> BorderMaskBlurFilterContents::RenderFilter(
126126
}
127127
out_texture->SetLabel("BorderMaskBlurFilter Texture");
128128

129-
return Snapshot{.texture = out_texture,
130-
.transform = Matrix::MakeTranslation(coverage.origin),
131-
.opacity = input_snapshot->opacity};
129+
return Contents::EntityFromSnapshot(
130+
Snapshot{.texture = out_texture,
131+
.transform = Matrix::MakeTranslation(coverage.origin),
132+
.opacity = input_snapshot->opacity},
133+
entity.GetBlendMode(), entity.GetStencilDepth());
132134
}
133135

134136
std::optional<Rect> BorderMaskBlurFilterContents::GetFilterCoverage(

impeller/entity/contents/filters/border_mask_blur_filter_contents.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,11 @@ class BorderMaskBlurFilterContents final : public FilterContents {
2929

3030
private:
3131
// |FilterContents|
32-
std::optional<Snapshot> RenderFilter(
33-
const FilterInput::Vector& input_textures,
34-
const ContentContext& renderer,
35-
const Entity& entity,
36-
const Matrix& effect_transform,
37-
const Rect& coverage) const override;
32+
std::optional<Entity> RenderFilter(const FilterInput::Vector& input_textures,
33+
const ContentContext& renderer,
34+
const Entity& entity,
35+
const Matrix& effect_transform,
36+
const Rect& coverage) const override;
3837

3938
Sigma sigma_x_;
4039
Sigma sigma_y_;

impeller/entity/contents/filters/color_matrix_filter_contents.cc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void ColorMatrixFilterContents::SetMatrix(const ColorMatrix& matrix) {
2323
matrix_ = matrix;
2424
}
2525

26-
std::optional<Snapshot> ColorMatrixFilterContents::RenderFilter(
26+
std::optional<Entity> ColorMatrixFilterContents::RenderFilter(
2727
const FilterInput::Vector& inputs,
2828
const ContentContext& renderer,
2929
const Entity& entity,
@@ -104,11 +104,12 @@ std::optional<Snapshot> ColorMatrixFilterContents::RenderFilter(
104104
}
105105
out_texture->SetLabel("ColorMatrixFilter Texture");
106106

107-
return Snapshot{
108-
.texture = out_texture,
109-
.transform = input_snapshot->transform,
110-
.sampler_descriptor = input_snapshot->sampler_descriptor,
111-
.opacity = GetAbsorbOpacity() ? 1.0f : input_snapshot->opacity};
107+
return Contents::EntityFromSnapshot(
108+
Snapshot{.texture = out_texture,
109+
.transform = input_snapshot->transform,
110+
.sampler_descriptor = input_snapshot->sampler_descriptor,
111+
.opacity = GetAbsorbOpacity() ? 1.0f : input_snapshot->opacity},
112+
entity.GetBlendMode(), entity.GetStencilDepth());
112113
}
113114

114115
} // namespace impeller

impeller/entity/contents/filters/color_matrix_filter_contents.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,11 @@ class ColorMatrixFilterContents final : public ColorFilterContents {
2424

2525
private:
2626
// |FilterContents|
27-
std::optional<Snapshot> RenderFilter(
28-
const FilterInput::Vector& input_textures,
29-
const ContentContext& renderer,
30-
const Entity& entity,
31-
const Matrix& effect_transform,
32-
const Rect& coverage) const override;
27+
std::optional<Entity> RenderFilter(const FilterInput::Vector& input_textures,
28+
const ContentContext& renderer,
29+
const Entity& entity,
30+
const Matrix& effect_transform,
31+
const Rect& coverage) const override;
3332

3433
ColorMatrix matrix_;
3534

impeller/entity/contents/filters/filter_contents.cc

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -167,26 +167,11 @@ bool FilterContents::Render(const ContentContext& renderer,
167167

168168
// Run the filter.
169169

170-
auto maybe_snapshot = RenderToSnapshot(renderer, entity);
171-
if (!maybe_snapshot.has_value()) {
172-
return false;
170+
auto maybe_entity = GetEntity(renderer, entity);
171+
if (!maybe_entity.has_value()) {
172+
return true;
173173
}
174-
auto& snapshot = maybe_snapshot.value();
175-
176-
// Draw the result texture, respecting the transform and clip stack.
177-
178-
auto texture_rect = Rect::MakeSize(snapshot.texture->GetSize());
179-
auto contents = TextureContents::MakeRect(texture_rect);
180-
contents->SetTexture(snapshot.texture);
181-
contents->SetSamplerDescriptor(snapshot.sampler_descriptor);
182-
contents->SetSourceRect(texture_rect);
183-
contents->SetOpacity(snapshot.opacity);
184-
185-
Entity e;
186-
e.SetBlendMode(entity.GetBlendMode());
187-
e.SetStencilDepth(entity.GetStencilDepth());
188-
e.SetTransformation(snapshot.transform);
189-
return contents->Render(renderer, e, pass);
174+
return maybe_entity->Render(renderer, pass);
190175
}
191176

192177
std::optional<Rect> FilterContents::GetLocalCoverage(
@@ -234,11 +219,8 @@ std::optional<Rect> FilterContents::GetFilterCoverage(
234219
return result;
235220
}
236221

237-
std::optional<Snapshot> FilterContents::RenderToSnapshot(
238-
const ContentContext& renderer,
239-
const Entity& entity,
240-
const std::optional<SamplerDescriptor>& sampler_descriptor,
241-
bool msaa_enabled) const {
222+
std::optional<Entity> FilterContents::GetEntity(const ContentContext& renderer,
223+
const Entity& entity) const {
242224
Entity entity_with_local_transform = entity;
243225
entity_with_local_transform.SetTransformation(
244226
GetTransform(entity.GetTransformation()));
@@ -252,6 +234,21 @@ std::optional<Snapshot> FilterContents::RenderToSnapshot(
252234
effect_transform_, coverage.value());
253235
}
254236

237+
std::optional<Snapshot> FilterContents::RenderToSnapshot(
238+
const ContentContext& renderer,
239+
const Entity& entity,
240+
const std::optional<SamplerDescriptor>& sampler_descriptor,
241+
bool msaa_enabled) const {
242+
// Resolve the render instruction (entity) from the filter and render it to a
243+
// snapshot.
244+
if (std::optional<Entity> result = GetEntity(renderer, entity);
245+
result.has_value()) {
246+
return result->GetContents()->RenderToSnapshot(renderer, result.value());
247+
}
248+
249+
return std::nullopt;
250+
}
251+
255252
Matrix FilterContents::GetLocalTransform(const Matrix& parent_transform) const {
256253
return Matrix();
257254
}

0 commit comments

Comments
 (0)