14 #include "flutter/fml/logging.h"
15 #include "flutter/fml/trace_event.h"
33 #if IMPELLER_ENABLE_3D
35 #endif // IMPELLER_ENABLE_3D
39 #define UNIMPLEMENTED \
40 FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
44 case flutter::DlBlendMode::kClear:
46 case flutter::DlBlendMode::kSrc:
48 case flutter::DlBlendMode::kDst:
50 case flutter::DlBlendMode::kSrcOver:
52 case flutter::DlBlendMode::kDstOver:
54 case flutter::DlBlendMode::kSrcIn:
56 case flutter::DlBlendMode::kDstIn:
58 case flutter::DlBlendMode::kSrcOut:
60 case flutter::DlBlendMode::kDstOut:
62 case flutter::DlBlendMode::kSrcATop:
64 case flutter::DlBlendMode::kDstATop:
66 case flutter::DlBlendMode::kXor:
68 case flutter::DlBlendMode::kPlus:
70 case flutter::DlBlendMode::kModulate:
72 case flutter::DlBlendMode::kScreen:
74 case flutter::DlBlendMode::kOverlay:
76 case flutter::DlBlendMode::kDarken:
78 case flutter::DlBlendMode::kLighten:
80 case flutter::DlBlendMode::kColorDodge:
82 case flutter::DlBlendMode::kColorBurn:
84 case flutter::DlBlendMode::kHardLight:
86 case flutter::DlBlendMode::kSoftLight:
88 case flutter::DlBlendMode::kDifference:
90 case flutter::DlBlendMode::kExclusion:
92 case flutter::DlBlendMode::kMultiply:
94 case flutter::DlBlendMode::kHue:
96 case flutter::DlBlendMode::kSaturation:
98 case flutter::DlBlendMode::kColor:
100 case flutter::DlBlendMode::kLuminosity:
108 case flutter::DlTileMode::kClamp:
110 case flutter::DlTileMode::kRepeat:
112 case flutter::DlTileMode::kMirror:
114 case flutter::DlTileMode::kDecal:
120 const flutter::DlImageSampling options) {
123 case flutter::DlImageSampling::kNearestNeighbor:
126 desc.
label =
"Nearest Sampler";
128 case flutter::DlImageSampling::kLinear:
131 desc.
label =
"Linear Sampler";
133 case flutter::DlImageSampling::kCubic:
134 case flutter::DlImageSampling::kMipmapLinear:
137 desc.
label =
"Mipmap Linear Sampler";
144 const flutter::DlFilterMode options) {
147 case flutter::DlFilterMode::kNearest:
149 desc.
label =
"Nearest Sampler";
151 case flutter::DlFilterMode::kLinear:
153 desc.
label =
"Linear Sampler";
179 case flutter::DlDrawStyle::kFill:
181 case flutter::DlDrawStyle::kStroke:
183 case flutter::DlDrawStyle::kStrokeAndFill:
218 case flutter::DlStrokeCap::kButt:
221 case flutter::DlStrokeCap::kRound:
224 case flutter::DlStrokeCap::kSquare:
233 case flutter::DlStrokeJoin::kMiter:
236 case flutter::DlStrokeJoin::kRound:
239 case flutter::DlStrokeJoin::kBevel:
245 static std::vector<Color>
ToColors(
const flutter::DlColor colors[],
int count) {
246 auto result = std::vector<Color>();
247 if (colors ==
nullptr) {
250 for (
int i = 0; i < count; i++) {
257 flutter::DlColorSourceType
type) {
259 case flutter::DlColorSourceType::kColor:
261 case flutter::DlColorSourceType::kImage:
263 case flutter::DlColorSourceType::kLinearGradient:
265 case flutter::DlColorSourceType::kRadialGradient:
267 case flutter::DlColorSourceType::kConicalGradient:
269 case flutter::DlColorSourceType::kSweepGradient:
271 case flutter::DlColorSourceType::kRuntimeEffect:
273 #ifdef IMPELLER_ENABLE_3D
274 case flutter::DlColorSourceType::kScene:
276 #endif // IMPELLER_ENABLE_3D
289 if (!
type.has_value()) {
290 FML_LOG(ERROR) <<
"Requested ColorSourceType::kUnknown";
295 switch (
type.value()) {
297 const flutter::DlColorColorSource*
color = source->asColor();
305 const flutter::DlLinearGradientColorSource* linear =
306 source->asLinearGradient();
310 std::vector<Color> colors;
311 std::vector<float> stops;
314 auto tile_mode =
ToTileMode(linear->tile_mode());
315 auto matrix =
ToMatrix(linear->matrix());
318 start_point, end_point, std::move(colors), std::move(stops),
323 const flutter::DlConicalGradientColorSource* conical_gradient =
324 source->asConicalGradient();
325 FML_DCHECK(conical_gradient);
327 SkScalar radius = conical_gradient->end_radius();
330 SkScalar focus_radius = conical_gradient->start_radius();
331 std::vector<Color> colors;
332 std::vector<float> stops;
335 auto tile_mode =
ToTileMode(conical_gradient->tile_mode());
336 auto matrix =
ToMatrix(conical_gradient->matrix());
339 center, radius, std::move(colors), std::move(stops), focus_center,
340 focus_radius, tile_mode, matrix);
344 const flutter::DlRadialGradientColorSource* radialGradient =
345 source->asRadialGradient();
346 FML_DCHECK(radialGradient);
348 auto radius = radialGradient->radius();
349 std::vector<Color> colors;
350 std::vector<float> stops;
353 auto tile_mode =
ToTileMode(radialGradient->tile_mode());
354 auto matrix =
ToMatrix(radialGradient->matrix());
357 std::move(stops), tile_mode, matrix);
361 const flutter::DlSweepGradientColorSource* sweepGradient =
362 source->asSweepGradient();
363 FML_DCHECK(sweepGradient);
366 auto start_angle =
Degrees(sweepGradient->start());
367 auto end_angle =
Degrees(sweepGradient->end());
368 std::vector<Color> colors;
369 std::vector<float> stops;
372 auto tile_mode =
ToTileMode(sweepGradient->tile_mode());
373 auto matrix =
ToMatrix(sweepGradient->matrix());
375 center, start_angle, end_angle, std::move(colors), std::move(stops),
380 const flutter::DlImageColorSource* image_color_source = source->asImage();
381 FML_DCHECK(image_color_source &&
382 image_color_source->image()->impeller_texture());
383 auto texture = image_color_source->image()->impeller_texture();
384 auto x_tile_mode =
ToTileMode(image_color_source->horizontal_tile_mode());
385 auto y_tile_mode =
ToTileMode(image_color_source->vertical_tile_mode());
387 auto matrix =
ToMatrix(image_color_source->matrix());
389 y_tile_mode, desc, matrix);
393 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
394 source->asRuntimeEffect();
396 runtime_effect_color_source->runtime_effect()->runtime_stage();
397 auto uniform_data = runtime_effect_color_source->uniform_data();
398 auto samplers = runtime_effect_color_source->samplers();
400 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
402 for (
auto& sampler : samplers) {
403 if (sampler ==
nullptr) {
406 auto* image = sampler->asImage();
407 if (!sampler->asImage()) {
411 FML_DCHECK(image->image()->impeller_texture());
412 texture_inputs.push_back({
414 .texture = image->image()->impeller_texture(),
419 runtime_stage, uniform_data, texture_inputs);
423 #ifdef IMPELLER_ENABLE_3D
424 const flutter::DlSceneColorSource* scene_color_source = source->asScene();
425 std::shared_ptr<scene::Node> scene_node =
426 scene_color_source->scene_node();
427 Matrix camera_transform = scene_color_source->camera_matrix();
430 ColorSource::MakeScene(scene_node, camera_transform);
431 #else // IMPELLER_ENABLE_3D
432 FML_LOG(ERROR) <<
"ColorSourceType::kScene can only be used if Impeller "
434 #endif // IMPELLER_ENABLE_3D
441 const flutter::DlColorFilter* filter) {
442 if (filter ==
nullptr) {
445 switch (filter->type()) {
446 case flutter::DlColorFilterType::kBlend: {
447 auto dl_blend = filter->asBlend();
452 case flutter::DlColorFilterType::kMatrix: {
453 const flutter::DlMatrixColorFilter* dl_matrix = filter->asMatrix();
455 dl_matrix->get_matrix(color_matrix.
array);
458 case flutter::DlColorFilterType::kSrgbToLinearGamma:
460 case flutter::DlColorFilterType::kLinearToSrgbGamma:
482 switch (blur_style) {
483 case flutter::DlBlurStyle::kNormal:
485 case flutter::DlBlurStyle::kSolid:
487 case flutter::DlBlurStyle::kOuter:
489 case flutter::DlBlurStyle::kInner:
497 if (filter ==
nullptr) {
501 switch (filter->type()) {
502 case flutter::DlMaskFilterType::kBlur: {
503 auto blur = filter->asBlur();
507 .sigma =
Sigma(blur->sigma()),
508 .respect_ctm = blur->respectCTM(),
516 const flutter::DlImageFilter* filter) {
517 if (filter ==
nullptr) {
521 switch (filter->type()) {
522 case flutter::DlImageFilterType::kBlur: {
523 auto blur = filter->asBlur();
524 auto sigma_x =
Sigma(blur->sigma_x());
525 auto sigma_y =
Sigma(blur->sigma_y());
526 auto tile_mode =
ToTileMode(blur->tile_mode());
530 case flutter::DlImageFilterType::kDilate: {
531 auto dilate = filter->asDilate();
533 if (dilate->radius_x() < 0 || dilate->radius_y() < 0) {
536 auto radius_x =
Radius(dilate->radius_x());
537 auto radius_y =
Radius(dilate->radius_y());
540 case flutter::DlImageFilterType::kErode: {
541 auto erode = filter->asErode();
543 if (erode->radius_x() < 0 || erode->radius_y() < 0) {
546 auto radius_x =
Radius(erode->radius_x());
547 auto radius_y =
Radius(erode->radius_y());
550 case flutter::DlImageFilterType::kMatrix: {
551 auto matrix_filter = filter->asMatrix();
552 FML_DCHECK(matrix_filter);
553 auto matrix =
ToMatrix(matrix_filter->matrix());
557 case flutter::DlImageFilterType::kCompose: {
558 auto compose = filter->asCompose();
560 auto outer_dl_filter = compose->outer();
561 auto inner_dl_filter = compose->inner();
570 FML_DCHECK(outer_filter && inner_filter);
574 case flutter::DlImageFilterType::kColorFilter: {
575 auto color_filter_image_filter = filter->asColorFilter();
576 FML_DCHECK(color_filter_image_filter);
578 ToColorFilter(color_filter_image_filter->color_filter().get());
588 case flutter::DlImageFilterType::kLocalMatrix: {
589 auto local_matrix_filter = filter->asLocalMatrix();
590 FML_DCHECK(local_matrix_filter);
591 auto internal_filter = local_matrix_filter->image_filter();
592 FML_DCHECK(internal_filter);
599 auto matrix =
ToMatrix(local_matrix_filter->matrix());
617 const flutter::SaveLayerOptions& options,
618 uint32_t total_content_depth,
619 flutter::DlBlendMode max_content_mode,
620 const flutter::DlImageFilter* backdrop) {
621 auto paint = options.renders_with_attributes() ? paint_ :
Paint{};
622 auto promise = options.content_is_clipped()
627 options.can_distribute_opacity());
709 flutter::DlCanvas::ClipOp clip_op) {
711 case flutter::DlCanvas::ClipOp::kDifference:
713 case flutter::DlCanvas::ClipOp::kIntersect:
731 if (rrect.isRect()) {
733 }
else if (rrect.isOval()) {
735 }
else if (rrect.isSimple()) {
749 const Path& DlDispatcherBase::GetOrCachePath(
const CacheablePath& cache) {
750 if (cache.cached_impeller_path.IsEmpty() && !cache.sk_path.isEmpty()) {
753 return cache.cached_impeller_path;
763 if (cache.sk_path.isRect(&rect)) {
765 }
else if (cache.sk_path.isOval(&rect)) {
769 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
781 flutter::DlBlendMode dl_mode) {
803 Scalar length = p0.GetDistance(p1);
809 if (length > 0.0f && on_length >= 0.0f && off_length > 0.0f) {
810 Point delta = (p1 - p0) / length;
814 while (consumed < length) {
815 builder.
MoveTo(p0 + delta * consumed);
817 Scalar dash_end = consumed + on_length;
818 if (dash_end < length) {
819 builder.
LineTo(p0 + delta * dash_end);
827 consumed = dash_end + off_length;
830 Paint stroke_paint = paint_;
834 drawLine(flutter::ToSkPoint(p0), flutter::ToSkPoint(p1));
879 SimplifyOrDrawPath(
GetCanvas(), cache, paint_);
882 void DlDispatcherBase::SimplifyOrDrawPath(
Canvas& canvas,
883 const CacheablePath& cache,
889 if (cache.sk_path.isRect(&rect, &closed) && closed) {
895 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
902 if (cache.sk_path.isOval(&oval)) {
912 SkScalar start_degrees,
913 SkScalar sweep_degrees,
917 Degrees(sweep_degrees), use_center);
924 const SkPoint points[]) {
928 case flutter::DlCanvas::PointMode::kPoints: {
932 auto radius =
paint.stroke_width;
939 case flutter::DlCanvas::PointMode::kLines:
940 for (uint32_t i = 1; i < count; i += 2) {
946 case flutter::DlCanvas::PointMode::kPolygon:
949 for (uint32_t i = 1; i < count; i++) {
961 const std::shared_ptr<flutter::DlVertices>& vertices,
962 flutter::DlBlendMode dl_mode) {
970 flutter::DlImageSampling sampling,
971 bool render_with_attributes) {
976 auto texture = image->impeller_texture();
981 const auto size = texture->GetSize();
982 const auto src = SkRect::MakeWH(size.width, size.height);
984 SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);
990 render_with_attributes,
991 SrcRectConstraint::kStrict
997 const sk_sp<flutter::DlImage> image,
1000 flutter::DlImageSampling sampling,
1001 bool render_with_attributes,
1002 SrcRectConstraint constraint = SrcRectConstraint::kFast) {
1004 std::make_shared<Image>(image->impeller_texture()),
1007 render_with_attributes ? paint_ :
Paint(),
1014 const SkIRect& center,
1016 flutter::DlFilterMode filter,
1017 bool render_with_attributes) {
1020 std::make_shared<Image>(image->impeller_texture()),
1021 Rect::MakeLTRB(center.fLeft, center.fTop, center.fRight, center.fBottom),
1028 const SkRSXform xform[],
1030 const flutter::DlColor colors[],
1032 flutter::DlBlendMode mode,
1033 flutter::DlImageSampling sampling,
1034 const SkRect* cull_rect,
1035 bool render_with_attributes) {
1046 const sk_sp<flutter::DisplayList> display_list,
1049 Paint saved_paint = paint_;
1050 Matrix saved_initial_matrix = initial_matrix_;
1065 if (opacity < SK_Scalar1) {
1071 display_list->can_apply_group_opacity());
1080 if (display_list->has_rtree() && !initial_matrix_.
HasPerspective()) {
1087 if (cull_bounds.has_value()) {
1088 Rect cull_rect = cull_bounds.value();
1089 display_list->Dispatch(
1090 *
this, SkRect::MakeLTRB(cull_rect.
GetLeft(), cull_rect.
GetTop(),
1093 display_list->Dispatch(*
this);
1096 display_list->Dispatch(*
this);
1102 initial_matrix_ = saved_initial_matrix;
1103 paint_ = saved_paint;
1116 const std::shared_ptr<TextFrame>& text_frame,
1127 const flutter::DlColor
color,
1128 const SkScalar elevation,
1129 bool transparent_occluder,
1136 const flutter::DlColor
color,
1137 const SkScalar elevation,
1138 bool transparent_occluder,
1141 spot_color.
alpha *= 0.25;
1146 std::max(std::max(spot_color.
red, spot_color.
green), spot_color.
blue);
1148 std::min(std::min(spot_color.
red, spot_color.
green), spot_color.
blue);
1149 Scalar luminance = (min + max) * 0.5;
1152 (2.6f + (-2.66667f + 1.06667f * spot_color.
alpha) * spot_color.
alpha) *
1155 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
1157 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
1160 std::clamp(spot_color.
alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
1162 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
1163 Scalar tonal_alpha = color_scale + greyscale_alpha;
1164 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
1165 spot_color =
Color(unpremul_scale * spot_color.
red,
1166 unpremul_scale * spot_color.
green,
1167 unpremul_scale * spot_color.
blue, tonal_alpha);
1170 Vector3 light_position(0, -1, 1);
1171 Scalar occluder_z = dpr * elevation;
1173 constexpr
Scalar kLightRadius = 800 / 600;
1177 paint.color = spot_color;
1180 .sigma =
Radius{kLightRadius * occluder_z /
1194 TRACE_EVENT0(
"impeller",
"DisplayListDispatcher::EndRecordingAsPicture");
1206 Canvas& DlDispatcher::GetCanvas() {
1212 flutter::DlBlendMode max_root_blend_mode) {
1220 bool has_root_backdrop_filter,
1221 flutter::DlBlendMode max_root_blend_mode,
1225 has_root_backdrop_filter ||
1229 Canvas& ExperimentalDlDispatcher::GetCanvas() {
1236 const Matrix& initial_matrix)
1237 : renderer_(renderer), matrix_(initial_matrix) {}
1240 stack_.emplace_back(matrix_);
1244 const flutter::SaveLayerOptions options,
1245 const flutter::DlImageFilter* backdrop) {
1250 matrix_ = stack_.back();
1259 matrix_ = matrix_.
Scale({sx, sy, 1.0f});
1273 SkScalar myx, SkScalar myy, SkScalar myt) {
1275 mxx, myx, 0.0f, 0.0f,
1276 mxy, myy, 0.0f, 0.0f,
1277 0.0f, 0.0f, 1.0f, 0.0f,
1278 mxt, myt, 0.0f, 1.0f
1284 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
1285 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
1286 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
1287 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
1302 const std::shared_ptr<impeller::TextFrame>& text_frame,
1307 properties.
stroke =
true;
1313 if (text_frame->HasColor()) {
1326 const sk_sp<flutter::DisplayList> display_list,
1328 [[maybe_unused]]
size_t stack_depth = stack_.size();
1330 display_list->Dispatch(*
this);
1332 FML_DCHECK(stack_depth == stack_.size());
1363 case flutter::DlStrokeCap::kButt:
1366 case flutter::DlStrokeCap::kRound:
1369 case flutter::DlStrokeCap::kSquare:
1378 case flutter::DlStrokeJoin::kMiter:
1381 case flutter::DlStrokeJoin::kRound:
1384 case flutter::DlStrokeJoin::kBevel: