Flutter Engine
 
Loading...
Searching...
No Matches
impeller::Paint Struct Reference

#include <paint.h>

Classes

struct  MaskBlurDescriptor
 

Public Types

enum class  Style {
  kFill ,
  kStroke
}
 
using ImageFilterProc = std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, const Matrix &effect_transform, Entity::RenderingMode rendering_mode)>
 
using MaskFilterProc = std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, bool is_solid_color, const Matrix &effect_transform)>
 
using ColorSourceProc = std::function< std::shared_ptr< ColorSourceContents >()>
 

Public Member Functions

std::shared_ptr< ContentsWithFilters (std::shared_ptr< Contents > input) const
 Wrap this paint's configured filters to the given contents.
 
std::shared_ptr< ContentsWithFiltersForSubpassTarget (std::shared_ptr< Contents > input, const Matrix &effect_transform=Matrix()) const
 Wrap this paint's configured filters to the given contents of subpass target.
 
bool HasColorFilter () const
 Whether this paint has a color filter that can apply opacity.
 
std::shared_ptr< ColorSourceContentsCreateContents () const
 
std::shared_ptr< ContentsWithMaskBlur (std::shared_ptr< Contents > input, bool is_solid_color, const Matrix &ctm) const
 
std::shared_ptr< FilterContentsWithImageFilter (const FilterInput::Variant &input, const Matrix &effect_transform, Entity::RenderingMode rendering_mode) const
 

Static Public Member Functions

static bool CanApplyOpacityPeephole (const Paint &paint)
 Whether or not a save layer with the provided paint can perform the opacity peephole optimization.
 
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 stops monotonically increase from 0.0 to 1.0.
 

Public Attributes

Color color = Color::Black()
 
const flutter::DlColorSourcecolor_source = nullptr
 
const flutter::DlColorFiltercolor_filter = nullptr
 
const flutter::DlImageFilterimage_filter = nullptr
 
StrokeParameters stroke
 
Style style = Style::kFill
 
BlendMode blend_mode = BlendMode::kSrcOver
 
bool invert_colors = false
 
std::optional< MaskBlurDescriptormask_blur_descriptor
 

Detailed Description

Definition at line 27 of file paint.h.

Member Typedef Documentation

◆ ColorSourceProc

using impeller::Paint::ColorSourceProc = std::function<std::shared_ptr<ColorSourceContents>()>

Definition at line 36 of file paint.h.

◆ ImageFilterProc

using impeller::Paint::ImageFilterProc = std::function<std::shared_ptr<FilterContents>( FilterInput::Ref, const Matrix& effect_transform, Entity::RenderingMode rendering_mode)>

Definition at line 28 of file paint.h.

◆ MaskFilterProc

using impeller::Paint::MaskFilterProc = std::function<std::shared_ptr<FilterContents>( FilterInput::Ref, bool is_solid_color, const Matrix& effect_transform)>

Definition at line 32 of file paint.h.

Member Enumeration Documentation

◆ Style

enum class impeller::Paint::Style
strong
Enumerator
kFill 
kStroke 

Definition at line 47 of file paint.h.

Member Function Documentation

◆ CanApplyOpacityPeephole()

static bool impeller::Paint::CanApplyOpacityPeephole ( const Paint paint)
inlinestatic

Whether or not a save layer with the provided paint can perform the opacity peephole optimization.

Definition at line 40 of file paint.h.

40 {
41 return paint.blend_mode == BlendMode::kSrcOver &&
42 paint.invert_colors == false &&
43 !paint.mask_blur_descriptor.has_value() &&
44 paint.image_filter == nullptr && paint.color_filter == nullptr;
45 }

References blend_mode, color_filter, image_filter, invert_colors, impeller::kSrcOver, and mask_blur_descriptor.

Referenced by impeller::Canvas::SaveLayer().

◆ ConvertStops()

void impeller::Paint::ConvertStops ( const flutter::DlGradientColorSourceBase gradient,
std::vector< Color > &  colors,
std::vector< float > &  stops 
)
static

Convert display list colors + stops into impeller colors and stops, taking care to ensure that the stops monotonically increase from 0.0 to 1.0.

The general process is:

  • Ensure that the first gradient stop value is 0.0. If not, insert a new stop with a value of 0.0 and use the first gradient color as this new stops color.
  • Ensure the last gradient stop value is 1.0. If not, insert a new stop with a value of 1.0 and use the last gradient color as this stops color.
  • Clamp all gradient values between the values of 0.0 and 1.0.
  • For all stop values, ensure that the values are monotonically increasing by clamping each value to a minimum of the previous stop value and itself. For example, with stop values of 0.0, 0.5, 0.4, 1.0, we would clamp such that the values were 0.0, 0.5, 0.5, 1.0.

Definition at line 37 of file paint.cc.

39 {
40 FML_DCHECK(gradient->stop_count() >= 2)
41 << "stop_count:" << gradient->stop_count();
42
43 auto* dl_colors = gradient->colors();
44 auto* dl_stops = gradient->stops();
45 if (dl_stops[0] != 0.0) {
46 colors.emplace_back(skia_conversions::ToColor(dl_colors[0]));
47 stops.emplace_back(0);
48 }
49 for (auto i = 0; i < gradient->stop_count(); i++) {
50 colors.emplace_back(skia_conversions::ToColor(dl_colors[i]));
51 stops.emplace_back(std::clamp(dl_stops[i], 0.0f, 1.0f));
52 }
53 if (dl_stops[gradient->stop_count() - 1] != 1.0) {
54 colors.emplace_back(colors.back());
55 stops.emplace_back(1.0);
56 }
57 for (auto i = 1; i < gradient->stop_count(); i++) {
58 stops[i] = std::clamp(stops[i], stops[i - 1], stops[i]);
59 }
60}
#define FML_DCHECK(condition)
Definition logging.h:122
Color ToColor(const flutter::DlColor &color)

References flutter::DlGradientColorSourceBase::colors(), FML_DCHECK, i, flutter::DlGradientColorSourceBase::stop_count(), flutter::DlGradientColorSourceBase::stops(), and impeller::skia_conversions::ToColor().

Referenced by CreateContents(), impeller::testing::TEST(), impeller::testing::TEST(), impeller::testing::TEST(), impeller::testing::TEST(), and impeller::testing::TEST().

◆ CreateContents()

std::shared_ptr< ColorSourceContents > impeller::Paint::CreateContents ( ) const

Definition at line 62 of file paint.cc.

62 {
63 if (color_source == nullptr) {
64 auto contents = std::make_shared<SolidColorContents>();
65 contents->SetColor(color);
66 return contents;
67 }
68
69 switch (color_source->type()) {
73 FML_DCHECK(linear);
74 auto start_point = linear->start_point();
75 auto end_point = linear->end_point();
76 std::vector<Color> colors;
77 std::vector<float> stops;
78 ConvertStops(linear, colors, stops);
79
80 auto tile_mode = static_cast<Entity::TileMode>(linear->tile_mode());
81 auto effect_transform = linear->matrix();
82
83 auto contents = std::make_shared<LinearGradientContents>();
84 contents->SetOpacityFactor(color.alpha);
85 contents->SetColors(std::move(colors));
86 contents->SetStops(std::move(stops));
87 contents->SetEndPoints(start_point, end_point);
88 contents->SetTileMode(tile_mode);
89 contents->SetEffectTransform(effect_transform);
90
91 std::array<Point, 2> bounds{start_point, end_point};
92 auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
93 if (intrinsic_size.has_value()) {
94 contents->SetColorSourceSize(intrinsic_size->GetSize().Max({1, 1}));
95 }
96 return contents;
97 }
99 const flutter::DlRadialGradientColorSource* radialGradient =
101 FML_DCHECK(radialGradient);
102 auto center = radialGradient->center();
103 auto radius = radialGradient->radius();
104 std::vector<Color> colors;
105 std::vector<float> stops;
106 ConvertStops(radialGradient, colors, stops);
107
108 auto tile_mode =
109 static_cast<Entity::TileMode>(radialGradient->tile_mode());
110 auto effect_transform = radialGradient->matrix();
111
112 auto contents = std::make_shared<RadialGradientContents>();
113 contents->SetOpacityFactor(color.alpha);
114 contents->SetColors(std::move(colors));
115 contents->SetStops(std::move(stops));
116 contents->SetCenterAndRadius(center, radius);
117 contents->SetTileMode(tile_mode);
118 contents->SetEffectTransform(effect_transform);
119
120 auto radius_pt = Point(radius, radius);
121 std::array<Point, 2> bounds{center + radius_pt, center - radius_pt};
122 auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
123 if (intrinsic_size.has_value()) {
124 contents->SetColorSourceSize(intrinsic_size->GetSize().Max({1, 1}));
125 }
126 return contents;
127 }
129 const flutter::DlConicalGradientColorSource* conical_gradient =
131 FML_DCHECK(conical_gradient);
132 Point center = conical_gradient->end_center();
133 DlScalar radius = conical_gradient->end_radius();
134 Point focus_center = conical_gradient->start_center();
135 DlScalar focus_radius = conical_gradient->start_radius();
136 std::vector<Color> colors;
137 std::vector<float> stops;
138 ConvertStops(conical_gradient, colors, stops);
139
140 auto tile_mode =
141 static_cast<Entity::TileMode>(conical_gradient->tile_mode());
142 auto effect_transform = conical_gradient->matrix();
143
144 std::shared_ptr<ConicalGradientContents> contents =
145 std::make_shared<ConicalGradientContents>();
146 contents->SetOpacityFactor(color.alpha);
147 contents->SetColors(std::move(colors));
148 contents->SetStops(std::move(stops));
149 contents->SetCenterAndRadius(center, radius);
150 contents->SetTileMode(tile_mode);
151 contents->SetEffectTransform(effect_transform);
152 contents->SetFocus(focus_center, focus_radius);
153
154 auto radius_pt = Point(radius, radius);
155 std::array<Point, 2> bounds{center + radius_pt, center - radius_pt};
156 auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
157 if (intrinsic_size.has_value()) {
158 contents->SetColorSourceSize(intrinsic_size->GetSize().Max({1, 1}));
159 }
160 return contents;
161 }
163 const flutter::DlSweepGradientColorSource* sweepGradient =
165 FML_DCHECK(sweepGradient);
166
167 auto center = sweepGradient->center();
168 auto start_angle = Degrees(sweepGradient->start());
169 auto end_angle = Degrees(sweepGradient->end());
170 std::vector<Color> colors;
171 std::vector<float> stops;
172 ConvertStops(sweepGradient, colors, stops);
173
174 auto tile_mode =
175 static_cast<Entity::TileMode>(sweepGradient->tile_mode());
176 auto effect_transform = sweepGradient->matrix();
177
178 auto contents = std::make_shared<SweepGradientContents>();
179 contents->SetOpacityFactor(color.alpha);
180 contents->SetCenterAndAngles(center, start_angle, end_angle);
181 contents->SetColors(std::move(colors));
182 contents->SetStops(std::move(stops));
183 contents->SetTileMode(tile_mode);
184 contents->SetEffectTransform(effect_transform);
185
186 return contents;
187 }
189 const flutter::DlImageColorSource* image_color_source =
191 FML_DCHECK(image_color_source &&
192 image_color_source->image()->impeller_texture());
193 auto texture = image_color_source->image()->impeller_texture();
194 auto x_tile_mode = static_cast<Entity::TileMode>(
195 image_color_source->horizontal_tile_mode());
196 auto y_tile_mode = static_cast<Entity::TileMode>(
197 image_color_source->vertical_tile_mode());
198 auto sampler_descriptor =
199 skia_conversions::ToSamplerDescriptor(image_color_source->sampling());
200 // See https://github.com/flutter/flutter/issues/165205
201 flutter::DlMatrix effect_transform = image_color_source->matrix().To3x3();
202
203 auto contents = std::make_shared<TiledTextureContents>();
204 contents->SetOpacityFactor(color.alpha);
205 contents->SetTexture(texture);
206 contents->SetTileModes(x_tile_mode, y_tile_mode);
207 contents->SetSamplerDescriptor(sampler_descriptor);
208 contents->SetEffectTransform(effect_transform);
214 std::shared_ptr<FilterContents> color_filter_output =
219 FilterInput::Make(color_filter_output),
221 }
222 if (color_filter) {
226 }
229 };
230 contents->SetColorFilter(filter_proc);
231 }
232 contents->SetColorSourceSize(Size::Ceil(texture->GetSize()));
233 return contents;
234 }
236 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
238 auto runtime_stage =
239 runtime_effect_color_source->runtime_effect()->runtime_stage();
240 auto uniform_data = runtime_effect_color_source->uniform_data();
241 auto samplers = runtime_effect_color_source->samplers();
242
243 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
244
245 for (auto& sampler : samplers) {
246 if (sampler == nullptr) {
247 VALIDATION_LOG << "Runtime effect sampler is null";
248 auto contents = std::make_shared<SolidColorContents>();
249 contents->SetColor(Color::BlackTransparent());
250 return contents;
251 }
252 auto* image = sampler->asImage();
253 if (!sampler->asImage()) {
254 VALIDATION_LOG << "Runtime effect sampler is not an image";
255 auto contents = std::make_shared<SolidColorContents>();
256 contents->SetColor(Color::BlackTransparent());
257 return contents;
258 }
259 FML_DCHECK(image->image()->impeller_texture());
260 texture_inputs.push_back({
261 .sampler_descriptor =
263 .texture = image->image()->impeller_texture(),
264 });
265 }
266
267 auto contents = std::make_shared<RuntimeEffectContents>();
268 contents->SetOpacityFactor(color.alpha);
269 contents->SetRuntimeStage(std::move(runtime_stage));
270 contents->SetUniformData(std::move(uniform_data));
271 contents->SetTextureInputs(std::move(texture_inputs));
272 return contents;
273 }
274 }
276}
virtual T type() const =0
virtual const DlRuntimeEffectColorSource * asRuntimeEffect() const
virtual const DlRadialGradientColorSource * asRadialGradient() const
virtual const DlLinearGradientColorSource * asLinearGradient() const
virtual const DlImageColorSource * asImage() const
virtual const DlSweepGradientColorSource * asSweepGradient() const
virtual const DlConicalGradientColorSource * asConicalGradient() const
DlImageSampling sampling() const
DlTileMode horizontal_tile_mode() const
sk_sp< const DlImage > image() const
const std::shared_ptr< std::vector< uint8_t > > uniform_data() const
const sk_sp< DlRuntimeEffect > runtime_effect() const
const std::vector< std::shared_ptr< DlColorSource > > samplers() const
std::shared_ptr< FilterInput > Ref
static FilterInput::Ref Make(Variant input, bool msaa_enabled=true)
std::function< std::shared_ptr< ColorFilterContents >(FilterInput::Ref)> ColorFilterProc
static int input(yyscan_t yyscanner)
FlutterVulkanImage * image
#define FML_UNREACHABLE()
Definition logging.h:128
FlTexture * texture
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)
std::shared_ptr< ColorFilterContents > WrapWithInvertColors(const std::shared_ptr< FilterInput > &input, ColorFilterContents::AbsorbOpacity absorb_opacity)
TPoint< Scalar > Point
Definition point.h:327
flutter::DlScalar DlScalar
FlutterVulkanImageHandle image
Definition embedder.h:931
static constexpr Color BlackTransparent()
Definition color.h:270
Scalar alpha
Definition color.h:143
A 4x4 matrix using column-major storage.
Definition matrix.h:37
constexpr Matrix To3x3() const
Definition matrix.h:252
const flutter::DlColorFilter * color_filter
Definition paint.h:77
const flutter::DlColorSource * color_source
Definition paint.h:76
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:37
bool invert_colors
Definition paint.h:83
Color color
Definition paint.h:75
static constexpr std::optional< TRect > MakePointBounds(const U &value)
Definition rect.h:165
constexpr TSize Ceil() const
Definition size.h:114
#define VALIDATION_LOG
Definition validation.h:91

References impeller::Color::alpha, flutter::DlColorSource::asConicalGradient(), flutter::DlColorSource::asImage(), flutter::DlColorSource::asLinearGradient(), flutter::DlColorSource::asRadialGradient(), flutter::DlColorSource::asRuntimeEffect(), flutter::DlColorSource::asSweepGradient(), impeller::Color::BlackTransparent(), impeller::TSize< Scalar >::Ceil(), flutter::DlRadialGradientColorSource::center(), flutter::DlSweepGradientColorSource::center(), color, color_filter, color_source, ConvertStops(), flutter::DlSweepGradientColorSource::end(), flutter::DlConicalGradientColorSource::end_center(), flutter::DlLinearGradientColorSource::end_point(), flutter::DlConicalGradientColorSource::end_radius(), FML_DCHECK, FML_UNREACHABLE, flutter::DlImageColorSource::horizontal_tile_mode(), flutter::DlImageColorSource::image(), FlutterVulkanImage::image, image, input(), invert_colors, flutter::kConicalGradient, flutter::kImage, flutter::kLinearGradient, impeller::ColorFilterContents::kNo, flutter::kRadialGradient, flutter::kRuntimeEffect, flutter::kSweepGradient, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakePointBounds(), flutter::DlMatrixColorSourceBase::matrix(), flutter::DlRadialGradientColorSource::radius(), flutter::DlRuntimeEffectColorSource::runtime_effect(), flutter::DlRuntimeEffectColorSource::samplers(), flutter::DlImageColorSource::sampling(), flutter::DlSweepGradientColorSource::start(), flutter::DlConicalGradientColorSource::start_center(), flutter::DlLinearGradientColorSource::start_point(), flutter::DlConicalGradientColorSource::start_radius(), texture, flutter::DlGradientColorSourceBase::tile_mode(), impeller::Matrix::To3x3(), impeller::skia_conversions::ToSamplerDescriptor(), flutter::DlAttribute< D, T >::type(), flutter::DlRuntimeEffectColorSource::uniform_data(), VALIDATION_LOG, flutter::DlImageColorSource::vertical_tile_mode(), impeller::WrapWithGPUColorFilter(), and impeller::WrapWithInvertColors().

◆ HasColorFilter()

bool impeller::Paint::HasColorFilter ( ) const

Whether this paint has a color filter that can apply opacity.

Definition at line 469 of file paint.cc.

469 {
470 return color_filter || invert_colors;
471}

Referenced by impeller::Canvas::DrawImageRect().

◆ WithFilters()

std::shared_ptr< Contents > impeller::Paint::WithFilters ( std::shared_ptr< Contents input) const

Wrap this paint's configured filters to the given contents.

Parameters
[in]inputThe contents to wrap with paint's filters.
Returns
The filter-wrapped contents. If there are no filters that need to be wrapped for the current paint configuration, the original contents is returned.

Definition at line 278 of file paint.cc.

279 {
281 auto image_filter =
283 if (image_filter) {
285 }
286 return input;
287}
const flutter::DlImageFilter * image_filter
Definition paint.h:78
std::shared_ptr< FilterContents > WithImageFilter(const FilterInput::Variant &input, const Matrix &effect_transform, Entity::RenderingMode rendering_mode) const
Definition paint.cc:312

References image_filter, input(), impeller::Entity::kDirect, impeller::ColorFilterContents::kYes, and WithImageFilter().

Referenced by impeller::Canvas::DrawAtlas(), impeller::Canvas::DrawImageRect(), impeller::Canvas::DrawTextFrame(), and impeller::Canvas::DrawVertices().

◆ WithFiltersForSubpassTarget()

std::shared_ptr< Contents > impeller::Paint::WithFiltersForSubpassTarget ( std::shared_ptr< Contents input,
const Matrix effect_transform = Matrix() 
) const

Wrap this paint's configured filters to the given contents of subpass target.

Parameters
[in]inputThe contents of subpass target to wrap with paint's filters.
Returns
The filter-wrapped contents. If there are no filters that need to be wrapped for the current paint configuration, the original contents is returned.

Definition at line 289 of file paint.cc.

291 {
292 auto image_filter =
293 WithImageFilter(input, effect_transform,
295 if (image_filter) {
297 }
299 return input;
300}

References image_filter, input(), impeller::Entity::kSubpassPrependSnapshotTransform, impeller::ColorFilterContents::kYes, and WithImageFilter().

◆ WithImageFilter()

std::shared_ptr< FilterContents > impeller::Paint::WithImageFilter ( const FilterInput::Variant input,
const Matrix effect_transform,
Entity::RenderingMode  rendering_mode 
) const

Definition at line 312 of file paint.cc.

315 {
316 if (!image_filter) {
317 return nullptr;
318 }
320 filter->SetRenderingMode(rendering_mode);
321 filter->SetEffectTransform(effect_transform);
322 return filter;
323}
std::shared_ptr< FilterContents > WrapInput(const flutter::DlImageFilter *filter, const FilterInput::Ref &input)
Generate a new FilterContents using this filter's configuration.

References image_filter, input(), impeller::FilterInput::Make(), and impeller::WrapInput().

Referenced by impeller::Canvas::SaveLayer(), WithFilters(), and WithFiltersForSubpassTarget().

◆ WithMaskBlur()

std::shared_ptr< Contents > impeller::Paint::WithMaskBlur ( std::shared_ptr< Contents input,
bool  is_solid_color,
const Matrix ctm 
) const

Definition at line 302 of file paint.cc.

304 {
305 if (mask_blur_descriptor.has_value()) {
307 is_solid_color, ctm);
308 }
309 return input;
310}
std::optional< MaskBlurDescriptor > mask_blur_descriptor
Definition paint.h:85

References input(), impeller::FilterInput::Make(), and mask_blur_descriptor.

Member Data Documentation

◆ blend_mode

◆ color

◆ color_filter

◆ color_source

◆ image_filter

◆ invert_colors

bool impeller::Paint::invert_colors = false

◆ mask_blur_descriptor

◆ stroke

◆ style


The documentation for this struct was generated from the following files: