14 #include "flutter/fml/logging.h"
15 #include "flutter/fml/trace_event.h"
30 #if IMPELLER_ENABLE_3D
32 #endif // IMPELLER_ENABLE_3D
36 #define UNIMPLEMENTED \
37 FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
49 case flutter::DlBlendMode::kClear:
51 case flutter::DlBlendMode::kSrc:
53 case flutter::DlBlendMode::kDst:
55 case flutter::DlBlendMode::kSrcOver:
57 case flutter::DlBlendMode::kDstOver:
59 case flutter::DlBlendMode::kSrcIn:
61 case flutter::DlBlendMode::kDstIn:
63 case flutter::DlBlendMode::kSrcOut:
65 case flutter::DlBlendMode::kDstOut:
67 case flutter::DlBlendMode::kSrcATop:
69 case flutter::DlBlendMode::kDstATop:
71 case flutter::DlBlendMode::kXor:
73 case flutter::DlBlendMode::kPlus:
75 case flutter::DlBlendMode::kModulate:
77 case flutter::DlBlendMode::kScreen:
79 case flutter::DlBlendMode::kOverlay:
81 case flutter::DlBlendMode::kDarken:
83 case flutter::DlBlendMode::kLighten:
85 case flutter::DlBlendMode::kColorDodge:
87 case flutter::DlBlendMode::kColorBurn:
89 case flutter::DlBlendMode::kHardLight:
91 case flutter::DlBlendMode::kSoftLight:
93 case flutter::DlBlendMode::kDifference:
95 case flutter::DlBlendMode::kExclusion:
97 case flutter::DlBlendMode::kMultiply:
99 case flutter::DlBlendMode::kHue:
101 case flutter::DlBlendMode::kSaturation:
105 case flutter::DlBlendMode::kLuminosity:
113 case flutter::DlTileMode::kClamp:
115 case flutter::DlTileMode::kRepeat:
117 case flutter::DlTileMode::kMirror:
119 case flutter::DlTileMode::kDecal:
125 const flutter::DlImageSampling options) {
128 case flutter::DlImageSampling::kNearestNeighbor:
130 desc.
label =
"Nearest Sampler";
132 case flutter::DlImageSampling::kLinear:
135 case flutter::DlImageSampling::kCubic:
137 desc.
label =
"Linear Sampler";
139 case flutter::DlImageSampling::kMipmapLinear:
142 desc.
label =
"Mipmap Linear Sampler";
149 const flutter::DlFilterMode options) {
152 case flutter::DlFilterMode::kNearest:
154 desc.
label =
"Nearest Sampler";
156 case flutter::DlFilterMode::kLinear:
158 desc.
label =
"Linear Sampler";
184 case flutter::DlDrawStyle::kFill:
186 case flutter::DlDrawStyle::kStroke:
188 case flutter::DlDrawStyle::kStrokeAndFill:
223 case flutter::DlStrokeCap::kButt:
226 case flutter::DlStrokeCap::kRound:
229 case flutter::DlStrokeCap::kSquare:
238 case flutter::DlStrokeJoin::kMiter:
241 case flutter::DlStrokeJoin::kRound:
244 case flutter::DlStrokeJoin::kBevel:
250 static std::vector<Color>
ToColors(
const flutter::DlColor colors[],
int count) {
251 auto result = std::vector<Color>();
252 if (colors ==
nullptr) {
255 for (
int i = 0; i < count; i++) {
262 flutter::DlColorSourceType type) {
266 case flutter::DlColorSourceType::kImage:
268 case flutter::DlColorSourceType::kLinearGradient:
270 case flutter::DlColorSourceType::kRadialGradient:
272 case flutter::DlColorSourceType::kConicalGradient:
274 case flutter::DlColorSourceType::kSweepGradient:
276 case flutter::DlColorSourceType::kRuntimeEffect:
278 #ifdef IMPELLER_ENABLE_3D
279 case flutter::DlColorSourceType::kScene:
281 #endif // IMPELLER_ENABLE_3D
294 if (!type.has_value()) {
295 FML_LOG(ERROR) <<
"Requested ColorSourceType::kUnknown";
300 switch (type.value()) {
302 const flutter::DlColorColorSource* color = source->asColor();
310 const flutter::DlLinearGradientColorSource* linear =
311 source->asLinearGradient();
315 std::vector<Color> colors;
316 std::vector<float> stops;
319 auto tile_mode =
ToTileMode(linear->tile_mode());
320 auto matrix =
ToMatrix(linear->matrix());
323 start_point, end_point, std::move(colors), std::move(stops),
328 const flutter::DlConicalGradientColorSource* conical_gradient =
329 source->asConicalGradient();
330 FML_DCHECK(conical_gradient);
332 SkScalar radius = conical_gradient->end_radius();
335 SkScalar focus_radius = conical_gradient->start_radius();
336 std::vector<Color> colors;
337 std::vector<float> stops;
340 auto tile_mode =
ToTileMode(conical_gradient->tile_mode());
341 auto matrix =
ToMatrix(conical_gradient->matrix());
344 center, radius, std::move(colors), std::move(stops), focus_center,
345 focus_radius, tile_mode, matrix);
349 const flutter::DlRadialGradientColorSource* radialGradient =
350 source->asRadialGradient();
351 FML_DCHECK(radialGradient);
353 auto radius = radialGradient->radius();
354 std::vector<Color> colors;
355 std::vector<float> stops;
358 auto tile_mode =
ToTileMode(radialGradient->tile_mode());
359 auto matrix =
ToMatrix(radialGradient->matrix());
362 std::move(stops), tile_mode, matrix);
366 const flutter::DlSweepGradientColorSource* sweepGradient =
367 source->asSweepGradient();
368 FML_DCHECK(sweepGradient);
371 auto start_angle =
Degrees(sweepGradient->start());
372 auto end_angle =
Degrees(sweepGradient->end());
373 std::vector<Color> colors;
374 std::vector<float> stops;
377 auto tile_mode =
ToTileMode(sweepGradient->tile_mode());
378 auto matrix =
ToMatrix(sweepGradient->matrix());
380 center, start_angle, end_angle, std::move(colors), std::move(stops),
385 const flutter::DlImageColorSource* image_color_source = source->asImage();
386 FML_DCHECK(image_color_source &&
387 image_color_source->image()->impeller_texture());
388 auto texture = image_color_source->image()->impeller_texture();
389 auto x_tile_mode =
ToTileMode(image_color_source->horizontal_tile_mode());
390 auto y_tile_mode =
ToTileMode(image_color_source->vertical_tile_mode());
392 auto matrix =
ToMatrix(image_color_source->matrix());
394 y_tile_mode, desc, matrix);
398 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
399 source->asRuntimeEffect();
401 runtime_effect_color_source->runtime_effect()->runtime_stage();
402 auto uniform_data = runtime_effect_color_source->uniform_data();
403 auto samplers = runtime_effect_color_source->samplers();
405 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
407 for (
auto& sampler : samplers) {
408 if (sampler ==
nullptr) {
411 auto* image = sampler->asImage();
412 if (!sampler->asImage()) {
416 FML_DCHECK(image->image()->impeller_texture());
417 texture_inputs.push_back({
419 .texture = image->image()->impeller_texture(),
424 runtime_stage, uniform_data, texture_inputs);
428 #ifdef IMPELLER_ENABLE_3D
429 const flutter::DlSceneColorSource* scene_color_source = source->asScene();
430 std::shared_ptr<scene::Node> scene_node =
431 scene_color_source->scene_node();
432 Matrix camera_transform = scene_color_source->camera_matrix();
435 ColorSource::MakeScene(scene_node, camera_transform);
436 #else // IMPELLER_ENABLE_3D
437 FML_LOG(ERROR) <<
"ColorSourceType::kScene can only be used if Impeller "
439 #endif // IMPELLER_ENABLE_3D
446 const flutter::DlColorFilter* filter) {
447 if (filter ==
nullptr) {
450 switch (filter->type()) {
451 case flutter::DlColorFilterType::kBlend: {
452 auto dl_blend = filter->asBlend();
457 case flutter::DlColorFilterType::kMatrix: {
458 const flutter::DlMatrixColorFilter* dl_matrix = filter->asMatrix();
460 dl_matrix->get_matrix(color_matrix.
array);
463 case flutter::DlColorFilterType::kSrgbToLinearGamma:
465 case flutter::DlColorFilterType::kLinearToSrgbGamma:
493 switch (blur_style) {
494 case flutter::DlBlurStyle::kNormal:
496 case flutter::DlBlurStyle::kSolid:
498 case flutter::DlBlurStyle::kOuter:
500 case flutter::DlBlurStyle::kInner:
508 if (filter ==
nullptr) {
512 switch (filter->type()) {
513 case flutter::DlMaskFilterType::kBlur: {
514 auto blur = filter->asBlur();
518 .sigma =
Sigma(blur->sigma()),
526 const flutter::DlImageFilter* filter) {
527 if (filter ==
nullptr) {
531 switch (filter->type()) {
532 case flutter::DlImageFilterType::kBlur: {
533 auto blur = filter->asBlur();
534 auto sigma_x =
Sigma(blur->sigma_x());
535 auto sigma_y =
Sigma(blur->sigma_y());
536 auto tile_mode =
ToTileMode(blur->tile_mode());
540 case flutter::DlImageFilterType::kDilate: {
541 auto dilate = filter->asDilate();
543 if (dilate->radius_x() < 0 || dilate->radius_y() < 0) {
546 auto radius_x =
Radius(dilate->radius_x());
547 auto radius_y =
Radius(dilate->radius_y());
550 case flutter::DlImageFilterType::kErode: {
551 auto erode = filter->asErode();
553 if (erode->radius_x() < 0 || erode->radius_y() < 0) {
556 auto radius_x =
Radius(erode->radius_x());
557 auto radius_y =
Radius(erode->radius_y());
560 case flutter::DlImageFilterType::kMatrix: {
561 auto matrix_filter = filter->asMatrix();
562 FML_DCHECK(matrix_filter);
563 auto matrix =
ToMatrix(matrix_filter->matrix());
567 case flutter::DlImageFilterType::kCompose: {
568 auto compose = filter->asCompose();
570 auto outer_dl_filter = compose->outer();
571 auto inner_dl_filter = compose->inner();
580 FML_DCHECK(outer_filter && inner_filter);
584 case flutter::DlImageFilterType::kColorFilter: {
585 auto color_filter_image_filter = filter->asColorFilter();
586 FML_DCHECK(color_filter_image_filter);
588 ToColorFilter(color_filter_image_filter->color_filter().get());
598 case flutter::DlImageFilterType::kLocalMatrix: {
599 auto local_matrix_filter = filter->asLocalMatrix();
600 FML_DCHECK(local_matrix_filter);
601 auto internal_filter = local_matrix_filter->image_filter();
602 FML_DCHECK(internal_filter);
609 auto matrix =
ToMatrix(local_matrix_filter->matrix());
627 const flutter::SaveLayerOptions options,
628 const flutter::DlImageFilter* backdrop) {
629 auto paint = options.renders_with_attributes() ? paint_ :
Paint{};
630 auto promise = options.content_is_clipped()
649 canvas_.
Scale({sx, sy, 1.0});
659 canvas_.
Skew(sx, sy);
716 flutter::DlCanvas::ClipOp clip_op) {
718 case flutter::DlCanvas::ClipOp::kDifference:
720 case flutter::DlCanvas::ClipOp::kIntersect:
733 if (rrect.isRect()) {
735 }
else if (rrect.isOval()) {
737 }
else if (rrect.isSimple()) {
751 const Path& DlDispatcher::GetOrCachePath(
const CacheablePath& cache) {
752 if (cache.cached_impeller_path.IsEmpty() && !cache.sk_path.isEmpty()) {
755 return cache.cached_impeller_path;
765 if (cache.sk_path.isRect(&rect)) {
767 }
else if (cache.sk_path.isOval(&rect)) {
771 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
776 canvas_.
ClipPath(GetOrCachePath(cache), clip_op);
783 flutter::DlBlendMode dl_mode) {
818 if (rrect.isSimple()) {
841 SimplifyOrDrawPath(canvas_, cache, paint_);
844 void DlDispatcher::SimplifyOrDrawPath(
CanvasType& canvas,
845 const CacheablePath& cache,
846 const Paint& paint) {
851 if (cache.sk_path.isRect(&rect, &closed) && closed) {
857 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
864 if (cache.sk_path.isOval(&oval)) {
869 canvas.
DrawPath(GetOrCachePath(cache), paint);
874 SkScalar start_degrees,
875 SkScalar sweep_degrees,
879 Degrees(sweep_degrees), use_center);
886 const SkPoint points[]) {
887 Paint paint = paint_;
890 case flutter::DlCanvas::PointMode::kPoints: {
901 case flutter::DlCanvas::PointMode::kLines:
902 for (uint32_t i = 1; i < count; i += 2) {
908 case flutter::DlCanvas::PointMode::kPolygon:
911 for (uint32_t i = 1; i < count; i++) {
923 flutter::DlBlendMode dl_mode) {
930 flutter::DlImageSampling sampling,
931 bool render_with_attributes) {
936 auto texture = image->impeller_texture();
941 const auto size = texture->GetSize();
942 const auto src = SkRect::MakeWH(size.width, size.height);
944 SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);
950 render_with_attributes,
951 SrcRectConstraint::kStrict
957 const sk_sp<flutter::DlImage> image,
960 flutter::DlImageSampling sampling,
961 bool render_with_attributes,
962 SrcRectConstraint constraint = SrcRectConstraint::kFast) {
964 std::make_shared<Image>(image->impeller_texture()),
967 render_with_attributes ? paint_ :
Paint(),
974 const SkIRect& center,
976 flutter::DlFilterMode filter,
977 bool render_with_attributes) {
980 std::make_shared<Image>(image->impeller_texture()),
981 Rect::MakeLTRB(center.fLeft, center.fTop, center.fRight, center.fBottom),
988 const SkRSXform xform[],
990 const flutter::DlColor colors[],
992 flutter::DlBlendMode mode,
993 flutter::DlImageSampling sampling,
994 const SkRect* cull_rect,
995 bool render_with_attributes) {
996 canvas_.
DrawAtlas(std::make_shared<Image>(atlas->impeller_texture()),
1006 const sk_sp<flutter::DisplayList> display_list,
1009 Paint saved_paint = paint_;
1010 Matrix saved_initial_matrix = initial_matrix_;
1029 if (opacity < SK_Scalar1) {
1037 if (display_list->has_rtree() && !initial_matrix_.
HasPerspective()) {
1044 if (cull_bounds.has_value()) {
1045 Rect cull_rect = cull_bounds.value();
1046 display_list->Dispatch(
1047 *
this, SkRect::MakeLTRB(cull_rect.
GetLeft(), cull_rect.
GetTop(),
1050 display_list->Dispatch(*
this);
1053 display_list->Dispatch(*
this);
1059 initial_matrix_ = saved_initial_matrix;
1060 paint_ = saved_paint;
1083 const flutter::DlColor color,
1084 const SkScalar elevation,
1085 bool transparent_occluder,
1092 const flutter::DlColor color,
1093 const SkScalar elevation,
1094 bool transparent_occluder,
1097 spot_color.
alpha *= 0.25;
1102 std::max(std::max(spot_color.
red, spot_color.
green), spot_color.
blue);
1104 std::min(std::min(spot_color.
red, spot_color.
green), spot_color.
blue);
1105 Scalar luminance = (min + max) * 0.5;
1108 (2.6f + (-2.66667f + 1.06667f * spot_color.
alpha) * spot_color.
alpha) *
1111 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
1113 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
1116 std::clamp(spot_color.
alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
1118 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
1119 Scalar tonal_alpha = color_scale + greyscale_alpha;
1120 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
1121 spot_color =
Color(unpremul_scale * spot_color.
red,
1122 unpremul_scale * spot_color.
green,
1123 unpremul_scale * spot_color.
blue, tonal_alpha);
1126 Vector3 light_position(0, -1, 1);
1127 Scalar occluder_z = dpr * elevation;
1129 constexpr
Scalar kLightRadius = 800 / 600;
1133 paint.
color = spot_color;
1136 .sigma =
Radius{kLightRadius * occluder_z /
1144 SimplifyOrDrawPath(canvas_, cache, paint);
1150 TRACE_EVENT0(
"impeller",
"DisplayListDispatcher::EndRecordingAsPicture");