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{};
646 canvas_.
Scale({sx, sy, 1.0});
656 canvas_.
Skew(sx, sy);
713 flutter::DlCanvas::ClipOp clip_op) {
715 case flutter::DlCanvas::ClipOp::kDifference:
717 case flutter::DlCanvas::ClipOp::kIntersect:
730 if (rrect.isRect()) {
732 }
else if (rrect.isOval()) {
734 }
else if (rrect.isSimple()) {
748 if (path.isRect(&rect)) {
750 }
else if (path.isOval(&rect)) {
754 if (path.isRRect(&rrect) && rrect.isSimple()) {
766 flutter::DlBlendMode dl_mode) {
801 if (rrect.isSimple()) {
819 SimplifyOrDrawPath(canvas_, path, paint_);
822 void DlDispatcher::SimplifyOrDrawPath(
CanvasType& canvas,
824 const Paint& paint) {
829 if (path.isRect(&rect, &closed) && closed) {
835 if (path.isRRect(&rrect) && rrect.isSimple()) {
842 if (path.isOval(&oval)) {
852 SkScalar start_degrees,
853 SkScalar sweep_degrees,
857 Degrees(sweep_degrees), use_center);
864 const SkPoint points[]) {
865 Paint paint = paint_;
868 case flutter::DlCanvas::PointMode::kPoints: {
879 case flutter::DlCanvas::PointMode::kLines:
880 for (uint32_t i = 1; i < count; i += 2) {
886 case flutter::DlCanvas::PointMode::kPolygon:
889 for (uint32_t i = 1; i < count; i++) {
901 flutter::DlBlendMode dl_mode) {
908 flutter::DlImageSampling sampling,
909 bool render_with_attributes) {
914 auto texture = image->impeller_texture();
919 const auto size = texture->GetSize();
920 const auto src = SkRect::MakeWH(size.width, size.height);
922 SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);
928 render_with_attributes,
929 SrcRectConstraint::kStrict
935 const sk_sp<flutter::DlImage> image,
938 flutter::DlImageSampling sampling,
939 bool render_with_attributes,
940 SrcRectConstraint constraint = SrcRectConstraint::kFast) {
942 std::make_shared<Image>(image->impeller_texture()),
945 render_with_attributes ? paint_ :
Paint(),
952 const SkIRect& center,
954 flutter::DlFilterMode filter,
955 bool render_with_attributes) {
958 std::make_shared<Image>(image->impeller_texture()),
959 Rect::MakeLTRB(center.fLeft, center.fTop, center.fRight, center.fBottom),
966 const SkRSXform xform[],
968 const flutter::DlColor colors[],
970 flutter::DlBlendMode mode,
971 flutter::DlImageSampling sampling,
972 const SkRect* cull_rect,
973 bool render_with_attributes) {
974 canvas_.
DrawAtlas(std::make_shared<Image>(atlas->impeller_texture()),
984 const sk_sp<flutter::DisplayList> display_list,
987 Paint saved_paint = paint_;
988 Matrix saved_initial_matrix = initial_matrix_;
1007 if (opacity < SK_Scalar1) {
1015 if (display_list->has_rtree() && !initial_matrix_.
HasPerspective()) {
1022 if (cull_bounds.has_value()) {
1023 Rect cull_rect = cull_bounds.value();
1024 display_list->Dispatch(
1025 *
this, SkRect::MakeLTRB(cull_rect.
GetLeft(), cull_rect.
GetTop(),
1028 display_list->Dispatch(*
this);
1031 display_list->Dispatch(*
this);
1037 initial_matrix_ = saved_initial_matrix;
1038 paint_ = saved_paint;
1061 const flutter::DlColor color,
1062 const SkScalar elevation,
1063 bool transparent_occluder,
1066 spot_color.
alpha *= 0.25;
1071 std::max(std::max(spot_color.
red, spot_color.
green), spot_color.
blue);
1073 std::min(std::min(spot_color.
red, spot_color.
green), spot_color.
blue);
1074 Scalar luminance = (min + max) * 0.5;
1077 (2.6f + (-2.66667f + 1.06667f * spot_color.
alpha) * spot_color.
alpha) *
1080 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
1082 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
1085 std::clamp(spot_color.
alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
1087 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
1088 Scalar tonal_alpha = color_scale + greyscale_alpha;
1089 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
1090 spot_color =
Color(unpremul_scale * spot_color.
red,
1091 unpremul_scale * spot_color.
green,
1092 unpremul_scale * spot_color.
blue, tonal_alpha);
1095 Vector3 light_position(0, -1, 1);
1096 Scalar occluder_z = dpr * elevation;
1098 constexpr
Scalar kLightRadius = 800 / 600;
1102 paint.
color = spot_color;
1105 .sigma =
Radius{kLightRadius * occluder_z /
1113 SimplifyOrDrawPath(canvas_, path, paint);
1119 TRACE_EVENT0(
"impeller",
"DisplayListDispatcher::EndRecordingAsPicture");