| Flutter Impeller |

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
5 #include "impeller/display_list/dl_dispatcher.h"
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"
16 #include "impeller/aiks/color_filter.h"
17 #include "impeller/core/formats.h"
18 #include "impeller/display_list/dl_vertices_geometry.h"
19 #include "impeller/display_list/nine_patch_converter.h"
20 #include "impeller/display_list/skia_conversions.h"
21 #include "impeller/entity/contents/content_context.h"
22 #include "impeller/entity/contents/filters/filter_contents.h"
23 #include "impeller/entity/contents/filters/inputs/filter_input.h"
24 #include "impeller/entity/contents/runtime_effect_contents.h"
25 #include "impeller/entity/entity.h"
26 #include "impeller/geometry/color.h"
27 #include "impeller/geometry/path.h"
28 #include "impeller/geometry/path_builder.h"
29 #include "impeller/geometry/scalar.h"
30 #include "impeller/geometry/sigma.h"
31 #include "impeller/typographer/font_glyph_pair.h"
32
33 #if IMPELLER_ENABLE_3D
34 #include "impeller/entity/contents/scene_contents.h"
35 #endif // IMPELLER_ENABLE_3D
36
37 namespace impeller {
38
39 #define UNIMPLEMENTED \
40 FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
41
42 static BlendMode ToBlendMode(flutter::DlBlendMode mode) {
43 switch (mode) {
44 case flutter::DlBlendMode::kClear:
45 return BlendMode::kClear;
46 case flutter::DlBlendMode::kSrc:
47 return BlendMode::kSource;
48 case flutter::DlBlendMode::kDst:
49 return BlendMode::kDestination;
50 case flutter::DlBlendMode::kSrcOver:
51 return BlendMode::kSourceOver;
52 case flutter::DlBlendMode::kDstOver:
53 return BlendMode::kDestinationOver;
54 case flutter::DlBlendMode::kSrcIn:
55 return BlendMode::kSourceIn;
56 case flutter::DlBlendMode::kDstIn:
57 return BlendMode::kDestinationIn;
58 case flutter::DlBlendMode::kSrcOut:
59 return BlendMode::kSourceOut;
60 case flutter::DlBlendMode::kDstOut:
61 return BlendMode::kDestinationOut;
62 case flutter::DlBlendMode::kSrcATop:
63 return BlendMode::kSourceATop;
64 case flutter::DlBlendMode::kDstATop:
65 return BlendMode::kDestinationATop;
66 case flutter::DlBlendMode::kXor:
67 return BlendMode::kXor;
68 case flutter::DlBlendMode::kPlus:
69 return BlendMode::kPlus;
70 case flutter::DlBlendMode::kModulate:
71 return BlendMode::kModulate;
72 case flutter::DlBlendMode::kScreen:
73 return BlendMode::kScreen;
74 case flutter::DlBlendMode::kOverlay:
75 return BlendMode::kOverlay;
76 case flutter::DlBlendMode::kDarken:
77 return BlendMode::kDarken;
78 case flutter::DlBlendMode::kLighten:
79 return BlendMode::kLighten;
80 case flutter::DlBlendMode::kColorDodge:
81 return BlendMode::kColorDodge;
82 case flutter::DlBlendMode::kColorBurn:
83 return BlendMode::kColorBurn;
84 case flutter::DlBlendMode::kHardLight:
85 return BlendMode::kHardLight;
86 case flutter::DlBlendMode::kSoftLight:
87 return BlendMode::kSoftLight;
88 case flutter::DlBlendMode::kDifference:
89 return BlendMode::kDifference;
90 case flutter::DlBlendMode::kExclusion:
91 return BlendMode::kExclusion;
92 case flutter::DlBlendMode::kMultiply:
93 return BlendMode::kMultiply;
94 case flutter::DlBlendMode::kHue:
95 return BlendMode::kHue;
96 case flutter::DlBlendMode::kSaturation:
97 return BlendMode::kSaturation;
98 case flutter::DlBlendMode::kColor:
99 return BlendMode::kColor;
100 case flutter::DlBlendMode::kLuminosity:
101 return BlendMode::kLuminosity;
102 }
103 FML_UNREACHABLE();
104 }
105
106 static Entity::TileMode ToTileMode(flutter::DlTileMode tile_mode) {
107 switch (tile_mode) {
108 case flutter::DlTileMode::kClamp:
109 return Entity::TileMode::kClamp;
110 case flutter::DlTileMode::kRepeat:
111 return Entity::TileMode::kRepeat;
112 case flutter::DlTileMode::kMirror:
113 return Entity::TileMode::kMirror;
114 case flutter::DlTileMode::kDecal:
115 return Entity::TileMode::kDecal;
116 }
117 }
118
119 static impeller::SamplerDescriptor ToSamplerDescriptor(
120 const flutter::DlImageSampling options) {
121 impeller::SamplerDescriptor desc;
122 switch (options) {
123 case flutter::DlImageSampling::kNearestNeighbor:
124 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
125 desc.mip_filter = impeller::MipFilter::kBase;
126 desc.label = "Nearest Sampler";
127 break;
128 case flutter::DlImageSampling::kLinear:
129 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
130 desc.mip_filter = impeller::MipFilter::kBase;
131 desc.label = "Linear Sampler";
132 break;
133 case flutter::DlImageSampling::kCubic:
134 case flutter::DlImageSampling::kMipmapLinear:
135 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
136 desc.mip_filter = impeller::MipFilter::kLinear;
137 desc.label = "Mipmap Linear Sampler";
138 break;
139 }
140 return desc;
141 }
142
143 static impeller::SamplerDescriptor ToSamplerDescriptor(
144 const flutter::DlFilterMode options) {
145 impeller::SamplerDescriptor desc;
146 switch (options) {
147 case flutter::DlFilterMode::kNearest:
148 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
149 desc.label = "Nearest Sampler";
150 break;
151 case flutter::DlFilterMode::kLinear:
152 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
153 desc.label = "Linear Sampler";
154 break;
155 default:
156 break;
157 }
158 return desc;
159 }
160
161 static Matrix ToMatrix(const SkMatrix& m) {
162 return Matrix{
163 // clang-format off
164 m[0], m[3], 0, m[6],
165 m[1], m[4], 0, m[7],
166 0, 0, 1, 0,
167 m[2], m[5], 0, m[8],
168 // clang-format on
169 };
170 }
171
172 // |flutter::DlOpReceiver|
173 void DlDispatcherBase::setAntiAlias(bool aa) {
174 // Nothing to do because AA is implicit.
175 }
176
177 static Paint::Style ToStyle(flutter::DlDrawStyle style) {
178 switch (style) {
179 case flutter::DlDrawStyle::kFill:
180 return Paint::Style::kFill;
181 case flutter::DlDrawStyle::kStroke:
182 return Paint::Style::kStroke;
183 case flutter::DlDrawStyle::kStrokeAndFill:
184 UNIMPLEMENTED;
185 break;
186 }
187 return Paint::Style::kFill;
188 }
189
190 // |flutter::DlOpReceiver|
191 void DlDispatcherBase::setDrawStyle(flutter::DlDrawStyle style) {
192 paint_.style = ToStyle(style);
193 }
194
195 // |flutter::DlOpReceiver|
196 void DlDispatcherBase::setColor(flutter::DlColor color) {
197 paint_.color = {
198 color.getRedF(),
199 color.getGreenF(),
200 color.getBlueF(),
201 color.getAlphaF(),
202 };
203 }
204
205 // |flutter::DlOpReceiver|
206 void DlDispatcherBase::setStrokeWidth(SkScalar width) {
207 paint_.stroke_width = width;
208 }
209
210 // |flutter::DlOpReceiver|
211 void DlDispatcherBase::setStrokeMiter(SkScalar limit) {
212 paint_.stroke_miter = limit;
213 }
214
215 // |flutter::DlOpReceiver|
216 void DlDispatcherBase::setStrokeCap(flutter::DlStrokeCap cap) {
217 switch (cap) {
218 case flutter::DlStrokeCap::kButt:
219 paint_.stroke_cap = Cap::kButt;
220 break;
221 case flutter::DlStrokeCap::kRound:
222 paint_.stroke_cap = Cap::kRound;
223 break;
224 case flutter::DlStrokeCap::kSquare:
225 paint_.stroke_cap = Cap::kSquare;
226 break;
227 }
228 }
229
230 // |flutter::DlOpReceiver|
231 void DlDispatcherBase::setStrokeJoin(flutter::DlStrokeJoin join) {
232 switch (join) {
233 case flutter::DlStrokeJoin::kMiter:
234 paint_.stroke_join = Join::kMiter;
235 break;
236 case flutter::DlStrokeJoin::kRound:
237 paint_.stroke_join = Join::kRound;
238 break;
239 case flutter::DlStrokeJoin::kBevel:
240 paint_.stroke_join = Join::kBevel;
241 break;
242 }
243 }
244
245 static std::vector<Color> ToColors(const flutter::DlColor colors[], int count) {
246 auto result = std::vector<Color>();
247 if (colors == nullptr) {
248 return result;
249 }
250 for (int i = 0; i < count; i++) {
251 result.push_back(skia_conversions::ToColor(colors[i]));
252 }
253 return result;
254 }
255
256 static std::optional<ColorSource::Type> ToColorSourceType(
257 flutter::DlColorSourceType type) {
258 switch (type) {
259 case flutter::DlColorSourceType::kColor:
260 return ColorSource::Type::kColor;
261 case flutter::DlColorSourceType::kImage:
262 return ColorSource::Type::kImage;
263 case flutter::DlColorSourceType::kLinearGradient:
264 return ColorSource::Type::kLinearGradient;
265 case flutter::DlColorSourceType::kRadialGradient:
266 return ColorSource::Type::kRadialGradient;
267 case flutter::DlColorSourceType::kConicalGradient:
268 return ColorSource::Type::kConicalGradient;
269 case flutter::DlColorSourceType::kSweepGradient:
270 return ColorSource::Type::kSweepGradient;
271 case flutter::DlColorSourceType::kRuntimeEffect:
272 return ColorSource::Type::kRuntimeEffect;
273 #ifdef IMPELLER_ENABLE_3D
274 case flutter::DlColorSourceType::kScene:
275 return ColorSource::Type::kScene;
276 #endif // IMPELLER_ENABLE_3D
277 }
278 }
279
280 // |flutter::DlOpReceiver|
281 void DlDispatcherBase::setColorSource(const flutter::DlColorSource* source) {
282 if (!source) {
283 paint_.color_source = ColorSource::MakeColor();
284 return;
285 }
286
287 std::optional<ColorSource::Type> type = ToColorSourceType(source->type());
288
289 if (!type.has_value()) {
290 FML_LOG(ERROR) << "Requested ColorSourceType::kUnknown";
291 paint_.color_source = ColorSource::MakeColor();
292 return;
293 }
294
295 switch (type.value()) {
296 case ColorSource::Type::kColor: {
297 const flutter::DlColorColorSource* color = source->asColor();
298
299 paint_.color_source = ColorSource::MakeColor();
300 setColor(color->color());
301 FML_DCHECK(color);
302 return;
303 }
304 case ColorSource::Type::kLinearGradient: {
305 const flutter::DlLinearGradientColorSource* linear =
306 source->asLinearGradient();
307 FML_DCHECK(linear);
308 auto start_point = skia_conversions::ToPoint(linear->start_point());
309 auto end_point = skia_conversions::ToPoint(linear->end_point());
310 std::vector<Color> colors;
311 std::vector<float> stops;
312 skia_conversions::ConvertStops(linear, colors, stops);
313
314 auto tile_mode = ToTileMode(linear->tile_mode());
315 auto matrix = ToMatrix(linear->matrix());
316
317 paint_.color_source = ColorSource::MakeLinearGradient(
318 start_point, end_point, std::move(colors), std::move(stops),
319 tile_mode, matrix);
320 return;
321 }
322 case ColorSource::Type::kConicalGradient: {
323 const flutter::DlConicalGradientColorSource* conical_gradient =
324 source->asConicalGradient();
325 FML_DCHECK(conical_gradient);
326 Point center = skia_conversions::ToPoint(conical_gradient->end_center());
327 SkScalar radius = conical_gradient->end_radius();
328 Point focus_center =
329 skia_conversions::ToPoint(conical_gradient->start_center());
330 SkScalar focus_radius = conical_gradient->start_radius();
331 std::vector<Color> colors;
332 std::vector<float> stops;
333 skia_conversions::ConvertStops(conical_gradient, colors, stops);
334
335 auto tile_mode = ToTileMode(conical_gradient->tile_mode());
336 auto matrix = ToMatrix(conical_gradient->matrix());
337
338 paint_.color_source = ColorSource::MakeConicalGradient(
339 center, radius, std::move(colors), std::move(stops), focus_center,
340 focus_radius, tile_mode, matrix);
341 return;
342 }
343 case ColorSource::Type::kRadialGradient: {
344 const flutter::DlRadialGradientColorSource* radialGradient =
345 source->asRadialGradient();
346 FML_DCHECK(radialGradient);
347 auto center = skia_conversions::ToPoint(radialGradient->center());
348 auto radius = radialGradient->radius();
349 std::vector<Color> colors;
350 std::vector<float> stops;
351 skia_conversions::ConvertStops(radialGradient, colors, stops);
352
353 auto tile_mode = ToTileMode(radialGradient->tile_mode());
354 auto matrix = ToMatrix(radialGradient->matrix());
355 paint_.color_source =
356 ColorSource::MakeRadialGradient(center, radius, std::move(colors),
357 std::move(stops), tile_mode, matrix);
358 return;
359 }
360 case ColorSource::Type::kSweepGradient: {
361 const flutter::DlSweepGradientColorSource* sweepGradient =
362 source->asSweepGradient();
363 FML_DCHECK(sweepGradient);
364
365 auto center = skia_conversions::ToPoint(sweepGradient->center());
366 auto start_angle = Degrees(sweepGradient->start());
367 auto end_angle = Degrees(sweepGradient->end());
368 std::vector<Color> colors;
369 std::vector<float> stops;
370 skia_conversions::ConvertStops(sweepGradient, colors, stops);
371
372 auto tile_mode = ToTileMode(sweepGradient->tile_mode());
373 auto matrix = ToMatrix(sweepGradient->matrix());
374 paint_.color_source = ColorSource::MakeSweepGradient(
375 center, start_angle, end_angle, std::move(colors), std::move(stops),
376 tile_mode, matrix);
377 return;
378 }
379 case ColorSource::Type::kImage: {
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());
386 auto desc = ToSamplerDescriptor(image_color_source->sampling());
387 auto matrix = ToMatrix(image_color_source->matrix());
388 paint_.color_source = ColorSource::MakeImage(texture, x_tile_mode,
389 y_tile_mode, desc, matrix);
390 return;
391 }
392 case ColorSource::Type::kRuntimeEffect: {
393 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
394 source->asRuntimeEffect();
395 auto runtime_stage =
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();
399
400 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
401
402 for (auto& sampler : samplers) {
403 if (sampler == nullptr) {
404 return;
405 }
406 auto* image = sampler->asImage();
407 if (!sampler->asImage()) {
408 UNIMPLEMENTED;
409 return;
410 }
411 FML_DCHECK(image->image()->impeller_texture());
412 texture_inputs.push_back({
413 .sampler_descriptor = ToSamplerDescriptor(image->sampling()),
414 .texture = image->image()->impeller_texture(),
415 });
416 }
417
418 paint_.color_source = ColorSource::MakeRuntimeEffect(
419 runtime_stage, uniform_data, texture_inputs);
420 return;
421 }
422 case ColorSource::Type::kScene: {
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();
428
429 paint_.color_source =
430 ColorSource::MakeScene(scene_node, camera_transform);
431 #else // IMPELLER_ENABLE_3D
432 FML_LOG(ERROR) << "ColorSourceType::kScene can only be used if Impeller "
433 "Scene is enabled.";
434 #endif // IMPELLER_ENABLE_3D
435 return;
436 }
437 }
438 }
439
440 static std::shared_ptr<ColorFilter> ToColorFilter(
441 const flutter::DlColorFilter* filter) {
442 if (filter == nullptr) {
443 return nullptr;
444 }
445 switch (filter->type()) {
446 case flutter::DlColorFilterType::kBlend: {
447 auto dl_blend = filter->asBlend();
448 auto blend_mode = ToBlendMode(dl_blend->mode());
449 auto color = skia_conversions::ToColor(dl_blend->color());
450 return ColorFilter::MakeBlend(blend_mode, color);
451 }
452 case flutter::DlColorFilterType::kMatrix: {
453 const flutter::DlMatrixColorFilter* dl_matrix = filter->asMatrix();
454 impeller::ColorMatrix color_matrix;
455 dl_matrix->get_matrix(color_matrix.array);
456 return ColorFilter::MakeMatrix(color_matrix);
457 }
458 case flutter::DlColorFilterType::kSrgbToLinearGamma:
459 return ColorFilter::MakeSrgbToLinear();
460 case flutter::DlColorFilterType::kLinearToSrgbGamma:
461 return ColorFilter::MakeLinearToSrgb();
462 }
463 return nullptr;
464 }
465
466 // |flutter::DlOpReceiver|
467 void DlDispatcherBase::setColorFilter(const flutter::DlColorFilter* filter) {
468 paint_.color_filter = ToColorFilter(filter);
469 }
470
471 // |flutter::DlOpReceiver|
472 void DlDispatcherBase::setInvertColors(bool invert) {
473 paint_.invert_colors = invert;
474 }
475
476 // |flutter::DlOpReceiver|
477 void DlDispatcherBase::setBlendMode(flutter::DlBlendMode dl_mode) {
478 paint_.blend_mode = ToBlendMode(dl_mode);
479 }
480
481 static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style) {
482 switch (blur_style) {
483 case flutter::DlBlurStyle::kNormal:
484 return FilterContents::BlurStyle::kNormal;
485 case flutter::DlBlurStyle::kSolid:
486 return FilterContents::BlurStyle::kSolid;
487 case flutter::DlBlurStyle::kOuter:
488 return FilterContents::BlurStyle::kOuter;
489 case flutter::DlBlurStyle::kInner:
490 return FilterContents::BlurStyle::kInner;
491 }
492 }
493
494 // |flutter::DlOpReceiver|
495 void DlDispatcherBase::setMaskFilter(const flutter::DlMaskFilter* filter) {
496 // Needs https://github.com/flutter/flutter/issues/95434
497 if (filter == nullptr) {
498 paint_.mask_blur_descriptor = std::nullopt;
499 return;
500 }
501 switch (filter->type()) {
502 case flutter::DlMaskFilterType::kBlur: {
503 auto blur = filter->asBlur();
504
505 paint_.mask_blur_descriptor = {
506 .style = ToBlurStyle(blur->style()),
507 .sigma = Sigma(blur->sigma()),
508 .respect_ctm = blur->respectCTM(),
509 };
510 break;
511 }
512 }
513 }
514
515 static std::shared_ptr<ImageFilter> ToImageFilter(
516 const flutter::DlImageFilter* filter) {
517 if (filter == nullptr) {
518 return nullptr;
519 }
520
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());
527 return ImageFilter::MakeBlur(
528 sigma_x, sigma_y, FilterContents::BlurStyle::kNormal, tile_mode);
529 }
530 case flutter::DlImageFilterType::kDilate: {
531 auto dilate = filter->asDilate();
532 FML_DCHECK(dilate);
533 if (dilate->radius_x() < 0 || dilate->radius_y() < 0) {
534 return nullptr;
535 }
536 auto radius_x = Radius(dilate->radius_x());
537 auto radius_y = Radius(dilate->radius_y());
538 return ImageFilter::MakeDilate(radius_x, radius_y);
539 }
540 case flutter::DlImageFilterType::kErode: {
541 auto erode = filter->asErode();
542 FML_DCHECK(erode);
543 if (erode->radius_x() < 0 || erode->radius_y() < 0) {
544 return nullptr;
545 }
546 auto radius_x = Radius(erode->radius_x());
547 auto radius_y = Radius(erode->radius_y());
548 return ImageFilter::MakeErode(radius_x, radius_y);
549 }
550 case flutter::DlImageFilterType::kMatrix: {
551 auto matrix_filter = filter->asMatrix();
552 FML_DCHECK(matrix_filter);
553 auto matrix = ToMatrix(matrix_filter->matrix());
554 auto desc = ToSamplerDescriptor(matrix_filter->sampling());
555 return ImageFilter::MakeMatrix(matrix, desc);
556 }
557 case flutter::DlImageFilterType::kCompose: {
558 auto compose = filter->asCompose();
559 FML_DCHECK(compose);
560 auto outer_dl_filter = compose->outer();
561 auto inner_dl_filter = compose->inner();
562 auto outer_filter = ToImageFilter(outer_dl_filter.get());
563 auto inner_filter = ToImageFilter(inner_dl_filter.get());
564 if (!outer_filter) {
565 return inner_filter;
566 }
567 if (!inner_filter) {
568 return outer_filter;
569 }
570 FML_DCHECK(outer_filter && inner_filter);
571
572 return ImageFilter::MakeCompose(*inner_filter, *outer_filter);
573 }
574 case flutter::DlImageFilterType::kColorFilter: {
575 auto color_filter_image_filter = filter->asColorFilter();
576 FML_DCHECK(color_filter_image_filter);
577 auto color_filter =
578 ToColorFilter(color_filter_image_filter->color_filter().get());
579 if (!color_filter) {
580 return nullptr;
581 }
582 // When color filters are used as image filters, set the color filter's
583 // "absorb opacity" flag to false. For image filters, the snapshot
584 // opacity needs to be deferred until the result of the filter chain is
585 // being blended with the layer.
586 return ImageFilter::MakeFromColorFilter(*color_filter);
587 }
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);
593
594 auto image_filter = ToImageFilter(internal_filter.get());
595 if (!image_filter) {
596 return nullptr;
597 }
598
599 auto matrix = ToMatrix(local_matrix_filter->matrix());
600 return ImageFilter::MakeLocalMatrix(matrix, *image_filter);
601 }
602 }
603 }
604
605 // |flutter::DlOpReceiver|
606 void DlDispatcherBase::setImageFilter(const flutter::DlImageFilter* filter) {
607 paint_.image_filter = ToImageFilter(filter);
608 }
609
610 // |flutter::DlOpReceiver|
611 void DlDispatcherBase::save(uint32_t total_content_depth) {
612 GetCanvas().Save(total_content_depth);
613 }
614
615 static constexpr SkRect kMaxCullRect =
616 SkRect::MakeLTRB(-1E9F, -1E9F, 1E9F, 1E9F);
617
618 // |flutter::DlOpReceiver|
619 void DlDispatcherBase::saveLayer(const SkRect& bounds,
620 const flutter::SaveLayerOptions& options,
621 uint32_t total_content_depth,
622 flutter::DlBlendMode max_content_mode,
623 const flutter::DlImageFilter* backdrop) {
624 auto paint = options.renders_with_attributes() ? paint_ : Paint{};
625 auto promise = options.content_is_clipped()
626 ? ContentBoundsPromise::kMayClipContents
627 : ContentBoundsPromise::kContainsContents;
628 std::optional<Rect> impeller_bounds;
629 if (bounds == kMaxCullRect) {
630 impeller_bounds = std::nullopt;
631 } else {
632 impeller_bounds = skia_conversions::ToRect(bounds);
633 }
634
635 GetCanvas().SaveLayer(paint, impeller_bounds, ToImageFilter(backdrop),
636 promise, total_content_depth,
637 options.can_distribute_opacity());
638 }
639
640 // |flutter::DlOpReceiver|
641 void DlDispatcherBase::restore() {
642 GetCanvas().Restore();
643 }
644
645 // |flutter::DlOpReceiver|
646 void DlDispatcherBase::translate(SkScalar tx, SkScalar ty) {
647 GetCanvas().Translate({tx, ty, 0.0});
648 }
649
650 // |flutter::DlOpReceiver|
651 void DlDispatcherBase::scale(SkScalar sx, SkScalar sy) {
652 GetCanvas().Scale({sx, sy, 1.0});
653 }
654
655 // |flutter::DlOpReceiver|
656 void DlDispatcherBase::rotate(SkScalar degrees) {
657 GetCanvas().Rotate(Degrees{degrees});
658 }
659
660 // |flutter::DlOpReceiver|
661 void DlDispatcherBase::skew(SkScalar sx, SkScalar sy) {
662 GetCanvas().Skew(sx, sy);
663 }
664
665 // |flutter::DlOpReceiver|
666 void DlDispatcherBase::transform2DAffine(SkScalar mxx,
667 SkScalar mxy,
668 SkScalar mxt,
669 SkScalar myx,
670 SkScalar myy,
671 SkScalar myt) {
672 // clang-format off
673 transformFullPerspective(
674 mxx, mxy, 0, mxt,
675 myx, myy, 0, myt,
676 0 , 0, 1, 0,
677 0 , 0, 0, 1
678 );
679 // clang-format on
680 }
681
682 // |flutter::DlOpReceiver|
683 void DlDispatcherBase::transformFullPerspective(SkScalar mxx,
684 SkScalar mxy,
685 SkScalar mxz,
686 SkScalar mxt,
687 SkScalar myx,
688 SkScalar myy,
689 SkScalar myz,
690 SkScalar myt,
691 SkScalar mzx,
692 SkScalar mzy,
693 SkScalar mzz,
694 SkScalar mzt,
695 SkScalar mwx,
696 SkScalar mwy,
697 SkScalar mwz,
698 SkScalar mwt) {
699 // The order of arguments is row-major but Impeller matrices are
700 // column-major.
701 // clang-format off
702 auto transform = Matrix{
703 mxx, myx, mzx, mwx,
704 mxy, myy, mzy, mwy,
705 mxz, myz, mzz, mwz,
706 mxt, myt, mzt, mwt
707 };
708 // clang-format on
709 GetCanvas().Transform(transform);
710 }
711
712 // |flutter::DlOpReceiver|
713 void DlDispatcherBase::transformReset() {
714 GetCanvas().ResetTransform();
715 GetCanvas().Transform(initial_matrix_);
716 }
717
718 static Entity::ClipOperation ToClipOperation(
719 flutter::DlCanvas::ClipOp clip_op) {
720 switch (clip_op) {
721 case flutter::DlCanvas::ClipOp::kDifference:
722 return Entity::ClipOperation::kDifference;
723 case flutter::DlCanvas::ClipOp::kIntersect:
724 return Entity::ClipOperation::kIntersect;
725 }
726 }
727
728 // |flutter::DlOpReceiver|
729 void DlDispatcherBase::clipRect(const SkRect& rect,
730 ClipOp clip_op,
731 bool is_aa) {
732 GetCanvas().ClipRect(skia_conversions::ToRect(rect),
733 ToClipOperation(clip_op));
734 }
735
736 // |flutter::DlOpReceiver|
737 void DlDispatcherBase::clipRRect(const SkRRect& rrect,
738 ClipOp sk_op,
739 bool is_aa) {
740 auto clip_op = ToClipOperation(sk_op);
741 if (rrect.isRect()) {
742 GetCanvas().ClipRect(skia_conversions::ToRect(rrect.rect()), clip_op);
743 } else if (rrect.isOval()) {
744 GetCanvas().ClipOval(skia_conversions::ToRect(rrect.rect()), clip_op);
745 } else if (rrect.isSimple()) {
746 GetCanvas().ClipRRect(skia_conversions::ToRect(rrect.rect()),
747 skia_conversions::ToSize(rrect.getSimpleRadii()),
748 clip_op);
749 } else {
750 GetCanvas().ClipPath(skia_conversions::ToPath(rrect), clip_op);
751 }
752 }
753
754 // |flutter::DlOpReceiver|
755 void DlDispatcherBase::clipPath(const SkPath& path, ClipOp sk_op, bool is_aa) {
756 UNIMPLEMENTED;
757 }
758
759 const Path& DlDispatcherBase::GetOrCachePath(const CacheablePath& cache) {
760 if (cache.cached_impeller_path.IsEmpty() && !cache.sk_path.isEmpty()) {
761 cache.cached_impeller_path = skia_conversions::ToPath(cache.sk_path);
762 }
763 return cache.cached_impeller_path;
764 }
765
766 // |flutter::DlOpReceiver|
767 void DlDispatcherBase::clipPath(const CacheablePath& cache,
768 ClipOp sk_op,
769 bool is_aa) {
770 auto clip_op = ToClipOperation(sk_op);
771
772 SkRect rect;
773 if (cache.sk_path.isRect(&rect)) {
774 GetCanvas().ClipRect(skia_conversions::ToRect(rect), clip_op);
775 } else if (cache.sk_path.isOval(&rect)) {
776 GetCanvas().ClipOval(skia_conversions::ToRect(rect), clip_op);
777 } else {
778 SkRRect rrect;
779 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
780 GetCanvas().ClipRRect(skia_conversions::ToRect(rrect.rect()),
781 skia_conversions::ToSize(rrect.getSimpleRadii()),
782 clip_op);
783 } else {
784 GetCanvas().ClipPath(GetOrCachePath(cache), clip_op);
785 }
786 }
787 }
788
789 // |flutter::DlOpReceiver|
790 void DlDispatcherBase::drawColor(flutter::DlColor color,
791 flutter::DlBlendMode dl_mode) {
792 Paint paint;
793 paint.color = skia_conversions::ToColor(color);
794 paint.blend_mode = ToBlendMode(dl_mode);
795 GetCanvas().DrawPaint(paint);
796 }
797
798 // |flutter::DlOpReceiver|
799 void DlDispatcherBase::drawPaint() {
800 GetCanvas().DrawPaint(paint_);
801 }
802
803 // |flutter::DlOpReceiver|
804 void DlDispatcherBase::drawLine(const SkPoint& p0, const SkPoint& p1) {
805 GetCanvas().DrawLine(skia_conversions::ToPoint(p0),
806 skia_conversions::ToPoint(p1), paint_);
807 }
808
809 void DlDispatcherBase::drawDashedLine(const DlPoint& p0,
810 const DlPoint& p1,
811 DlScalar on_length,
812 DlScalar off_length) {
813 Scalar length = p0.GetDistance(p1);
814 // Reasons to defer to regular DrawLine:
815 // length is non-positive - drawLine will draw appropriate "dot"
816 // off_length is non-positive - no gaps, drawLine will draw it solid
817 // on_length is negative - invalid dashing
818 // Note that a 0 length "on" dash will draw "dot"s every "off" distance apart
819 if (length > 0.0f && on_length >= 0.0f && off_length > 0.0f) {
820 Point delta = (p1 - p0) / length; // length > 0 already tested
821 PathBuilder builder;
822
823 Scalar consumed = 0.0f;
824 while (consumed < length) {
825 builder.MoveTo(p0 + delta * consumed);
826
827 Scalar dash_end = consumed + on_length;
828 if (dash_end < length) {
829 builder.LineTo(p0 + delta * dash_end);
830 } else {
831 builder.LineTo(p1);
832 // Should happen anyway due to the math, but let's make it explicit
833 // in case of bit errors. We're done with this line.
834 break;
835 }
836
837 consumed = dash_end + off_length;
838 }
839
840 Paint stroke_paint = paint_;
841 stroke_paint.style = Paint::Style::kStroke;
842 GetCanvas().DrawPath(builder.TakePath(), stroke_paint);
843 } else {
844 drawLine(flutter::ToSkPoint(p0), flutter::ToSkPoint(p1));
845 }
846 }
847
848 // |flutter::DlOpReceiver|
849 void DlDispatcherBase::drawRect(const SkRect& rect) {
850 GetCanvas().DrawRect(skia_conversions::ToRect(rect), paint_);
851 }
852
853 // |flutter::DlOpReceiver|
854 void DlDispatcherBase::drawOval(const SkRect& bounds) {
855 GetCanvas().DrawOval(skia_conversions::ToRect(bounds), paint_);
856 }
857
858 // |flutter::DlOpReceiver|
859 void DlDispatcherBase::drawCircle(const SkPoint& center, SkScalar radius) {
860 GetCanvas().DrawCircle(skia_conversions::ToPoint(center), radius, paint_);
861 }
862
863 // |flutter::DlOpReceiver|
864 void DlDispatcherBase::drawRRect(const SkRRect& rrect) {
865 if (skia_conversions::IsNearlySimpleRRect(rrect)) {
866 GetCanvas().DrawRRect(skia_conversions::ToRect(rrect.rect()),
867 skia_conversions::ToSize(rrect.getSimpleRadii()),
868 paint_);
869 } else {
870 GetCanvas().DrawPath(skia_conversions::ToPath(rrect), paint_);
871 }
872 }
873
874 // |flutter::DlOpReceiver|
875 void DlDispatcherBase::drawDRRect(const SkRRect& outer, const SkRRect& inner) {
876 PathBuilder builder;
877 builder.AddPath(skia_conversions::ToPath(outer));
878 builder.AddPath(skia_conversions::ToPath(inner));
879 GetCanvas().DrawPath(builder.TakePath(FillType::kOdd), paint_);
880 }
881
882 // |flutter::DlOpReceiver|
883 void DlDispatcherBase::drawPath(const SkPath& path) {
884 UNIMPLEMENTED;
885 }
886
887 // |flutter::DlOpReceiver|
888 void DlDispatcherBase::drawPath(const CacheablePath& cache) {
889 SimplifyOrDrawPath(GetCanvas(), cache, paint_);
890 }
891
892 void DlDispatcherBase::SimplifyOrDrawPath(Canvas& canvas,
893 const CacheablePath& cache,
894 const Paint& paint) {
895 SkRect rect;
896
897 // We can't "optimize" a path into a rectangle if it's open.
898 bool closed;
899 if (cache.sk_path.isRect(&rect, &closed) && closed) {
900 canvas.DrawRect(skia_conversions::ToRect(rect), paint);
901 return;
902 }
903
904 SkRRect rrect;
905 if (cache.sk_path.isRRect(&rrect) && rrect.isSimple()) {
906 canvas.DrawRRect(skia_conversions::ToRect(rrect.rect()),
907 skia_conversions::ToSize(rrect.getSimpleRadii()), paint);
908 return;
909 }
910
911 SkRect oval;
912 if (cache.sk_path.isOval(&oval)) {
913 canvas.DrawOval(skia_conversions::ToRect(oval), paint);
914 return;
915 }
916
917 canvas.DrawPath(GetOrCachePath(cache), paint);
918 }
919
920 // |flutter::DlOpReceiver|
921 void DlDispatcherBase::drawArc(const SkRect& oval_bounds,
922 SkScalar start_degrees,
923 SkScalar sweep_degrees,
924 bool use_center) {
925 PathBuilder builder;
926 builder.AddArc(skia_conversions::ToRect(oval_bounds), Degrees(start_degrees),
927 Degrees(sweep_degrees), use_center);
928 GetCanvas().DrawPath(builder.TakePath(), paint_);
929 }
930
931 // |flutter::DlOpReceiver|
932 void DlDispatcherBase::drawPoints(PointMode mode,
933 uint32_t count,
934 const SkPoint points[]) {
935 Paint paint = paint_;
936 paint.style = Paint::Style::kStroke;
937 switch (mode) {
938 case flutter::DlCanvas::PointMode::kPoints: {
939 // Cap::kButt is also treated as a square.
940 auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound
941 : PointStyle::kSquare;
942 auto radius = paint.stroke_width;
943 if (radius > 0) {
944 radius /= 2.0;
945 }
946 GetCanvas().DrawPoints(skia_conversions::ToPoints(points, count), radius,
947 paint, point_style);
948 } break;
949 case flutter::DlCanvas::PointMode::kLines:
950 for (uint32_t i = 1; i < count; i += 2) {
951 Point p0 = skia_conversions::ToPoint(points[i - 1]);
952 Point p1 = skia_conversions::ToPoint(points[i]);
953 GetCanvas().DrawLine(p0, p1, paint);
954 }
955 break;
956 case flutter::DlCanvas::PointMode::kPolygon:
957 if (count > 1) {
958 Point p0 = skia_conversions::ToPoint(points[0]);
959 for (uint32_t i = 1; i < count; i++) {
960 Point p1 = skia_conversions::ToPoint(points[i]);
961 GetCanvas().DrawLine(p0, p1, paint);
962 p0 = p1;
963 }
964 }
965 break;
966 }
967 }
968
969 // |flutter::DlOpReceiver|
970 void DlDispatcherBase::drawVertices(
971 const std::shared_ptr<flutter::DlVertices>& vertices,
972 flutter::DlBlendMode dl_mode) {
973 GetCanvas().DrawVertices(MakeVertices(vertices), ToBlendMode(dl_mode),
974 paint_);
975 }
976
977 // |flutter::DlOpReceiver|
978 void DlDispatcherBase::drawImage(const sk_sp<flutter::DlImage> image,
979 const SkPoint point,
980 flutter::DlImageSampling sampling,
981 bool render_with_attributes) {
982 if (!image) {
983 return;
984 }
985
986 auto texture = image->impeller_texture();
987 if (!texture) {
988 return;
989 }
990
991 const auto size = texture->GetSize();
992 const auto src = SkRect::MakeWH(size.width, size.height);
993 const auto dest =
994 SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);
995
996 drawImageRect(image, // image
997 src, // source rect
998 dest, // destination rect
999 sampling, // sampling options
1000 render_with_attributes, // render with attributes
1001 SrcRectConstraint::kStrict // constraint
1002 );
1003 }
1004
1005 // |flutter::DlOpReceiver|
1006 void DlDispatcherBase::drawImageRect(
1007 const sk_sp<flutter::DlImage> image,
1008 const SkRect& src,
1009 const SkRect& dst,
1010 flutter::DlImageSampling sampling,
1011 bool render_with_attributes,
1012 SrcRectConstraint constraint = SrcRectConstraint::kFast) {
1013 GetCanvas().DrawImageRect(
1014 std::make_shared<Image>(image->impeller_texture()), // image
1015 skia_conversions::ToRect(src), // source rect
1016 skia_conversions::ToRect(dst), // destination rect
1017 render_with_attributes ? paint_ : Paint(), // paint
1018 ToSamplerDescriptor(sampling) // sampling
1019 );
1020 }
1021
1022 // |flutter::DlOpReceiver|
1023 void DlDispatcherBase::drawImageNine(const sk_sp<flutter::DlImage> image,
1024 const SkIRect& center,
1025 const SkRect& dst,
1026 flutter::DlFilterMode filter,
1027 bool render_with_attributes) {
1028 NinePatchConverter converter = {};
1029 converter.DrawNinePatch(
1030 std::make_shared<Image>(image->impeller_texture()),
1031 Rect::MakeLTRB(center.fLeft, center.fTop, center.fRight, center.fBottom),
1032 skia_conversions::ToRect(dst), ToSamplerDescriptor(filter), &GetCanvas(),
1033 &paint_);
1034 }
1035
1036 // |flutter::DlOpReceiver|
1037 void DlDispatcherBase::drawAtlas(const sk_sp<flutter::DlImage> atlas,
1038 const SkRSXform xform[],
1039 const SkRect tex[],
1040 const flutter::DlColor colors[],
1041 int count,
1042 flutter::DlBlendMode mode,
1043 flutter::DlImageSampling sampling,
1044 const SkRect* cull_rect,
1045 bool render_with_attributes) {
1046 GetCanvas().DrawAtlas(std::make_shared<Image>(atlas->impeller_texture()),
1047 skia_conversions::ToRSXForms(xform, count),
1048 skia_conversions::ToRects(tex, count),
1049 ToColors(colors, count), ToBlendMode(mode),
1050 ToSamplerDescriptor(sampling),
1051 skia_conversions::ToRect(cull_rect), paint_);
1052 }
1053
1054 // |flutter::DlOpReceiver|
1055 void DlDispatcherBase::drawDisplayList(
1056 const sk_sp<flutter::DisplayList> display_list,
1057 SkScalar opacity) {
1058 // Save all values that must remain untouched after the operation.
1059 Paint saved_paint = paint_;
1060 Matrix saved_initial_matrix = initial_matrix_;
1061
1062 // Establish a new baseline for interpreting the new DL.
1063 // Matrix and clip are left untouched, the current
1064 // transform is saved as the new base matrix, and paint
1065 // values are reset to defaults.
1066 initial_matrix_ = GetCanvas().GetCurrentTransform();
1067 paint_ = Paint();
1068
1069 // Handle passed opacity in the most brute-force way by using
1070 // a SaveLayer. If the display_list is able to inherit the
1071 // opacity, this could also be handled by modulating all of its
1072 // attribute settings (for example, color), by the indicated
1073 // opacity.
1074 int restore_count = GetCanvas().GetSaveCount();
1075 if (opacity < SK_Scalar1) {
1076 Paint save_paint;
1077 save_paint.color = Color(0, 0, 0, opacity);
1078 GetCanvas().SaveLayer(
1079 save_paint, skia_conversions::ToRect(display_list->bounds()), nullptr,
1080 ContentBoundsPromise::kContainsContents, display_list->total_depth(),
1081 display_list->can_apply_group_opacity());
1082 } else {
1083 // The display list may alter the clip, which must be restored to the
1084 // current clip at the end of playback.
1085 GetCanvas().Save(display_list->total_depth());
1086 }
1087
1088 // TODO(131445): Remove this restriction if we can correctly cull with
1089 // perspective transforms.
1090 if (display_list->has_rtree() && !initial_matrix_.HasPerspective()) {
1091 // The canvas remembers the screen-space culling bounds clipped by
1092 // the surface and the history of clip calls. DisplayList can cull
1093 // the ops based on a rectangle expressed in its "destination bounds"
1094 // so we need the canvas to transform those into the current local
1095 // coordinate space into which the DisplayList will be rendered.
1096 auto cull_bounds = GetCanvas().GetCurrentLocalCullingBounds();
1097 if (cull_bounds.has_value()) {
1098 Rect cull_rect = cull_bounds.value();
1099 display_list->Dispatch(
1100 *this, SkRect::MakeLTRB(cull_rect.GetLeft(), cull_rect.GetTop(),
1101 cull_rect.GetRight(), cull_rect.GetBottom()));
1102 } else {
1103 display_list->Dispatch(*this);
1104 }
1105 } else {
1106 display_list->Dispatch(*this);
1107 }
1108
1109 // Restore all saved state back to what it was before we interpreted
1110 // the display_list
1111 GetCanvas().RestoreToCount(restore_count);
1112 initial_matrix_ = saved_initial_matrix;
1113 paint_ = saved_paint;
1114 }
1115
1116 // |flutter::DlOpReceiver|
1117 void DlDispatcherBase::drawTextBlob(const sk_sp<SkTextBlob> blob,
1118 SkScalar x,
1119 SkScalar y) {
1120 // When running with Impeller enabled Skia text blobs are converted to
1121 // Impeller text frames in paragraph_skia.cc
1122 UNIMPLEMENTED;
1123 }
1124
1125 void DlDispatcherBase::drawTextFrame(
1126 const std::shared_ptr<TextFrame>& text_frame,
1127 SkScalar x,
1128 SkScalar y) {
1129 GetCanvas().DrawTextFrame(text_frame, //
1130 impeller::Point{x, y}, //
1131 paint_ //
1132 );
1133 }
1134
1135 // |flutter::DlOpReceiver|
1136 void DlDispatcherBase::drawShadow(const SkPath& path,
1137 const flutter::DlColor color,
1138 const SkScalar elevation,
1139 bool transparent_occluder,
1140 SkScalar dpr) {
1141 UNIMPLEMENTED;
1142 }
1143
1144 // |flutter::DlOpReceiver|
1145 void DlDispatcherBase::drawShadow(const CacheablePath& cache,
1146 const flutter::DlColor color,
1147 const SkScalar elevation,
1148 bool transparent_occluder,
1149 SkScalar dpr) {
1150 Color spot_color = skia_conversions::ToColor(color);
1151 spot_color.alpha *= 0.25;
1152
1153 // Compute the spot color -- ported from SkShadowUtils::ComputeTonalColors.
1154 {
1155 Scalar max =
1156 std::max(std::max(spot_color.red, spot_color.green), spot_color.blue);
1157 Scalar min =
1158 std::min(std::min(spot_color.red, spot_color.green), spot_color.blue);
1159 Scalar luminance = (min + max) * 0.5;
1160
1161 Scalar alpha_adjust =
1162 (2.6f + (-2.66667f + 1.06667f * spot_color.alpha) * spot_color.alpha) *
1163 spot_color.alpha;
1164 Scalar color_alpha =
1165 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
1166 luminance;
1167 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
1168
1169 Scalar greyscale_alpha =
1170 std::clamp(spot_color.alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
1171
1172 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
1173 Scalar tonal_alpha = color_scale + greyscale_alpha;
1174 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
1175 spot_color = Color(unpremul_scale * spot_color.red,
1176 unpremul_scale * spot_color.green,
1177 unpremul_scale * spot_color.blue, tonal_alpha);
1178 }
1179
1180 Vector3 light_position(0, -1, 1);
1181 Scalar occluder_z = dpr * elevation;
1182
1183 constexpr Scalar kLightRadius = 800 / 600; // Light radius / light height
1184
1185 Paint paint;
1186 paint.style = Paint::Style::kFill;
1187 paint.color = spot_color;
1188 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1189 .style = FilterContents::BlurStyle::kNormal,
1190 .sigma = Radius{kLightRadius * occluder_z /
1191 GetCanvas().GetCurrentTransform().GetScale().y},
1192 };
1193
1194 GetCanvas().Save(1u);
1195 GetCanvas().PreConcat(
1196 Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y)));
1197
1198 SimplifyOrDrawPath(GetCanvas(), cache, paint);
1199
1200 GetCanvas().Restore();
1201 }
1202
1203 Picture DlDispatcherBase::EndRecordingAsPicture() {
1204 TRACE_EVENT0("impeller", "DisplayListDispatcher::EndRecordingAsPicture");
1205 return GetCanvas().EndRecordingAsPicture();
1206 }
1207
1208 /// Subclasses
1209
1210 DlDispatcher::DlDispatcher() = default;
1211
1212 DlDispatcher::DlDispatcher(IRect cull_rect) : canvas_(cull_rect) {}
1213
1214 DlDispatcher::DlDispatcher(Rect cull_rect) : canvas_(cull_rect) {}
1215
1216 Canvas& DlDispatcher::GetCanvas() {
1217 return canvas_;
1218 }
1219
1220 static bool RequiresReadbackForBlends(
1221 const ContentContext& renderer,
1222 flutter::DlBlendMode max_root_blend_mode) {
1223 return !renderer.GetDeviceCapabilities().SupportsFramebufferFetch() &&
1224 ToBlendMode(max_root_blend_mode) > Entity::kLastPipelineBlendMode;
1225 }
1226
1227 ExperimentalDlDispatcher::ExperimentalDlDispatcher(
1228 ContentContext& renderer,
1229 RenderTarget& render_target,
1230 bool has_root_backdrop_filter,
1231 flutter::DlBlendMode max_root_blend_mode,
1232 IRect cull_rect)
1233 : canvas_(renderer,
1234 render_target,
1235 has_root_backdrop_filter ||
1236 RequiresReadbackForBlends(renderer, max_root_blend_mode),
1237 cull_rect) {}
1238
1239 Canvas& ExperimentalDlDispatcher::GetCanvas() {
1240 return canvas_;
1241 }
1242
1243 //// Text Frame Dispatcher
1244
1245 TextFrameDispatcher::TextFrameDispatcher(const ContentContext& renderer,
1246 const Matrix& initial_matrix)
1247 : renderer_(renderer), matrix_(initial_matrix) {}
1248
1249 void TextFrameDispatcher::save() {
1250 stack_.emplace_back(matrix_);
1251 }
1252
1253 void TextFrameDispatcher::saveLayer(const SkRect& bounds,
1254 const flutter::SaveLayerOptions options,
1255 const flutter::DlImageFilter* backdrop) {
1256 save();
1257 }
1258
1259 void TextFrameDispatcher::restore() {
1260 matrix_ = stack_.back();
1261 stack_.pop_back();
1262 }
1263
1264 void TextFrameDispatcher::translate(SkScalar tx, SkScalar ty) {
1265 matrix_ = matrix_.Translate({tx, ty});
1266 }
1267
1268 void TextFrameDispatcher::scale(SkScalar sx, SkScalar sy) {
1269 matrix_ = matrix_.Scale({sx, sy, 1.0f});
1270 }
1271
1272 void TextFrameDispatcher::rotate(SkScalar degrees) {
1273 matrix_ = matrix_ * Matrix::MakeRotationZ(Degrees(degrees));
1274 }
1275
1276 void TextFrameDispatcher::skew(SkScalar sx, SkScalar sy) {
1277 matrix_ = matrix_ * Matrix::MakeSkew(sx, sy);
1278 }
1279
1280 // clang-format off
1281 // 2x3 2D affine subset of a 4x4 transform in row major order
1282 void TextFrameDispatcher::transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt,
1283 SkScalar myx, SkScalar myy, SkScalar myt) {
1284 matrix_ = matrix_ * Matrix::MakeColumn(
1285 mxx, myx, 0.0f, 0.0f,
1286 mxy, myy, 0.0f, 0.0f,
1287 0.0f, 0.0f, 1.0f, 0.0f,
1288 mxt, myt, 0.0f, 1.0f
1289 );
1290 }
1291
1292 // full 4x4 transform in row major order
1293 void TextFrameDispatcher::transformFullPerspective(
1294 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
1295 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
1296 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
1297 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
1298 matrix_ = matrix_ * Matrix::MakeColumn(
1299 mxx, myx, mzx, mwx,
1300 mxy, myy, mzy, mwy,
1301 mxz, myz, mzz, mwz,
1302 mxt, myt, mzt, mwt
1303 );
1304 }
1305 // clang-format on
1306
1307 void TextFrameDispatcher::transformReset() {
1308 matrix_ = Matrix();
1309 }
1310
1311 void TextFrameDispatcher::drawTextFrame(
1312 const std::shared_ptr<impeller::TextFrame>& text_frame,
1313 SkScalar x,
1314 SkScalar y) {
1315 GlyphProperties properties;
1316 if (paint_.style == Paint::Style::kStroke) {
1317 properties.stroke = true;
1318 properties.stroke_cap = paint_.stroke_cap;
1319 properties.stroke_join = paint_.stroke_join;
1320 properties.stroke_miter = paint_.stroke_miter;
1321 properties.stroke_width = paint_.stroke_width;
1322 }
1323 if (text_frame->HasColor()) {
1324 properties.color = paint_.color;
1325 }
1326 auto scale =
1327 (matrix_ * Matrix::MakeTranslation(Point(x, y))).GetMaxBasisLengthXY();
1328 renderer_.GetLazyGlyphAtlas()->AddTextFrame(*text_frame, //
1329 scale, //
1330 Point(x, y), //
1331 properties //
1332 );
1333 }
1334
1335 void TextFrameDispatcher::drawDisplayList(
1336 const sk_sp<flutter::DisplayList> display_list,
1337 SkScalar opacity) {
1338 [[maybe_unused]] size_t stack_depth = stack_.size();
1339 save();
1340 display_list->Dispatch(*this);
1341 restore();
1342 FML_DCHECK(stack_depth == stack_.size());
1343 }
1344
1345 // |flutter::DlOpReceiver|
1346 void TextFrameDispatcher::setDrawStyle(flutter::DlDrawStyle style) {
1347 paint_.style = ToStyle(style);
1348 }
1349
1350 // |flutter::DlOpReceiver|
1351 void TextFrameDispatcher::setColor(flutter::DlColor color) {
1352 paint_.color = {
1353 color.getRedF(),
1354 color.getGreenF(),
1355 color.getBlueF(),
1356 color.getAlphaF(),
1357 };
1358 }
1359
1360 // |flutter::DlOpReceiver|
1361 void TextFrameDispatcher::setStrokeWidth(SkScalar width) {
1362 paint_.stroke_width = width;
1363 }
1364
1365 // |flutter::DlOpReceiver|
1366 void TextFrameDispatcher::setStrokeMiter(SkScalar limit) {
1367 paint_.stroke_miter = limit;
1368 }
1369
1370 // |flutter::DlOpReceiver|
1371 void TextFrameDispatcher::setStrokeCap(flutter::DlStrokeCap cap) {
1372 switch (cap) {
1373 case flutter::DlStrokeCap::kButt:
1374 paint_.stroke_cap = Cap::kButt;
1375 break;
1376 case flutter::DlStrokeCap::kRound:
1377 paint_.stroke_cap = Cap::kRound;
1378 break;
1379 case flutter::DlStrokeCap::kSquare:
1380 paint_.stroke_cap = Cap::kSquare;
1381 break;
1382 }
1383 }
1384
1385 // |flutter::DlOpReceiver|
1386 void TextFrameDispatcher::setStrokeJoin(flutter::DlStrokeJoin join) {
1387 switch (join) {
1388 case flutter::DlStrokeJoin::kMiter:
1389 paint_.stroke_join = Join::kMiter;
1390 break;
1391 case flutter::DlStrokeJoin::kRound:
1392 paint_.stroke_join = Join::kRound;
1393 break;
1394 case flutter::DlStrokeJoin::kBevel:
1395 paint_.stroke_join = Join::kBevel;
1396 break;
1397 }
1398 }
1399
1400 } // namespace impeller
impeller::DlDispatcherBase::drawDRRect
void drawDRRect(const SkRRect &outer, const SkRRect &inner) override
Definition: dl_dispatcher.cc:875
impeller::Matrix::MakeSkew
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
Definition: matrix.h:117
impeller::DlDispatcherBase::translate
void translate(SkScalar tx, SkScalar ty) override
Definition: dl_dispatcher.cc:646
impeller::Paint::stroke_cap
Cap stroke_cap
Definition: paint.h:72
impeller::DlDispatcherBase::transformReset
void transformReset() override
Definition: dl_dispatcher.cc:713
impeller::DlDispatcherBase::EndRecordingAsPicture
Picture EndRecordingAsPicture()
Definition: dl_dispatcher.cc:1203
impeller::Matrix::HasPerspective
constexpr bool HasPerspective() const
Definition: matrix.h:330
impeller::Canvas::DrawPoints
void DrawPoints(std::vector< Point > points, Scalar radius, const Paint &paint, PointStyle point_style)
Definition: canvas.cc:733
impeller::Entity::ClipOperation::kIntersect
@ kIntersect
path.h
impeller::Entity::TileMode::kClamp
@ kClamp
impeller::Canvas::EndRecordingAsPicture
Picture EndRecordingAsPicture()
Definition: canvas.cc:804
impeller::Canvas::ClipOval
void ClipOval(const Rect &bounds, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:620
impeller::ColorSource::Type::kScene
@ kScene
impeller::ColorSource::Type::kLinearGradient
@ kLinearGradient
impeller::ToClipOperation
static Entity::ClipOperation ToClipOperation(flutter::DlCanvas::ClipOp clip_op)
Definition: dl_dispatcher.cc:718
impeller::Cap::kRound
@ kRound
impeller::DlDispatcherBase::drawShadow
void drawShadow(const SkPath &path, const flutter::DlColor color, const SkScalar elevation, bool transparent_occluder, SkScalar dpr) override
Definition: dl_dispatcher.cc:1136
impeller::Entity::kLastPipelineBlendMode
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:22
impeller::DlDispatcherBase::drawPoints
void drawPoints(PointMode mode, uint32_t count, const SkPoint points[]) override
Definition: dl_dispatcher.cc:932
impeller::Cap::kSquare
@ kSquare
impeller::BlendMode::kDestinationATop
@ kDestinationATop
impeller::DlDispatcher::DlDispatcher
DlDispatcher()
Subclasses.
impeller::Canvas::DrawRRect
void DrawRRect(const Rect &rect, const Size &corner_radii, const Paint &paint)
Definition: canvas.cc:540
impeller::TextFrameDispatcher::saveLayer
void saveLayer(const SkRect &bounds, const flutter::SaveLayerOptions options, const flutter::DlImageFilter *backdrop) override
Definition: dl_dispatcher.cc:1253
impeller::DlScalar
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:20
impeller::ImageFilter::MakeDilate
static std::shared_ptr< ImageFilter > MakeDilate(Radius radius_x, Radius radius_y)
Definition: image_filter.cc:29
impeller::skia_conversions::ToPoints
std::vector< Point > ToPoints(const SkPoint points[], int count)
Definition: skia_conversions.cc:45
impeller::Entity::ClipOperation::kDifference
@ kDifference
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Canvas::RestoreToCount
void RestoreToCount(size_t count)
Definition: canvas.cc:335
impeller::TextFrameDispatcher::rotate
void rotate(SkScalar degrees) override
Definition: dl_dispatcher.cc:1272
impeller::DlDispatcherBase::save
void save(uint32_t total_content_depth) override
Definition: dl_dispatcher.cc:611
impeller::Canvas::DrawImageRect
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:766
impeller::DlDispatcherBase::drawColor
void drawColor(flutter::DlColor color, flutter::DlBlendMode mode) override
Definition: dl_dispatcher.cc:790
impeller::ExperimentalDlDispatcher::ExperimentalDlDispatcher
ExperimentalDlDispatcher(ContentContext &renderer, RenderTarget &render_target, bool has_root_backdrop_filter, flutter::DlBlendMode max_root_blend_mode, IRect cull_rect)
Definition: dl_dispatcher.cc:1227
impeller::ContentBoundsPromise::kMayClipContents
@ kMayClipContents
The caller claims the bounds are a subset of an estimate of the reasonably tight bounds but likely cl...
impeller::ContentContext::GetLazyGlyphAtlas
const std::shared_ptr< LazyGlyphAtlas > & GetLazyGlyphAtlas() const
Definition: content_context.h:720
impeller::skia_conversions::IsNearlySimpleRRect
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.
Definition: skia_conversions.cc:12
impeller::TextFrameDispatcher::setDrawStyle
void setDrawStyle(flutter::DlDrawStyle style) override
Definition: dl_dispatcher.cc:1346
impeller::ColorSource::Type::kRadialGradient
@ kRadialGradient
impeller::kMaxCullRect
static constexpr SkRect kMaxCullRect
Definition: dl_dispatcher.cc:615
impeller::GlyphProperties
Definition: font_glyph_pair.h:19
impeller::Paint::Style::kStroke
@ kStroke
impeller::TextFrameDispatcher::setStrokeJoin
void setStrokeJoin(flutter::DlStrokeJoin join) override
Definition: dl_dispatcher.cc:1386
impeller::skia_conversions::ConvertStops
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...
Definition: skia_conversions.cc:212
entity.h
impeller::ColorSource::MakeLinearGradient
static ColorSource MakeLinearGradient(Point start_point, Point end_point, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:166
impeller::Paint
Definition: paint.h:23
impeller::FillType::kOdd
@ kOdd
impeller::DlDispatcherBase::setStrokeCap
void setStrokeCap(flutter::DlStrokeCap cap) override
Definition: dl_dispatcher.cc:216
impeller::skia_conversions::ToSize
Size ToSize(const SkPoint &point)
Definition: skia_conversions.cc:158
impeller::Canvas::Skew
void Skew(Scalar sx, Scalar sy)
Definition: canvas.cc:323
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::FilterContents::BlurStyle
BlurStyle
Definition: filter_contents.h:26
impeller::Color
Definition: color.h:124
impeller::ToImageFilter
static std::shared_ptr< ImageFilter > ToImageFilter(const flutter::DlImageFilter *filter)
Definition: dl_dispatcher.cc:515
impeller::TextFrameDispatcher::transform2DAffine
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
Definition: dl_dispatcher.cc:1282
impeller::TextFrameDispatcher::restore
void restore() override
Definition: dl_dispatcher.cc:1259
impeller::BlendMode::kLuminosity
@ kLuminosity
impeller::Paint::color
Color color
Definition: paint.h:68
impeller::Entity::TileMode::kDecal
@ kDecal
impeller::BlendMode::kSource
@ kSource
impeller::TextFrameDispatcher::save
void save() override
Definition: dl_dispatcher.cc:1249
impeller::BlendMode::kColorDodge
@ kColorDodge
impeller::Canvas::DrawTextFrame
virtual void DrawTextFrame(const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint)
Definition: canvas.cc:884
impeller::BlendMode::kDestination
@ kDestination
dl_dispatcher.h
impeller::Canvas
Definition: canvas.h:60
impeller::BlendMode::kDarken
@ kDarken
impeller::PathBuilder::AddPath
PathBuilder & AddPath(const Path &path)
Definition: path_builder.cc:430
formats.h
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Paint::MaskBlurDescriptor::style
FilterContents::BlurStyle style
Definition: paint.h:49
impeller::PointStyle::kRound
@ kRound
Points are drawn as squares.
impeller::Vector2
Point Vector2
Definition: point.h:326
impeller::Canvas::ResetTransform
void ResetTransform()
Definition: canvas.cc:290
impeller::Canvas::DrawVertices
void DrawVertices(const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
Definition: canvas.cc:933
impeller::BlendMode::kColor
@ kColor
impeller::DlDispatcherBase::transform2DAffine
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
Definition: dl_dispatcher.cc:666
impeller::skia_conversions::ToRects
std::vector< Rect > ToRects(const SkRect tex[], int count)
Definition: skia_conversions.cc:37
impeller::NinePatchConverter::DrawNinePatch
void DrawNinePatch(const std::shared_ptr< Image > &image, Rect center, Rect dst, const SamplerDescriptor &sampler, Canvas *canvas, Paint *paint)
Definition: nine_patch_converter.cc:60
impeller::Color::alpha
Scalar alpha
Definition: color.h:143
impeller::ImageFilter::MakeBlur
static std::shared_ptr< ImageFilter > MakeBlur(Sigma sigma_x, Sigma sigma_y, FilterContents::BlurStyle blur_style, Entity::TileMode tile_mode)
Definition: image_filter.cc:20
impeller::BlendMode::kDestinationOver
@ kDestinationOver
impeller::BlendMode::kPlus
@ kPlus
impeller::Paint::MaskBlurDescriptor
Definition: paint.h:48
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:162
impeller::ColorSource::MakeSweepGradient
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)
Definition: color_source.cc:210
impeller::TextFrameDispatcher::setStrokeCap
void setStrokeCap(flutter::DlStrokeCap cap) override
Definition: dl_dispatcher.cc:1371
impeller::BlendMode::kOverlay
@ kOverlay
impeller::DlDispatcherBase::setColorFilter
void setColorFilter(const flutter::DlColorFilter *filter) override
Definition: dl_dispatcher.cc:467
impeller::ColorSource::MakeColor
static ColorSource MakeColor()
Definition: color_source.cc:162
impeller::GlyphProperties::stroke_miter
Scalar stroke_miter
Definition: font_glyph_pair.h:24
impeller::ColorSource::MakeImage
static ColorSource MakeImage(std::shared_ptr< Texture > texture, Entity::TileMode x_tile_mode, Entity::TileMode y_tile_mode, SamplerDescriptor sampler_descriptor, Matrix effect_transform)
Definition: color_source.cc:225
impeller::FilterContents::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.
impeller::TextFrameDispatcher::TextFrameDispatcher
TextFrameDispatcher(const ContentContext &renderer, const Matrix &initial_matrix)
Definition: dl_dispatcher.cc:1245
impeller::DlDispatcherBase::transformFullPerspective
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
Definition: dl_dispatcher.cc:683
impeller::Cap::kButt
@ kButt
impeller::TextFrameDispatcher::transformFullPerspective
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
Definition: dl_dispatcher.cc:1293
impeller::Entity::TileMode::kRepeat
@ kRepeat
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Canvas::DrawLine
void DrawLine(const Point &p0, const Point &p1, const Paint &paint)
Definition: canvas.cc:485
impeller::DlDispatcherBase::clipRect
void clipRect(const SkRect &rect, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:729
impeller::Paint::color_source
ColorSource color_source
Definition: paint.h:69
impeller::Color::green
Scalar green
Definition: color.h:133
impeller::Canvas::DrawRect
void DrawRect(const Rect &rect, const Paint &paint)
Definition: canvas.cc:495
impeller::Canvas::GetCurrentTransform
const Matrix & GetCurrentTransform() const
Definition: canvas.cc:298
UNIMPLEMENTED
#define UNIMPLEMENTED
Definition: dl_dispatcher.cc:39
impeller::GlyphProperties::color
Color color
Definition: font_glyph_pair.h:20
impeller::ToTileMode
static Entity::TileMode ToTileMode(flutter::DlTileMode tile_mode)
Definition: dl_dispatcher.cc:106
impeller::BlendMode::kModulate
@ kModulate
impeller::DlDispatcherBase::drawImageRect
void drawImageRect(const sk_sp< flutter::DlImage > image, const SkRect &src, const SkRect &dst, flutter::DlImageSampling sampling, bool render_with_attributes, SrcRectConstraint constraint) override
Definition: dl_dispatcher.cc:1006
impeller::DlDispatcherBase::drawOval
void drawOval(const SkRect &bounds) override
Definition: dl_dispatcher.cc:854
impeller::Join::kMiter
@ kMiter
runtime_effect_contents.h
impeller::BlendMode::kSourceOut
@ kSourceOut
impeller::DlDispatcherBase::drawVertices
void drawVertices(const std::shared_ptr< flutter::DlVertices > &vertices, flutter::DlBlendMode dl_mode) override
Definition: dl_dispatcher.cc:970
impeller::ImageFilter::MakeFromColorFilter
static std::shared_ptr< ImageFilter > MakeFromColorFilter(const ColorFilter &color_filter)
Definition: image_filter.cc:52
impeller::BlendMode::kSaturation
@ kSaturation
impeller::Entity::TileMode::kMirror
@ kMirror
impeller::Paint::stroke_miter
Scalar stroke_miter
Definition: paint.h:74
impeller::BlendMode::kDifference
@ kDifference
impeller::ToMatrix
static Matrix ToMatrix(const SkMatrix &m)
Definition: dl_dispatcher.cc:161
path_builder.h
impeller::ToColors
static std::vector< Color > ToColors(const flutter::DlColor colors[], int count)
Definition: dl_dispatcher.cc:245
impeller::MinMagFilter::kNearest
@ kNearest
Select nearest to the sample point. Most widely supported.
impeller::TextFrameDispatcher::setColor
void setColor(flutter::DlColor color) override
Definition: dl_dispatcher.cc:1351
impeller::SamplerDescriptor::mag_filter
MinMagFilter mag_filter
Definition: sampler_descriptor.h:17
impeller::skia_conversions::ToRect
Rect ToRect(const SkRect &rect)
Definition: skia_conversions.cc:26
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::BlendMode::kLighten
@ kLighten
impeller::Paint::color_filter
std::shared_ptr< ColorFilter > color_filter
Definition: paint.h:80
impeller::Picture
Definition: picture.h:17
impeller::DlDispatcherBase::drawTextBlob
void drawTextBlob(const sk_sp< SkTextBlob > blob, SkScalar x, SkScalar y) override
Definition: dl_dispatcher.cc:1117
impeller::PointStyle::kSquare
@ kSquare
Points are drawn as circles.
impeller::SamplerDescriptor::min_filter
MinMagFilter min_filter
Definition: sampler_descriptor.h:16
impeller::BlendMode::kSoftLight
@ kSoftLight
impeller::Point
TPoint< Scalar > Point
Definition: point.h:322
impeller::DlDispatcherBase::drawRRect
void drawRRect(const SkRRect &rrect) override
Definition: dl_dispatcher.cc:864
filter_contents.h
impeller::DlDispatcherBase::drawArc
void drawArc(const SkRect &oval_bounds, SkScalar start_degrees, SkScalar sweep_degrees, bool use_center) override
Definition: dl_dispatcher.cc:921
impeller::BlendMode::kColorBurn
@ kColorBurn
impeller::TRect::GetLeft
constexpr auto GetLeft() const
Definition: rect.h:341
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:315
scene_contents.h
skia_conversions.h
impeller::DlDispatcherBase::setImageFilter
void setImageFilter(const flutter::DlImageFilter *filter) override
Definition: dl_dispatcher.cc:606
impeller::BlendMode::kHardLight
@ kHardLight
sigma.h
impeller::DlDispatcherBase::clipPath
void clipPath(const SkPath &path, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:755
impeller::DlDispatcherBase::setColorSource
void setColorSource(const flutter::DlColorSource *source) override
Definition: dl_dispatcher.cc:281
impeller::Radius
For convolution filters, the "radius" is the size of the convolution kernel to use on the local space...
Definition: sigma.h:48
impeller::FilterContents::BlurStyle::kSolid
@ kSolid
Solid inside, blurred outside.
impeller::DlDispatcherBase::setDrawStyle
void setDrawStyle(flutter::DlDrawStyle style) override
Definition: dl_dispatcher.cc:191
impeller::Matrix::GetScale
constexpr Vector3 GetScale() const
Definition: matrix.h:311
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
impeller::ColorSource::MakeConicalGradient
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)
Definition: color_source.cc:180
impeller::ColorFilter::MakeBlend
static std::shared_ptr< ColorFilter > MakeBlend(BlendMode blend_mode, Color color)
Definition: color_filter.cc:23
impeller::DlDispatcherBase::setStrokeJoin
void setStrokeJoin(flutter::DlStrokeJoin join) override
Definition: dl_dispatcher.cc:231
impeller::ColorSource::Type::kRuntimeEffect
@ kRuntimeEffect
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:231
impeller::TextFrameDispatcher::transformReset
void transformReset() override
Definition: dl_dispatcher.cc:1307
impeller::BlendMode::kClear
@ kClear
impeller::DlDispatcherBase::drawPath
void drawPath(const SkPath &path) override
Definition: dl_dispatcher.cc:883
impeller::DlDispatcherBase::drawImageNine
void drawImageNine(const sk_sp< flutter::DlImage > image, const SkIRect &center, const SkRect &dst, flutter::DlFilterMode filter, bool render_with_attributes) override
Definition: dl_dispatcher.cc:1023
impeller::MinMagFilter::kLinear
@ kLinear
impeller::Paint::style
Style style
Definition: paint.h:75
impeller::ImageFilter::MakeLocalMatrix
static std::shared_ptr< ImageFilter > MakeLocalMatrix(const Matrix &matrix, const ImageFilter &internal_filter)
Definition: image_filter.cc:57
impeller::Paint::Style::kFill
@ kFill
impeller::ToColorSourceType
static std::optional< ColorSource::Type > ToColorSourceType(flutter::DlColorSourceType type)
Definition: dl_dispatcher.cc:256
impeller::ColorMatrix::array
Scalar array[20]
Definition: color.h:118
impeller::Canvas::DrawCircle
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition: canvas.cc:566
impeller::ToStyle
static Paint::Style ToStyle(flutter::DlDrawStyle style)
Definition: dl_dispatcher.cc:177
impeller::Matrix::Translate
constexpr Matrix Translate(const Vector3 &t) const
Definition: matrix.h:240
impeller::Color::red
Scalar red
Definition: color.h:128
impeller::DlDispatcherBase::drawImage
void drawImage(const sk_sp< flutter::DlImage > image, const SkPoint point, flutter::DlImageSampling sampling, bool render_with_attributes) override
Definition: dl_dispatcher.cc:978
font_glyph_pair.h
impeller::PathBuilder::LineTo
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:52
impeller::DlDispatcherBase::skew
void skew(SkScalar sx, SkScalar sy) override
Definition: dl_dispatcher.cc:661
type
GLenum type
Definition: blit_command_gles.cc:126
impeller::Sigma
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
impeller::Matrix::MakeColumn
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
impeller::DlDispatcherBase::saveLayer
void saveLayer(const SkRect &bounds, const flutter::SaveLayerOptions &options, uint32_t total_content_depth, flutter::DlBlendMode max_content_mode, const flutter::DlImageFilter *backdrop) override
Definition: dl_dispatcher.cc:619
impeller::DlDispatcherBase::setAntiAlias
void setAntiAlias(bool aa) override
Definition: dl_dispatcher.cc:173
impeller::Canvas::Restore
virtual bool Restore()
Definition: canvas.cc:257
impeller::ImageFilter::MakeErode
static std::shared_ptr< ImageFilter > MakeErode(Radius radius_x, Radius radius_y)
Definition: image_filter.cc:34
impeller::Canvas::DrawAtlas
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:1027
impeller::DlDispatcherBase::setStrokeMiter
void setStrokeMiter(SkScalar limit) override
Definition: dl_dispatcher.cc:211
impeller::DlDispatcherBase::setStrokeWidth
void setStrokeWidth(SkScalar width) override
Definition: dl_dispatcher.cc:206
impeller::RenderTarget
Definition: render_target.h:38
impeller::GlyphProperties::stroke_join
Join stroke_join
Definition: font_glyph_pair.h:23
impeller::Canvas::DrawPath
void DrawPath(const Path &path, const Paint &paint)
Definition: canvas.cc:343
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:22
impeller::DlDispatcherBase::drawLine
void drawLine(const SkPoint &p0, const SkPoint &p1) override
Definition: dl_dispatcher.cc:804
impeller::Canvas::DrawPaint
void DrawPaint(const Paint &paint)
Definition: canvas.cc:352
impeller::GlyphProperties::stroke
bool stroke
Definition: font_glyph_pair.h:25
filter_input.h
impeller::NinePatchConverter
Definition: nine_patch_converter.h:18
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:21
impeller::ToBlurStyle
static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style)
Definition: dl_dispatcher.cc:481
impeller::Canvas::GetSaveCount
size_t GetSaveCount() const
Definition: canvas.cc:331
impeller::Join::kRound
@ kRound
impeller::Vector3::y
Scalar y
Definition: vector.h:24
impeller::FilterContents::BlurStyle::kInner
@ kInner
Blurred inside, nothing outside.
impeller::DlDispatcherBase::GetCanvas
virtual Canvas & GetCanvas()=0
impeller::skia_conversions::ToPoint
Point ToPoint(const SkPoint &point)
Definition: skia_conversions.cc:154
impeller::Entity::TileMode
TileMode
Definition: entity.h:42
impeller::SamplerDescriptor::mip_filter
MipFilter mip_filter
Definition: sampler_descriptor.h:18
impeller::ColorSource::MakeRadialGradient
static ColorSource MakeRadialGradient(Point center, Scalar radius, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:196
impeller::GlyphProperties::stroke_width
Scalar stroke_width
Definition: font_glyph_pair.h:21
impeller::ImageFilter::MakeMatrix
static std::shared_ptr< ImageFilter > MakeMatrix(const Matrix &matrix, SamplerDescriptor sampler_descriptor)
Definition: image_filter.cc:39
dl_vertices_geometry.h
impeller::DlDispatcherBase::clipRRect
void clipRRect(const SkRRect &rrect, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:737
impeller::TextFrameDispatcher::drawDisplayList
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, SkScalar opacity) override
Definition: dl_dispatcher.cc:1335
impeller::ColorFilter::MakeMatrix
static std::shared_ptr< ColorFilter > MakeMatrix(ColorMatrix color_matrix)
Definition: color_filter.cc:28
impeller::Canvas::ClipRRect
void ClipRRect(const Rect &rect, const Size &corner_radii, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:640
scalar.h
impeller::DlDispatcherBase::drawDashedLine
void drawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length) override
Definition: dl_dispatcher.cc:809
impeller::Canvas::PreConcat
void PreConcat(const Matrix &transform)
Definition: canvas.cc:286
impeller::TextFrameDispatcher::drawTextFrame
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, SkScalar x, SkScalar y) override
Definition: dl_dispatcher.cc:1311
impeller::ImageFilter::MakeCompose
static std::shared_ptr< ImageFilter > MakeCompose(const ImageFilter &inner, const ImageFilter &outer)
Definition: image_filter.cc:46
impeller::BlendMode::kDestinationIn
@ kDestinationIn
impeller::Join::kBevel
@ kBevel
impeller::ColorSource::Type::kImage
@ kImage
impeller::ColorSource::MakeRuntimeEffect
static ColorSource MakeRuntimeEffect(std::shared_ptr< RuntimeStage > runtime_stage, std::shared_ptr< std::vector< uint8_t >> uniform_data, std::vector< RuntimeEffectContents::TextureInput > texture_inputs)
Definition: color_source.cc:238
impeller::Canvas::DrawOval
void DrawOval(const Rect &rect, const Paint &paint)
Definition: canvas.cc:514
impeller::BlendMode::kExclusion
@ kExclusion
content_context.h
impeller::BlendMode::kDestinationOut
@ kDestinationOut
impeller::TextFrameDispatcher::setStrokeMiter
void setStrokeMiter(SkScalar limit) override
Definition: dl_dispatcher.cc:1366
impeller::FilterContents::BlurStyle::kOuter
@ kOuter
Nothing inside, blurred outside.
impeller::TRect::GetRight
constexpr auto GetRight() const
Definition: rect.h:345
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:213
impeller::DlDispatcherBase::setBlendMode
void setBlendMode(flutter::DlBlendMode mode) override
Definition: dl_dispatcher.cc:477
impeller::ContentContext::GetDeviceCapabilities
const Capabilities & GetDeviceCapabilities() const
Definition: content_context.cc:557
impeller::GlyphProperties::stroke_cap
Cap stroke_cap
Definition: font_glyph_pair.h:22
impeller::Canvas::Rotate
void Rotate(Radians radians)
Definition: canvas.cc:327
impeller::ColorSource::Type::kConicalGradient
@ kConicalGradient
impeller::MipFilter::kBase
@ kBase
The texture is sampled as if it only had a single mipmap level.
impeller::ColorFilter::MakeLinearToSrgb
static std::shared_ptr< ColorFilter > MakeLinearToSrgb()
Definition: color_filter.cc:36
impeller::TPoint< Scalar >
impeller::Canvas::Transform
void Transform(const Matrix &transform)
Definition: canvas.cc:294
impeller::PathBuilder::MoveTo
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:33
impeller::skia_conversions::ToRSXForms
std::vector< Matrix > ToRSXForms(const SkRSXform xform[], int count)
Definition: skia_conversions.cc:171
impeller::Paint::invert_colors
bool invert_colors
Definition: paint.h:77
impeller::Canvas::Save
virtual void Save(uint32_t total_content_depth=kMaxDepth)
Definition: canvas.cc:184
impeller::TextFrameDispatcher::setStrokeWidth
void setStrokeWidth(SkScalar width) override
Definition: dl_dispatcher.cc:1361
impeller::MipFilter::kLinear
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
impeller::Canvas::GetCurrentLocalCullingBounds
const std::optional< Rect > GetCurrentLocalCullingBounds() const
Definition: canvas.cc:302
impeller::BlendMode::kSourceIn
@ kSourceIn
impeller::DlDispatcherBase::drawRect
void drawRect(const SkRect &rect) override
Definition: dl_dispatcher.cc:849
impeller::DlDispatcherBase::setColor
void setColor(flutter::DlColor color) override
Definition: dl_dispatcher.cc:196
impeller::BlendMode::kScreen
@ kScreen
paint
const Paint & paint
Definition: color_source.cc:38
impeller::SamplerDescriptor::label
std::string label
Definition: sampler_descriptor.h:24
impeller::Entity::ClipOperation
ClipOperation
Definition: entity.h:61
impeller::ToBlendMode
static BlendMode ToBlendMode(flutter::DlBlendMode mode)
Definition: dl_dispatcher.cc:42
impeller::TRect::GetBottom
constexpr auto GetBottom() const
Definition: rect.h:347
impeller::Degrees
Definition: scalar.h:46
color.h
color_filter.h
impeller::DlDispatcherBase::drawAtlas
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
Definition: dl_dispatcher.cc:1037
impeller::Paint::Style
Style
Definition: paint.h:43
color
DlColor color
Definition: dl_golden_blur_unittests.cc:23
impeller::BlendMode::kHue
@ kHue
impeller::Canvas::ClipRect
void ClipRect(const Rect &rect, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:599
impeller::ToSamplerDescriptor
static impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
Definition: dl_dispatcher.cc:119
impeller::DlDispatcherBase::restore
void restore() override
Definition: dl_dispatcher.cc:641
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::DlDispatcherBase::drawPaint
void drawPaint() override
Definition: dl_dispatcher.cc:799
impeller::TextFrameDispatcher::scale
void scale(SkScalar sx, SkScalar sy) override
Definition: dl_dispatcher.cc:1268
impeller::ToColorFilter
static std::shared_ptr< ColorFilter > ToColorFilter(const flutter::DlColorFilter *filter)
Definition: dl_dispatcher.cc:440
impeller::DlDispatcherBase::drawDisplayList
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, SkScalar opacity) override
Definition: dl_dispatcher.cc:1055
impeller::DlDispatcherBase::drawTextFrame
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, SkScalar x, SkScalar y) override
Definition: dl_dispatcher.cc:1125
impeller::TextFrameDispatcher::translate
void translate(SkScalar tx, SkScalar ty) override
Definition: dl_dispatcher.cc:1264
impeller::ColorFilter::MakeSrgbToLinear
static std::shared_ptr< ColorFilter > MakeSrgbToLinear()
Definition: color_filter.cc:32
nine_patch_converter.h
impeller::BlendMode::kXor
@ kXor
impeller::TextFrameDispatcher::skew
void skew(SkScalar sx, SkScalar sy) override
Definition: dl_dispatcher.cc:1276
impeller::Color::blue
Scalar blue
Definition: color.h:138
impeller::ColorSource::Type::kSweepGradient
@ kSweepGradient
impeller::DlDispatcherBase::setMaskFilter
void setMaskFilter(const flutter::DlMaskFilter *filter) override
Definition: dl_dispatcher.cc:495
impeller::ColorMatrix
Definition: color.h:117
impeller::Capabilities::SupportsFramebufferFetch
virtual bool SupportsFramebufferFetch() const =0
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
impeller::ContentBoundsPromise::kContainsContents
@ kContainsContents
The caller claims the bounds are a reasonably tight estimate of the coverage of the contents and shou...
impeller::DlDispatcherBase::setInvertColors
void setInvertColors(bool invert) override
Definition: dl_dispatcher.cc:472
impeller
Definition: aiks_blend_unittests.cc:18
impeller::BlendMode::kSourceATop
@ kSourceATop
impeller::Paint::mask_blur_descriptor
std::optional< MaskBlurDescriptor > mask_blur_descriptor
Definition: paint.h:81
impeller::BlendMode::kMultiply
@ kMultiply
impeller::ContentContext
Definition: content_context.h:366
impeller::TRect::GetTop
constexpr auto GetTop() const
Definition: rect.h:343
impeller::Paint::stroke_width
Scalar stroke_width
Definition: paint.h:71
impeller::skia_conversions::ToPath
Path ToPath(const SkPath &path, Point shift)
Definition: skia_conversions.cc:63
impeller::Canvas::SaveLayer
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, bool can_distribute_opacity=false)
Definition: canvas.cc:842
impeller::ColorSource::Type::kColor
@ kColor
impeller::MakeVertices
std::shared_ptr< impeller::VerticesGeometry > MakeVertices(const std::shared_ptr< const flutter::DlVertices > &vertices)
Definition: dl_vertices_geometry.cc:31
impeller::TRect< Scalar >
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::PathBuilder::AddArc
PathBuilder & AddArc(const Rect &oval_bounds, Radians start, Radians sweep, bool use_center=false)
Definition: path_builder.cc:318
impeller::Vector3
Definition: vector.h:20
impeller::RequiresReadbackForBlends
static bool RequiresReadbackForBlends(const ContentContext &renderer, flutter::DlBlendMode max_root_blend_mode)
Definition: dl_dispatcher.cc:1220
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::Paint::blend_mode
BlendMode blend_mode
Definition: paint.h:76
impeller::Matrix::Scale
constexpr Matrix Scale(const Vector3 &s) const
Definition: matrix.h:252
impeller::Paint::image_filter
std::shared_ptr< ImageFilter > image_filter
Definition: paint.h:79
impeller::DlDispatcherBase::drawCircle
void drawCircle(const SkPoint &center, SkScalar radius) override
Definition: dl_dispatcher.cc:859
impeller::Paint::stroke_join
Join stroke_join
Definition: paint.h:73
impeller::DlDispatcherBase::rotate
void rotate(SkScalar degrees) override
Definition: dl_dispatcher.cc:656
impeller::Canvas::Translate
void Translate(const Vector3 &offset)
Definition: canvas.cc:311
impeller::Canvas::ClipPath
void ClipPath(const Path &path, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:589
impeller::DlDispatcherBase::scale
void scale(SkScalar sx, SkScalar sy) override
Definition: dl_dispatcher.cc:651