Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
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"
29
30#if IMPELLER_ENABLE_3D
32#endif // IMPELLER_ENABLE_3D
33
34namespace impeller {
35
36#define UNIMPLEMENTED \
37 FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
38
40 switch (mode) {
42 return BlendMode::kClear;
44 return BlendMode::kSource;
64 return BlendMode::kXor;
66 return BlendMode::kPlus;
70 return BlendMode::kScreen;
74 return BlendMode::kDarken;
92 return BlendMode::kHue;
96 return BlendMode::kColor;
99 }
101}
102
115
119 switch (options) {
121 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
122 desc.label = "Nearest Sampler";
123 break;
125 // Impeller doesn't support cubic sampling, but linear is closer to correct
126 // than nearest for this case.
128 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
129 desc.label = "Linear Sampler";
130 break;
132 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
133 desc.mip_filter = impeller::MipFilter::kLinear;
134 desc.label = "Mipmap Linear Sampler";
135 break;
136 }
137 return desc;
138}
139
143 switch (options) {
145 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
146 desc.label = "Nearest Sampler";
147 break;
149 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
150 desc.label = "Linear Sampler";
151 break;
152 default:
153 break;
154 }
155 return desc;
156}
157
158static Matrix ToMatrix(const SkMatrix& m) {
159 return Matrix{
160 // clang-format off
161 m[0], m[3], 0, m[6],
162 m[1], m[4], 0, m[7],
163 0, 0, 1, 0,
164 m[2], m[5], 0, m[8],
165 // clang-format on
166 };
167}
168
169// |flutter::DlOpReceiver|
171 // Nothing to do because AA is implicit.
172}
173
175 switch (style) {
177 return Paint::Style::kFill;
182 break;
183 }
184 return Paint::Style::kFill;
185}
186
187// |flutter::DlOpReceiver|
189 paint_.style = ToStyle(style);
190}
191
192// |flutter::DlOpReceiver|
194 paint_.color = {
195 color.getRedF(),
196 color.getGreenF(),
197 color.getBlueF(),
198 color.getAlphaF(),
199 };
200}
201
202// |flutter::DlOpReceiver|
206
207// |flutter::DlOpReceiver|
209 paint_.stroke_miter = limit;
210}
211
212// |flutter::DlOpReceiver|
214 switch (cap) {
216 paint_.stroke_cap = Cap::kButt;
217 break;
219 paint_.stroke_cap = Cap::kRound;
220 break;
222 paint_.stroke_cap = Cap::kSquare;
223 break;
224 }
225}
226
227// |flutter::DlOpReceiver|
229 switch (join) {
231 paint_.stroke_join = Join::kMiter;
232 break;
234 paint_.stroke_join = Join::kRound;
235 break;
237 paint_.stroke_join = Join::kBevel;
238 break;
239 }
240}
241
242static std::vector<Color> ToColors(const flutter::DlColor colors[], int count) {
243 auto result = std::vector<Color>();
244 if (colors == nullptr) {
245 return result;
246 }
247 for (int i = 0; i < count; i++) {
248 result.push_back(skia_conversions::ToColor(colors[i]));
249 }
250 return result;
251}
252
276
277// |flutter::DlOpReceiver|
279 if (!source) {
281 return;
282 }
283
284 std::optional<ColorSource::Type> type = ToColorSourceType(source->type());
285
286 if (!type.has_value()) {
287 FML_LOG(ERROR) << "Requested ColorSourceType::kUnknown";
289 return;
290 }
291
292 switch (type.value()) {
294 const flutter::DlColorColorSource* color = source->asColor();
295
297 setColor(color->color());
299 return;
300 }
303 source->asLinearGradient();
305 auto start_point = skia_conversions::ToPoint(linear->start_point());
306 auto end_point = skia_conversions::ToPoint(linear->end_point());
307 std::vector<Color> colors;
308 std::vector<float> stops;
310
311 auto tile_mode = ToTileMode(linear->tile_mode());
312 auto matrix = ToMatrix(linear->matrix());
313
315 start_point, end_point, std::move(colors), std::move(stops),
316 tile_mode, matrix);
317 return;
318 }
320 const flutter::DlConicalGradientColorSource* conical_gradient =
321 source->asConicalGradient();
322 FML_DCHECK(conical_gradient);
323 Point center = skia_conversions::ToPoint(conical_gradient->end_center());
324 SkScalar radius = conical_gradient->end_radius();
325 Point focus_center =
326 skia_conversions::ToPoint(conical_gradient->start_center());
327 SkScalar focus_radius = conical_gradient->start_radius();
328 std::vector<Color> colors;
329 std::vector<float> stops;
330 skia_conversions::ConvertStops(conical_gradient, colors, stops);
331
332 auto tile_mode = ToTileMode(conical_gradient->tile_mode());
333 auto matrix = ToMatrix(conical_gradient->matrix());
334
336 center, radius, std::move(colors), std::move(stops), focus_center,
337 focus_radius, tile_mode, matrix);
338 return;
339 }
341 const flutter::DlRadialGradientColorSource* radialGradient =
342 source->asRadialGradient();
343 FML_DCHECK(radialGradient);
344 auto center = skia_conversions::ToPoint(radialGradient->center());
345 auto radius = radialGradient->radius();
346 std::vector<Color> colors;
347 std::vector<float> stops;
348 skia_conversions::ConvertStops(radialGradient, colors, stops);
349
350 auto tile_mode = ToTileMode(radialGradient->tile_mode());
351 auto matrix = ToMatrix(radialGradient->matrix());
352 paint_.color_source =
353 ColorSource::MakeRadialGradient(center, radius, std::move(colors),
354 std::move(stops), tile_mode, matrix);
355 return;
356 }
358 const flutter::DlSweepGradientColorSource* sweepGradient =
359 source->asSweepGradient();
360 FML_DCHECK(sweepGradient);
361
362 auto center = skia_conversions::ToPoint(sweepGradient->center());
363 auto start_angle = Degrees(sweepGradient->start());
364 auto end_angle = Degrees(sweepGradient->end());
365 std::vector<Color> colors;
366 std::vector<float> stops;
367 skia_conversions::ConvertStops(sweepGradient, colors, stops);
368
369 auto tile_mode = ToTileMode(sweepGradient->tile_mode());
370 auto matrix = ToMatrix(sweepGradient->matrix());
372 center, start_angle, end_angle, std::move(colors), std::move(stops),
373 tile_mode, matrix);
374 return;
375 }
377 const flutter::DlImageColorSource* image_color_source = source->asImage();
378 FML_DCHECK(image_color_source &&
379 image_color_source->image()->impeller_texture());
380 auto texture = image_color_source->image()->impeller_texture();
381 auto x_tile_mode = ToTileMode(image_color_source->horizontal_tile_mode());
382 auto y_tile_mode = ToTileMode(image_color_source->vertical_tile_mode());
383 auto desc = ToSamplerDescriptor(image_color_source->sampling());
384 auto matrix = ToMatrix(image_color_source->matrix());
385 paint_.color_source = ColorSource::MakeImage(texture, x_tile_mode,
386 y_tile_mode, desc, matrix);
387 return;
388 }
390 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
391 source->asRuntimeEffect();
392 auto runtime_stage =
393 runtime_effect_color_source->runtime_effect()->runtime_stage();
394 auto uniform_data = runtime_effect_color_source->uniform_data();
395 auto samplers = runtime_effect_color_source->samplers();
396
397 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
398
399 for (auto& sampler : samplers) {
400 if (sampler == nullptr) {
401 return;
402 }
403 auto* image = sampler->asImage();
404 if (!sampler->asImage()) {
406 return;
407 }
408 FML_DCHECK(image->image()->impeller_texture());
409 texture_inputs.push_back({
410 .sampler_descriptor = ToSamplerDescriptor(image->sampling()),
411 .texture = image->image()->impeller_texture(),
412 });
413 }
414
416 runtime_stage, uniform_data, texture_inputs);
417 return;
418 }
420#ifdef IMPELLER_ENABLE_3D
421 const flutter::DlSceneColorSource* scene_color_source = source->asScene();
422 std::shared_ptr<scene::Node> scene_node =
423 scene_color_source->scene_node();
424 Matrix camera_transform = scene_color_source->camera_matrix();
425
426 paint_.color_source =
427 ColorSource::MakeScene(scene_node, camera_transform);
428#else // IMPELLER_ENABLE_3D
429 FML_LOG(ERROR) << "ColorSourceType::kScene can only be used if Impeller "
430 "Scene is enabled.";
431#endif // IMPELLER_ENABLE_3D
432 return;
433 }
434 }
435}
436
437static std::shared_ptr<ColorFilter> ToColorFilter(
438 const flutter::DlColorFilter* filter) {
439 if (filter == nullptr) {
440 return nullptr;
441 }
442 switch (filter->type()) {
444 auto dl_blend = filter->asBlend();
445 auto blend_mode = ToBlendMode(dl_blend->mode());
446 auto color = skia_conversions::ToColor(dl_blend->color());
447 return ColorFilter::MakeBlend(blend_mode, color);
448 }
450 const flutter::DlMatrixColorFilter* dl_matrix = filter->asMatrix();
451 impeller::ColorMatrix color_matrix;
452 dl_matrix->get_matrix(color_matrix.array);
453 return ColorFilter::MakeMatrix(color_matrix);
454 }
459 }
460 return nullptr;
461}
462
463// |flutter::DlOpReceiver|
467
468// |flutter::DlOpReceiver|
472
473// |flutter::DlOpReceiver|
477
478// |flutter::DlOpReceiver|
480 // Needs https://github.com/flutter/flutter/issues/95434
482}
483
496
497// |flutter::DlOpReceiver|
499 // Needs https://github.com/flutter/flutter/issues/95434
500 if (filter == nullptr) {
501 paint_.mask_blur_descriptor = std::nullopt;
502 return;
503 }
504 switch (filter->type()) {
506 auto blur = filter->asBlur();
507
508 paint_.mask_blur_descriptor = {
509 .style = ToBlurStyle(blur->style()),
510 .sigma = Sigma(blur->sigma()),
511 };
512 break;
513 }
514 }
515}
516
517static std::shared_ptr<ImageFilter> ToImageFilter(
518 const flutter::DlImageFilter* filter) {
519 if (filter == nullptr) {
520 return nullptr;
521 }
522
523 switch (filter->type()) {
525 auto blur = filter->asBlur();
526 auto sigma_x = Sigma(blur->sigma_x());
527 auto sigma_y = Sigma(blur->sigma_y());
528 auto tile_mode = ToTileMode(blur->tile_mode());
530 sigma_x, sigma_y, FilterContents::BlurStyle::kNormal, tile_mode);
531 }
533 auto dilate = filter->asDilate();
534 FML_DCHECK(dilate);
535 if (dilate->radius_x() < 0 || dilate->radius_y() < 0) {
536 return nullptr;
537 }
538 auto radius_x = Radius(dilate->radius_x());
539 auto radius_y = Radius(dilate->radius_y());
540 return ImageFilter::MakeDilate(radius_x, radius_y);
541 }
543 auto erode = filter->asErode();
544 FML_DCHECK(erode);
545 if (erode->radius_x() < 0 || erode->radius_y() < 0) {
546 return nullptr;
547 }
548 auto radius_x = Radius(erode->radius_x());
549 auto radius_y = Radius(erode->radius_y());
550 return ImageFilter::MakeErode(radius_x, radius_y);
551 }
553 auto matrix_filter = filter->asMatrix();
554 FML_DCHECK(matrix_filter);
555 auto matrix = ToMatrix(matrix_filter->matrix());
556 auto desc = ToSamplerDescriptor(matrix_filter->sampling());
557 return ImageFilter::MakeMatrix(matrix, desc);
558 }
560 auto compose = filter->asCompose();
561 FML_DCHECK(compose);
562 auto outer_dl_filter = compose->outer();
563 auto inner_dl_filter = compose->inner();
564 auto outer_filter = ToImageFilter(outer_dl_filter.get());
565 auto inner_filter = ToImageFilter(inner_dl_filter.get());
566 if (!outer_filter) {
567 return inner_filter;
568 }
569 if (!inner_filter) {
570 return outer_filter;
571 }
572 FML_DCHECK(outer_filter && inner_filter);
573
574 return ImageFilter::MakeCompose(*inner_filter, *outer_filter);
575 }
577 auto color_filter_image_filter = filter->asColorFilter();
578 FML_DCHECK(color_filter_image_filter);
579 auto color_filter =
580 ToColorFilter(color_filter_image_filter->color_filter().get());
581 if (!color_filter) {
582 return nullptr;
583 }
584 // When color filters are used as image filters, set the color filter's
585 // "absorb opacity" flag to false. For image filters, the snapshot
586 // opacity needs to be deferred until the result of the filter chain is
587 // being blended with the layer.
589 }
591 auto local_matrix_filter = filter->asLocalMatrix();
592 FML_DCHECK(local_matrix_filter);
593 auto internal_filter = local_matrix_filter->image_filter();
594 FML_DCHECK(internal_filter);
595
596 auto image_filter = ToImageFilter(internal_filter.get());
597 if (!image_filter) {
598 return nullptr;
599 }
600
601 auto matrix = ToMatrix(local_matrix_filter->matrix());
602 return ImageFilter::MakeLocalMatrix(matrix, *image_filter);
603 }
604 }
605}
606
607// |flutter::DlOpReceiver|
611
612// |flutter::DlOpReceiver|
613void DlDispatcherBase::save(uint32_t total_content_depth) {
614 GetCanvas().Save(total_content_depth);
615}
616
617// |flutter::DlOpReceiver|
620 uint32_t total_content_depth,
621 const flutter::DlImageFilter* backdrop) {
622 auto paint = options.renders_with_attributes() ? paint_ : Paint{};
623 auto promise = options.content_is_clipped()
627 ToImageFilter(backdrop), promise, total_content_depth);
628}
629
630// |flutter::DlOpReceiver|
634
635// |flutter::DlOpReceiver|
637 GetCanvas().Translate({tx, ty, 0.0});
638}
639
640// |flutter::DlOpReceiver|
642 GetCanvas().Scale({sx, sy, 1.0});
643}
644
645// |flutter::DlOpReceiver|
647 GetCanvas().Rotate(Degrees{degrees});
648}
649
650// |flutter::DlOpReceiver|
652 GetCanvas().Skew(sx, sy);
653}
654
655// |flutter::DlOpReceiver|
657 SkScalar mxy,
658 SkScalar mxt,
659 SkScalar myx,
660 SkScalar myy,
661 SkScalar myt) {
662 // clang-format off
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|
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
700}
701
702// |flutter::DlOpReceiver|
705 GetCanvas().Transform(initial_matrix_);
706}
707
717
718// |flutter::DlOpReceiver|
720 ClipOp clip_op,
721 bool is_aa) {
723 ToClipOperation(clip_op));
724}
725
726// |flutter::DlOpReceiver|
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()) {
738 clip_op);
739 } else {
741 }
742}
743
744// |flutter::DlOpReceiver|
745void DlDispatcherBase::clipPath(const SkPath& path, ClipOp sk_op, bool is_aa) {
747}
748
749const 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|
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)) {
765 } else if (cache.sk_path.isOval(&rect)) {
767 } else {
768 SkRRect rrect;
769 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
772 clip_op);
773 } else {
774 GetCanvas().ClipPath(GetOrCachePath(cache), clip_op);
775 }
776 }
777}
778
779// |flutter::DlOpReceiver|
787
788// |flutter::DlOpReceiver|
792
793// |flutter::DlOpReceiver|
798
799// |flutter::DlOpReceiver|
802}
803
804// |flutter::DlOpReceiver|
807}
808
809// |flutter::DlOpReceiver|
813
814// |flutter::DlOpReceiver|
816 if (rrect.isSimple()) {
819 paint_);
820 } else {
822 }
823}
824
825// |flutter::DlOpReceiver|
826void DlDispatcherBase::drawDRRect(const SkRRect& outer, const SkRRect& inner) {
827 PathBuilder builder;
828 builder.AddPath(skia_conversions::ToPath(outer));
829 builder.AddPath(skia_conversions::ToPath(inner));
830 GetCanvas().DrawPath(builder.TakePath(FillType::kOdd), paint_);
831}
832
833// |flutter::DlOpReceiver|
836}
837
838// |flutter::DlOpReceiver|
840 SimplifyOrDrawPath(GetCanvas(), cache, paint_);
841}
842
843void DlDispatcherBase::SimplifyOrDrawPath(CanvasType& canvas,
844 const CacheablePath& cache,
845 const Paint& paint) {
846 SkRect rect;
847
848 // We can't "optimize" a path into a rectangle if it's open.
849 bool closed;
850 if (cache.sk_path.isRect(&rect, &closed) && closed) {
852 return;
853 }
854
855 SkRRect rrect;
856 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
859 return;
860 }
861
862 SkRect oval;
863 if (cache.sk_path.isOval(&oval)) {
865 return;
866 }
867
868 canvas.DrawPath(GetOrCachePath(cache), paint);
869}
870
871// |flutter::DlOpReceiver|
872void DlDispatcherBase::drawArc(const SkRect& oval_bounds,
873 SkScalar start_degrees,
874 SkScalar sweep_degrees,
875 bool use_center) {
876 PathBuilder builder;
877 builder.AddArc(skia_conversions::ToRect(oval_bounds), Degrees(start_degrees),
878 Degrees(sweep_degrees), use_center);
879 GetCanvas().DrawPath(builder.TakePath(), paint_);
880}
881
882// |flutter::DlOpReceiver|
884 uint32_t count,
885 const SkPoint points[]) {
886 Paint paint = paint_;
888 switch (mode) {
890 // Cap::kButt is also treated as a square.
891 auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound
893 auto radius = paint.stroke_width;
894 if (radius > 0) {
895 radius /= 2.0;
896 }
898 paint, point_style);
899 } break;
901 for (uint32_t i = 1; i < count; i += 2) {
904 GetCanvas().DrawLine(p0, p1, paint);
905 }
906 break;
908 if (count > 1) {
910 for (uint32_t i = 1; i < count; i++) {
912 GetCanvas().DrawLine(p0, p1, paint);
913 p0 = p1;
914 }
915 }
916 break;
917 }
918}
919
920// |flutter::DlOpReceiver|
922 flutter::DlBlendMode dl_mode) {
923 GetCanvas().DrawVertices(MakeVertices(vertices), ToBlendMode(dl_mode),
924 paint_);
925}
926
927// |flutter::DlOpReceiver|
929 const SkPoint point,
931 bool render_with_attributes) {
932 if (!image) {
933 return;
934 }
935
936 auto texture = image->impeller_texture();
937 if (!texture) {
938 return;
939 }
940
941 const auto size = texture->GetSize();
942 const auto src = SkRect::MakeWH(size.width, size.height);
943 const auto dest =
944 SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);
945
946 drawImageRect(image, // image
947 src, // source rect
948 dest, // destination rect
949 sampling, // sampling options
950 render_with_attributes, // render with attributes
951 SrcRectConstraint::kStrict // constraint
952 );
953}
954
955// |flutter::DlOpReceiver|
958 const SkRect& src,
959 const SkRect& dst,
961 bool render_with_attributes,
962 SrcRectConstraint constraint = SrcRectConstraint::kFast) {
964 std::make_shared<Image>(image->impeller_texture()), // image
965 skia_conversions::ToRect(src), // source rect
966 skia_conversions::ToRect(dst), // destination rect
967 render_with_attributes ? paint_ : Paint(), // paint
968 ToSamplerDescriptor(sampling) // sampling
969 );
970}
971
972// |flutter::DlOpReceiver|
974 const SkIRect& center,
975 const SkRect& dst,
977 bool render_with_attributes) {
978 NinePatchConverter converter = {};
979 converter.DrawNinePatch(
980 std::make_shared<Image>(image->impeller_texture()),
981 Rect::MakeLTRB(center.fLeft, center.fTop, center.fRight, center.fBottom),
983 &paint_);
984}
985
986// |flutter::DlOpReceiver|
988 const SkRSXform xform[],
989 const SkRect tex[],
990 const flutter::DlColor colors[],
991 int count,
994 const SkRect* cull_rect,
995 bool render_with_attributes) {
996 GetCanvas().DrawAtlas(std::make_shared<Image>(atlas->impeller_texture()),
999 ToColors(colors, count), ToBlendMode(mode),
1000 ToSamplerDescriptor(sampling),
1001 skia_conversions::ToRect(cull_rect), paint_);
1002}
1003
1004// |flutter::DlOpReceiver|
1006 const sk_sp<flutter::DisplayList> display_list,
1007 SkScalar opacity) {
1008 // Save all values that must remain untouched after the operation.
1009 Paint saved_paint = paint_;
1010 Matrix saved_initial_matrix = initial_matrix_;
1011
1012 // Establish a new baseline for interpreting the new DL.
1013 // Matrix and clip are left untouched, the current
1014 // transform is saved as the new base matrix, and paint
1015 // values are reset to defaults.
1016 initial_matrix_ = GetCanvas().GetCurrentTransform();
1017 paint_ = Paint();
1018
1019 // Handle passed opacity in the most brute-force way by using
1020 // a SaveLayer. If the display_list is able to inherit the
1021 // opacity, this could also be handled by modulating all of its
1022 // attribute settings (for example, color), by the indicated
1023 // opacity.
1024 int restore_count = GetCanvas().GetSaveCount();
1025 if (opacity < SK_Scalar1) {
1026 Paint save_paint;
1027 save_paint.color = Color(0, 0, 0, opacity);
1029 save_paint, skia_conversions::ToRect(display_list->bounds()), nullptr,
1030 ContentBoundsPromise::kContainsContents, display_list->total_depth());
1031 } else {
1032 // The display list may alter the clip, which must be restored to the
1033 // current clip at the end of playback.
1034 GetCanvas().Save(display_list->total_depth());
1035 }
1036
1037 // TODO(131445): Remove this restriction if we can correctly cull with
1038 // perspective transforms.
1039 if (display_list->has_rtree() && !initial_matrix_.HasPerspective()) {
1040 // The canvas remembers the screen-space culling bounds clipped by
1041 // the surface and the history of clip calls. DisplayList can cull
1042 // the ops based on a rectangle expressed in its "destination bounds"
1043 // so we need the canvas to transform those into the current local
1044 // coordinate space into which the DisplayList will be rendered.
1045 auto cull_bounds = GetCanvas().GetCurrentLocalCullingBounds();
1046 if (cull_bounds.has_value()) {
1047 Rect cull_rect = cull_bounds.value();
1048 display_list->Dispatch(
1049 *this, SkRect::MakeLTRB(cull_rect.GetLeft(), cull_rect.GetTop(),
1050 cull_rect.GetRight(), cull_rect.GetBottom()));
1051 } else {
1052 display_list->Dispatch(*this);
1053 }
1054 } else {
1055 display_list->Dispatch(*this);
1056 }
1057
1058 // Restore all saved state back to what it was before we interpreted
1059 // the display_list
1060 GetCanvas().RestoreToCount(restore_count);
1061 initial_matrix_ = saved_initial_matrix;
1062 paint_ = saved_paint;
1063}
1064
1065// |flutter::DlOpReceiver|
1067 SkScalar x,
1068 SkScalar y) {
1069 // When running with Impeller enabled Skia text blobs are converted to
1070 // Impeller text frames in paragraph_skia.cc
1072}
1073
1075 const std::shared_ptr<TextFrame>& text_frame,
1076 SkScalar x,
1077 SkScalar y) {
1078 GetCanvas().DrawTextFrame(text_frame, //
1079 impeller::Point{x, y}, //
1080 paint_ //
1081 );
1082}
1083
1084// |flutter::DlOpReceiver|
1086 const flutter::DlColor color,
1087 const SkScalar elevation,
1088 bool transparent_occluder,
1089 SkScalar dpr) {
1091}
1092
1093// |flutter::DlOpReceiver|
1095 const flutter::DlColor color,
1096 const SkScalar elevation,
1097 bool transparent_occluder,
1098 SkScalar dpr) {
1100 spot_color.alpha *= 0.25;
1101
1102 // Compute the spot color -- ported from SkShadowUtils::ComputeTonalColors.
1103 {
1104 Scalar max =
1105 std::max(std::max(spot_color.red, spot_color.green), spot_color.blue);
1106 Scalar min =
1107 std::min(std::min(spot_color.red, spot_color.green), spot_color.blue);
1108 Scalar luminance = (min + max) * 0.5;
1109
1110 Scalar alpha_adjust =
1111 (2.6f + (-2.66667f + 1.06667f * spot_color.alpha) * spot_color.alpha) *
1112 spot_color.alpha;
1113 Scalar color_alpha =
1114 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
1115 luminance;
1116 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
1117
1118 Scalar greyscale_alpha =
1119 std::clamp(spot_color.alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
1120
1121 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
1122 Scalar tonal_alpha = color_scale + greyscale_alpha;
1123 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
1124 spot_color = Color(unpremul_scale * spot_color.red,
1125 unpremul_scale * spot_color.green,
1126 unpremul_scale * spot_color.blue, tonal_alpha);
1127 }
1128
1129 Vector3 light_position(0, -1, 1);
1130 Scalar occluder_z = dpr * elevation;
1131
1132 constexpr Scalar kLightRadius = 800 / 600; // Light radius / light height
1133
1134 Paint paint;
1135 paint.style = Paint::Style::kFill;
1136 paint.color = spot_color;
1137 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1139 .sigma = Radius{kLightRadius * occluder_z /
1141 };
1142
1143 GetCanvas().Save(1u);
1145 Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y)));
1146
1147 SimplifyOrDrawPath(GetCanvas(), cache, paint);
1148
1149 GetCanvas().Restore();
1150}
1151
1153 TRACE_EVENT0("impeller", "DisplayListDispatcher::EndRecordingAsPicture");
1155}
1156
1157/// Subclasses
1158
1159DlDispatcher::DlDispatcher() = default;
1160
1161DlDispatcher::DlDispatcher(IRect cull_rect) : canvas_(cull_rect) {}
1162
1163DlDispatcher::DlDispatcher(Rect cull_rect) : canvas_(cull_rect) {}
1164
1166 return canvas_;
1167}
1168
1170 RenderTarget& render_target,
1171 IRect cull_rect)
1172 : canvas_(renderer, render_target, cull_rect) {}
1173
1175 return canvas_;
1176}
1177
1178//// Text Frame Dispatcher
1179
1181 const Matrix& initial_matrix)
1182 : renderer_(renderer), matrix_(initial_matrix) {}
1183
1185 stack_.emplace_back(matrix_);
1186}
1187
1190 const flutter::DlImageFilter* backdrop) {
1191 save();
1192}
1193
1195 matrix_ = stack_.back();
1196 stack_.pop_back();
1197}
1198
1200 matrix_ = matrix_.Translate({tx, ty});
1201}
1202
1204 matrix_ = matrix_.Scale({sx, sy, 1.0f});
1205}
1206
1208 matrix_ = matrix_ * Matrix::MakeRotationZ(Degrees(degrees));
1209}
1210
1212 matrix_ = matrix_ * Matrix::MakeSkew(sx, sy);
1213}
1214
1215// clang-format off
1216 // 2x3 2D affine subset of a 4x4 transform in row major order
1218 SkScalar myx, SkScalar myy, SkScalar myt) {
1219 matrix_ = matrix_ * Matrix::MakeColumn(
1220 mxx, myx, 0.0f, 0.0f,
1221 mxy, myy, 0.0f, 0.0f,
1222 0.0f, 0.0f, 1.0f, 0.0f,
1223 mxt, myt, 0.0f, 1.0f
1224 );
1225 }
1226
1227 // full 4x4 transform in row major order
1229 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
1230 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
1231 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
1232 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
1233 matrix_ = matrix_ * Matrix::MakeColumn(
1234 mxx, myx, mzx, mwx,
1235 mxy, myy, mzy, mwy,
1236 mxz, myz, mzz, mwz,
1237 mxt, myt, mzt, mwt
1238 );
1239 }
1240// clang-format on
1241
1243 matrix_ = Matrix();
1244}
1245
1247 const std::shared_ptr<impeller::TextFrame>& text_frame,
1248 SkScalar x,
1249 SkScalar y) {
1250 renderer_.GetLazyGlyphAtlas()->AddTextFrame(*text_frame,
1251 matrix_.GetMaxBasisLengthXY());
1252}
1253
1255 const sk_sp<flutter::DisplayList> display_list,
1256 SkScalar opacity) {
1257 [[maybe_unused]] size_t stack_depth = stack_.size();
1258 save();
1259 display_list->Dispatch(*this);
1260 restore();
1261 FML_DCHECK(stack_depth == stack_.size());
1262}
1263
1264} // 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
@ 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
virtual void save()=0
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
void DrawLine(const Point &p0, const Point &p1, const Paint &paint)
Definition canvas.cc:483
const Matrix & GetCurrentTransform() const
Definition canvas.cc:296
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:764
void DrawVertices(const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
Definition canvas.cc:916
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)
Definition canvas.cc:839
void DrawOval(const Rect &rect, const Paint &paint)
Definition canvas.cc:512
void RestoreToCount(size_t count)
Definition canvas.cc:333
void ClipPath(const Path &path, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition canvas.cc:587
void ClipRRect(const Rect &rect, const Size &corner_radii, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition canvas.cc:638
virtual bool Restore()
Definition canvas.cc:257
size_t GetSaveCount() const
Definition canvas.cc:329
void Transform(const Matrix &transform)
Definition canvas.cc:292
void PreConcat(const Matrix &transform)
Definition canvas.cc:284
void Rotate(Radians radians)
Definition canvas.cc:325
void ResetTransform()
Definition canvas.cc:288
virtual void DrawTextFrame(const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint)
Definition canvas.cc:875
void DrawPaint(const Paint &paint)
Definition canvas.cc:350
void ClipRect(const Rect &rect, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition canvas.cc:597
void Skew(Scalar sx, Scalar sy)
Definition canvas.cc:321
void Scale(const Vector2 &scale)
Definition canvas.cc:313
const std::optional< Rect > GetCurrentLocalCullingBounds() const
Definition canvas.cc:300
Picture EndRecordingAsPicture()
Definition canvas.cc:802
void DrawPath(const Path &path, const Paint &paint)
Definition canvas.cc:341
virtual void Save(uint32_t total_content_depth=kMaxDepth)
Definition canvas.cc:184
void DrawPoints(std::vector< Point > points, Scalar radius, const Paint &paint, PointStyle point_style)
Definition canvas.cc:731
void ClipOval(const Rect &bounds, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition canvas.cc:618
void DrawRect(const Rect &rect, const Paint &paint)
Definition canvas.cc:493
void DrawRRect(const Rect &rect, const Size &corner_radii, const Paint &paint)
Definition canvas.cc:538
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:1003
void Translate(const Vector3 &offset)
Definition canvas.cc:309
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition canvas.cc:564
static std::shared_ptr< ColorFilter > MakeMatrix(ColorMatrix color_matrix)
static std::shared_ptr< ColorFilter > MakeBlend(BlendMode blend_mode, Color color)
static std::shared_ptr< ColorFilter > MakeLinearToSrgb()
static std::shared_ptr< ColorFilter > MakeSrgbToLinear()
static ColorSource MakeLinearGradient(Point start_point, Point end_point, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
static ColorSource MakeColor()
static ColorSource MakeRadialGradient(Point center, Scalar radius, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
static ColorSource MakeImage(std::shared_ptr< Texture > texture, Entity::TileMode x_tile_mode, Entity::TileMode y_tile_mode, SamplerDescriptor sampler_descriptor, Matrix effect_transform)
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)
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)
static ColorSource MakeRuntimeEffect(std::shared_ptr< RuntimeStage > runtime_stage, std::shared_ptr< std::vector< uint8_t > > uniform_data, std::vector< RuntimeEffectContents::TextureInput > texture_inputs)
const std::shared_ptr< LazyGlyphAtlas > & GetLazyGlyphAtlas() const
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
void setImageFilter(const flutter::DlImageFilter *filter) override
void drawVertices(const flutter::DlVertices *vertices, flutter::DlBlendMode dl_mode) override
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, SkScalar x, SkScalar y) override
void setStrokeCap(flutter::DlStrokeCap cap) override
void drawPath(const SkPath &path) override
void saveLayer(const SkRect &bounds, const flutter::SaveLayerOptions &options, uint32_t total_content_depth, const flutter::DlImageFilter *backdrop) override
void setAntiAlias(bool aa) override
void drawPoints(PointMode mode, uint32_t count, const SkPoint points[]) override
void drawLine(const SkPoint &p0, const SkPoint &p1) override
void clipRect(const SkRect &rect, ClipOp clip_op, bool is_aa) override
void drawOval(const SkRect &bounds) override
void drawCircle(const SkPoint &center, SkScalar radius) override
void setStrokeJoin(flutter::DlStrokeJoin join) override
void setStrokeWidth(SkScalar width) override
void setColorFilter(const flutter::DlColorFilter *filter) override
void translate(SkScalar tx, SkScalar ty) override
void setDrawStyle(flutter::DlDrawStyle style) override
void clipRRect(const SkRRect &rrect, ClipOp clip_op, bool is_aa) override
void drawShadow(const SkPath &path, const flutter::DlColor color, const SkScalar elevation, bool transparent_occluder, SkScalar dpr) override
void setStrokeMiter(SkScalar limit) override
void setPathEffect(const flutter::DlPathEffect *effect) override
void scale(SkScalar sx, SkScalar sy) override
void skew(SkScalar sx, SkScalar sy) override
void clipPath(const SkPath &path, ClipOp clip_op, bool is_aa) override
void setInvertColors(bool invert) override
void drawImage(const sk_sp< flutter::DlImage > image, const SkPoint point, flutter::DlImageSampling sampling, bool render_with_attributes) override
void drawImageNine(const sk_sp< flutter::DlImage > image, const SkIRect &center, const SkRect &dst, flutter::DlFilterMode filter, bool render_with_attributes) override
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
void drawDRRect(const SkRRect &outer, const SkRRect &inner) override
void drawRect(const SkRect &rect) override
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, SkScalar opacity) override
void setColor(flutter::DlColor color) override
void drawImageRect(const sk_sp< flutter::DlImage > image, const SkRect &src, const SkRect &dst, flutter::DlImageSampling sampling, bool render_with_attributes, SrcRectConstraint constraint) override
void setMaskFilter(const flutter::DlMaskFilter *filter) override
virtual Canvas & GetCanvas()=0
void setColorSource(const flutter::DlColorSource *source) override
void setBlendMode(flutter::DlBlendMode mode) override
void drawArc(const SkRect &oval_bounds, SkScalar start_degrees, SkScalar sweep_degrees, bool use_center) override
void drawColor(flutter::DlColor color, flutter::DlBlendMode mode) override
void drawTextBlob(const sk_sp< SkTextBlob > blob, SkScalar x, SkScalar y) override
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
void rotate(SkScalar degrees) override
void drawRRect(const SkRRect &rrect) override
DlDispatcher()
Subclasses.
Canvas & GetCanvas() override
ExperimentalDlDispatcher(ContentContext &renderer, RenderTarget &render_target, IRect cull_rect)
@ kNormal
Blurred inside and outside.
@ kOuter
Nothing inside, blurred outside.
@ kInner
Blurred inside, nothing outside.
@ kSolid
Solid inside, blurred outside.
static std::shared_ptr< ImageFilter > MakeMatrix(const Matrix &matrix, SamplerDescriptor sampler_descriptor)
static std::shared_ptr< ImageFilter > MakeLocalMatrix(const Matrix &matrix, const ImageFilter &internal_filter)
static std::shared_ptr< ImageFilter > MakeErode(Radius radius_x, Radius radius_y)
static std::shared_ptr< ImageFilter > MakeBlur(Sigma sigma_x, Sigma sigma_y, FilterContents::BlurStyle blur_style, Entity::TileMode tile_mode)
static std::shared_ptr< ImageFilter > MakeDilate(Radius radius_x, Radius radius_y)
static std::shared_ptr< ImageFilter > MakeFromColorFilter(const ColorFilter &color_filter)
static std::shared_ptr< ImageFilter > MakeCompose(const ImageFilter &inner, const ImageFilter &outer)
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition path.h:51
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, SkScalar opacity) override
void rotate(SkScalar degrees) override
TextFrameDispatcher(const ContentContext &renderer, const Matrix &initial_matrix)
void skew(SkScalar sx, SkScalar sy) override
void saveLayer(const SkRect &bounds, const flutter::SaveLayerOptions options, const flutter::DlImageFilter *backdrop) override
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
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
void scale(SkScalar sx, SkScalar sy) override
void translate(SkScalar tx, SkScalar ty) override
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, SkScalar x, SkScalar y) override
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
SkRect oval
Definition SkRecords.h:249
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
@ 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
std::vector< Point > ToPoints(const SkPoint points[], int count)
Path ToPath(const SkPath &path, Point shift)
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...
Point ToPoint(const SkPoint &point)
Size ToSize(const SkPoint &point)
std::vector< Rect > ToRects(const SkRect tex[], int count)
std::vector< Matrix > ToRSXForms(const SkRSXform xform[], int count)
Rect ToRect(const SkRect &rect)
Color ToColor(const flutter::DlColor &color)
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)
@ kRound
Points are drawn as squares.
@ kSquare
Points are drawn as circles.
static std::optional< ColorSource::Type > ToColorSourceType(flutter::DlColorSourceType type)
static Entity::ClipOperation ToClipOperation(flutter::DlCanvas::ClipOp clip_op)
static Matrix ToMatrix(const SkMatrix &m)
BlendMode
Definition color.h:59
@ kMayClipContents
The caller claims the bounds are a subset of an estimate of the reasonably tight bounds but likely cl...
@ kContainsContents
The caller claims the bounds are a reasonably tight estimate of the coverage of the contents and shou...
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)
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
Scalar blue
Definition color.h:138
Scalar alpha
Definition color.h:143
Scalar red
Definition color.h:128
Scalar green
Definition color.h:133
A 4x4 matrix using column-major storage.
Definition matrix.h:37
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
constexpr Scalar GetMaxBasisLengthXY() const
Definition matrix.h:300
constexpr Matrix Translate(const Vector3 &t) const
Definition matrix.h:240
constexpr Vector3 GetScale() const
Definition matrix.h:311
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
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
Definition matrix.h:117
constexpr Matrix Scale(const Vector3 &s) const
Definition matrix.h:252
static Matrix MakeRotationZ(Radians r)
Definition matrix.h:213
constexpr bool HasPerspective() const
Definition matrix.h:330
FilterContents::BlurStyle style
Definition paint.h:40
ColorSource color_source
Definition paint.h:56
Cap stroke_cap
Definition paint.h:60
Join stroke_join
Definition paint.h:61
Scalar stroke_miter
Definition paint.h:62
Style style
Definition paint.h:63
bool invert_colors
Definition paint.h:65
std::shared_ptr< ImageFilter > image_filter
Definition paint.h:67
std::optional< MaskBlurDescriptor > mask_blur_descriptor
Definition paint.h:69
Color color
Definition paint.h:55
BlendMode blend_mode
Definition paint.h:64
std::shared_ptr< ColorFilter > color_filter
Definition paint.h:68
Scalar stroke_width
Definition paint.h:59
For convolution filters, the "radius" is the size of the convolution kernel to use on the local space...
Definition sigma.h:48
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition sigma.h:32
constexpr auto GetBottom() const
Definition rect.h:324
constexpr auto GetTop() const
Definition rect.h:320
constexpr auto GetLeft() const
Definition rect.h:318
constexpr auto GetRight() const
Definition rect.h:322
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129
#define ERROR(message)
#define TRACE_EVENT0(category_group, name)
static sk_sp< SkShader > linear(sk_sp< SkShader > shader)