| Flutter Impeller |

dl_dispatcher.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/dl_dispatcher.h"
6
7 #include <algorithm>
8 #include <cstring>
9 #include <memory>
10 #include <optional>
11 #include <utility>
12 #include <vector>
13
14 #include "flutter/fml/logging.h"
15 #include "flutter/fml/trace_event.h"
16 #include "impeller/aiks/color_filter.h"
17 #include "impeller/core/formats.h"
18 #include "impeller/display_list/dl_vertices_geometry.h"
19 #include "impeller/display_list/nine_patch_converter.h"
20 #include "impeller/display_list/skia_conversions.h"
21 #include "impeller/entity/contents/content_context.h"
22 #include "impeller/entity/contents/filters/filter_contents.h"
23 #include "impeller/entity/contents/filters/inputs/filter_input.h"
24 #include "impeller/entity/contents/runtime_effect_contents.h"
25 #include "impeller/entity/entity.h"
26 #include "impeller/geometry/color.h"
27 #include "impeller/geometry/path.h"
28 #include "impeller/geometry/path_builder.h"
29 #include "impeller/geometry/scalar.h"
30 #include "impeller/geometry/sigma.h"
31 #include "impeller/typographer/font_glyph_pair.h"
32
33 #if IMPELLER_ENABLE_3D
34 #include "impeller/entity/contents/scene_contents.h"
35 #endif // IMPELLER_ENABLE_3D
36
37 namespace impeller {
38
39 #define UNIMPLEMENTED \
40 FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
41
42 static BlendMode ToBlendMode(flutter::DlBlendMode mode) {
43 switch (mode) {
44 case flutter::DlBlendMode::kClear:
45 return BlendMode::kClear;
46 case flutter::DlBlendMode::kSrc:
47 return BlendMode::kSource;
48 case flutter::DlBlendMode::kDst:
49 return BlendMode::kDestination;
50 case flutter::DlBlendMode::kSrcOver:
51 return BlendMode::kSourceOver;
52 case flutter::DlBlendMode::kDstOver:
53 return BlendMode::kDestinationOver;
54 case flutter::DlBlendMode::kSrcIn:
55 return BlendMode::kSourceIn;
56 case flutter::DlBlendMode::kDstIn:
57 return BlendMode::kDestinationIn;
58 case flutter::DlBlendMode::kSrcOut:
59 return BlendMode::kSourceOut;
60 case flutter::DlBlendMode::kDstOut:
61 return BlendMode::kDestinationOut;
62 case flutter::DlBlendMode::kSrcATop:
63 return BlendMode::kSourceATop;
64 case flutter::DlBlendMode::kDstATop:
65 return BlendMode::kDestinationATop;
66 case flutter::DlBlendMode::kXor:
67 return BlendMode::kXor;
68 case flutter::DlBlendMode::kPlus:
69 return BlendMode::kPlus;
70 case flutter::DlBlendMode::kModulate:
71 return BlendMode::kModulate;
72 case flutter::DlBlendMode::kScreen:
73 return BlendMode::kScreen;
74 case flutter::DlBlendMode::kOverlay:
75 return BlendMode::kOverlay;
76 case flutter::DlBlendMode::kDarken:
77 return BlendMode::kDarken;
78 case flutter::DlBlendMode::kLighten:
79 return BlendMode::kLighten;
80 case flutter::DlBlendMode::kColorDodge:
81 return BlendMode::kColorDodge;
82 case flutter::DlBlendMode::kColorBurn:
83 return BlendMode::kColorBurn;
84 case flutter::DlBlendMode::kHardLight:
85 return BlendMode::kHardLight;
86 case flutter::DlBlendMode::kSoftLight:
87 return BlendMode::kSoftLight;
88 case flutter::DlBlendMode::kDifference:
89 return BlendMode::kDifference;
90 case flutter::DlBlendMode::kExclusion:
91 return BlendMode::kExclusion;
92 case flutter::DlBlendMode::kMultiply:
93 return BlendMode::kMultiply;
94 case flutter::DlBlendMode::kHue:
95 return BlendMode::kHue;
96 case flutter::DlBlendMode::kSaturation:
97 return BlendMode::kSaturation;
98 case flutter::DlBlendMode::kColor:
99 return BlendMode::kColor;
100 case flutter::DlBlendMode::kLuminosity:
101 return BlendMode::kLuminosity;
102 }
103 FML_UNREACHABLE();
104 }
105
106 static Entity::TileMode ToTileMode(flutter::DlTileMode tile_mode) {
107 switch (tile_mode) {
108 case flutter::DlTileMode::kClamp:
109 return Entity::TileMode::kClamp;
110 case flutter::DlTileMode::kRepeat:
111 return Entity::TileMode::kRepeat;
112 case flutter::DlTileMode::kMirror:
113 return Entity::TileMode::kMirror;
114 case flutter::DlTileMode::kDecal:
115 return Entity::TileMode::kDecal;
116 }
117 }
118
119 static impeller::SamplerDescriptor ToSamplerDescriptor(
120 const flutter::DlImageSampling options) {
121 impeller::SamplerDescriptor desc;
122 switch (options) {
123 case flutter::DlImageSampling::kNearestNeighbor:
124 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
125 desc.mip_filter = impeller::MipFilter::kBase;
126 desc.label = "Nearest Sampler";
127 break;
128 case flutter::DlImageSampling::kLinear:
129 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
130 desc.mip_filter = impeller::MipFilter::kBase;
131 desc.label = "Linear Sampler";
132 break;
133 case flutter::DlImageSampling::kCubic:
134 case flutter::DlImageSampling::kMipmapLinear:
135 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
136 desc.mip_filter = impeller::MipFilter::kLinear;
137 desc.label = "Mipmap Linear Sampler";
138 break;
139 }
140 return desc;
141 }
142
143 static impeller::SamplerDescriptor ToSamplerDescriptor(
144 const flutter::DlFilterMode options) {
145 impeller::SamplerDescriptor desc;
146 switch (options) {
147 case flutter::DlFilterMode::kNearest:
148 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
149 desc.label = "Nearest Sampler";
150 break;
151 case flutter::DlFilterMode::kLinear:
152 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
153 desc.label = "Linear Sampler";
154 break;
155 default:
156 break;
157 }
158 return desc;
159 }
160
161 static Matrix ToMatrix(const SkMatrix& m) {
162 return Matrix{
163 // clang-format off
164 m[0], m[3], 0, m[6],
165 m[1], m[4], 0, m[7],
166 0, 0, 1, 0,
167 m[2], m[5], 0, m[8],
168 // clang-format on
169 };
170 }
171
172 // |flutter::DlOpReceiver|
173 void DlDispatcherBase::setAntiAlias(bool aa) {
174 // Nothing to do because AA is implicit.
175 }
176
177 static Paint::Style ToStyle(flutter::DlDrawStyle style) {
178 switch (style) {
179 case flutter::DlDrawStyle::kFill:
180 return Paint::Style::kFill;
181 case flutter::DlDrawStyle::kStroke:
182 return Paint::Style::kStroke;
183 case flutter::DlDrawStyle::kStrokeAndFill:
184 UNIMPLEMENTED;
185 break;
186 }
187 return Paint::Style::kFill;
188 }
189
190 // |flutter::DlOpReceiver|
191 void DlDispatcherBase::setDrawStyle(flutter::DlDrawStyle style) {
192 paint_.style = ToStyle(style);
193 }
194
195 // |flutter::DlOpReceiver|
196 void DlDispatcherBase::setColor(flutter::DlColor color) {
197 paint_.color = {
198 color.getRedF(),
199 color.getGreenF(),
200 color.getBlueF(),
201 color.getAlphaF(),
202 };
203 }
204
205 // |flutter::DlOpReceiver|
206 void DlDispatcherBase::setStrokeWidth(SkScalar width) {
207 paint_.stroke_width = width;
208 }
209
210 // |flutter::DlOpReceiver|
211 void DlDispatcherBase::setStrokeMiter(SkScalar limit) {
212 paint_.stroke_miter = limit;
213 }
214
215 // |flutter::DlOpReceiver|
216 void DlDispatcherBase::setStrokeCap(flutter::DlStrokeCap cap) {
217 switch (cap) {
218 case flutter::DlStrokeCap::kButt:
219 paint_.stroke_cap = Cap::kButt;
220 break;
221 case flutter::DlStrokeCap::kRound:
222 paint_.stroke_cap = Cap::kRound;
223 break;
224 case flutter::DlStrokeCap::kSquare:
225 paint_.stroke_cap = Cap::kSquare;
226 break;
227 }
228 }
229
230 // |flutter::DlOpReceiver|
231 void DlDispatcherBase::setStrokeJoin(flutter::DlStrokeJoin join) {
232 switch (join) {
233 case flutter::DlStrokeJoin::kMiter:
234 paint_.stroke_join = Join::kMiter;
235 break;
236 case flutter::DlStrokeJoin::kRound:
237 paint_.stroke_join = Join::kRound;
238 break;
239 case flutter::DlStrokeJoin::kBevel:
240 paint_.stroke_join = Join::kBevel;
241 break;
242 }
243 }
244
245 static std::vector<Color> ToColors(const flutter::DlColor colors[], int count) {
246 auto result = std::vector<Color>();
247 if (colors == nullptr) {
248 return result;
249 }
250 for (int i = 0; i < count; i++) {
251 result.push_back(skia_conversions::ToColor(colors[i]));
252 }
253 return result;
254 }
255
256 static std::optional<ColorSource::Type> ToColorSourceType(
257 flutter::DlColorSourceType type) {
258 switch (type) {
259 case flutter::DlColorSourceType::kColor:
260 return ColorSource::Type::kColor;
261 case flutter::DlColorSourceType::kImage:
262 return ColorSource::Type::kImage;
263 case flutter::DlColorSourceType::kLinearGradient:
264 return ColorSource::Type::kLinearGradient;
265 case flutter::DlColorSourceType::kRadialGradient:
266 return ColorSource::Type::kRadialGradient;
267 case flutter::DlColorSourceType::kConicalGradient:
268 return ColorSource::Type::kConicalGradient;
269 case flutter::DlColorSourceType::kSweepGradient:
270 return ColorSource::Type::kSweepGradient;
271 case flutter::DlColorSourceType::kRuntimeEffect:
272 return ColorSource::Type::kRuntimeEffect;
273 #ifdef IMPELLER_ENABLE_3D
274 case flutter::DlColorSourceType::kScene:
275 return ColorSource::Type::kScene;
276 #endif // IMPELLER_ENABLE_3D
277 }
278 }
279
280 // |flutter::DlOpReceiver|
281 void DlDispatcherBase::setColorSource(const flutter::DlColorSource* source) {
282 if (!source) {
283 paint_.color_source = ColorSource::MakeColor();
284 return;
285 }
286
287 std::optional<ColorSource::Type> type = ToColorSourceType(source->type());
288
289 if (!type.has_value()) {
290 FML_LOG(ERROR) << "Requested ColorSourceType::kUnknown";
291 paint_.color_source = ColorSource::MakeColor();
292 return;
293 }
294
295 switch (type.value()) {
296 case ColorSource::Type::kColor: {
297 const flutter::DlColorColorSource* color = source->asColor();
298
299 paint_.color_source = ColorSource::MakeColor();
300 setColor(color->color());
301 FML_DCHECK(color);
302 return;
303 }
304 case ColorSource::Type::kLinearGradient: {
305 const flutter::DlLinearGradientColorSource* linear =
306 source->asLinearGradient();
307 FML_DCHECK(linear);
308 auto start_point = skia_conversions::ToPoint(linear->start_point());
309 auto end_point = skia_conversions::ToPoint(linear->end_point());
310 std::vector<Color> colors;
311 std::vector<float> stops;
312 skia_conversions::ConvertStops(linear, colors, stops);
313
314 auto tile_mode = ToTileMode(linear->tile_mode());
315 auto matrix = ToMatrix(linear->matrix());
316
317 paint_.color_source = ColorSource::MakeLinearGradient(
318 start_point, end_point, std::move(colors), std::move(stops),
319 tile_mode, matrix);
320 return;
321 }
322 case ColorSource::Type::kConicalGradient: {
323 const flutter::DlConicalGradientColorSource* conical_gradient =
324 source->asConicalGradient();
325 FML_DCHECK(conical_gradient);
326 Point center = skia_conversions::ToPoint(conical_gradient->end_center());
327 SkScalar radius = conical_gradient->end_radius();
328 Point focus_center =
329 skia_conversions::ToPoint(conical_gradient->start_center());
330 SkScalar focus_radius = conical_gradient->start_radius();
331 std::vector<Color> colors;
332 std::vector<float> stops;
333 skia_conversions::ConvertStops(conical_gradient, colors, stops);
334
335 auto tile_mode = ToTileMode(conical_gradient->tile_mode());
336 auto matrix = ToMatrix(conical_gradient->matrix());
337
338 paint_.color_source = ColorSource::MakeConicalGradient(
339 center, radius, std::move(colors), std::move(stops), focus_center,
340 focus_radius, tile_mode, matrix);
341 return;
342 }
343 case ColorSource::Type::kRadialGradient: {
344 const flutter::DlRadialGradientColorSource* radialGradient =
345 source->asRadialGradient();
346 FML_DCHECK(radialGradient);
347 auto center = skia_conversions::ToPoint(radialGradient->center());
348 auto radius = radialGradient->radius();
349 std::vector<Color> colors;
350 std::vector<float> stops;
351 skia_conversions::ConvertStops(radialGradient, colors, stops);
352
353 auto tile_mode = ToTileMode(radialGradient->tile_mode());
354 auto matrix = ToMatrix(radialGradient->matrix());
355 paint_.color_source =
356 ColorSource::MakeRadialGradient(center, radius, std::move(colors),
357 std::move(stops), tile_mode, matrix);
358 return;
359 }
360 case ColorSource::Type::kSweepGradient: {
361 const flutter::DlSweepGradientColorSource* sweepGradient =
362 source->asSweepGradient();
363 FML_DCHECK(sweepGradient);
364
365 auto center = skia_conversions::ToPoint(sweepGradient->center());
366 auto start_angle = Degrees(sweepGradient->start());
367 auto end_angle = Degrees(sweepGradient->end());
368 std::vector<Color> colors;
369 std::vector<float> stops;
370 skia_conversions::ConvertStops(sweepGradient, colors, stops);
371
372 auto tile_mode = ToTileMode(sweepGradient->tile_mode());
373 auto matrix = ToMatrix(sweepGradient->matrix());
374 paint_.color_source = ColorSource::MakeSweepGradient(
375 center, start_angle, end_angle, std::move(colors), std::move(stops),
376 tile_mode, matrix);
377 return;
378 }
379 case ColorSource::Type::kImage: {
380 const flutter::DlImageColorSource* image_color_source = source->asImage();
381 FML_DCHECK(image_color_source &&
382 image_color_source->image()->impeller_texture());
383 auto texture = image_color_source->image()->impeller_texture();
384 auto x_tile_mode = ToTileMode(image_color_source->horizontal_tile_mode());
385 auto y_tile_mode = ToTileMode(image_color_source->vertical_tile_mode());
386 auto desc = ToSamplerDescriptor(image_color_source->sampling());
387 auto matrix = ToMatrix(image_color_source->matrix());
388 paint_.color_source = ColorSource::MakeImage(texture, x_tile_mode,
389 y_tile_mode, desc, matrix);
390 return;
391 }
392 case ColorSource::Type::kRuntimeEffect: {
393 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
394 source->asRuntimeEffect();
395 auto runtime_stage =
396 runtime_effect_color_source->runtime_effect()->runtime_stage();
397 auto uniform_data = runtime_effect_color_source->uniform_data();
398 auto samplers = runtime_effect_color_source->samplers();
399
400 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
401
402 for (auto& sampler : samplers) {
403 if (sampler == nullptr) {
404 return;
405 }
406 auto* image = sampler->asImage();
407 if (!sampler->asImage()) {
408 UNIMPLEMENTED;
409 return;
410 }
411 FML_DCHECK(image->image()->impeller_texture());
412 texture_inputs.push_back({
413 .sampler_descriptor = ToSamplerDescriptor(image->sampling()),
414 .texture = image->image()->impeller_texture(),
415 });
416 }
417
418 paint_.color_source = ColorSource::MakeRuntimeEffect(
419 runtime_stage, uniform_data, texture_inputs);
420 return;
421 }
422 case ColorSource::Type::kScene: {
423 #ifdef IMPELLER_ENABLE_3D
424 const flutter::DlSceneColorSource* scene_color_source = source->asScene();
425 std::shared_ptr<scene::Node> scene_node =
426 scene_color_source->scene_node();
427 Matrix camera_transform = scene_color_source->camera_matrix();
428
429 paint_.color_source =
430 ColorSource::MakeScene(scene_node, camera_transform);
431 #else // IMPELLER_ENABLE_3D
432 FML_LOG(ERROR) << "ColorSourceType::kScene can only be used if Impeller "
433 "Scene is enabled.";
434 #endif // IMPELLER_ENABLE_3D
435 return;
436 }
437 }
438 }
439
440 static std::shared_ptr<ColorFilter> ToColorFilter(
441 const flutter::DlColorFilter* filter) {
442 if (filter == nullptr) {
443 return nullptr;
444 }
445 switch (filter->type()) {
446 case flutter::DlColorFilterType::kBlend: {
447 auto dl_blend = filter->asBlend();
448 auto blend_mode = ToBlendMode(dl_blend->mode());
449 auto color = skia_conversions::ToColor(dl_blend->color());
450 return ColorFilter::MakeBlend(blend_mode, color);
451 }
452 case flutter::DlColorFilterType::kMatrix: {
453 const flutter::DlMatrixColorFilter* dl_matrix = filter->asMatrix();
454 impeller::ColorMatrix color_matrix;
455 dl_matrix->get_matrix(color_matrix.array);
456 return ColorFilter::MakeMatrix(color_matrix);
457 }
458 case flutter::DlColorFilterType::kSrgbToLinearGamma:
459 return ColorFilter::MakeSrgbToLinear();
460 case flutter::DlColorFilterType::kLinearToSrgbGamma:
461 return ColorFilter::MakeLinearToSrgb();
462 }
463 return nullptr;
464 }
465
466 // |flutter::DlOpReceiver|
467 void DlDispatcherBase::setColorFilter(const flutter::DlColorFilter* filter) {
468 paint_.color_filter = ToColorFilter(filter);
469 }
470
471 // |flutter::DlOpReceiver|
472 void DlDispatcherBase::setInvertColors(bool invert) {
473 paint_.invert_colors = invert;
474 }
475
476 // |flutter::DlOpReceiver|
477 void DlDispatcherBase::setBlendMode(flutter::DlBlendMode dl_mode) {
478 paint_.blend_mode = ToBlendMode(dl_mode);
479 }
480
481 static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style) {
482 switch (blur_style) {
483 case flutter::DlBlurStyle::kNormal:
484 return FilterContents::BlurStyle::kNormal;
485 case flutter::DlBlurStyle::kSolid:
486 return FilterContents::BlurStyle::kSolid;
487 case flutter::DlBlurStyle::kOuter:
488 return FilterContents::BlurStyle::kOuter;
489 case flutter::DlBlurStyle::kInner:
490 return FilterContents::BlurStyle::kInner;
491 }
492 }
493
494 // |flutter::DlOpReceiver|
495 void DlDispatcherBase::setMaskFilter(const flutter::DlMaskFilter* filter) {
496 // Needs https://github.com/flutter/flutter/issues/95434
497 if (filter == nullptr) {
498 paint_.mask_blur_descriptor = std::nullopt;
499 return;
500 }
501 switch (filter->type()) {
502 case flutter::DlMaskFilterType::kBlur: {
503 auto blur = filter->asBlur();
504
505 paint_.mask_blur_descriptor = {
506 .style = ToBlurStyle(blur->style()),
507 .sigma = Sigma(blur->sigma()),
508 .respect_ctm = blur->respectCTM(),
509 };
510 break;
511 }
512 }
513 }
514
515 static std::shared_ptr<ImageFilter> ToImageFilter(
516 const flutter::DlImageFilter* filter) {
517 if (filter == nullptr) {
518 return nullptr;
519 }
520
521 switch (filter->type()) {
522 case flutter::DlImageFilterType::kBlur: {
523 auto blur = filter->asBlur();
524 auto sigma_x = Sigma(blur->sigma_x());
525 auto sigma_y = Sigma(blur->sigma_y());
526 auto tile_mode = ToTileMode(blur->tile_mode());
527 return ImageFilter::MakeBlur(
528 sigma_x, sigma_y, FilterContents::BlurStyle::kNormal, tile_mode);
529 }
530 case flutter::DlImageFilterType::kDilate: {
531 auto dilate = filter->asDilate();
532 FML_DCHECK(dilate);
533 if (dilate->radius_x() < 0 || dilate->radius_y() < 0) {
534 return nullptr;
535 }
536 auto radius_x = Radius(dilate->radius_x());
537 auto radius_y = Radius(dilate->radius_y());
538 return ImageFilter::MakeDilate(radius_x, radius_y);
539 }
540 case flutter::DlImageFilterType::kErode: {
541 auto erode = filter->asErode();
542 FML_DCHECK(erode);
543 if (erode->radius_x() < 0 || erode->radius_y() < 0) {
544 return nullptr;
545 }
546 auto radius_x = Radius(erode->radius_x());
547 auto radius_y = Radius(erode->radius_y());
548 return ImageFilter::MakeErode(radius_x, radius_y);
549 }
550 case flutter::DlImageFilterType::kMatrix: {
551 auto matrix_filter = filter->asMatrix();
552 FML_DCHECK(matrix_filter);
553 auto matrix = ToMatrix(matrix_filter->matrix());
554 auto desc = ToSamplerDescriptor(matrix_filter->sampling());
555 return ImageFilter::MakeMatrix(matrix, desc);
556 }
557 case flutter::DlImageFilterType::kCompose: {
558 auto compose = filter->asCompose();
559 FML_DCHECK(compose);
560 auto outer_dl_filter = compose->outer();
561 auto inner_dl_filter = compose->inner();
562 auto outer_filter = ToImageFilter(outer_dl_filter.get());
563 auto inner_filter = ToImageFilter(inner_dl_filter.get());
564 if (!outer_filter) {
565 return inner_filter;
566 }
567 if (!inner_filter) {
568 return outer_filter;
569 }
570 FML_DCHECK(outer_filter && inner_filter);
571
572 return ImageFilter::MakeCompose(*inner_filter, *outer_filter);
573 }
574 case flutter::DlImageFilterType::kColorFilter: {
575 auto color_filter_image_filter = filter->asColorFilter();
576 FML_DCHECK(color_filter_image_filter);
577 auto color_filter =
578 ToColorFilter(color_filter_image_filter->color_filter().get());
579 if (!color_filter) {
580 return nullptr;
581 }
582 // When color filters are used as image filters, set the color filter's
583 // "absorb opacity" flag to false. For image filters, the snapshot
584 // opacity needs to be deferred until the result of the filter chain is
585 // being blended with the layer.
586 return ImageFilter::MakeFromColorFilter(*color_filter);
587 }
588 case flutter::DlImageFilterType::kLocalMatrix: {
589 auto local_matrix_filter = filter->asLocalMatrix();
590 FML_DCHECK(local_matrix_filter);
591 auto internal_filter = local_matrix_filter->image_filter();
592 FML_DCHECK(internal_filter);
593
594 auto image_filter = ToImageFilter(internal_filter.get());
595 if (!image_filter) {
596 return nullptr;
597 }
598
599 auto matrix = ToMatrix(local_matrix_filter->matrix());
600 return ImageFilter::MakeLocalMatrix(matrix, *image_filter);
601 }
602 }
603 }
604
605 // |flutter::DlOpReceiver|
606 void DlDispatcherBase::setImageFilter(const flutter::DlImageFilter* filter) {
607 paint_.image_filter = ToImageFilter(filter);
608 }
609
610 // |flutter::DlOpReceiver|
611 void DlDispatcherBase::save(uint32_t total_content_depth) {
612 GetCanvas().Save(total_content_depth);
613 }
614
615 // |flutter::DlOpReceiver|
616 void DlDispatcherBase::saveLayer(const SkRect& bounds,
617 const flutter::SaveLayerOptions& options,
618 uint32_t total_content_depth,
619 flutter::DlBlendMode max_content_mode,
620 const flutter::DlImageFilter* backdrop) {
621 auto paint = options.renders_with_attributes() ? paint_ : Paint{};
622 auto promise = options.content_is_clipped()
623 ? ContentBoundsPromise::kMayClipContents
624 : ContentBoundsPromise::kContainsContents;
625 GetCanvas().SaveLayer(paint, skia_conversions::ToRect(bounds),
626 ToImageFilter(backdrop), promise, total_content_depth,
627 options.can_distribute_opacity());
628 }
629
630 // |flutter::DlOpReceiver|
631 void DlDispatcherBase::restore() {
632 GetCanvas().Restore();
633 }
634
635 // |flutter::DlOpReceiver|
636 void DlDispatcherBase::translate(SkScalar tx, SkScalar ty) {
637 GetCanvas().Translate({tx, ty, 0.0});
638 }
639
640 // |flutter::DlOpReceiver|
641 void DlDispatcherBase::scale(SkScalar sx, SkScalar sy) {
642 GetCanvas().Scale({sx, sy, 1.0});
643 }
644
645 // |flutter::DlOpReceiver|
646 void DlDispatcherBase::rotate(SkScalar degrees) {
647 GetCanvas().Rotate(Degrees{degrees});
648 }
649
650 // |flutter::DlOpReceiver|
651 void DlDispatcherBase::skew(SkScalar sx, SkScalar sy) {
652 GetCanvas().Skew(sx, sy);
653 }
654
655 // |flutter::DlOpReceiver|
656 void DlDispatcherBase::transform2DAffine(SkScalar mxx,
657 SkScalar mxy,
658 SkScalar mxt,
659 SkScalar myx,
660 SkScalar myy,
661 SkScalar myt) {
662 // clang-format off
663 transformFullPerspective(
664 mxx, mxy, 0, mxt,
665 myx, myy, 0, myt,
666 0 , 0, 1, 0,
667 0 , 0, 0, 1
668 );
669 // clang-format on
670 }
671
672 // |flutter::DlOpReceiver|
673 void DlDispatcherBase::transformFullPerspective(SkScalar mxx,
674 SkScalar mxy,
675 SkScalar mxz,
676 SkScalar mxt,
677 SkScalar myx,
678 SkScalar myy,
679 SkScalar myz,
680 SkScalar myt,
681 SkScalar mzx,
682 SkScalar mzy,
683 SkScalar mzz,
684 SkScalar mzt,
685 SkScalar mwx,
686 SkScalar mwy,
687 SkScalar mwz,
688 SkScalar mwt) {
689 // The order of arguments is row-major but Impeller matrices are
690 // column-major.
691 // clang-format off
692 auto transform = Matrix{
693 mxx, myx, mzx, mwx,
694 mxy, myy, mzy, mwy,
695 mxz, myz, mzz, mwz,
696 mxt, myt, mzt, mwt
697 };
698 // clang-format on
699 GetCanvas().Transform(transform);
700 }
701
702 // |flutter::DlOpReceiver|
703 void DlDispatcherBase::transformReset() {
704 GetCanvas().ResetTransform();
705 GetCanvas().Transform(initial_matrix_);
706 }
707
708 static Entity::ClipOperation ToClipOperation(
709 flutter::DlCanvas::ClipOp clip_op) {
710 switch (clip_op) {
711 case flutter::DlCanvas::ClipOp::kDifference:
712 return Entity::ClipOperation::kDifference;
713 case flutter::DlCanvas::ClipOp::kIntersect:
714 return Entity::ClipOperation::kIntersect;
715 }
716 }
717
718 // |flutter::DlOpReceiver|
719 void DlDispatcherBase::clipRect(const SkRect& rect,
720 ClipOp clip_op,
721 bool is_aa) {
722 GetCanvas().ClipRect(skia_conversions::ToRect(rect),
723 ToClipOperation(clip_op));
724 }
725
726 // |flutter::DlOpReceiver|
727 void DlDispatcherBase::clipRRect(const SkRRect& rrect,
728 ClipOp sk_op,
729 bool is_aa) {
730 auto clip_op = ToClipOperation(sk_op);
731 if (rrect.isRect()) {
732 GetCanvas().ClipRect(skia_conversions::ToRect(rrect.rect()), clip_op);
733 } else if (rrect.isOval()) {
734 GetCanvas().ClipOval(skia_conversions::ToRect(rrect.rect()), clip_op);
735 } else if (rrect.isSimple()) {
736 GetCanvas().ClipRRect(skia_conversions::ToRect(rrect.rect()),
737 skia_conversions::ToSize(rrect.getSimpleRadii()),
738 clip_op);
739 } else {
740 GetCanvas().ClipPath(skia_conversions::ToPath(rrect), clip_op);
741 }
742 }
743
744 // |flutter::DlOpReceiver|
745 void DlDispatcherBase::clipPath(const SkPath& path, ClipOp sk_op, bool is_aa) {
746 UNIMPLEMENTED;
747 }
748
749 const Path& DlDispatcherBase::GetOrCachePath(const CacheablePath& cache) {
750 if (cache.cached_impeller_path.IsEmpty() && !cache.sk_path.isEmpty()) {
751 cache.cached_impeller_path = skia_conversions::ToPath(cache.sk_path);
752 }
753 return cache.cached_impeller_path;
754 }
755
756 // |flutter::DlOpReceiver|
757 void DlDispatcherBase::clipPath(const CacheablePath& cache,
758 ClipOp sk_op,
759 bool is_aa) {
760 auto clip_op = ToClipOperation(sk_op);
761
762 SkRect rect;
763 if (cache.sk_path.isRect(&rect)) {
764 GetCanvas().ClipRect(skia_conversions::ToRect(rect), clip_op);
765 } else if (cache.sk_path.isOval(&rect)) {
766 GetCanvas().ClipOval(skia_conversions::ToRect(rect), clip_op);
767 } else {
768 SkRRect rrect;
769 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
770 GetCanvas().ClipRRect(skia_conversions::ToRect(rrect.rect()),
771 skia_conversions::ToSize(rrect.getSimpleRadii()),
772 clip_op);
773 } else {
774 GetCanvas().ClipPath(GetOrCachePath(cache), clip_op);
775 }
776 }
777 }
778
779 // |flutter::DlOpReceiver|
780 void DlDispatcherBase::drawColor(flutter::DlColor color,
781 flutter::DlBlendMode dl_mode) {
782 Paint paint;
783 paint.color = skia_conversions::ToColor(color);
784 paint.blend_mode = ToBlendMode(dl_mode);
785 GetCanvas().DrawPaint(paint);
786 }
787
788 // |flutter::DlOpReceiver|
789 void DlDispatcherBase::drawPaint() {
790 GetCanvas().DrawPaint(paint_);
791 }
792
793 // |flutter::DlOpReceiver|
794 void DlDispatcherBase::drawLine(const SkPoint& p0, const SkPoint& p1) {
795 GetCanvas().DrawLine(skia_conversions::ToPoint(p0),
796 skia_conversions::ToPoint(p1), paint_);
797 }
798
799 void DlDispatcherBase::drawDashedLine(const DlPoint& p0,
800 const DlPoint& p1,
801 DlScalar on_length,
802 DlScalar off_length) {
803 Scalar length = p0.GetDistance(p1);
804 // Reasons to defer to regular DrawLine:
805 // length is non-positive - drawLine will draw appropriate "dot"
806 // off_length is non-positive - no gaps, drawLine will draw it solid
807 // on_length is negative - invalid dashing
808 // Note that a 0 length "on" dash will draw "dot"s every "off" distance apart
809 if (length > 0.0f && on_length >= 0.0f && off_length > 0.0f) {
810 Point delta = (p1 - p0) / length; // length > 0 already tested
811 PathBuilder builder;
812
813 Scalar consumed = 0.0f;
814 while (consumed < length) {
815 builder.MoveTo(p0 + delta * consumed);
816
817 Scalar dash_end = consumed + on_length;
818 if (dash_end < length) {
819 builder.LineTo(p0 + delta * dash_end);
820 } else {
821 builder.LineTo(p1);
822 // Should happen anyway due to the math, but let's make it explicit
823 // in case of bit errors. We're done with this line.
824 break;
825 }
826
827 consumed = dash_end + off_length;
828 }
829
830 Paint stroke_paint = paint_;
831 stroke_paint.style = Paint::Style::kStroke;
832 GetCanvas().DrawPath(builder.TakePath(), stroke_paint);
833 } else {
834 drawLine(flutter::ToSkPoint(p0), flutter::ToSkPoint(p1));
835 }
836 }
837
838 // |flutter::DlOpReceiver|
839 void DlDispatcherBase::drawRect(const SkRect& rect) {
840 GetCanvas().DrawRect(skia_conversions::ToRect(rect), paint_);
841 }
842
843 // |flutter::DlOpReceiver|
844 void DlDispatcherBase::drawOval(const SkRect& bounds) {
845 GetCanvas().DrawOval(skia_conversions::ToRect(bounds), paint_);
846 }
847
848 // |flutter::DlOpReceiver|
849 void DlDispatcherBase::drawCircle(const SkPoint& center, SkScalar radius) {
850 GetCanvas().DrawCircle(skia_conversions::ToPoint(center), radius, paint_);
851 }
852
853 // |flutter::DlOpReceiver|
854 void DlDispatcherBase::drawRRect(const SkRRect& rrect) {
855 if (skia_conversions::IsNearlySimpleRRect(rrect)) {
856 GetCanvas().DrawRRect(skia_conversions::ToRect(rrect.rect()),
857 skia_conversions::ToSize(rrect.getSimpleRadii()),
858 paint_);
859 } else {
860 GetCanvas().DrawPath(skia_conversions::ToPath(rrect), paint_);
861 }
862 }
863
864 // |flutter::DlOpReceiver|
865 void DlDispatcherBase::drawDRRect(const SkRRect& outer, const SkRRect& inner) {
866 PathBuilder builder;
867 builder.AddPath(skia_conversions::ToPath(outer));
868 builder.AddPath(skia_conversions::ToPath(inner));
869 GetCanvas().DrawPath(builder.TakePath(FillType::kOdd), paint_);
870 }
871
872 // |flutter::DlOpReceiver|
873 void DlDispatcherBase::drawPath(const SkPath& path) {
874 UNIMPLEMENTED;
875 }
876
877 // |flutter::DlOpReceiver|
878 void DlDispatcherBase::drawPath(const CacheablePath& cache) {
879 SimplifyOrDrawPath(GetCanvas(), cache, paint_);
880 }
881
882 void DlDispatcherBase::SimplifyOrDrawPath(Canvas& canvas,
883 const CacheablePath& cache,
884 const Paint& paint) {
885 SkRect rect;
886
887 // We can't "optimize" a path into a rectangle if it's open.
888 bool closed;
889 if (cache.sk_path.isRect(&rect, &closed) && closed) {
890 canvas.DrawRect(skia_conversions::ToRect(rect), paint);
891 return;
892 }
893
894 SkRRect rrect;
895 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
896 canvas.DrawRRect(skia_conversions::ToRect(rrect.rect()),
897 skia_conversions::ToSize(rrect.getSimpleRadii()), paint);
898 return;
899 }
900
901 SkRect oval;
902 if (cache.sk_path.isOval(&oval)) {
903 canvas.DrawOval(skia_conversions::ToRect(oval), paint);
904 return;
905 }
906
907 canvas.DrawPath(GetOrCachePath(cache), paint);
908 }
909
910 // |flutter::DlOpReceiver|
911 void DlDispatcherBase::drawArc(const SkRect& oval_bounds,
912 SkScalar start_degrees,
913 SkScalar sweep_degrees,
914 bool use_center) {
915 PathBuilder builder;
916 builder.AddArc(skia_conversions::ToRect(oval_bounds), Degrees(start_degrees),
917 Degrees(sweep_degrees), use_center);
918 GetCanvas().DrawPath(builder.TakePath(), paint_);
919 }
920
921 // |flutter::DlOpReceiver|
922 void DlDispatcherBase::drawPoints(PointMode mode,
923 uint32_t count,
924 const SkPoint points[]) {
925 Paint paint = paint_;
926 paint.style = Paint::Style::kStroke;
927 switch (mode) {
928 case flutter::DlCanvas::PointMode::kPoints: {
929 // Cap::kButt is also treated as a square.
930 auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound
931 : PointStyle::kSquare;
932 auto radius = paint.stroke_width;
933 if (radius > 0) {
934 radius /= 2.0;
935 }
936 GetCanvas().DrawPoints(skia_conversions::ToPoints(points, count), radius,
937 paint, point_style);
938 } break;
939 case flutter::DlCanvas::PointMode::kLines:
940 for (uint32_t i = 1; i < count; i += 2) {
941 Point p0 = skia_conversions::ToPoint(points[i - 1]);
942 Point p1 = skia_conversions::ToPoint(points[i]);
943 GetCanvas().DrawLine(p0, p1, paint);
944 }
945 break;
946 case flutter::DlCanvas::PointMode::kPolygon:
947 if (count > 1) {
948 Point p0 = skia_conversions::ToPoint(points[0]);
949 for (uint32_t i = 1; i < count; i++) {
950 Point p1 = skia_conversions::ToPoint(points[i]);
951 GetCanvas().DrawLine(p0, p1, paint);
952 p0 = p1;
953 }
954 }
955 break;
956 }
957 }
958
959 // |flutter::DlOpReceiver|
960 void DlDispatcherBase::drawVertices(
961 const std::shared_ptr<flutter::DlVertices>& vertices,
962 flutter::DlBlendMode dl_mode) {
963 GetCanvas().DrawVertices(MakeVertices(vertices), ToBlendMode(dl_mode),
964 paint_);
965 }
966
967 // |flutter::DlOpReceiver|
968 void DlDispatcherBase::drawImage(const sk_sp<flutter::DlImage> image,
969 const SkPoint point,
970 flutter::DlImageSampling sampling,
971 bool render_with_attributes) {
972 if (!image) {
973 return;
974 }
975
976 auto texture = image->impeller_texture();
977 if (!texture) {
978 return;
979 }
980
981 const auto size = texture->GetSize();
982 const auto src = SkRect::MakeWH(size.width, size.height);
983 const auto dest =
984 SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);
985
986 drawImageRect(image, // image
987 src, // source rect
988 dest, // destination rect
989 sampling, // sampling options
990 render_with_attributes, // render with attributes
991 SrcRectConstraint::kStrict // constraint
992 );
993 }
994
995 // |flutter::DlOpReceiver|
996 void DlDispatcherBase::drawImageRect(
997 const sk_sp<flutter::DlImage> image,
998 const SkRect& src,
999 const SkRect& dst,
1000 flutter::DlImageSampling sampling,
1001 bool render_with_attributes,
1002 SrcRectConstraint constraint = SrcRectConstraint::kFast) {
1003 GetCanvas().DrawImageRect(
1004 std::make_shared<Image>(image->impeller_texture()), // image
1005 skia_conversions::ToRect(src), // source rect
1006 skia_conversions::ToRect(dst), // destination rect
1007 render_with_attributes ? paint_ : Paint(), // paint
1008 ToSamplerDescriptor(sampling) // sampling
1009 );
1010 }
1011
1012 // |flutter::DlOpReceiver|
1013 void DlDispatcherBase::drawImageNine(const sk_sp<flutter::DlImage> image,
1014 const SkIRect& center,
1015 const SkRect& dst,
1016 flutter::DlFilterMode filter,
1017 bool render_with_attributes) {
1018 NinePatchConverter converter = {};
1019 converter.DrawNinePatch(
1020 std::make_shared<Image>(image->impeller_texture()),
1021 Rect::MakeLTRB(center.fLeft, center.fTop, center.fRight, center.fBottom),
1022 skia_conversions::ToRect(dst), ToSamplerDescriptor(filter), &GetCanvas(),
1023 &paint_);
1024 }
1025
1026 // |flutter::DlOpReceiver|
1027 void DlDispatcherBase::drawAtlas(const sk_sp<flutter::DlImage> atlas,
1028 const SkRSXform xform[],
1029 const SkRect tex[],
1030 const flutter::DlColor colors[],
1031 int count,
1032 flutter::DlBlendMode mode,
1033 flutter::DlImageSampling sampling,
1034 const SkRect* cull_rect,
1035 bool render_with_attributes) {
1036 GetCanvas().DrawAtlas(std::make_shared<Image>(atlas->impeller_texture()),
1037 skia_conversions::ToRSXForms(xform, count),
1038 skia_conversions::ToRects(tex, count),
1039 ToColors(colors, count), ToBlendMode(mode),
1040 ToSamplerDescriptor(sampling),
1041 skia_conversions::ToRect(cull_rect), paint_);
1042 }
1043
1044 // |flutter::DlOpReceiver|
1045 void DlDispatcherBase::drawDisplayList(
1046 const sk_sp<flutter::DisplayList> display_list,
1047 SkScalar opacity) {
1048 // Save all values that must remain untouched after the operation.
1049 Paint saved_paint = paint_;
1050 Matrix saved_initial_matrix = initial_matrix_;
1051
1052 // Establish a new baseline for interpreting the new DL.
1053 // Matrix and clip are left untouched, the current
1054 // transform is saved as the new base matrix, and paint
1055 // values are reset to defaults.
1056 initial_matrix_ = GetCanvas().GetCurrentTransform();
1057 paint_ = Paint();
1058
1059 // Handle passed opacity in the most brute-force way by using
1060 // a SaveLayer. If the display_list is able to inherit the
1061 // opacity, this could also be handled by modulating all of its
1062 // attribute settings (for example, color), by the indicated
1063 // opacity.
1064 int restore_count = GetCanvas().GetSaveCount();
1065 if (opacity < SK_Scalar1) {
1066 Paint save_paint;
1067 save_paint.color = Color(0, 0, 0, opacity);
1068 GetCanvas().SaveLayer(
1069 save_paint, skia_conversions::ToRect(display_list->bounds()), nullptr,
1070 ContentBoundsPromise::kContainsContents, display_list->total_depth(),
1071 display_list->can_apply_group_opacity());
1072 } else {
1073 // The display list may alter the clip, which must be restored to the
1074 // current clip at the end of playback.
1075 GetCanvas().Save(display_list->total_depth());
1076 }
1077
1078 // TODO(131445): Remove this restriction if we can correctly cull with
1079 // perspective transforms.
1080 if (display_list->has_rtree() && !initial_matrix_.HasPerspective()) {
1081 // The canvas remembers the screen-space culling bounds clipped by
1082 // the surface and the history of clip calls. DisplayList can cull
1083 // the ops based on a rectangle expressed in its "destination bounds"
1084 // so we need the canvas to transform those into the current local
1085 // coordinate space into which the DisplayList will be rendered.
1086 auto cull_bounds = GetCanvas().GetCurrentLocalCullingBounds();
1087 if (cull_bounds.has_value()) {
1088 Rect cull_rect = cull_bounds.value();
1089 display_list->Dispatch(
1090 *this, SkRect::MakeLTRB(cull_rect.GetLeft(), cull_rect.GetTop(),
1091 cull_rect.GetRight(), cull_rect.GetBottom()));
1092 } else {
1093 display_list->Dispatch(*this);
1094 }
1095 } else {
1096 display_list->Dispatch(*this);
1097 }
1098
1099 // Restore all saved state back to what it was before we interpreted
1100 // the display_list
1101 GetCanvas().RestoreToCount(restore_count);
1102 initial_matrix_ = saved_initial_matrix;
1103 paint_ = saved_paint;
1104 }
1105
1106 // |flutter::DlOpReceiver|
1107 void DlDispatcherBase::drawTextBlob(const sk_sp<SkTextBlob> blob,
1108 SkScalar x,
1109 SkScalar y) {
1110 // When running with Impeller enabled Skia text blobs are converted to
1111 // Impeller text frames in paragraph_skia.cc
1112 UNIMPLEMENTED;
1113 }
1114
1115 void DlDispatcherBase::drawTextFrame(
1116 const std::shared_ptr<TextFrame>& text_frame,
1117 SkScalar x,
1118 SkScalar y) {
1119 GetCanvas().DrawTextFrame(text_frame, //
1120 impeller::Point{x, y}, //
1121 paint_ //
1122 );
1123 }
1124
1125 // |flutter::DlOpReceiver|
1126 void DlDispatcherBase::drawShadow(const SkPath& path,
1127 const flutter::DlColor color,
1128 const SkScalar elevation,
1129 bool transparent_occluder,
1130 SkScalar dpr) {
1131 UNIMPLEMENTED;
1132 }
1133
1134 // |flutter::DlOpReceiver|
1135 void DlDispatcherBase::drawShadow(const CacheablePath& cache,
1136 const flutter::DlColor color,
1137 const SkScalar elevation,
1138 bool transparent_occluder,
1139 SkScalar dpr) {
1140 Color spot_color = skia_conversions::ToColor(color);
1141 spot_color.alpha *= 0.25;
1142
1143 // Compute the spot color -- ported from SkShadowUtils::ComputeTonalColors.
1144 {
1145 Scalar max =
1146 std::max(std::max(spot_color.red, spot_color.green), spot_color.blue);
1147 Scalar min =
1148 std::min(std::min(spot_color.red, spot_color.green), spot_color.blue);
1149 Scalar luminance = (min + max) * 0.5;
1150
1151 Scalar alpha_adjust =
1152 (2.6f + (-2.66667f + 1.06667f * spot_color.alpha) * spot_color.alpha) *
1153 spot_color.alpha;
1154 Scalar color_alpha =
1155 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
1156 luminance;
1157 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
1158
1159 Scalar greyscale_alpha =
1160 std::clamp(spot_color.alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
1161
1162 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
1163 Scalar tonal_alpha = color_scale + greyscale_alpha;
1164 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
1165 spot_color = Color(unpremul_scale * spot_color.red,
1166 unpremul_scale * spot_color.green,
1167 unpremul_scale * spot_color.blue, tonal_alpha);
1168 }
1169
1170 Vector3 light_position(0, -1, 1);
1171 Scalar occluder_z = dpr * elevation;
1172
1173 constexpr Scalar kLightRadius = 800 / 600; // Light radius / light height
1174
1175 Paint paint;
1176 paint.style = Paint::Style::kFill;
1177 paint.color = spot_color;
1178 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1179 .style = FilterContents::BlurStyle::kNormal,
1180 .sigma = Radius{kLightRadius * occluder_z /
1181 GetCanvas().GetCurrentTransform().GetScale().y},
1182 };
1183
1184 GetCanvas().Save(1u);
1185 GetCanvas().PreConcat(
1186 Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y)));
1187
1188 SimplifyOrDrawPath(GetCanvas(), cache, paint);
1189
1190 GetCanvas().Restore();
1191 }
1192
1193 Picture DlDispatcherBase::EndRecordingAsPicture() {
1194 TRACE_EVENT0("impeller", "DisplayListDispatcher::EndRecordingAsPicture");
1195 return GetCanvas().EndRecordingAsPicture();
1196 }
1197
1198 /// Subclasses
1199
1200 DlDispatcher::DlDispatcher() = default;
1201
1202 DlDispatcher::DlDispatcher(IRect cull_rect) : canvas_(cull_rect) {}
1203
1204 DlDispatcher::DlDispatcher(Rect cull_rect) : canvas_(cull_rect) {}
1205
1206 Canvas& DlDispatcher::GetCanvas() {
1207 return canvas_;
1208 }
1209
1210 static bool RequiresReadbackForBlends(
1211 const ContentContext& renderer,
1212 flutter::DlBlendMode max_root_blend_mode) {
1213 return !renderer.GetDeviceCapabilities().SupportsFramebufferFetch() &&
1214 ToBlendMode(max_root_blend_mode) > Entity::kLastPipelineBlendMode;
1215 }
1216
1217 ExperimentalDlDispatcher::ExperimentalDlDispatcher(
1218 ContentContext& renderer,
1219 RenderTarget& render_target,
1220 bool has_root_backdrop_filter,
1221 flutter::DlBlendMode max_root_blend_mode,
1222 IRect cull_rect)
1223 : canvas_(renderer,
1224 render_target,
1225 has_root_backdrop_filter ||
1226 RequiresReadbackForBlends(renderer, max_root_blend_mode),
1227 cull_rect) {}
1228
1229 Canvas& ExperimentalDlDispatcher::GetCanvas() {
1230 return canvas_;
1231 }
1232
1233 //// Text Frame Dispatcher
1234
1235 TextFrameDispatcher::TextFrameDispatcher(const ContentContext& renderer,
1236 const Matrix& initial_matrix)
1237 : renderer_(renderer), matrix_(initial_matrix) {}
1238
1239 void TextFrameDispatcher::save() {
1240 stack_.emplace_back(matrix_);
1241 }
1242
1243 void TextFrameDispatcher::saveLayer(const SkRect& bounds,
1244 const flutter::SaveLayerOptions options,
1245 const flutter::DlImageFilter* backdrop) {
1246 save();
1247 }
1248
1249 void TextFrameDispatcher::restore() {
1250 matrix_ = stack_.back();
1251 stack_.pop_back();
1252 }
1253
1254 void TextFrameDispatcher::translate(SkScalar tx, SkScalar ty) {
1255 matrix_ = matrix_.Translate({tx, ty});
1256 }
1257
1258 void TextFrameDispatcher::scale(SkScalar sx, SkScalar sy) {
1259 matrix_ = matrix_.Scale({sx, sy, 1.0f});
1260 }
1261
1262 void TextFrameDispatcher::rotate(SkScalar degrees) {
1263 matrix_ = matrix_ * Matrix::MakeRotationZ(Degrees(degrees));
1264 }
1265
1266 void TextFrameDispatcher::skew(SkScalar sx, SkScalar sy) {
1267 matrix_ = matrix_ * Matrix::MakeSkew(sx, sy);
1268 }
1269
1270 // clang-format off
1271 // 2x3 2D affine subset of a 4x4 transform in row major order
1272 void TextFrameDispatcher::transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt,
1273 SkScalar myx, SkScalar myy, SkScalar myt) {
1274 matrix_ = matrix_ * Matrix::MakeColumn(
1275 mxx, myx, 0.0f, 0.0f,
1276 mxy, myy, 0.0f, 0.0f,
1277 0.0f, 0.0f, 1.0f, 0.0f,
1278 mxt, myt, 0.0f, 1.0f
1279 );
1280 }
1281
1282 // full 4x4 transform in row major order
1283 void TextFrameDispatcher::transformFullPerspective(
1284 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
1285 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
1286 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
1287 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
1288 matrix_ = matrix_ * Matrix::MakeColumn(
1289 mxx, myx, mzx, mwx,
1290 mxy, myy, mzy, mwy,
1291 mxz, myz, mzz, mwz,
1292 mxt, myt, mzt, mwt
1293 );
1294 }
1295 // clang-format on
1296
1297 void TextFrameDispatcher::transformReset() {
1298 matrix_ = Matrix();
1299 }
1300
1301 void TextFrameDispatcher::drawTextFrame(
1302 const std::shared_ptr<impeller::TextFrame>& text_frame,
1303 SkScalar x,
1304 SkScalar y) {
1305 GlyphProperties properties;
1306 if (paint_.style == Paint::Style::kStroke) {
1307 properties.stroke = true;
1308 properties.stroke_cap = paint_.stroke_cap;
1309 properties.stroke_join = paint_.stroke_join;
1310 properties.stroke_miter = paint_.stroke_miter;
1311 properties.stroke_width = paint_.stroke_width;
1312 }
1313 if (text_frame->HasColor()) {
1314 properties.color = paint_.color;
1315 }
1316 auto scale =
1317 (matrix_ * Matrix::MakeTranslation(Point(x, y))).GetMaxBasisLengthXY();
1318 renderer_.GetLazyGlyphAtlas()->AddTextFrame(*text_frame, //
1319 scale, //
1320 Point(x, y), //
1321 properties //
1322 );
1323 }
1324
1325 void TextFrameDispatcher::drawDisplayList(
1326 const sk_sp<flutter::DisplayList> display_list,
1327 SkScalar opacity) {
1328 [[maybe_unused]] size_t stack_depth = stack_.size();
1329 save();
1330 display_list->Dispatch(*this);
1331 restore();
1332 FML_DCHECK(stack_depth == stack_.size());
1333 }
1334
1335 // |flutter::DlOpReceiver|
1336 void TextFrameDispatcher::setDrawStyle(flutter::DlDrawStyle style) {
1337 paint_.style = ToStyle(style);
1338 }
1339
1340 // |flutter::DlOpReceiver|
1341 void TextFrameDispatcher::setColor(flutter::DlColor color) {
1342 paint_.color = {
1343 color.getRedF(),
1344 color.getGreenF(),
1345 color.getBlueF(),
1346 color.getAlphaF(),
1347 };
1348 }
1349
1350 // |flutter::DlOpReceiver|
1351 void TextFrameDispatcher::setStrokeWidth(SkScalar width) {
1352 paint_.stroke_width = width;
1353 }
1354
1355 // |flutter::DlOpReceiver|
1356 void TextFrameDispatcher::setStrokeMiter(SkScalar limit) {
1357 paint_.stroke_miter = limit;
1358 }
1359
1360 // |flutter::DlOpReceiver|
1361 void TextFrameDispatcher::setStrokeCap(flutter::DlStrokeCap cap) {
1362 switch (cap) {
1363 case flutter::DlStrokeCap::kButt:
1364 paint_.stroke_cap = Cap::kButt;
1365 break;
1366 case flutter::DlStrokeCap::kRound:
1367 paint_.stroke_cap = Cap::kRound;
1368 break;
1369 case flutter::DlStrokeCap::kSquare:
1370 paint_.stroke_cap = Cap::kSquare;
1371 break;
1372 }
1373 }
1374
1375 // |flutter::DlOpReceiver|
1376 void TextFrameDispatcher::setStrokeJoin(flutter::DlStrokeJoin join) {
1377 switch (join) {
1378 case flutter::DlStrokeJoin::kMiter:
1379 paint_.stroke_join = Join::kMiter;
1380 break;
1381 case flutter::DlStrokeJoin::kRound:
1382 paint_.stroke_join = Join::kRound;
1383 break;
1384 case flutter::DlStrokeJoin::kBevel:
1385 paint_.stroke_join = Join::kBevel;
1386 break;
1387 }
1388 }
1389
1390 } // namespace impeller
impeller::DlDispatcherBase::drawDRRect
void drawDRRect(const SkRRect &outer, const SkRRect &inner) override
Definition: dl_dispatcher.cc:865
impeller::Matrix::MakeSkew
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
Definition: matrix.h:117
impeller::DlDispatcherBase::translate
void translate(SkScalar tx, SkScalar ty) override
Definition: dl_dispatcher.cc:636
impeller::Paint::stroke_cap
Cap stroke_cap
Definition: paint.h:72
impeller::DlDispatcherBase::transformReset
void transformReset() override
Definition: dl_dispatcher.cc:703
impeller::DlDispatcherBase::EndRecordingAsPicture
Picture EndRecordingAsPicture()
Definition: dl_dispatcher.cc:1193
impeller::Matrix::HasPerspective
constexpr bool HasPerspective() const
Definition: matrix.h:330
impeller::Canvas::DrawPoints
void DrawPoints(std::vector< Point > points, Scalar radius, const Paint &paint, PointStyle point_style)
Definition: canvas.cc:733
impeller::Entity::ClipOperation::kIntersect
@ kIntersect
path.h
impeller::Entity::TileMode::kClamp
@ kClamp
impeller::Canvas::EndRecordingAsPicture
Picture EndRecordingAsPicture()
Definition: canvas.cc:804
impeller::Canvas::ClipOval
void ClipOval(const Rect &bounds, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:620
impeller::ColorSource::Type::kScene
@ kScene
impeller::ColorSource::Type::kLinearGradient
@ kLinearGradient
impeller::ToClipOperation
static Entity::ClipOperation ToClipOperation(flutter::DlCanvas::ClipOp clip_op)
Definition: dl_dispatcher.cc:708
impeller::Cap::kRound
@ kRound
impeller::DlDispatcherBase::drawShadow
void drawShadow(const SkPath &path, const flutter::DlColor color, const SkScalar elevation, bool transparent_occluder, SkScalar dpr) override
Definition: dl_dispatcher.cc:1126
impeller::Entity::kLastPipelineBlendMode
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:22
impeller::DlDispatcherBase::drawPoints
void drawPoints(PointMode mode, uint32_t count, const SkPoint points[]) override
Definition: dl_dispatcher.cc:922
impeller::Cap::kSquare
@ kSquare
impeller::BlendMode::kDestinationATop
@ kDestinationATop
impeller::DlDispatcher::DlDispatcher
DlDispatcher()
Subclasses.
impeller::Canvas::DrawRRect
void DrawRRect(const Rect &rect, const Size &corner_radii, const Paint &paint)
Definition: canvas.cc:540
impeller::TextFrameDispatcher::saveLayer
void saveLayer(const SkRect &bounds, const flutter::SaveLayerOptions options, const flutter::DlImageFilter *backdrop) override
Definition: dl_dispatcher.cc:1243
impeller::DlScalar
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:20
impeller::ImageFilter::MakeDilate
static std::shared_ptr< ImageFilter > MakeDilate(Radius radius_x, Radius radius_y)
Definition: image_filter.cc:29
impeller::skia_conversions::ToPoints
std::vector< Point > ToPoints(const SkPoint points[], int count)
Definition: skia_conversions.cc:45
impeller::Entity::ClipOperation::kDifference
@ kDifference
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Canvas::RestoreToCount
void RestoreToCount(size_t count)
Definition: canvas.cc:335
impeller::TextFrameDispatcher::rotate
void rotate(SkScalar degrees) override
Definition: dl_dispatcher.cc:1262
impeller::DlDispatcherBase::save
void save(uint32_t total_content_depth) override
Definition: dl_dispatcher.cc:611
impeller::Canvas::DrawImageRect
void DrawImageRect(const std::shared_ptr< Image > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
Definition: canvas.cc:766
impeller::DlDispatcherBase::drawColor
void drawColor(flutter::DlColor color, flutter::DlBlendMode mode) override
Definition: dl_dispatcher.cc:780
impeller::ExperimentalDlDispatcher::ExperimentalDlDispatcher
ExperimentalDlDispatcher(ContentContext &renderer, RenderTarget &render_target, bool has_root_backdrop_filter, flutter::DlBlendMode max_root_blend_mode, IRect cull_rect)
Definition: dl_dispatcher.cc:1217
impeller::ContentBoundsPromise::kMayClipContents
@ kMayClipContents
The caller claims the bounds are a subset of an estimate of the reasonably tight bounds but likely cl...
impeller::ContentContext::GetLazyGlyphAtlas
const std::shared_ptr< LazyGlyphAtlas > & GetLazyGlyphAtlas() const
Definition: content_context.h:720
impeller::skia_conversions::IsNearlySimpleRRect
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.
Definition: skia_conversions.cc:12
impeller::TextFrameDispatcher::setDrawStyle
void setDrawStyle(flutter::DlDrawStyle style) override
Definition: dl_dispatcher.cc:1336
impeller::ColorSource::Type::kRadialGradient
@ kRadialGradient
impeller::GlyphProperties
Definition: font_glyph_pair.h:19
impeller::Paint::Style::kStroke
@ kStroke
impeller::TextFrameDispatcher::setStrokeJoin
void setStrokeJoin(flutter::DlStrokeJoin join) override
Definition: dl_dispatcher.cc:1376
impeller::skia_conversions::ConvertStops
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: skia_conversions.cc:212
entity.h
impeller::ColorSource::MakeLinearGradient
static ColorSource MakeLinearGradient(Point start_point, Point end_point, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:166
impeller::Paint
Definition: paint.h:23
impeller::FillType::kOdd
@ kOdd
impeller::DlDispatcherBase::setStrokeCap
void setStrokeCap(flutter::DlStrokeCap cap) override
Definition: dl_dispatcher.cc:216
impeller::skia_conversions::ToSize
Size ToSize(const SkPoint &point)
Definition: skia_conversions.cc:158
impeller::Canvas::Skew
void Skew(Scalar sx, Scalar sy)
Definition: canvas.cc:323
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::FilterContents::BlurStyle
BlurStyle
Definition: filter_contents.h:26
impeller::Color
Definition: color.h:124
impeller::ToImageFilter
static std::shared_ptr< ImageFilter > ToImageFilter(const flutter::DlImageFilter *filter)
Definition: dl_dispatcher.cc:515
impeller::TextFrameDispatcher::transform2DAffine
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
Definition: dl_dispatcher.cc:1272
impeller::TextFrameDispatcher::restore
void restore() override
Definition: dl_dispatcher.cc:1249
impeller::BlendMode::kLuminosity
@ kLuminosity
impeller::Paint::color
Color color
Definition: paint.h:68
impeller::Entity::TileMode::kDecal
@ kDecal
impeller::BlendMode::kSource
@ kSource
impeller::TextFrameDispatcher::save
void save() override
Definition: dl_dispatcher.cc:1239
impeller::BlendMode::kColorDodge
@ kColorDodge
impeller::Canvas::DrawTextFrame
virtual void DrawTextFrame(const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint)
Definition: canvas.cc:884
impeller::BlendMode::kDestination
@ kDestination
dl_dispatcher.h
impeller::Canvas
Definition: canvas.h:60
impeller::BlendMode::kDarken
@ kDarken
impeller::PathBuilder::AddPath
PathBuilder & AddPath(const Path &path)
Definition: path_builder.cc:430
formats.h
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Paint::MaskBlurDescriptor::style
FilterContents::BlurStyle style
Definition: paint.h:49
impeller::PointStyle::kRound
@ kRound
Points are drawn as squares.
impeller::Vector2
Point Vector2
Definition: point.h:326
impeller::Canvas::ResetTransform
void ResetTransform()
Definition: canvas.cc:290
impeller::Canvas::DrawVertices
void DrawVertices(const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
Definition: canvas.cc:933
impeller::BlendMode::kColor
@ kColor
impeller::DlDispatcherBase::transform2DAffine
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
Definition: dl_dispatcher.cc:656
impeller::skia_conversions::ToRects
std::vector< Rect > ToRects(const SkRect tex[], int count)
Definition: skia_conversions.cc:37
impeller::NinePatchConverter::DrawNinePatch
void DrawNinePatch(const std::shared_ptr< Image > &image, Rect center, Rect dst, const SamplerDescriptor &sampler, Canvas *canvas, Paint *paint)
Definition: nine_patch_converter.cc:60
impeller::Color::alpha
Scalar alpha
Definition: color.h:143
impeller::ImageFilter::MakeBlur
static std::shared_ptr< ImageFilter > MakeBlur(Sigma sigma_x, Sigma sigma_y, FilterContents::BlurStyle blur_style, Entity::TileMode tile_mode)
Definition: image_filter.cc:20
impeller::BlendMode::kDestinationOver
@ kDestinationOver
impeller::BlendMode::kPlus
@ kPlus
impeller::Paint::MaskBlurDescriptor
Definition: paint.h:48
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:162
impeller::ColorSource::MakeSweepGradient
static ColorSource MakeSweepGradient(Point center, Degrees start_angle, Degrees end_angle, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:210
impeller::TextFrameDispatcher::setStrokeCap
void setStrokeCap(flutter::DlStrokeCap cap) override
Definition: dl_dispatcher.cc:1361
impeller::BlendMode::kOverlay
@ kOverlay
impeller::DlDispatcherBase::setColorFilter
void setColorFilter(const flutter::DlColorFilter *filter) override
Definition: dl_dispatcher.cc:467
impeller::ColorSource::MakeColor
static ColorSource MakeColor()
Definition: color_source.cc:162
impeller::GlyphProperties::stroke_miter
Scalar stroke_miter
Definition: font_glyph_pair.h:24
impeller::ColorSource::MakeImage
static ColorSource MakeImage(std::shared_ptr< Texture > texture, Entity::TileMode x_tile_mode, Entity::TileMode y_tile_mode, SamplerDescriptor sampler_descriptor, Matrix effect_transform)
Definition: color_source.cc:225
impeller::FilterContents::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.
impeller::TextFrameDispatcher::TextFrameDispatcher
TextFrameDispatcher(const ContentContext &renderer, const Matrix &initial_matrix)
Definition: dl_dispatcher.cc:1235
impeller::DlDispatcherBase::transformFullPerspective
void transformFullPerspective(SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override
Definition: dl_dispatcher.cc:673
impeller::Cap::kButt
@ kButt
impeller::TextFrameDispatcher::transformFullPerspective
void transformFullPerspective(SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override
Definition: dl_dispatcher.cc:1283
impeller::Entity::TileMode::kRepeat
@ kRepeat
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Canvas::DrawLine
void DrawLine(const Point &p0, const Point &p1, const Paint &paint)
Definition: canvas.cc:485
impeller::DlDispatcherBase::clipRect
void clipRect(const SkRect &rect, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:719
impeller::Paint::color_source
ColorSource color_source
Definition: paint.h:69
impeller::Color::green
Scalar green
Definition: color.h:133
impeller::Canvas::DrawRect
void DrawRect(const Rect &rect, const Paint &paint)
Definition: canvas.cc:495
impeller::Canvas::GetCurrentTransform
const Matrix & GetCurrentTransform() const
Definition: canvas.cc:298
UNIMPLEMENTED
#define UNIMPLEMENTED
Definition: dl_dispatcher.cc:39
impeller::GlyphProperties::color
Color color
Definition: font_glyph_pair.h:20
impeller::ToTileMode
static Entity::TileMode ToTileMode(flutter::DlTileMode tile_mode)
Definition: dl_dispatcher.cc:106
impeller::BlendMode::kModulate
@ kModulate
impeller::DlDispatcherBase::drawImageRect
void drawImageRect(const sk_sp< flutter::DlImage > image, const SkRect &src, const SkRect &dst, flutter::DlImageSampling sampling, bool render_with_attributes, SrcRectConstraint constraint) override
Definition: dl_dispatcher.cc:996
impeller::DlDispatcherBase::drawOval
void drawOval(const SkRect &bounds) override
Definition: dl_dispatcher.cc:844
impeller::Join::kMiter
@ kMiter
runtime_effect_contents.h
impeller::BlendMode::kSourceOut
@ kSourceOut
impeller::DlDispatcherBase::drawVertices
void drawVertices(const std::shared_ptr< flutter::DlVertices > &vertices, flutter::DlBlendMode dl_mode) override
Definition: dl_dispatcher.cc:960
impeller::ImageFilter::MakeFromColorFilter
static std::shared_ptr< ImageFilter > MakeFromColorFilter(const ColorFilter &color_filter)
Definition: image_filter.cc:52
impeller::BlendMode::kSaturation
@ kSaturation
impeller::Entity::TileMode::kMirror
@ kMirror
impeller::Paint::stroke_miter
Scalar stroke_miter
Definition: paint.h:74
impeller::BlendMode::kDifference
@ kDifference
impeller::ToMatrix
static Matrix ToMatrix(const SkMatrix &m)
Definition: dl_dispatcher.cc:161
path_builder.h
impeller::ToColors
static std::vector< Color > ToColors(const flutter::DlColor colors[], int count)
Definition: dl_dispatcher.cc:245
impeller::MinMagFilter::kNearest
@ kNearest
Select nearest to the sample point. Most widely supported.
impeller::TextFrameDispatcher::setColor
void setColor(flutter::DlColor color) override
Definition: dl_dispatcher.cc:1341
impeller::SamplerDescriptor::mag_filter
MinMagFilter mag_filter
Definition: sampler_descriptor.h:17
impeller::skia_conversions::ToRect
Rect ToRect(const SkRect &rect)
Definition: skia_conversions.cc:26
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::BlendMode::kLighten
@ kLighten
impeller::Paint::color_filter
std::shared_ptr< ColorFilter > color_filter
Definition: paint.h:80
impeller::Picture
Definition: picture.h:17
impeller::DlDispatcherBase::drawTextBlob
void drawTextBlob(const sk_sp< SkTextBlob > blob, SkScalar x, SkScalar y) override
Definition: dl_dispatcher.cc:1107
impeller::PointStyle::kSquare
@ kSquare
Points are drawn as circles.
impeller::SamplerDescriptor::min_filter
MinMagFilter min_filter
Definition: sampler_descriptor.h:16
impeller::BlendMode::kSoftLight
@ kSoftLight
impeller::Point
TPoint< Scalar > Point
Definition: point.h:322
impeller::DlDispatcherBase::drawRRect
void drawRRect(const SkRRect &rrect) override
Definition: dl_dispatcher.cc:854
filter_contents.h
impeller::DlDispatcherBase::drawArc
void drawArc(const SkRect &oval_bounds, SkScalar start_degrees, SkScalar sweep_degrees, bool use_center) override
Definition: dl_dispatcher.cc:911
impeller::BlendMode::kColorBurn
@ kColorBurn
impeller::TRect::GetLeft
constexpr auto GetLeft() const
Definition: rect.h:341
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:315
scene_contents.h
skia_conversions.h
impeller::DlDispatcherBase::setImageFilter
void setImageFilter(const flutter::DlImageFilter *filter) override
Definition: dl_dispatcher.cc:606
impeller::BlendMode::kHardLight
@ kHardLight
sigma.h
impeller::DlDispatcherBase::clipPath
void clipPath(const SkPath &path, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:745
impeller::DlDispatcherBase::setColorSource
void setColorSource(const flutter::DlColorSource *source) override
Definition: dl_dispatcher.cc:281
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::FilterContents::BlurStyle::kSolid
@ kSolid
Solid inside, blurred outside.
impeller::DlDispatcherBase::setDrawStyle
void setDrawStyle(flutter::DlDrawStyle style) override
Definition: dl_dispatcher.cc:191
impeller::Matrix::GetScale
constexpr Vector3 GetScale() const
Definition: matrix.h:311
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
impeller::ColorSource::MakeConicalGradient
static ColorSource MakeConicalGradient(Point center, Scalar radius, std::vector< Color > colors, std::vector< Scalar > stops, Point focus_center, Scalar focus_radius, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:180
impeller::ColorFilter::MakeBlend
static std::shared_ptr< ColorFilter > MakeBlend(BlendMode blend_mode, Color color)
Definition: color_filter.cc:23
impeller::DlDispatcherBase::setStrokeJoin
void setStrokeJoin(flutter::DlStrokeJoin join) override
Definition: dl_dispatcher.cc:231
impeller::ColorSource::Type::kRuntimeEffect
@ kRuntimeEffect
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:231
impeller::TextFrameDispatcher::transformReset
void transformReset() override
Definition: dl_dispatcher.cc:1297
impeller::BlendMode::kClear
@ kClear
impeller::DlDispatcherBase::drawPath
void drawPath(const SkPath &path) override
Definition: dl_dispatcher.cc:873
impeller::DlDispatcherBase::drawImageNine
void drawImageNine(const sk_sp< flutter::DlImage > image, const SkIRect &center, const SkRect &dst, flutter::DlFilterMode filter, bool render_with_attributes) override
Definition: dl_dispatcher.cc:1013
impeller::MinMagFilter::kLinear
@ kLinear
impeller::Paint::style
Style style
Definition: paint.h:75
impeller::ImageFilter::MakeLocalMatrix
static std::shared_ptr< ImageFilter > MakeLocalMatrix(const Matrix &matrix, const ImageFilter &internal_filter)
Definition: image_filter.cc:57
impeller::Paint::Style::kFill
@ kFill
impeller::ToColorSourceType
static std::optional< ColorSource::Type > ToColorSourceType(flutter::DlColorSourceType type)
Definition: dl_dispatcher.cc:256
impeller::ColorMatrix::array
Scalar array[20]
Definition: color.h:118
impeller::Canvas::DrawCircle
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition: canvas.cc:566
impeller::ToStyle
static Paint::Style ToStyle(flutter::DlDrawStyle style)
Definition: dl_dispatcher.cc:177
impeller::Matrix::Translate
constexpr Matrix Translate(const Vector3 &t) const
Definition: matrix.h:240
impeller::Color::red
Scalar red
Definition: color.h:128
impeller::DlDispatcherBase::drawImage
void drawImage(const sk_sp< flutter::DlImage > image, const SkPoint point, flutter::DlImageSampling sampling, bool render_with_attributes) override
Definition: dl_dispatcher.cc:968
font_glyph_pair.h
impeller::PathBuilder::LineTo
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:52
impeller::DlDispatcherBase::skew
void skew(SkScalar sx, SkScalar sy) override
Definition: dl_dispatcher.cc:651
type
GLenum type
Definition: blit_command_gles.cc:126
impeller::Sigma
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
impeller::Matrix::MakeColumn
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Definition: matrix.h:69
impeller::DlDispatcherBase::saveLayer
void saveLayer(const SkRect &bounds, const flutter::SaveLayerOptions &options, uint32_t total_content_depth, flutter::DlBlendMode max_content_mode, const flutter::DlImageFilter *backdrop) override
Definition: dl_dispatcher.cc:616
impeller::DlDispatcherBase::setAntiAlias
void setAntiAlias(bool aa) override
Definition: dl_dispatcher.cc:173
impeller::Canvas::Restore
virtual bool Restore()
Definition: canvas.cc:257
impeller::ImageFilter::MakeErode
static std::shared_ptr< ImageFilter > MakeErode(Radius radius_x, Radius radius_y)
Definition: image_filter.cc:34
impeller::Canvas::DrawAtlas
void DrawAtlas(const std::shared_ptr< Image > &atlas, std::vector< Matrix > transforms, std::vector< Rect > texture_coordinates, std::vector< Color > colors, BlendMode blend_mode, SamplerDescriptor sampler, std::optional< Rect > cull_rect, const Paint &paint)
Definition: canvas.cc:1020
impeller::DlDispatcherBase::setStrokeMiter
void setStrokeMiter(SkScalar limit) override
Definition: dl_dispatcher.cc:211
impeller::DlDispatcherBase::setStrokeWidth
void setStrokeWidth(SkScalar width) override
Definition: dl_dispatcher.cc:206
impeller::RenderTarget
Definition: render_target.h:38
impeller::GlyphProperties::stroke_join
Join stroke_join
Definition: font_glyph_pair.h:23
impeller::Canvas::DrawPath
void DrawPath(const Path &path, const Paint &paint)
Definition: canvas.cc:343
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:22
impeller::DlDispatcherBase::drawLine
void drawLine(const SkPoint &p0, const SkPoint &p1) override
Definition: dl_dispatcher.cc:794
impeller::Canvas::DrawPaint
void DrawPaint(const Paint &paint)
Definition: canvas.cc:352
impeller::GlyphProperties::stroke
bool stroke
Definition: font_glyph_pair.h:25
filter_input.h
impeller::NinePatchConverter
Definition: nine_patch_converter.h:18
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:21
impeller::ToBlurStyle
static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style)
Definition: dl_dispatcher.cc:481
impeller::Canvas::GetSaveCount
size_t GetSaveCount() const
Definition: canvas.cc:331
impeller::Join::kRound
@ kRound
impeller::Vector3::y
Scalar y
Definition: vector.h:24
impeller::FilterContents::BlurStyle::kInner
@ kInner
Blurred inside, nothing outside.
impeller::DlDispatcherBase::GetCanvas
virtual Canvas & GetCanvas()=0
impeller::skia_conversions::ToPoint
Point ToPoint(const SkPoint &point)
Definition: skia_conversions.cc:154
impeller::Entity::TileMode
TileMode
Definition: entity.h:42
impeller::SamplerDescriptor::mip_filter
MipFilter mip_filter
Definition: sampler_descriptor.h:18
impeller::ColorSource::MakeRadialGradient
static ColorSource MakeRadialGradient(Point center, Scalar radius, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:196
impeller::GlyphProperties::stroke_width
Scalar stroke_width
Definition: font_glyph_pair.h:21
impeller::ImageFilter::MakeMatrix
static std::shared_ptr< ImageFilter > MakeMatrix(const Matrix &matrix, SamplerDescriptor sampler_descriptor)
Definition: image_filter.cc:39
dl_vertices_geometry.h
impeller::DlDispatcherBase::clipRRect
void clipRRect(const SkRRect &rrect, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:727
impeller::TextFrameDispatcher::drawDisplayList
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, SkScalar opacity) override
Definition: dl_dispatcher.cc:1325
impeller::ColorFilter::MakeMatrix
static std::shared_ptr< ColorFilter > MakeMatrix(ColorMatrix color_matrix)
Definition: color_filter.cc:28
impeller::Canvas::ClipRRect
void ClipRRect(const Rect &rect, const Size &corner_radii, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:640
scalar.h
impeller::DlDispatcherBase::drawDashedLine
void drawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length) override
Definition: dl_dispatcher.cc:799
impeller::Canvas::PreConcat
void PreConcat(const Matrix &transform)
Definition: canvas.cc:286
impeller::TextFrameDispatcher::drawTextFrame
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, SkScalar x, SkScalar y) override
Definition: dl_dispatcher.cc:1301
impeller::ImageFilter::MakeCompose
static std::shared_ptr< ImageFilter > MakeCompose(const ImageFilter &inner, const ImageFilter &outer)
Definition: image_filter.cc:46
impeller::BlendMode::kDestinationIn
@ kDestinationIn
impeller::Join::kBevel
@ kBevel
impeller::ColorSource::Type::kImage
@ kImage
impeller::ColorSource::MakeRuntimeEffect
static ColorSource MakeRuntimeEffect(std::shared_ptr< RuntimeStage > runtime_stage, std::shared_ptr< std::vector< uint8_t >> uniform_data, std::vector< RuntimeEffectContents::TextureInput > texture_inputs)
Definition: color_source.cc:238
impeller::Canvas::DrawOval
void DrawOval(const Rect &rect, const Paint &paint)
Definition: canvas.cc:514
impeller::BlendMode::kExclusion
@ kExclusion
content_context.h
impeller::BlendMode::kDestinationOut
@ kDestinationOut
impeller::TextFrameDispatcher::setStrokeMiter
void setStrokeMiter(SkScalar limit) override
Definition: dl_dispatcher.cc:1356
impeller::FilterContents::BlurStyle::kOuter
@ kOuter
Nothing inside, blurred outside.
impeller::TRect::GetRight
constexpr auto GetRight() const
Definition: rect.h:345
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:213
impeller::DlDispatcherBase::setBlendMode
void setBlendMode(flutter::DlBlendMode mode) override
Definition: dl_dispatcher.cc:477
impeller::ContentContext::GetDeviceCapabilities
const Capabilities & GetDeviceCapabilities() const
Definition: content_context.cc:557
impeller::GlyphProperties::stroke_cap
Cap stroke_cap
Definition: font_glyph_pair.h:22
impeller::Canvas::Rotate
void Rotate(Radians radians)
Definition: canvas.cc:327
impeller::ColorSource::Type::kConicalGradient
@ kConicalGradient
impeller::MipFilter::kBase
@ kBase
The texture is sampled as if it only had a single mipmap level.
impeller::ColorFilter::MakeLinearToSrgb
static std::shared_ptr< ColorFilter > MakeLinearToSrgb()
Definition: color_filter.cc:36
impeller::TPoint< Scalar >
impeller::Canvas::Transform
void Transform(const Matrix &transform)
Definition: canvas.cc:294
impeller::PathBuilder::MoveTo
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:33
impeller::skia_conversions::ToRSXForms
std::vector< Matrix > ToRSXForms(const SkRSXform xform[], int count)
Definition: skia_conversions.cc:171
impeller::Paint::invert_colors
bool invert_colors
Definition: paint.h:77
impeller::Canvas::Save
virtual void Save(uint32_t total_content_depth=kMaxDepth)
Definition: canvas.cc:184
impeller::TextFrameDispatcher::setStrokeWidth
void setStrokeWidth(SkScalar width) override
Definition: dl_dispatcher.cc:1351
impeller::MipFilter::kLinear
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
impeller::Canvas::GetCurrentLocalCullingBounds
const std::optional< Rect > GetCurrentLocalCullingBounds() const
Definition: canvas.cc:302
impeller::BlendMode::kSourceIn
@ kSourceIn
impeller::DlDispatcherBase::drawRect
void drawRect(const SkRect &rect) override
Definition: dl_dispatcher.cc:839
impeller::DlDispatcherBase::setColor
void setColor(flutter::DlColor color) override
Definition: dl_dispatcher.cc:196
impeller::BlendMode::kScreen
@ kScreen
paint
const Paint & paint
Definition: color_source.cc:38
impeller::SamplerDescriptor::label
std::string label
Definition: sampler_descriptor.h:24
impeller::Entity::ClipOperation
ClipOperation
Definition: entity.h:61
impeller::ToBlendMode
static BlendMode ToBlendMode(flutter::DlBlendMode mode)
Definition: dl_dispatcher.cc:42
impeller::TRect::GetBottom
constexpr auto GetBottom() const
Definition: rect.h:347
impeller::Degrees
Definition: scalar.h:46
color.h
color_filter.h
impeller::DlDispatcherBase::drawAtlas
void drawAtlas(const sk_sp< flutter::DlImage > atlas, const SkRSXform xform[], const SkRect tex[], const flutter::DlColor colors[], int count, flutter::DlBlendMode mode, flutter::DlImageSampling sampling, const SkRect *cull_rect, bool render_with_attributes) override
Definition: dl_dispatcher.cc:1027
impeller::Paint::Style
Style
Definition: paint.h:43
color
DlColor color
Definition: dl_golden_blur_unittests.cc:23
impeller::BlendMode::kHue
@ kHue
impeller::Canvas::ClipRect
void ClipRect(const Rect &rect, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:599
impeller::ToSamplerDescriptor
static impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
Definition: dl_dispatcher.cc:119
impeller::DlDispatcherBase::restore
void restore() override
Definition: dl_dispatcher.cc:631
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::DlDispatcherBase::drawPaint
void drawPaint() override
Definition: dl_dispatcher.cc:789
impeller::TextFrameDispatcher::scale
void scale(SkScalar sx, SkScalar sy) override
Definition: dl_dispatcher.cc:1258
impeller::ToColorFilter
static std::shared_ptr< ColorFilter > ToColorFilter(const flutter::DlColorFilter *filter)
Definition: dl_dispatcher.cc:440
impeller::DlDispatcherBase::drawDisplayList
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, SkScalar opacity) override
Definition: dl_dispatcher.cc:1045
impeller::DlDispatcherBase::drawTextFrame
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, SkScalar x, SkScalar y) override
Definition: dl_dispatcher.cc:1115
impeller::TextFrameDispatcher::translate
void translate(SkScalar tx, SkScalar ty) override
Definition: dl_dispatcher.cc:1254
impeller::ColorFilter::MakeSrgbToLinear
static std::shared_ptr< ColorFilter > MakeSrgbToLinear()
Definition: color_filter.cc:32
nine_patch_converter.h
impeller::BlendMode::kXor
@ kXor
impeller::TextFrameDispatcher::skew
void skew(SkScalar sx, SkScalar sy) override
Definition: dl_dispatcher.cc:1266
impeller::Color::blue
Scalar blue
Definition: color.h:138
impeller::ColorSource::Type::kSweepGradient
@ kSweepGradient
impeller::DlDispatcherBase::setMaskFilter
void setMaskFilter(const flutter::DlMaskFilter *filter) override
Definition: dl_dispatcher.cc:495
impeller::ColorMatrix
Definition: color.h:117
impeller::Capabilities::SupportsFramebufferFetch
virtual bool SupportsFramebufferFetch() const =0
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
impeller::ContentBoundsPromise::kContainsContents
@ kContainsContents
The caller claims the bounds are a reasonably tight estimate of the coverage of the contents and shou...
impeller::DlDispatcherBase::setInvertColors
void setInvertColors(bool invert) override
Definition: dl_dispatcher.cc:472
impeller
Definition: aiks_blend_unittests.cc:18
impeller::BlendMode::kSourceATop
@ kSourceATop
impeller::Paint::mask_blur_descriptor
std::optional< MaskBlurDescriptor > mask_blur_descriptor
Definition: paint.h:81
impeller::BlendMode::kMultiply
@ kMultiply
impeller::ContentContext
Definition: content_context.h:366
impeller::TRect::GetTop
constexpr auto GetTop() const
Definition: rect.h:343
impeller::Paint::stroke_width
Scalar stroke_width
Definition: paint.h:71
impeller::skia_conversions::ToPath
Path ToPath(const SkPath &path, Point shift)
Definition: skia_conversions.cc:63
impeller::Canvas::SaveLayer
virtual void SaveLayer(const Paint &paint, std::optional< Rect > bounds=std::nullopt, const std::shared_ptr< ImageFilter > &backdrop_filter=nullptr, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, uint32_t total_content_depth=kMaxDepth, bool can_distribute_opacity=false)
Definition: canvas.cc:842
impeller::ColorSource::Type::kColor
@ kColor
impeller::MakeVertices
std::shared_ptr< impeller::VerticesGeometry > MakeVertices(const std::shared_ptr< const flutter::DlVertices > &vertices)
Definition: dl_vertices_geometry.cc:31
impeller::TRect< Scalar >
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::PathBuilder::AddArc
PathBuilder & AddArc(const Rect &oval_bounds, Radians start, Radians sweep, bool use_center=false)
Definition: path_builder.cc:318
impeller::Vector3
Definition: vector.h:20
impeller::RequiresReadbackForBlends
static bool RequiresReadbackForBlends(const ContentContext &renderer, flutter::DlBlendMode max_root_blend_mode)
Definition: dl_dispatcher.cc:1210
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::Paint::blend_mode
BlendMode blend_mode
Definition: paint.h:76
impeller::Matrix::Scale
constexpr Matrix Scale(const Vector3 &s) const
Definition: matrix.h:252
impeller::Paint::image_filter
std::shared_ptr< ImageFilter > image_filter
Definition: paint.h:79
impeller::DlDispatcherBase::drawCircle
void drawCircle(const SkPoint &center, SkScalar radius) override
Definition: dl_dispatcher.cc:849
impeller::Paint::stroke_join
Join stroke_join
Definition: paint.h:73
impeller::DlDispatcherBase::rotate
void rotate(SkScalar degrees) override
Definition: dl_dispatcher.cc:646
impeller::Canvas::Translate
void Translate(const Vector3 &offset)
Definition: canvas.cc:311
impeller::Canvas::ClipPath
void ClipPath(const Path &path, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:589
impeller::DlDispatcherBase::scale
void scale(SkScalar sx, SkScalar sy) override
Definition: dl_dispatcher.cc:641