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 
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"
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 
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(), //
34  );
35  }
36  case flutter::DlImageFilterType::kDilate: {
37  auto dilate_filter = filter->asDilate();
38  FML_DCHECK(dilate_filter);
39 
41  input, //
42  Radius(dilate_filter->radius_x()), //
43  Radius(dilate_filter->radius_y()), //
45  );
46  }
47  case flutter::DlImageFilterType::kErode: {
48  auto erode_filter = filter->asErode();
49  FML_DCHECK(erode_filter);
50 
52  input, //
53  Radius(erode_filter->radius_x()), //
54  Radius(erode_filter->radius_y()), //
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();
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,
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
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)
@ kNormal
Blurred inside and outside.
static std::shared_ptr< FilterContents > MakeMorphology(FilterInput::Ref input, Radius radius_x, Radius radius_y, MorphType morph_type)
static std::shared_ptr< FilterContents > MakeLocalMatrixFilter(FilterInput::Ref input, const Matrix &matrix)
static std::shared_ptr< FilterContents > MakeMatrixFilter(FilterInput::Ref input, const Matrix &matrix, const SamplerDescriptor &desc)
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)
std::shared_ptr< FilterInput > Ref
Definition: filter_input.h:32
static FilterInput::Ref Make(Variant input, bool msaa_enabled=true)
Definition: filter_input.cc:19
impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
std::shared_ptr< ColorFilterContents > WrapWithGPUColorFilter(const flutter::DlColorFilter *filter, const std::shared_ptr< FilterInput > &input, ColorFilterContents::AbsorbOpacity absorb_opacity)
Definition: color_filter.cc:24
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
For convolution filters, the "radius" is the size of the convolution kernel to use on the local space...
Definition: sigma.h:48
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32