Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
dl_sk_conversions.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
13#include "third_party/skia/include/core/SkColorFilter.h"
14#include "third_party/skia/include/effects/SkGradient.h"
15#include "third_party/skia/include/effects/SkImageFilters.h"
16#include "third_party/skia/include/effects/SkRuntimeEffect.h"
17
18namespace flutter {
19
20// clang-format off
21constexpr float kInvertColorMatrix[20] = {
22 -1.0, 0, 0, 1.0, 0,
23 0, -1.0, 0, 1.0, 0,
24 0, 0, -1.0, 1.0, 0,
25 1.0, 1.0, 1.0, 1.0, 0
26};
27// clang-format on
28
29SkPaint ToSk(const DlPaint& paint) {
30 SkPaint sk_paint;
31
32 sk_paint.setAntiAlias(paint.isAntiAlias());
33 sk_paint.setColor(ToSkColor4f(paint.getColor()));
34 sk_paint.setBlendMode(ToSk(paint.getBlendMode()));
35 sk_paint.setStyle(ToSk(paint.getDrawStyle()));
36 sk_paint.setStrokeWidth(paint.getStrokeWidth());
37 sk_paint.setStrokeMiter(paint.getStrokeMiter());
38 sk_paint.setStrokeCap(ToSk(paint.getStrokeCap()));
39 sk_paint.setStrokeJoin(ToSk(paint.getStrokeJoin()));
40 sk_paint.setImageFilter(ToSk(paint.getImageFilterPtr()));
41 auto color_filter = ToSk(paint.getColorFilterPtr());
42 if (paint.isInvertColors()) {
43 auto invert_filter = SkColorFilters::Matrix(kInvertColorMatrix);
44 if (color_filter) {
45 invert_filter = invert_filter->makeComposed(color_filter);
46 }
47 color_filter = invert_filter;
48 }
49 sk_paint.setColorFilter(color_filter);
50
51 auto color_source = paint.getColorSourcePtr();
52 if (color_source) {
53 // Unconditionally set dither to true for gradient shaders.
54 sk_paint.setDither(color_source->isGradient());
55 sk_paint.setShader(ToSk(color_source));
56 }
57
58 sk_paint.setMaskFilter(ToSk(paint.getMaskFilterPtr()));
59
60 return sk_paint;
61}
62
63SkPaint ToStrokedSk(const DlPaint& paint) {
64 DlPaint stroked_paint = paint;
66 return ToSk(stroked_paint);
67}
68
69SkPaint ToNonShaderSk(const DlPaint& paint) {
70 DlPaint non_shader_paint = paint;
71 non_shader_paint.setColorSource(nullptr);
72 return ToSk(non_shader_paint);
73}
74
75sk_sp<SkShader> ToSk(const DlColorSource* source) {
76 if (!source) {
77 return nullptr;
78 }
79 SkMatrix scratch_matrix;
80 std::vector<SkColor4f> scratch_colors;
81 static auto ToSkGradient =
82 [](const DlGradientColorSourceBase* gradient,
83 std::vector<SkColor4f>& scratch_colors) -> SkGradient {
84 scratch_colors.clear();
85 scratch_colors.reserve(gradient->stop_count());
86 for (int i = 0; i < gradient->stop_count(); ++i) {
87 DlColor color = gradient->colors()[i];
88 // TODO(180904): avoid clamp and truncation
89 scratch_colors.push_back(SkColor4f::FromColor(color.argb()));
90 // DlColor esrgb = color.withColorSpace(DlColorSpace::kExtendedSRGB);
91 // scratch_colors.emplace_back(esrgb.getRedF(), esrgb.getGreenF(),
92 // esrgb.getBlueF(), esrgb.getAlphaF());
93 }
94 return SkGradient(
95 SkGradient::Colors(scratch_colors,
96 {gradient->stops(), gradient->stop_count()},
97 ToSk(gradient->tile_mode())),
98 SkGradient::Interpolation());
99 };
100 switch (source->type()) {
102 const DlImageColorSource* image_source = source->asImage();
103 FML_DCHECK(image_source != nullptr);
104 auto image = image_source->image();
105 auto skia_image = image ? image->asSkiaImage() : nullptr;
106 if (!skia_image || !skia_image->skia_image()) {
107 return nullptr;
108 }
109 return skia_image->skia_image()->makeShader(
110 ToSk(image_source->horizontal_tile_mode()),
111 ToSk(image_source->vertical_tile_mode()),
112 ToSk(image_source->sampling()),
113 ToSk(image_source->matrix_ptr(), scratch_matrix));
114 }
116 const DlLinearGradientColorSource* linear_source =
117 source->asLinearGradient();
118 FML_DCHECK(linear_source != nullptr);
119 SkPoint pts[] = {ToSkPoint(linear_source->start_point()),
120 ToSkPoint(linear_source->end_point())};
121 return SkShaders::LinearGradient(
122 pts, ToSkGradient(linear_source, scratch_colors),
123 ToSk(linear_source->matrix_ptr(), scratch_matrix));
124 }
126 const DlRadialGradientColorSource* radial_source =
127 source->asRadialGradient();
128 FML_DCHECK(radial_source != nullptr);
129 return SkShaders::RadialGradient(
130 ToSkPoint(radial_source->center()), radial_source->radius(),
131 ToSkGradient(radial_source, scratch_colors),
132 ToSk(radial_source->matrix_ptr(), scratch_matrix));
133 }
135 const DlConicalGradientColorSource* conical_source =
136 source->asConicalGradient();
137 FML_DCHECK(conical_source != nullptr);
138 return SkShaders::TwoPointConicalGradient(
139 ToSkPoint(conical_source->start_center()),
140 conical_source->start_radius(),
141 ToSkPoint(conical_source->end_center()), conical_source->end_radius(),
142 ToSkGradient(conical_source, scratch_colors),
143 ToSk(conical_source->matrix_ptr(), scratch_matrix));
144 }
146 const DlSweepGradientColorSource* sweep_source =
147 source->asSweepGradient();
148 FML_DCHECK(sweep_source != nullptr);
149 return SkShaders::SweepGradient(
150 SkPoint(sweep_source->center().x, sweep_source->center().y),
151 sweep_source->start(), sweep_source->end(),
152 ToSkGradient(sweep_source, scratch_colors),
153 ToSk(sweep_source->matrix_ptr(), scratch_matrix));
154 }
156 const DlRuntimeEffectColorSource* runtime_source =
157 source->asRuntimeEffect();
158 FML_DCHECK(runtime_source != nullptr);
159 auto runtime_effect = runtime_source->runtime_effect();
160 if (!runtime_effect || !runtime_effect->skia_runtime_effect()) {
161 return nullptr;
162 }
163
164 auto samplers = runtime_source->samplers();
165 std::vector<sk_sp<SkShader>> sk_samplers(samplers.size());
166 for (size_t i = 0; i < samplers.size(); i++) {
167 const auto& sampler = samplers[i];
168 if (sampler == nullptr) {
169 return nullptr;
170 }
171 sk_samplers[i] = ToSk(sampler);
172 }
173
174 auto uniform_data = runtime_source->uniform_data();
175 auto ref = new std::shared_ptr<std::vector<uint8_t>>(uniform_data);
176 auto sk_uniform_data = SkData::MakeWithProc(
177 uniform_data->data(), uniform_data->size(),
178 [](const void* ptr, void* context) {
179 delete reinterpret_cast<std::shared_ptr<std::vector<uint8_t>>*>(
180 context);
181 },
182 ref);
183
184 return runtime_effect->skia_runtime_effect()->makeShader(
185 sk_uniform_data, sk_samplers.data(), sk_samplers.size());
186 }
187 }
188}
189
190sk_sp<SkImageFilter> ToSk(const DlImageFilter* filter) {
191 if (!filter) {
192 return nullptr;
193 }
194 switch (filter->type()) {
196 const DlBlurImageFilter* blur_filter = filter->asBlur();
197 FML_DCHECK(blur_filter != nullptr);
198 return SkImageFilters::Blur(blur_filter->sigma_x(),
199 blur_filter->sigma_y(),
200 ToSk(blur_filter->tile_mode()), nullptr);
201 }
203 const DlDilateImageFilter* dilate_filter = filter->asDilate();
204 FML_DCHECK(dilate_filter != nullptr);
205 return SkImageFilters::Dilate(dilate_filter->radius_x(),
206 dilate_filter->radius_y(), nullptr);
207 }
209 const DlErodeImageFilter* erode_filter = filter->asErode();
210 FML_DCHECK(erode_filter != nullptr);
211 return SkImageFilters::Erode(erode_filter->radius_x(),
212 erode_filter->radius_y(), nullptr);
213 }
215 const DlMatrixImageFilter* matrix_filter = filter->asMatrix();
216 FML_DCHECK(matrix_filter != nullptr);
217 return SkImageFilters::MatrixTransform(
218 ToSkMatrix(matrix_filter->matrix()), ToSk(matrix_filter->sampling()),
219 nullptr);
220 }
222 const DlComposeImageFilter* compose_filter = filter->asCompose();
223 FML_DCHECK(compose_filter != nullptr);
224 return SkImageFilters::Compose(ToSk(compose_filter->outer()),
225 ToSk(compose_filter->inner()));
226 }
228 const DlColorFilterImageFilter* cf_filter = filter->asColorFilter();
229 FML_DCHECK(cf_filter != nullptr);
230 return SkImageFilters::ColorFilter(ToSk(cf_filter->color_filter()),
231 nullptr);
232 }
234 const DlLocalMatrixImageFilter* lm_filter = filter->asLocalMatrix();
235 FML_DCHECK(lm_filter != nullptr);
236 sk_sp<SkImageFilter> skia_filter = ToSk(lm_filter->image_filter());
237 // The image_filter property itself might have been null, or the
238 // construction of the SkImageFilter might be optimized to null
239 // for any number of reasons. In any case, if the filter is null
240 // or optimizaed away, let's then optimize away this local matrix
241 // case by returning null.
242 if (!skia_filter) {
243 return nullptr;
244 }
245 return skia_filter->makeWithLocalMatrix(ToSkMatrix(lm_filter->matrix()));
246 }
248 // UNSUPPORTED.
249 return nullptr;
250 }
251}
252
253sk_sp<SkColorFilter> ToSk(const DlColorFilter* filter) {
254 if (!filter) {
255 return nullptr;
256 }
257 switch (filter->type()) {
259 const DlBlendColorFilter* blend_filter = filter->asBlend();
260 FML_DCHECK(blend_filter != nullptr);
261 return SkColorFilters::Blend(ToSkColor4f(blend_filter->color()), nullptr,
262 ToSk(blend_filter->mode()));
263 }
265 const DlMatrixColorFilter* matrix_filter = filter->asMatrix();
266 FML_DCHECK(matrix_filter != nullptr);
267 float matrix[20];
268 matrix_filter->get_matrix(matrix);
269 return SkColorFilters::Matrix(matrix);
270 }
272 return SkColorFilters::SRGBToLinearGamma();
273 }
275 return SkColorFilters::LinearToSRGBGamma();
276 }
277 }
278}
279
280sk_sp<SkMaskFilter> ToSk(const DlMaskFilter* filter) {
281 if (!filter) {
282 return nullptr;
283 }
284 switch (filter->type()) {
286 const DlBlurMaskFilter* blur_filter = filter->asBlur();
287 FML_DCHECK(blur_filter != nullptr);
288 return SkMaskFilter::MakeBlur(ToSk(blur_filter->style()),
289 blur_filter->sigma(),
290 blur_filter->respectCTM());
291 }
292 }
293}
294
295sk_sp<SkVertices> ToSk(const std::shared_ptr<DlVertices>& vertices) {
296 std::vector<SkColor> sk_colors;
297 const SkColor* sk_colors_ptr = nullptr;
298 if (vertices->colors()) {
299 sk_colors.reserve(vertices->vertex_count());
300 for (int i = 0; i < vertices->vertex_count(); ++i) {
301 sk_colors.push_back(vertices->colors()[i].argb());
302 }
303 sk_colors_ptr = sk_colors.data();
304 }
305 return SkVertices::MakeCopy(ToSk(vertices->mode()), vertices->vertex_count(),
306 ToSkPoints(vertices->vertex_data()),
307 ToSkPoints(vertices->texture_coordinate_data()),
308 sk_colors_ptr, vertices->index_count(),
309 vertices->indices());
310}
311
312} // namespace flutter
virtual T type() const =0
DlBlurStyle style() const
virtual const DlBlendColorFilter * asBlend() const
virtual const DlMatrixColorFilter * asMatrix() const
const std::shared_ptr< const DlColorFilter > color_filter() const
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
std::shared_ptr< DlImageFilter > inner() const
std::shared_ptr< DlImageFilter > outer() const
DlImageSampling sampling() const
DlTileMode horizontal_tile_mode() const
sk_sp< const DlImage > image() const
virtual const DlLocalMatrixImageFilter * asLocalMatrix() const
virtual const DlColorFilterImageFilter * asColorFilter() const
virtual const DlMatrixImageFilter * asMatrix() const
virtual const DlComposeImageFilter * asCompose() const
virtual const DlBlurImageFilter * asBlur() const
virtual const DlDilateImageFilter * asDilate() const
virtual const DlErodeImageFilter * asErode() const
const std::shared_ptr< DlImageFilter > image_filter() const
virtual const DlBlurMaskFilter * asBlur() const
void get_matrix(float matrix[20]) const
const DlMatrix & matrix() const
bool isAntiAlias() const
Definition dl_paint.h:57
DlStrokeCap getStrokeCap() const
Definition dl_paint.h:98
DlColor getColor() const
Definition dl_paint.h:69
DlBlendMode getBlendMode() const
Definition dl_paint.h:82
float getStrokeMiter() const
Definition dl_paint.h:120
DlStrokeJoin getStrokeJoin() const
Definition dl_paint.h:106
const DlColorSource * getColorSourcePtr() const
Definition dl_paint.h:129
const DlMaskFilter * getMaskFilterPtr() const
Definition dl_paint.h:183
const DlColorFilter * getColorFilterPtr() const
Definition dl_paint.h:147
const DlImageFilter * getImageFilterPtr() const
Definition dl_paint.h:165
DlDrawStyle getDrawStyle() const
Definition dl_paint.h:90
float getStrokeWidth() const
Definition dl_paint.h:114
DlPaint & setDrawStyle(DlDrawStyle style)
Definition dl_paint.h:93
DlPaint & setColorSource(std::nullptr_t source)
Definition dl_paint.h:131
bool isInvertColors() const
Definition dl_paint.h:63
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
FlutterVulkanImage * image
#define FML_DCHECK(condition)
Definition logging.h:122
SkPaint ToSk(const DlPaint &paint)
const SkPoint & ToSkPoint(const DlPoint &point)
SkPaint ToStrokedSk(const DlPaint &paint)
SkColor4f ToSkColor4f(DlColor color)
SkPaint ToNonShaderSk(const DlPaint &paint)
@ kStroke
strokes boundary of shapes
constexpr float kInvertColorMatrix[20]
SkMatrix ToSkMatrix(const DlMatrix &matrix)
const SkPoint * ToSkPoints(const DlPoint *points)
uint32_t argb() const
Definition dl_color.h:158