| Flutter Impeller |

image_filter.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/display_list/image_filter.h"
6
7 #include "flutter/display_list/effects/dl_color_sources.h"
8 #include "flutter/display_list/effects/dl_image_filters.h"
9 #include "fml/logging.h"
10 #include "impeller/display_list/color_filter.h"
11 #include "impeller/display_list/skia_conversions.h"
12 #include "impeller/entity/contents/filters/color_filter_contents.h"
13 #include "impeller/entity/contents/filters/filter_contents.h"
14 #include "impeller/entity/contents/filters/inputs/filter_input.h"
15
16 namespace impeller {
17
18 std::shared_ptr<FilterContents> WrapInput(const flutter::DlImageFilter* filter,
19 const FilterInput::Ref& input) {
20 FML_DCHECK(filter);
21
22 switch (filter->type()) {
23 case flutter::DlImageFilterType::kBlur: {
24 auto blur_filter = filter->asBlur();
25 FML_DCHECK(blur_filter);
26
27 return FilterContents::MakeGaussianBlur(
28 input, //
29 Sigma(blur_filter->sigma_x()), //
30 Sigma(blur_filter->sigma_y()), //
31 static_cast<Entity::TileMode>(blur_filter->tile_mode()), //
32 blur_filter->bounds(), //
33 FilterContents::BlurStyle::kNormal //
34 );
35 }
36 case flutter::DlImageFilterType::kDilate: {
37 auto dilate_filter = filter->asDilate();
38 FML_DCHECK(dilate_filter);
39
40 return FilterContents::MakeMorphology(
41 input, //
42 Radius(dilate_filter->radius_x()), //
43 Radius(dilate_filter->radius_y()), //
44 FilterContents::MorphType::kDilate //
45 );
46 }
47 case flutter::DlImageFilterType::kErode: {
48 auto erode_filter = filter->asErode();
49 FML_DCHECK(erode_filter);
50
51 return FilterContents::MakeMorphology(
52 input, //
53 Radius(erode_filter->radius_x()), //
54 Radius(erode_filter->radius_y()), //
55 FilterContents::MorphType::kErode //
56 );
57 }
58 case flutter::DlImageFilterType::kMatrix: {
59 auto matrix_filter = filter->asMatrix();
60 FML_DCHECK(matrix_filter);
61
62 auto matrix = matrix_filter->matrix();
63 auto desc =
64 skia_conversions::ToSamplerDescriptor(matrix_filter->sampling());
65 return FilterContents::MakeMatrixFilter(input, matrix, desc);
66 }
67 case flutter::DlImageFilterType::kLocalMatrix: {
68 auto matrix_filter = filter->asLocalMatrix();
69 FML_DCHECK(matrix_filter);
70 FML_DCHECK(matrix_filter->image_filter());
71
72 auto matrix = matrix_filter->matrix();
73 return FilterContents::MakeLocalMatrixFilter(
74 FilterInput::Make(
75 WrapInput(matrix_filter->image_filter().get(), input)),
76 matrix);
77 }
78 case flutter::DlImageFilterType::kColorFilter: {
79 auto image_color_filter = filter->asColorFilter();
80 FML_DCHECK(image_color_filter);
81 auto color_filter = image_color_filter->color_filter();
82 FML_DCHECK(color_filter);
83
84 // When color filters are used as image filters, set the color filter's
85 // "absorb opacity" flag to false. For image filters, the snapshot
86 // opacity needs to be deferred until the result of the filter chain is
87 // being blended with the layer.
88 return WrapWithGPUColorFilter(color_filter.get(), input,
89 ColorFilterContents::AbsorbOpacity::kNo);
90 }
91 case flutter::DlImageFilterType::kCompose: {
92 auto compose = filter->asCompose();
93 FML_DCHECK(compose);
94
95 auto outer_dl_filter = compose->outer();
96 auto inner_dl_filter = compose->inner();
97 if (!outer_dl_filter) {
98 return WrapInput(inner_dl_filter.get(), input);
99 }
100 if (!inner_dl_filter) {
101 return WrapInput(outer_dl_filter.get(), input);
102 }
103 FML_DCHECK(outer_dl_filter && inner_dl_filter);
104
105 return WrapInput(
106 outer_dl_filter.get(),
107 FilterInput::Make(WrapInput(inner_dl_filter.get(), input)));
108 }
109 case flutter::DlImageFilterType::kRuntimeEffect: {
110 const flutter::DlRuntimeEffectImageFilter* runtime_filter =
111 filter->asRuntimeEffectFilter();
112 FML_DCHECK(runtime_filter);
113 std::shared_ptr<impeller::RuntimeStage> runtime_stage =
114 runtime_filter->runtime_effect()->runtime_stage();
115
116 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
117 size_t index = 0;
118 for (const std::shared_ptr<flutter::DlColorSource>& sampler :
119 runtime_filter->samplers()) {
120 if (index == 0 && sampler == nullptr) {
121 // Insert placeholder for filter.
122 texture_inputs.push_back(
123 {.sampler_descriptor = skia_conversions::ToSamplerDescriptor({}),
124 .texture = nullptr});
125 continue;
126 }
127 if (sampler == nullptr) {
128 return nullptr;
129 }
130 auto* image = sampler->asImage();
131 if (!image) {
132 return nullptr;
133 }
134 FML_DCHECK(image->image()->impeller_texture());
135 index++;
136 texture_inputs.push_back({
137 .sampler_descriptor =
138 skia_conversions::ToSamplerDescriptor(image->sampling()),
139 .texture = image->image()->impeller_texture(),
140 });
141 }
142 return FilterContents::MakeRuntimeEffect(input, std::move(runtime_stage),
143 runtime_filter->uniform_data(),
144 std::move(texture_inputs));
145 }
146 }
147 FML_UNREACHABLE();
148 }
149
150 } // namespace impeller
impeller::ColorFilterContents::AbsorbOpacity::kNo
@ kNo
impeller::Entity::TileMode
TileMode
Definition: entity.h:48
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::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.
impeller::FilterContents::MorphType::kErode
@ kErode
impeller::FilterContents::MorphType::kDilate
@ kDilate
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::MakeLocalMatrixFilter
static std::shared_ptr< FilterContents > MakeLocalMatrixFilter(FilterInput::Ref input, const Matrix &matrix)
Definition: filter_contents.cc:100
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::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::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
color_filter_contents.h
color_filter.h
image_filter.h
filter_contents.h
filter_input.h
impeller::skia_conversions::ToSamplerDescriptor
impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
Definition: skia_conversions.cc:24
impeller
Definition: allocation.cc:12
impeller::WrapWithGPUColorFilter
std::shared_ptr< ColorFilterContents > WrapWithGPUColorFilter(const flutter::DlColorFilter *filter, const std::shared_ptr< FilterInput > &input, ColorFilterContents::AbsorbOpacity absorb_opacity)
Definition: color_filter.cc:24
impeller::WrapInput
std::shared_ptr< FilterContents > WrapInput(const flutter::DlImageFilter *filter, const FilterInput::Ref &input)
Generate a new FilterContents using this filter's configuration.
Definition: image_filter.cc:18
skia_conversions.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::Sigma
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32