Flutter Impeller
paint.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_DISPLAY_LIST_PAINT_H_
6 #define FLUTTER_IMPELLER_DISPLAY_LIST_PAINT_H_
7 
8 #include <memory>
9 
10 #include "display_list/effects/dl_color_filter.h"
11 #include "display_list/effects/dl_color_sources.h"
12 #include "display_list/effects/dl_image_filter.h"
21 #include "impeller/entity/entity.h"
26 
27 namespace impeller {
28 
29 struct Paint {
30  using ImageFilterProc = std::function<std::shared_ptr<FilterContents>(
32  const Matrix& effect_transform,
33  Entity::RenderingMode rendering_mode)>;
34  using MaskFilterProc = std::function<std::shared_ptr<FilterContents>(
36  bool is_solid_color,
37  const Matrix& effect_transform)>;
38  using ColorSourceProc = std::function<std::shared_ptr<ColorSourceContents>()>;
39 
40  /// @brief Whether or not a save layer with the provided paint can perform the
41  /// opacity peephole optimization.
42  static bool CanApplyOpacityPeephole(const Paint& paint) {
43  return paint.blend_mode == BlendMode::kSrcOver &&
44  paint.invert_colors == false &&
45  !paint.mask_blur_descriptor.has_value() &&
46  paint.image_filter == nullptr && paint.color_filter == nullptr;
47  }
48 
49  enum class Style {
50  kFill,
51  kStroke,
52  };
53 
57  /// Text mask blurs need to not apply the CTM to the blur kernel.
58  /// See: https://github.com/flutter/flutter/issues/115112
59  bool respect_ctm = true;
60 
61  std::shared_ptr<FilterContents> CreateMaskBlur(
62  std::shared_ptr<TextureContents> texture_contents,
63  FillRectGeometry* rect_geom) const;
64 
65  std::shared_ptr<FilterContents> CreateMaskBlur(
66  const FilterInput::Ref& input,
67  bool is_solid_color,
68  const Matrix& ctm) const;
69 
70  std::shared_ptr<Contents> CreateMaskBlur(
71  const Paint& paint,
72  const ContentContext& renderer,
73  const Geometry* geometry,
74  std::shared_ptr<ColorSourceContents> contents,
75  bool needs_color_filter,
76  FillRectGeometry* out_geom) const;
77  };
78 
80  const flutter::DlColorSource* color_source = nullptr;
81  const flutter::DlColorFilter* color_filter = nullptr;
82  const flutter::DlImageFilter* image_filter = nullptr;
83 
87  bool invert_colors = false;
88  bool anti_alias = true;
89 
90  std::optional<MaskBlurDescriptor> mask_blur_descriptor;
91 
92  /// @brief Return an optional StrokeParameters if this Paint is a stroked
93  /// Paint, otherwise return a nullopt.
94  /// @return An optional set of StrokeParameters
95  std::optional<StrokeParameters> GetStroke() const {
96  return (style == Style::kStroke) ? std::optional(stroke) : std::nullopt;
97  }
98 
99  /// @brief Wrap this paint's configured filters to the given contents.
100  /// @param[in] input The contents to wrap with paint's filters.
101  /// @return The filter-wrapped contents. If there are no filters that need
102  /// to be wrapped for the current paint configuration, the
103  /// original contents is returned.
104  std::shared_ptr<Contents> WithFilters(const ContentContext& renderer,
105  std::shared_ptr<Contents> input) const;
106 
107  /// @brief Wrap this paint's configured filters to the given contents of
108  /// subpass target.
109  /// @param[in] input The contents of subpass target to wrap with paint's
110  /// filters.
111  ///
112  /// @return The filter-wrapped contents. If there are no filters that need
113  /// to be wrapped for the current paint configuration, the
114  /// original contents is returned.
115  std::shared_ptr<Contents> WithFiltersForSubpassTarget(
116  const ContentContext& renderer,
117  std::shared_ptr<Contents> input,
118  const Matrix& effect_transform = Matrix()) const;
119 
120  /// @brief Whether this paint has a color filter that can apply opacity
121  bool HasColorFilter() const;
122 
123  /// @brief Create a `ColorSourceContents` representing this paint's
124  /// shader/colors.
125  /// @param[in] renderer The content context renderer.
126  /// @param[in] geometry The geometry the color source is drawn
127  /// onto.
128  /// @param[in] geometry_transform An optional transform representing a
129  /// layout/positioning transform applied to
130  /// the geometry. If provided, this is used to
131  /// adjust the color source's effect transform
132  /// to align it with the geometry's coordinate
133  /// space.
134  /// @return The generated color source contents.
135  std::shared_ptr<ColorSourceContents> CreateContents(
136  const ContentContext& renderer,
137  const Geometry* geometry,
138  const std::optional<Matrix>& geometry_transform = std::nullopt) const;
139 
140  std::shared_ptr<Contents> WithMaskBlur(std::shared_ptr<Contents> input,
141  bool is_solid_color,
142  const Matrix& ctm) const;
143 
144  std::shared_ptr<FilterContents> WithImageFilter(
145  const ContentContext& renderer,
146  const FilterInput::Variant& input,
147  const Matrix& effect_transform,
148  Entity::RenderingMode rendering_mode) const;
149 
150  /// @brief Convert display list colors + stops into impeller colors and
151  /// stops, taking care to ensure that the stops monotonically
152  /// increase from 0.0 to 1.0.
153  ///
154  /// The general process is:
155  /// * Ensure that the first gradient stop value is 0.0. If not, insert a
156  /// new stop with a value of 0.0 and use the first gradient color as this
157  /// new stops color.
158  /// * Ensure the last gradient stop value is 1.0. If not, insert a new stop
159  /// with a value of 1.0 and use the last gradient color as this stops color.
160  /// * Clamp all gradient values between the values of 0.0 and 1.0.
161  /// * For all stop values, ensure that the values are monotonically
162  /// increasing by clamping each value to a minimum of the previous stop
163  /// value and itself. For example, with stop values of 0.0, 0.5, 0.4, 1.0,
164  /// we would clamp such that the values were 0.0, 0.5, 0.5, 1.0.
165  static void ConvertStops(const flutter::DlGradientColorSourceBase* gradient,
166  std::vector<Color>& colors,
167  std::vector<float>& stops);
168 
169  private:
170  std::shared_ptr<Contents> WithColorFilter(
171  std::shared_ptr<Contents> input,
172  ColorFilterContents::AbsorbOpacity absorb_opacity =
174 };
175 
176 } // namespace impeller
177 
178 #endif // FLUTTER_IMPELLER_DISPLAY_LIST_PAINT_H_
std::shared_ptr< FilterInput > Ref
Definition: filter_input.h:32
std::variant< std::shared_ptr< FilterContents >, std::shared_ptr< Contents >, std::shared_ptr< Texture >, Rect > Variant
Definition: filter_input.h:37
BlendMode
Definition: color.h:58
static constexpr Color Black()
Definition: color.h:271
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
std::shared_ptr< FilterContents > CreateMaskBlur(std::shared_ptr< TextureContents > texture_contents, FillRectGeometry *rect_geom) const
Definition: paint.cc:376
FilterContents::BlurStyle style
Definition: paint.h:55
std::shared_ptr< FilterContents > WithImageFilter(const ContentContext &renderer, const FilterInput::Variant &input, const Matrix &effect_transform, Entity::RenderingMode rendering_mode) const
Definition: paint.cc:322
std::optional< StrokeParameters > GetStroke() const
Return an optional StrokeParameters if this Paint is a stroked Paint, otherwise return a nullopt.
Definition: paint.h:95
const flutter::DlColorFilter * color_filter
Definition: paint.h:81
std::shared_ptr< Contents > WithFiltersForSubpassTarget(const ContentContext &renderer, std::shared_ptr< Contents > input, const Matrix &effect_transform=Matrix()) const
Wrap this paint's configured filters to the given contents of subpass target.
Definition: paint.cc:298
const flutter::DlColorSource * color_source
Definition: paint.h:80
std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, const Matrix &effect_transform, Entity::RenderingMode rendering_mode)> ImageFilterProc
Definition: paint.h:33
static void ConvertStops(const flutter::DlGradientColorSourceBase *gradient, std::vector< Color > &colors, std::vector< float > &stops)
Convert display list colors + stops into impeller colors and stops, taking care to ensure that the st...
Definition: paint.cc:39
bool anti_alias
Definition: paint.h:88
const flutter::DlImageFilter * image_filter
Definition: paint.h:82
std::function< std::shared_ptr< ColorSourceContents >()> ColorSourceProc
Definition: paint.h:38
std::shared_ptr< Contents > WithFilters(const ContentContext &renderer, std::shared_ptr< Contents > input) const
Wrap this paint's configured filters to the given contents.
Definition: paint.cc:286
Style style
Definition: paint.h:85
std::shared_ptr< Contents > WithMaskBlur(std::shared_ptr< Contents > input, bool is_solid_color, const Matrix &ctm) const
Definition: paint.cc:312
bool invert_colors
Definition: paint.h:87
static bool CanApplyOpacityPeephole(const Paint &paint)
Whether or not a save layer with the provided paint can perform the opacity peephole optimization.
Definition: paint.h:42
std::optional< MaskBlurDescriptor > mask_blur_descriptor
Definition: paint.h:90
Color color
Definition: paint.h:79
BlendMode blend_mode
Definition: paint.h:86
std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, bool is_solid_color, const Matrix &effect_transform)> MaskFilterProc
Definition: paint.h:37
std::shared_ptr< ColorSourceContents > CreateContents(const ContentContext &renderer, const Geometry *geometry, const std::optional< Matrix > &geometry_transform=std::nullopt) const
Create a ColorSourceContents representing this paint's shader/colors.
Definition: paint.cc:64
StrokeParameters stroke
Definition: paint.h:84
bool HasColorFilter() const
Whether this paint has a color filter that can apply opacity.
Definition: paint.cc:480
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
A structure to store all of the parameters related to stroking a path or basic geometry object.