Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Namespaces | Macros | Functions
dl_dispatcher.cc File Reference
#include "impeller/display_list/dl_dispatcher.h"
#include <algorithm>
#include <cstring>
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "flutter/fml/logging.h"
#include "flutter/fml/trace_event.h"
#include "impeller/aiks/color_filter.h"
#include "impeller/core/formats.h"
#include "impeller/display_list/dl_vertices_geometry.h"
#include "impeller/display_list/nine_patch_converter.h"
#include "impeller/display_list/skia_conversions.h"
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/entity/contents/filters/inputs/filter_input.h"
#include "impeller/entity/contents/runtime_effect_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/path.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/sigma.h"

Go to the source code of this file.

Namespaces

namespace  impeller
 

Macros

#define UNIMPLEMENTED    FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
 

Functions

static BlendMode impeller::ToBlendMode (flutter::DlBlendMode mode)
 
static Entity::TileMode impeller::ToTileMode (flutter::DlTileMode tile_mode)
 
static impeller::SamplerDescriptor impeller::ToSamplerDescriptor (const flutter::DlImageSampling options)
 
static impeller::SamplerDescriptor impeller::ToSamplerDescriptor (const flutter::DlFilterMode options)
 
static Matrix impeller::ToMatrix (const SkMatrix &m)
 
static Paint::Style impeller::ToStyle (flutter::DlDrawStyle style)
 
static std::vector< Colorimpeller::ToColors (const flutter::DlColor colors[], int count)
 
static std::optional< ColorSource::Typeimpeller::ToColorSourceType (flutter::DlColorSourceType type)
 
static std::shared_ptr< ColorFilterimpeller::ToColorFilter (const flutter::DlColorFilter *filter)
 
static FilterContents::BlurStyle impeller::ToBlurStyle (flutter::DlBlurStyle blur_style)
 
static std::shared_ptr< ImageFilterimpeller::ToImageFilter (const flutter::DlImageFilter *filter)
 
static Entity::ClipOperation impeller::ToClipOperation (flutter::DlCanvas::ClipOp clip_op)
 

Macro Definition Documentation

◆ UNIMPLEMENTED

#define UNIMPLEMENTED    FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;

Definition at line 36 of file dl_dispatcher.cc.

38 {
39 switch (mode) {
41 return BlendMode::kClear;
43 return BlendMode::kSource;
45 return BlendMode::kDestination;
47 return BlendMode::kSourceOver;
49 return BlendMode::kDestinationOver;
51 return BlendMode::kSourceIn;
53 return BlendMode::kDestinationIn;
55 return BlendMode::kSourceOut;
57 return BlendMode::kDestinationOut;
59 return BlendMode::kSourceATop;
61 return BlendMode::kDestinationATop;
63 return BlendMode::kXor;
65 return BlendMode::kPlus;
67 return BlendMode::kModulate;
69 return BlendMode::kScreen;
71 return BlendMode::kOverlay;
73 return BlendMode::kDarken;
75 return BlendMode::kLighten;
77 return BlendMode::kColorDodge;
79 return BlendMode::kColorBurn;
81 return BlendMode::kHardLight;
83 return BlendMode::kSoftLight;
85 return BlendMode::kDifference;
87 return BlendMode::kExclusion;
89 return BlendMode::kMultiply;
91 return BlendMode::kHue;
93 return BlendMode::kSaturation;
95 return BlendMode::kColor;
97 return BlendMode::kLuminosity;
98 }
100}
101
102static Entity::TileMode ToTileMode(flutter::DlTileMode tile_mode) {
103 switch (tile_mode) {
105 return Entity::TileMode::kClamp;
107 return Entity::TileMode::kRepeat;
109 return Entity::TileMode::kMirror;
111 return Entity::TileMode::kDecal;
112 }
113}
114
118 switch (options) {
120 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
121 desc.label = "Nearest Sampler";
122 break;
124 // Impeller doesn't support cubic sampling, but linear is closer to correct
125 // than nearest for this case.
127 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
128 desc.label = "Linear Sampler";
129 break;
131 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
133 desc.label = "Mipmap Linear Sampler";
134 break;
135 }
136 return desc;
137}
138
142 switch (options) {
144 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
145 desc.label = "Nearest Sampler";
146 break;
148 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
149 desc.label = "Linear Sampler";
150 break;
151 default:
152 break;
153 }
154 return desc;
155}
156
157static Matrix ToMatrix(const SkMatrix& m) {
158 return Matrix{
159 // clang-format off
160 m[0], m[3], 0, m[6],
161 m[1], m[4], 0, m[7],
162 0, 0, 1, 0,
163 m[2], m[5], 0, m[8],
164 // clang-format on
165 };
166}
167
168// |flutter::DlOpReceiver|
169void DlDispatcherBase::setAntiAlias(bool aa) {
170 // Nothing to do because AA is implicit.
171}
172
173static Paint::Style ToStyle(flutter::DlDrawStyle style) {
174 switch (style) {
176 return Paint::Style::kFill;
178 return Paint::Style::kStroke;
181 break;
182 }
183 return Paint::Style::kFill;
184}
185
186// |flutter::DlOpReceiver|
187void DlDispatcherBase::setDrawStyle(flutter::DlDrawStyle style) {
188 paint_.style = ToStyle(style);
189}
190
191// |flutter::DlOpReceiver|
192void DlDispatcherBase::setColor(flutter::DlColor color) {
193 paint_.color = {
194 color.getRedF(),
195 color.getGreenF(),
196 color.getBlueF(),
197 color.getAlphaF(),
198 };
199}
200
201// |flutter::DlOpReceiver|
202void DlDispatcherBase::setStrokeWidth(SkScalar width) {
203 paint_.stroke_width = width;
204}
205
206// |flutter::DlOpReceiver|
207void DlDispatcherBase::setStrokeMiter(SkScalar limit) {
208 paint_.stroke_miter = limit;
209}
210
211// |flutter::DlOpReceiver|
212void DlDispatcherBase::setStrokeCap(flutter::DlStrokeCap cap) {
213 switch (cap) {
215 paint_.stroke_cap = Cap::kButt;
216 break;
218 paint_.stroke_cap = Cap::kRound;
219 break;
221 paint_.stroke_cap = Cap::kSquare;
222 break;
223 }
224}
225
226// |flutter::DlOpReceiver|
227void DlDispatcherBase::setStrokeJoin(flutter::DlStrokeJoin join) {
228 switch (join) {
230 paint_.stroke_join = Join::kMiter;
231 break;
233 paint_.stroke_join = Join::kRound;
234 break;
236 paint_.stroke_join = Join::kBevel;
237 break;
238 }
239}
240
241static std::vector<Color> ToColors(const flutter::DlColor colors[], int count) {
242 auto result = std::vector<Color>();
243 if (colors == nullptr) {
244 return result;
245 }
246 for (int i = 0; i < count; i++) {
247 result.push_back(skia_conversions::ToColor(colors[i]));
248 }
249 return result;
250}
251
252static std::optional<ColorSource::Type> ToColorSourceType(
254 switch (type) {
256 return ColorSource::Type::kColor;
258 return ColorSource::Type::kImage;
260 return ColorSource::Type::kLinearGradient;
262 return ColorSource::Type::kRadialGradient;
264 return ColorSource::Type::kConicalGradient;
266 return ColorSource::Type::kSweepGradient;
268 return ColorSource::Type::kRuntimeEffect;
269#ifdef IMPELLER_ENABLE_3D
270 case flutter::DlColorSourceType::kScene:
271 return ColorSource::Type::kScene;
272#endif // IMPELLER_ENABLE_3D
273 }
274}
275
276// |flutter::DlOpReceiver|
277void DlDispatcherBase::setColorSource(const flutter::DlColorSource* source) {
278 if (!source) {
279 paint_.color_source = ColorSource::MakeColor();
280 return;
281 }
282
283 std::optional<ColorSource::Type> type = ToColorSourceType(source->type());
284
285 if (!type.has_value()) {
286 FML_LOG(ERROR) << "Requested ColorSourceType::kUnknown";
287 paint_.color_source = ColorSource::MakeColor();
288 return;
289 }
290
291 switch (type.value()) {
292 case ColorSource::Type::kColor: {
293 const flutter::DlColorColorSource* color = source->asColor();
294
295 paint_.color_source = ColorSource::MakeColor();
296 setColor(color->color());
298 return;
299 }
300 case ColorSource::Type::kLinearGradient: {
302 source->asLinearGradient();
304 auto start_point = skia_conversions::ToPoint(linear->start_point());
305 auto end_point = skia_conversions::ToPoint(linear->end_point());
306 std::vector<Color> colors;
307 std::vector<float> stops;
308 skia_conversions::ConvertStops(linear, colors, stops);
309
310 auto tile_mode = ToTileMode(linear->tile_mode());
311 auto matrix = ToMatrix(linear->matrix());
312
313 paint_.color_source = ColorSource::MakeLinearGradient(
314 start_point, end_point, std::move(colors), std::move(stops),
315 tile_mode, matrix);
316 return;
317 }
318 case ColorSource::Type::kConicalGradient: {
319 const flutter::DlConicalGradientColorSource* conical_gradient =
320 source->asConicalGradient();
321 FML_DCHECK(conical_gradient);
322 Point center = skia_conversions::ToPoint(conical_gradient->end_center());
323 SkScalar radius = conical_gradient->end_radius();
324 Point focus_center =
325 skia_conversions::ToPoint(conical_gradient->start_center());
326 SkScalar focus_radius = conical_gradient->start_radius();
327 std::vector<Color> colors;
328 std::vector<float> stops;
329 skia_conversions::ConvertStops(conical_gradient, colors, stops);
330
331 auto tile_mode = ToTileMode(conical_gradient->tile_mode());
332 auto matrix = ToMatrix(conical_gradient->matrix());
333
334 paint_.color_source = ColorSource::MakeConicalGradient(
335 center, radius, std::move(colors), std::move(stops), focus_center,
336 focus_radius, tile_mode, matrix);
337 return;
338 }
339 case ColorSource::Type::kRadialGradient: {
340 const flutter::DlRadialGradientColorSource* radialGradient =
341 source->asRadialGradient();
342 FML_DCHECK(radialGradient);
343 auto center = skia_conversions::ToPoint(radialGradient->center());
344 auto radius = radialGradient->radius();
345 std::vector<Color> colors;
346 std::vector<float> stops;
347 skia_conversions::ConvertStops(radialGradient, colors, stops);
348
349 auto tile_mode = ToTileMode(radialGradient->tile_mode());
350 auto matrix = ToMatrix(radialGradient->matrix());
351 paint_.color_source =
352 ColorSource::MakeRadialGradient(center, radius, std::move(colors),
353 std::move(stops), tile_mode, matrix);
354 return;
355 }
356 case ColorSource::Type::kSweepGradient: {
357 const flutter::DlSweepGradientColorSource* sweepGradient =
358 source->asSweepGradient();
359 FML_DCHECK(sweepGradient);
360
361 auto center = skia_conversions::ToPoint(sweepGradient->center());
362 auto start_angle = Degrees(sweepGradient->start());
363 auto end_angle = Degrees(sweepGradient->end());
364 std::vector<Color> colors;
365 std::vector<float> stops;
366 skia_conversions::ConvertStops(sweepGradient, colors, stops);
367
368 auto tile_mode = ToTileMode(sweepGradient->tile_mode());
369 auto matrix = ToMatrix(sweepGradient->matrix());
370 paint_.color_source = ColorSource::MakeSweepGradient(
371 center, start_angle, end_angle, std::move(colors), std::move(stops),
372 tile_mode, matrix);
373 return;
374 }
375 case ColorSource::Type::kImage: {
376 const flutter::DlImageColorSource* image_color_source = source->asImage();
377 FML_DCHECK(image_color_source &&
378 image_color_source->image()->impeller_texture());
379 auto texture = image_color_source->image()->impeller_texture();
380 auto x_tile_mode = ToTileMode(image_color_source->horizontal_tile_mode());
381 auto y_tile_mode = ToTileMode(image_color_source->vertical_tile_mode());
382 auto desc = ToSamplerDescriptor(image_color_source->sampling());
383 auto matrix = ToMatrix(image_color_source->matrix());
384 paint_.color_source = ColorSource::MakeImage(texture, x_tile_mode,
385 y_tile_mode, desc, matrix);
386 return;
387 }
388 case ColorSource::Type::kRuntimeEffect: {
389 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
390 source->asRuntimeEffect();
391 auto runtime_stage =
392 runtime_effect_color_source->runtime_effect()->runtime_stage();
393 auto uniform_data = runtime_effect_color_source->uniform_data();
394 auto samplers = runtime_effect_color_source->samplers();
395
396 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
397
398 for (auto& sampler : samplers) {
399 if (sampler == nullptr) {
400 return;
401 }
402 auto* image = sampler->asImage();
403 if (!sampler->asImage()) {
405 return;
406 }
407 FML_DCHECK(image->image()->impeller_texture());
408 texture_inputs.push_back({
409 .sampler_descriptor = ToSamplerDescriptor(image->sampling()),
410 .texture = image->image()->impeller_texture(),
411 });
412 }
413
414 paint_.color_source = ColorSource::MakeRuntimeEffect(
415 runtime_stage, uniform_data, texture_inputs);
416 return;
417 }
418 case ColorSource::Type::kScene: {
419#ifdef IMPELLER_ENABLE_3D
420 const flutter::DlSceneColorSource* scene_color_source = source->asScene();
421 std::shared_ptr<scene::Node> scene_node =
422 scene_color_source->scene_node();
423 Matrix camera_transform = scene_color_source->camera_matrix();
424
425 paint_.color_source =
426 ColorSource::MakeScene(scene_node, camera_transform);
427#else // IMPELLER_ENABLE_3D
428 FML_LOG(ERROR) << "ColorSourceType::kScene can only be used if Impeller "
429 "Scene is enabled.";
430#endif // IMPELLER_ENABLE_3D
431 return;
432 }
433 }
434}
435
436static std::shared_ptr<ColorFilter> ToColorFilter(
437 const flutter::DlColorFilter* filter) {
438 if (filter == nullptr) {
439 return nullptr;
440 }
441 switch (filter->type()) {
443 auto dl_blend = filter->asBlend();
444 auto blend_mode = ToBlendMode(dl_blend->mode());
445 auto color = skia_conversions::ToColor(dl_blend->color());
446 return ColorFilter::MakeBlend(blend_mode, color);
447 }
449 const flutter::DlMatrixColorFilter* dl_matrix = filter->asMatrix();
450 impeller::ColorMatrix color_matrix;
451 dl_matrix->get_matrix(color_matrix.array);
452 return ColorFilter::MakeMatrix(color_matrix);
453 }
455 return ColorFilter::MakeSrgbToLinear();
457 return ColorFilter::MakeLinearToSrgb();
458 }
459 return nullptr;
460}
461
462// |flutter::DlOpReceiver|
463void DlDispatcherBase::setColorFilter(const flutter::DlColorFilter* filter) {
464 paint_.color_filter = ToColorFilter(filter);
465}
466
467// |flutter::DlOpReceiver|
468void DlDispatcherBase::setInvertColors(bool invert) {
469 paint_.invert_colors = invert;
470}
471
472// |flutter::DlOpReceiver|
473void DlDispatcherBase::setBlendMode(flutter::DlBlendMode dl_mode) {
474 paint_.blend_mode = ToBlendMode(dl_mode);
475}
476
477// |flutter::DlOpReceiver|
478void DlDispatcherBase::setPathEffect(const flutter::DlPathEffect* effect) {
479 // Needs https://github.com/flutter/flutter/issues/95434
481}
482
483static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style) {
484 switch (blur_style) {
486 return FilterContents::BlurStyle::kNormal;
488 return FilterContents::BlurStyle::kSolid;
490 return FilterContents::BlurStyle::kOuter;
492 return FilterContents::BlurStyle::kInner;
493 }
494}
495
496// |flutter::DlOpReceiver|
497void DlDispatcherBase::setMaskFilter(const flutter::DlMaskFilter* filter) {
498 // Needs https://github.com/flutter/flutter/issues/95434
499 if (filter == nullptr) {
500 paint_.mask_blur_descriptor = std::nullopt;
501 return;
502 }
503 switch (filter->type()) {
505 auto blur = filter->asBlur();
506
507 paint_.mask_blur_descriptor = {
508 .style = ToBlurStyle(blur->style()),
509 .sigma = Sigma(blur->sigma()),
510 };
511 break;
512 }
513 }
514}
515
516static std::shared_ptr<ImageFilter> ToImageFilter(
517 const flutter::DlImageFilter* filter) {
518 if (filter == nullptr) {
519 return nullptr;
520 }
521
522 switch (filter->type()) {
524 auto blur = filter->asBlur();
525 auto sigma_x = Sigma(blur->sigma_x());
526 auto sigma_y = Sigma(blur->sigma_y());
527 auto tile_mode = ToTileMode(blur->tile_mode());
528 return ImageFilter::MakeBlur(
529 sigma_x, sigma_y, FilterContents::BlurStyle::kNormal, tile_mode);
530 }
532 auto dilate = filter->asDilate();
533 FML_DCHECK(dilate);
534 if (dilate->radius_x() < 0 || dilate->radius_y() < 0) {
535 return nullptr;
536 }
537 auto radius_x = Radius(dilate->radius_x());
538 auto radius_y = Radius(dilate->radius_y());
539 return ImageFilter::MakeDilate(radius_x, radius_y);
540 }
542 auto erode = filter->asErode();
543 FML_DCHECK(erode);
544 if (erode->radius_x() < 0 || erode->radius_y() < 0) {
545 return nullptr;
546 }
547 auto radius_x = Radius(erode->radius_x());
548 auto radius_y = Radius(erode->radius_y());
549 return ImageFilter::MakeErode(radius_x, radius_y);
550 }
552 auto matrix_filter = filter->asMatrix();
553 FML_DCHECK(matrix_filter);
554 auto matrix = ToMatrix(matrix_filter->matrix());
555 auto desc = ToSamplerDescriptor(matrix_filter->sampling());
556 return ImageFilter::MakeMatrix(matrix, desc);
557 }
559 auto compose = filter->asCompose();
560 FML_DCHECK(compose);
561 auto outer_dl_filter = compose->outer();
562 auto inner_dl_filter = compose->inner();
563 auto outer_filter = ToImageFilter(outer_dl_filter.get());
564 auto inner_filter = ToImageFilter(inner_dl_filter.get());
565 if (!outer_filter) {
566 return inner_filter;
567 }
568 if (!inner_filter) {
569 return outer_filter;
570 }
571 FML_DCHECK(outer_filter && inner_filter);
572
573 return ImageFilter::MakeCompose(*inner_filter, *outer_filter);
574 }
576 auto color_filter_image_filter = filter->asColorFilter();
577 FML_DCHECK(color_filter_image_filter);
578 auto color_filter =
579 ToColorFilter(color_filter_image_filter->color_filter().get());
580 if (!color_filter) {
581 return nullptr;
582 }
583 // When color filters are used as image filters, set the color filter's
584 // "absorb opacity" flag to false. For image filters, the snapshot
585 // opacity needs to be deferred until the result of the filter chain is
586 // being blended with the layer.
587 return ImageFilter::MakeFromColorFilter(*color_filter);
588 }
590 auto local_matrix_filter = filter->asLocalMatrix();
591 FML_DCHECK(local_matrix_filter);
592 auto internal_filter = local_matrix_filter->image_filter();
593 FML_DCHECK(internal_filter);
594
595 auto image_filter = ToImageFilter(internal_filter.get());
596 if (!image_filter) {
597 return nullptr;
598 }
599
600 auto matrix = ToMatrix(local_matrix_filter->matrix());
601 return ImageFilter::MakeLocalMatrix(matrix, *image_filter);
602 }
603 }
604}
605
606// |flutter::DlOpReceiver|
607void DlDispatcherBase::setImageFilter(const flutter::DlImageFilter* filter) {
608 paint_.image_filter = ToImageFilter(filter);
609}
610
611// |flutter::DlOpReceiver|
612void DlDispatcherBase::save(uint32_t total_content_depth) {
613 GetCanvas().Save(total_content_depth);
614}
615
616// |flutter::DlOpReceiver|
617void DlDispatcherBase::saveLayer(const SkRect& bounds,
619 uint32_t total_content_depth,
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}
628
629// |flutter::DlOpReceiver|
630void DlDispatcherBase::restore() {
631 GetCanvas().Restore();
632}
633
634// |flutter::DlOpReceiver|
635void DlDispatcherBase::translate(SkScalar tx, SkScalar ty) {
636 GetCanvas().Translate({tx, ty, 0.0});
637}
638
639// |flutter::DlOpReceiver|
640void DlDispatcherBase::scale(SkScalar sx, SkScalar sy) {
641 GetCanvas().Scale({sx, sy, 1.0});
642}
643
644// |flutter::DlOpReceiver|
645void DlDispatcherBase::rotate(SkScalar degrees) {
646 GetCanvas().Rotate(Degrees{degrees});
647}
648
649// |flutter::DlOpReceiver|
650void DlDispatcherBase::skew(SkScalar sx, SkScalar sy) {
651 GetCanvas().Skew(sx, sy);
652}
653
654// |flutter::DlOpReceiver|
655void DlDispatcherBase::transform2DAffine(SkScalar mxx,
656 SkScalar mxy,
657 SkScalar mxt,
658 SkScalar myx,
659 SkScalar myy,
660 SkScalar myt) {
661 // clang-format off
662 transformFullPerspective(
663 mxx, mxy, 0, mxt,
664 myx, myy, 0, myt,
665 0 , 0, 1, 0,
666 0 , 0, 0, 1
667 );
668 // clang-format on
669}
670
671// |flutter::DlOpReceiver|
672void DlDispatcherBase::transformFullPerspective(SkScalar mxx,
673 SkScalar mxy,
674 SkScalar mxz,
675 SkScalar mxt,
676 SkScalar myx,
677 SkScalar myy,
678 SkScalar myz,
679 SkScalar myt,
680 SkScalar mzx,
681 SkScalar mzy,
682 SkScalar mzz,
683 SkScalar mzt,
684 SkScalar mwx,
685 SkScalar mwy,
686 SkScalar mwz,
687 SkScalar mwt) {
688 // The order of arguments is row-major but Impeller matrices are
689 // column-major.
690 // clang-format off
691 auto transform = Matrix{
692 mxx, myx, mzx, mwx,
693 mxy, myy, mzy, mwy,
694 mxz, myz, mzz, mwz,
695 mxt, myt, mzt, mwt
696 };
697 // clang-format on
698 GetCanvas().Transform(transform);
699}
700
701// |flutter::DlOpReceiver|
702void DlDispatcherBase::transformReset() {
703 GetCanvas().ResetTransform();
704 GetCanvas().Transform(initial_matrix_);
705}
706
707static Entity::ClipOperation ToClipOperation(
709 switch (clip_op) {
711 return Entity::ClipOperation::kDifference;
713 return Entity::ClipOperation::kIntersect;
714 }
715}
716
717// |flutter::DlOpReceiver|
718void DlDispatcherBase::clipRect(const SkRect& rect,
719 ClipOp clip_op,
720 bool is_aa) {
721 GetCanvas().ClipRect(skia_conversions::ToRect(rect),
722 ToClipOperation(clip_op));
723}
724
725// |flutter::DlOpReceiver|
726void DlDispatcherBase::clipRRect(const SkRRect& rrect,
727 ClipOp sk_op,
728 bool is_aa) {
729 auto clip_op = ToClipOperation(sk_op);
730 if (rrect.isRect()) {
731 GetCanvas().ClipRect(skia_conversions::ToRect(rrect.rect()), clip_op);
732 } else if (rrect.isOval()) {
733 GetCanvas().ClipOval(skia_conversions::ToRect(rrect.rect()), clip_op);
734 } else if (rrect.isSimple()) {
735 GetCanvas().ClipRRect(skia_conversions::ToRect(rrect.rect()),
736 skia_conversions::ToSize(rrect.getSimpleRadii()),
737 clip_op);
738 } else {
739 GetCanvas().ClipPath(skia_conversions::ToPath(rrect), clip_op);
740 }
741}
742
743// |flutter::DlOpReceiver|
744void DlDispatcherBase::clipPath(const SkPath& path, ClipOp sk_op, bool is_aa) {
746}
747
748const Path& DlDispatcherBase::GetOrCachePath(const CacheablePath& cache) {
749 if (cache.cached_impeller_path.IsEmpty() && !cache.sk_path.isEmpty()) {
750 cache.cached_impeller_path = skia_conversions::ToPath(cache.sk_path);
751 }
752 return cache.cached_impeller_path;
753}
754
755// |flutter::DlOpReceiver|
756void DlDispatcherBase::clipPath(const CacheablePath& cache,
757 ClipOp sk_op,
758 bool is_aa) {
759 auto clip_op = ToClipOperation(sk_op);
760
761 SkRect rect;
762 if (cache.sk_path.isRect(&rect)) {
763 GetCanvas().ClipRect(skia_conversions::ToRect(rect), clip_op);
764 } else if (cache.sk_path.isOval(&rect)) {
765 GetCanvas().ClipOval(skia_conversions::ToRect(rect), clip_op);
766 } else {
768 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
769 GetCanvas().ClipRRect(skia_conversions::ToRect(rrect.rect()),
770 skia_conversions::ToSize(rrect.getSimpleRadii()),
771 clip_op);
772 } else {
773 GetCanvas().ClipPath(GetOrCachePath(cache), clip_op);
774 }
775 }
776}
777
778// |flutter::DlOpReceiver|
779void DlDispatcherBase::drawColor(flutter::DlColor color,
780 flutter::DlBlendMode dl_mode) {
781 Paint paint;
782 paint.color = skia_conversions::ToColor(color);
783 paint.blend_mode = ToBlendMode(dl_mode);
784 GetCanvas().DrawPaint(paint);
785}
786
787// |flutter::DlOpReceiver|
788void DlDispatcherBase::drawPaint() {
789 GetCanvas().DrawPaint(paint_);
790}
791
792// |flutter::DlOpReceiver|
793void DlDispatcherBase::drawLine(const SkPoint& p0, const SkPoint& p1) {
794 GetCanvas().DrawLine(skia_conversions::ToPoint(p0),
795 skia_conversions::ToPoint(p1), paint_);
796}
797
798// |flutter::DlOpReceiver|
799void DlDispatcherBase::drawRect(const SkRect& rect) {
800 GetCanvas().DrawRect(skia_conversions::ToRect(rect), paint_);
801}
802
803// |flutter::DlOpReceiver|
804void DlDispatcherBase::drawOval(const SkRect& bounds) {
805 GetCanvas().DrawOval(skia_conversions::ToRect(bounds), paint_);
806}
807
808// |flutter::DlOpReceiver|
809void DlDispatcherBase::drawCircle(const SkPoint& center, SkScalar radius) {
810 GetCanvas().DrawCircle(skia_conversions::ToPoint(center), radius, paint_);
811}
812
813// |flutter::DlOpReceiver|
814void DlDispatcherBase::drawRRect(const SkRRect& rrect) {
815 if (rrect.isSimple()) {
816 GetCanvas().DrawRRect(skia_conversions::ToRect(rrect.rect()),
817 skia_conversions::ToSize(rrect.getSimpleRadii()),
818 paint_);
819 } else {
820 GetCanvas().DrawPath(skia_conversions::ToPath(rrect), paint_);
821 }
822}
823
824// |flutter::DlOpReceiver|
825void DlDispatcherBase::drawDRRect(const SkRRect& outer, const SkRRect& inner) {
826 PathBuilder builder;
827 builder.AddPath(skia_conversions::ToPath(outer));
828 builder.AddPath(skia_conversions::ToPath(inner));
829 GetCanvas().DrawPath(builder.TakePath(FillType::kOdd), paint_);
830}
831
832// |flutter::DlOpReceiver|
833void DlDispatcherBase::drawPath(const SkPath& path) {
835}
836
837// |flutter::DlOpReceiver|
838void DlDispatcherBase::drawPath(const CacheablePath& cache) {
839 SimplifyOrDrawPath(GetCanvas(), cache, paint_);
840}
841
842void DlDispatcherBase::SimplifyOrDrawPath(CanvasType& canvas,
843 const CacheablePath& cache,
844 const Paint& paint) {
845 SkRect rect;
846
847 // We can't "optimize" a path into a rectangle if it's open.
848 bool closed;
849 if (cache.sk_path.isRect(&rect, &closed) && closed) {
850 canvas.DrawRect(skia_conversions::ToRect(rect), paint);
851 return;
852 }
853
855 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
856 canvas.DrawRRect(skia_conversions::ToRect(rrect.rect()),
857 skia_conversions::ToSize(rrect.getSimpleRadii()), paint);
858 return;
859 }
860
861 SkRect oval;
862 if (cache.sk_path.isOval(&oval)) {
863 canvas.DrawOval(skia_conversions::ToRect(oval), paint);
864 return;
865 }
866
867 canvas.DrawPath(GetOrCachePath(cache), paint);
868}
869
870// |flutter::DlOpReceiver|
871void DlDispatcherBase::drawArc(const SkRect& oval_bounds,
872 SkScalar start_degrees,
873 SkScalar sweep_degrees,
874 bool use_center) {
875 PathBuilder builder;
876 builder.AddArc(skia_conversions::ToRect(oval_bounds), Degrees(start_degrees),
877 Degrees(sweep_degrees), use_center);
878 GetCanvas().DrawPath(builder.TakePath(), paint_);
879}
880
881// |flutter::DlOpReceiver|
882void DlDispatcherBase::drawPoints(PointMode mode,
883 uint32_t count,
884 const SkPoint points[]) {
885 Paint paint = paint_;
886 paint.style = Paint::Style::kStroke;
887 switch (mode) {
889 // Cap::kButt is also treated as a square.
890 auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound
891 : PointStyle::kSquare;
892 auto radius = paint.stroke_width;
893 if (radius > 0) {
894 radius /= 2.0;
895 }
896 GetCanvas().DrawPoints(skia_conversions::ToPoints(points, count), radius,
897 paint, point_style);
898 } break;
900 for (uint32_t i = 1; i < count; i += 2) {
901 Point p0 = skia_conversions::ToPoint(points[i - 1]);
902 Point p1 = skia_conversions::ToPoint(points[i]);
903 GetCanvas().DrawLine(p0, p1, paint);
904 }
905 break;
907 if (count > 1) {
908 Point p0 = skia_conversions::ToPoint(points[0]);
909 for (uint32_t i = 1; i < count; i++) {
910 Point p1 = skia_conversions::ToPoint(points[i]);
911 GetCanvas().DrawLine(p0, p1, paint);
912 p0 = p1;
913 }
914 }
915 break;
916 }
917}
918
919// |flutter::DlOpReceiver|
920void DlDispatcherBase::drawVertices(const flutter::DlVertices* vertices,
921 flutter::DlBlendMode dl_mode) {
922 GetCanvas().DrawVertices(MakeVertices(vertices), ToBlendMode(dl_mode),
923 paint_);
924}
925
926// |flutter::DlOpReceiver|
927void DlDispatcherBase::drawImage(const sk_sp<flutter::DlImage> image,
928 const SkPoint point,
930 bool render_with_attributes) {
931 if (!image) {
932 return;
933 }
934
935 auto texture = image->impeller_texture();
936 if (!texture) {
937 return;
938 }
939
940 const auto size = texture->GetSize();
941 const auto src = SkRect::MakeWH(size.width, size.height);
942 const auto dest =
943 SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);
944
945 drawImageRect(image, // image
946 src, // source rect
947 dest, // destination rect
948 sampling, // sampling options
949 render_with_attributes, // render with attributes
950 SrcRectConstraint::kStrict // constraint
951 );
952}
953
954// |flutter::DlOpReceiver|
955void DlDispatcherBase::drawImageRect(
957 const SkRect& src,
958 const SkRect& dst,
960 bool render_with_attributes,
961 SrcRectConstraint constraint = SrcRectConstraint::kFast) {
962 GetCanvas().DrawImageRect(
963 std::make_shared<Image>(image->impeller_texture()), // image
964 skia_conversions::ToRect(src), // source rect
965 skia_conversions::ToRect(dst), // destination rect
966 render_with_attributes ? paint_ : Paint(), // paint
967 ToSamplerDescriptor(sampling) // sampling
968 );
969}
970
971// |flutter::DlOpReceiver|
972void DlDispatcherBase::drawImageNine(const sk_sp<flutter::DlImage> image,
973 const SkIRect& center,
974 const SkRect& dst,
976 bool render_with_attributes) {
977 NinePatchConverter converter = {};
978 converter.DrawNinePatch(
979 std::make_shared<Image>(image->impeller_texture()),
980 Rect::MakeLTRB(center.fLeft, center.fTop, center.fRight, center.fBottom),
981 skia_conversions::ToRect(dst), ToSamplerDescriptor(filter), &GetCanvas(),
982 &paint_);
983}
984
985// |flutter::DlOpReceiver|
986void DlDispatcherBase::drawAtlas(const sk_sp<flutter::DlImage> atlas,
987 const SkRSXform xform[],
988 const SkRect tex[],
989 const flutter::DlColor colors[],
990 int count,
993 const SkRect* cull_rect,
994 bool render_with_attributes) {
995 GetCanvas().DrawAtlas(std::make_shared<Image>(atlas->impeller_texture()),
996 skia_conversions::ToRSXForms(xform, count),
997 skia_conversions::ToRects(tex, count),
998 ToColors(colors, count), ToBlendMode(mode),
999 ToSamplerDescriptor(sampling),
1000 skia_conversions::ToRect(cull_rect), paint_);
1001}
1002
1003// |flutter::DlOpReceiver|
1004void DlDispatcherBase::drawDisplayList(
1005 const sk_sp<flutter::DisplayList> display_list,
1006 SkScalar opacity) {
1007 // Save all values that must remain untouched after the operation.
1008 Paint saved_paint = paint_;
1009 Matrix saved_initial_matrix = initial_matrix_;
1010
1011 // Establish a new baseline for interpreting the new DL.
1012 // Matrix and clip are left untouched, the current
1013 // transform is saved as the new base matrix, and paint
1014 // values are reset to defaults.
1015 initial_matrix_ = GetCanvas().GetCurrentTransform();
1016 paint_ = Paint();
1017
1018 // Handle passed opacity in the most brute-force way by using
1019 // a SaveLayer. If the display_list is able to inherit the
1020 // opacity, this could also be handled by modulating all of its
1021 // attribute settings (for example, color), by the indicated
1022 // opacity.
1023 int restore_count = GetCanvas().GetSaveCount();
1024 if (opacity < SK_Scalar1) {
1025 Paint save_paint;
1026 save_paint.color = Color(0, 0, 0, opacity);
1027 GetCanvas().SaveLayer(
1028 save_paint, skia_conversions::ToRect(display_list->bounds()), nullptr,
1029 ContentBoundsPromise::kContainsContents, display_list->total_depth());
1030 } else {
1031 // The display list may alter the clip, which must be restored to the
1032 // current clip at the end of playback.
1033 GetCanvas().Save(display_list->total_depth());
1034 }
1035
1036 // TODO(131445): Remove this restriction if we can correctly cull with
1037 // perspective transforms.
1038 if (display_list->has_rtree() && !initial_matrix_.HasPerspective()) {
1039 // The canvas remembers the screen-space culling bounds clipped by
1040 // the surface and the history of clip calls. DisplayList can cull
1041 // the ops based on a rectangle expressed in its "destination bounds"
1042 // so we need the canvas to transform those into the current local
1043 // coordinate space into which the DisplayList will be rendered.
1044 auto cull_bounds = GetCanvas().GetCurrentLocalCullingBounds();
1045 if (cull_bounds.has_value()) {
1046 Rect cull_rect = cull_bounds.value();
1047 display_list->Dispatch(
1048 *this, SkRect::MakeLTRB(cull_rect.GetLeft(), cull_rect.GetTop(),
1049 cull_rect.GetRight(), cull_rect.GetBottom()));
1050 } else {
1051 display_list->Dispatch(*this);
1052 }
1053 } else {
1054 display_list->Dispatch(*this);
1055 }
1056
1057 // Restore all saved state back to what it was before we interpreted
1058 // the display_list
1059 GetCanvas().RestoreToCount(restore_count);
1060 initial_matrix_ = saved_initial_matrix;
1061 paint_ = saved_paint;
1062}
1063
1064// |flutter::DlOpReceiver|
1065void DlDispatcherBase::drawTextBlob(const sk_sp<SkTextBlob> blob,
1066 SkScalar x,
1067 SkScalar y) {
1068 // When running with Impeller enabled Skia text blobs are converted to
1069 // Impeller text frames in paragraph_skia.cc
1071}
1072
1073void DlDispatcherBase::drawTextFrame(
1074 const std::shared_ptr<TextFrame>& text_frame,
1075 SkScalar x,
1076 SkScalar y) {
1077 GetCanvas().DrawTextFrame(text_frame, //
1078 impeller::Point{x, y}, //
1079 paint_ //
1080 );
1081}
1082
1083// |flutter::DlOpReceiver|
1084void DlDispatcherBase::drawShadow(const SkPath& path,
1085 const flutter::DlColor color,
1086 const SkScalar elevation,
1087 bool transparent_occluder,
1088 SkScalar dpr) {
1090}
1091
1092// |flutter::DlOpReceiver|
1093void DlDispatcherBase::drawShadow(const CacheablePath& cache,
1094 const flutter::DlColor color,
1095 const SkScalar elevation,
1096 bool transparent_occluder,
1097 SkScalar dpr) {
1098 Color spot_color = skia_conversions::ToColor(color);
1099 spot_color.alpha *= 0.25;
1100
1101 // Compute the spot color -- ported from SkShadowUtils::ComputeTonalColors.
1102 {
1103 Scalar max =
1104 std::max(std::max(spot_color.red, spot_color.green), spot_color.blue);
1105 Scalar min =
1106 std::min(std::min(spot_color.red, spot_color.green), spot_color.blue);
1107 Scalar luminance = (min + max) * 0.5;
1108
1109 Scalar alpha_adjust =
1110 (2.6f + (-2.66667f + 1.06667f * spot_color.alpha) * spot_color.alpha) *
1111 spot_color.alpha;
1112 Scalar color_alpha =
1113 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
1114 luminance;
1115 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
1116
1117 Scalar greyscale_alpha =
1118 std::clamp(spot_color.alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
1119
1120 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
1121 Scalar tonal_alpha = color_scale + greyscale_alpha;
1122 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
1123 spot_color = Color(unpremul_scale * spot_color.red,
1124 unpremul_scale * spot_color.green,
1125 unpremul_scale * spot_color.blue, tonal_alpha);
1126 }
1127
1128 Vector3 light_position(0, -1, 1);
1129 Scalar occluder_z = dpr * elevation;
1130
1131 constexpr Scalar kLightRadius = 800 / 600; // Light radius / light height
1132
1133 Paint paint;
1134 paint.style = Paint::Style::kFill;
1135 paint.color = spot_color;
1136 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1137 .style = FilterContents::BlurStyle::kNormal,
1138 .sigma = Radius{kLightRadius * occluder_z /
1139 GetCanvas().GetCurrentTransform().GetScale().y},
1140 };
1141
1142 GetCanvas().Save(1u);
1143 GetCanvas().PreConcat(
1144 Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y)));
1145
1146 SimplifyOrDrawPath(GetCanvas(), cache, paint);
1147
1148 GetCanvas().Restore();
1149}
1150
1151Picture DlDispatcherBase::EndRecordingAsPicture() {
1152 TRACE_EVENT0("impeller", "DisplayListDispatcher::EndRecordingAsPicture");
1153 return GetCanvas().EndRecordingAsPicture();
1154}
1155
1156/// Subclasses
1157
1158DlDispatcher::DlDispatcher() = default;
1159
1160DlDispatcher::DlDispatcher(IRect cull_rect) : canvas_(cull_rect) {}
1161
1162DlDispatcher::DlDispatcher(Rect cull_rect) : canvas_(cull_rect) {}
1163
1164Canvas& DlDispatcher::GetCanvas() {
1165 return canvas_;
1166}
1167
1168ExperimentalDlDispatcher::ExperimentalDlDispatcher(ContentContext& renderer,
1169 RenderTarget& render_target,
1170 IRect cull_rect)
1171 : canvas_(renderer, render_target, cull_rect) {}
1172
1173Canvas& ExperimentalDlDispatcher::GetCanvas() {
1174 return canvas_;
1175}
1176
1177//// Text Frame Dispatcher
1178
1179TextFrameDispatcher::TextFrameDispatcher(const ContentContext& renderer,
1180 const Matrix& initial_matrix)
1181 : renderer_(renderer), matrix_(initial_matrix) {}
1182
1183void TextFrameDispatcher::save() {
1184 stack_.emplace_back(matrix_);
1185}
1186
1187void TextFrameDispatcher::saveLayer(const SkRect& bounds,
1189 const flutter::DlImageFilter* backdrop) {
1190 save();
1191}
1192
1193void TextFrameDispatcher::restore() {
1194 matrix_ = stack_.back();
1195 stack_.pop_back();
1196}
1197
1198void TextFrameDispatcher::translate(SkScalar tx, SkScalar ty) {
1199 matrix_ = matrix_.Translate({tx, ty});
1200}
1201
1202void TextFrameDispatcher::scale(SkScalar sx, SkScalar sy) {
1203 matrix_ = matrix_.Scale({sx, sy, 1.0f});
1204}
1205
1206void TextFrameDispatcher::rotate(SkScalar degrees) {
1207 matrix_ = matrix_ * Matrix::MakeRotationZ(Degrees(degrees));
1208}
1209
1210void TextFrameDispatcher::skew(SkScalar sx, SkScalar sy) {
1211 matrix_ = matrix_ * Matrix::MakeSkew(sx, sy);
1212}
1213
1214// clang-format off
1215 // 2x3 2D affine subset of a 4x4 transform in row major order
1216 void TextFrameDispatcher::transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt,
1217 SkScalar myx, SkScalar myy, SkScalar myt) {
1218 matrix_ = matrix_ * Matrix::MakeColumn(
1219 mxx, myx, 0.0f, 0.0f,
1220 mxy, myy, 0.0f, 0.0f,
1221 0.0f, 0.0f, 1.0f, 0.0f,
1222 mxt, myt, 0.0f, 1.0f
1223 );
1224 }
1225
1226 // full 4x4 transform in row major order
1227 void TextFrameDispatcher::transformFullPerspective(
1228 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
1229 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
1230 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
1231 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
1232 matrix_ = matrix_ * Matrix::MakeColumn(
1233 mxx, myx, mzx, mwx,
1234 mxy, myy, mzy, mwy,
1235 mxz, myz, mzz, mwz,
1236 mxt, myt, mzt, mwt
1237 );
1238 }
1239// clang-format on
1240
1241void TextFrameDispatcher::transformReset() {
1242 matrix_ = Matrix();
1243}
1244
1245void TextFrameDispatcher::drawTextFrame(
1246 const std::shared_ptr<impeller::TextFrame>& text_frame,
1247 SkScalar x,
1248 SkScalar y) {
1249 renderer_.GetLazyGlyphAtlas()->AddTextFrame(*text_frame,
1250 matrix_.GetMaxBasisLengthXY());
1251}
1252
1253void TextFrameDispatcher::drawDisplayList(
1254 const sk_sp<flutter::DisplayList> display_list,
1255 SkScalar opacity) {
1256 [[maybe_unused]] size_t stack_depth = stack_.size();
1257 save();
1258 display_list->Dispatch(*this);
1259 restore();
1260 FML_DCHECK(stack_depth == stack_.size());
1261}
1262
1263} // namespace impeller
const char * options
int count
static const int points[]
SkColor4f color
static sk_sp< SkImage > color_filter(const SkImage *image, SkColorFilter *colorFilter)
#define SK_Scalar1
Definition SkScalar.h:18
static SkScalar center(float pos0, float pos1)
sk_sp< SkImage > asImage() const
Definition SkBitmap.cpp:645
SkVector getSimpleRadii() const
Definition SkRRect.h:111
bool isOval() const
Definition SkRRect.h:85
const SkRect & rect() const
Definition SkRRect.h:264
bool isRect() const
Definition SkRRect.h:84
bool isSimple() const
Definition SkRRect.h:86
virtual T type() const =0
DlBlurStyle style() const
@ kLines
draw each separate pair of points as a line segment
@ kPolygon
draw each pair of overlapping points as a line segment
@ kPoints
draw each point separately
virtual const DlBlendColorFilter * asBlend() const
virtual const DlMatrixColorFilter * asMatrix() const
DlImageSampling sampling() const
DlTileMode vertical_tile_mode() 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
virtual const DlBlurMaskFilter * asBlur() const
void get_matrix(float matrix[20]) const
const SkMatrix & matrix() const
const std::shared_ptr< std::vector< uint8_t > > uniform_data() const
const sk_sp< DlRuntimeEffect > runtime_effect() const
const std::vector< std::shared_ptr< DlColorSource > > samplers() const
Holds all of the data (both required and optional) for a DisplayList drawVertices call.
Definition dl_vertices.h:71
const Paint & paint
#define UNIMPLEMENTED
sk_sp< SkImage > image
Definition examples.cpp:29
SkBitmap source
Definition examples.cpp:28
float SkScalar
Definition extension.cpp:12
gboolean invert
GAsyncResult * result
#define FML_LOG(severity)
Definition logging.h:82
#define FML_UNREACHABLE()
Definition logging.h:109
#define FML_DCHECK(condition)
Definition logging.h:103
static float max(float r, float g, float b)
Definition hsl.cpp:49
static float min(float r, float g, float b)
Definition hsl.cpp:48
FlTexture * texture
double y
double x
sk_sp< const SkImage > atlas
Definition SkRecords.h:331
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258
SkRRect rrect
Definition SkRecords.h:232
SkRect oval
Definition SkRecords.h:249
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
PODArray< SkColor > colors
Definition SkRecords.h:276
SkSamplingOptions sampling
Definition SkRecords.h:337
DlStrokeJoin
Definition dl_paint.h:38
@ kMiter
extends to miter limit
@ kBevel
connects outside edges
DlStrokeCap
Definition dl_paint.h:29
@ kRound
adds circle
@ kButt
no stroke extension
@ kSquare
adds square
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
Definition switches.h:191
DlDrawStyle
Definition dl_paint.h:20
@ kStrokeAndFill
both strokes and fills shapes
@ kStroke
strokes boundary of shapes
@ kFill
fills interior of shapes
@ kNormal
fuzzy inside and outside
@ kOuter
nothing inside, fuzzy outside
@ kInner
fuzzy inside, nothing outside
@ kSolid
solid inside, fuzzy outside
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
CanvasPath Path
Definition dart_ui.cc:58
@ kSrcOut
r = s * (1-da)
@ kExclusion
rc = s + d - two(s*d), ra = kSrcOver
@ kSaturation
saturation of source with hue and luminosity of destination
@ kColorBurn
darken destination to reflect source
@ kPlus
r = min(s + d, 1)
@ kLighten
rc = s + d - min(s*da, d*sa), ra = kSrcOver
@ kHue
hue of source with saturation and luminosity of destination
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kColorDodge
brighten destination to reflect source
@ kScreen
r = s + d - s*d
@ kSrcOver
r = s + (1-sa)*d
@ kXor
r = s*(1-da) + d*(1-sa)
@ kLuminosity
luminosity of source with hue and saturation of destination
@ kSoftLight
lighten or darken, depending on source
@ kDifference
rc = s + d - 2*(min(s*da, d*sa)), ra = kSrcOver
@ kOverlay
multiply or screen, depending on destination
@ kSrcATop
r = s*da + d*(1-sa)
@ kDstATop
r = d*sa + s*(1-da)
@ kDstOver
r = d + (1-da)*s
@ kColor
hue and saturation of source with luminosity of destination
@ kHardLight
multiply or screen, depending on source
@ kDstOut
r = d * (1-sa)
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
static BlendMode ToBlendMode(flutter::DlBlendMode mode)
Point Vector2
Definition point.h:320
float Scalar
Definition scalar.h:18
static Paint::Style ToStyle(flutter::DlDrawStyle style)
static std::shared_ptr< ImageFilter > ToImageFilter(const flutter::DlImageFilter *filter)
TRect< Scalar > Rect
Definition rect.h:746
static std::optional< ColorSource::Type > ToColorSourceType(flutter::DlColorSourceType type)
TPoint< Scalar > Point
Definition point.h:316
static Entity::ClipOperation ToClipOperation(flutter::DlCanvas::ClipOp clip_op)
static Matrix ToMatrix(const SkMatrix &m)
static std::shared_ptr< ColorFilter > ToColorFilter(const flutter::DlColorFilter *filter)
static impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
static Entity::TileMode ToTileMode(flutter::DlTileMode tile_mode)
@ kNearest
Select nearest to the sample point. Most widely supported.
static std::vector< Color > ToColors(const flutter::DlColor colors[], int count)
static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style)
std::shared_ptr< impeller::VerticesGeometry > MakeVertices(const flutter::DlVertices *vertices)
SK_API sk_sp< PrecompileShader > Picture()
dest
Definition zip.py:79
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition p3.cpp:47
int32_t width
float fX
x-axis value
float fY
y-axis value
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646
Scalar array[20]
Definition color.h:118
#define ERROR(message)
#define TRACE_EVENT0(category_group, name)
static sk_sp< SkShader > linear(sk_sp< SkShader > shader)