| 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 "display_list/effects/dl_color_source.h"
15 #include "flutter/fml/logging.h"
16 #include "impeller/core/formats.h"
17 #include "impeller/display_list/aiks_context.h"
18 #include "impeller/display_list/color_filter.h"
19 #include "impeller/display_list/dl_atlas_geometry.h"
20 #include "impeller/display_list/dl_vertices_geometry.h"
21 #include "impeller/display_list/nine_patch_converter.h"
22 #include "impeller/display_list/skia_conversions.h"
23 #include "impeller/entity/contents/atlas_contents.h"
24 #include "impeller/entity/contents/content_context.h"
25 #include "impeller/entity/contents/filters/filter_contents.h"
26 #include "impeller/entity/contents/filters/inputs/filter_input.h"
27 #include "impeller/entity/entity.h"
28 #include "impeller/entity/geometry/geometry.h"
29 #include "impeller/geometry/color.h"
30 #include "impeller/geometry/path.h"
31 #include "impeller/geometry/path_builder.h"
32 #include "impeller/geometry/scalar.h"
33 #include "impeller/geometry/sigma.h"
34 #include "impeller/typographer/font_glyph_pair.h"
35
36 namespace impeller {
37
38 #if !defined(NDEBUG)
39 #define USE_DEPTH_WATCHER true
40 #else
41 #define USE_DEPTH_WATCHER false
42 #endif // !defined(NDEBUG)
43
44 #if USE_DEPTH_WATCHER
45
46 // Invoke this macro at the top of any DlOpReceiver dispatch function
47 // using a number indicating the maximum depth that the operation is
48 // expected to consume in the Canvas. Most rendering ops consume 1
49 // except for DrawImageNine that currently consumes 1 per section (i.e. 9).
50 // Attribute, clip and transform ops do not consume depth but this
51 // macro can still be used with an argument of 0 to verify that expectation.
52 //
53 // The watchdog object allocated here will automatically double-check
54 // the depth usage at any exit point to the function, or any other
55 // point at which it falls out of scope.
56 #define AUTO_DEPTH_WATCHER(d) \
57 DepthWatcher _watcher(__FILE__, __LINE__, GetCanvas(), \
58 paint_.mask_blur_descriptor.has_value(), d)
59
60 // While the AUTO_DEPTH_WATCHER macro will check the depth usage at
61 // any exit point from the dispatch function, sometimes the dispatch
62 // functions are somewhat compounded and result in multiple Canvas
63 // calls.
64 //
65 // Invoke this macro at any key points in the middle of a dispatch
66 // function to verify that you still haven't exceeded the maximum
67 // allowed depth. This is especially useful if the function does
68 // an implicit save/restore where the restore call might assert the
69 // depth constraints in a function in Canvas that can't be as easily
70 // traced back to a given dispatch function as these macros can.
71 #define AUTO_DEPTH_CHECK() _watcher.check(__FILE__, __LINE__)
72
73 // Helper class, use the AUTO_DEPTH_WATCHER macros to access it
74 struct DepthWatcher {
75 DepthWatcher(const std::string& file,
76 int line,
77 const impeller::Canvas& canvas,
78 bool has_mask_blur,
79 int allowed)
80 : file_(file),
81 line_(line),
82 canvas_(canvas),
83 allowed_(has_mask_blur ? allowed + 1 : allowed),
84 old_depth_(canvas.GetOpDepth()),
85 old_max_(canvas.GetMaxOpDepth()) {}
86
87 ~DepthWatcher() { check(file_, line_); }
88
89 void check(const std::string& file, int line) {
90 FML_CHECK(canvas_.GetOpDepth() <= (old_depth_ + allowed_) &&
91 canvas_.GetOpDepth() <= old_max_)
92 << std::endl
93 << "from " << file << ":" << line << std::endl
94 << "old/allowed/current/max = " << old_depth_ << "/" << allowed_ << "/"
95 << canvas_.GetOpDepth() << "/" << old_max_;
96 }
97
98 private:
99 const std::string file_;
100 const int line_;
101
102 const impeller::Canvas& canvas_;
103 const uint64_t allowed_;
104 const uint64_t old_depth_;
105 const uint64_t old_max_;
106 };
107
108 #else // USE_DEPTH_WATCHER
109
110 #define AUTO_DEPTH_WATCHER(d)
111 #define AUTO_DEPTH_CHECK()
112
113 #endif // USE_DEPTH_WATCHER
114
115 #define UNIMPLEMENTED \
116 FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
117
118 static impeller::SamplerDescriptor ToSamplerDescriptor(
119 const flutter::DlFilterMode options) {
120 impeller::SamplerDescriptor desc;
121 switch (options) {
122 case flutter::DlFilterMode::kNearest:
123 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
124 desc.label = "Nearest Sampler";
125 break;
126 case flutter::DlFilterMode::kLinear:
127 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
128 desc.label = "Linear Sampler";
129 break;
130 default:
131 break;
132 }
133 return desc;
134 }
135
136 // |flutter::DlOpReceiver|
137 void DlDispatcherBase::setAntiAlias(bool aa) {
138 AUTO_DEPTH_WATCHER(0u);
139
140 // Nothing to do because AA is implicit.
141 }
142
143 static Paint::Style ToStyle(flutter::DlDrawStyle style) {
144 switch (style) {
145 case flutter::DlDrawStyle::kFill:
146 return Paint::Style::kFill;
147 case flutter::DlDrawStyle::kStroke:
148 return Paint::Style::kStroke;
149 case flutter::DlDrawStyle::kStrokeAndFill:
150 UNIMPLEMENTED;
151 break;
152 }
153 return Paint::Style::kFill;
154 }
155
156 // |flutter::DlOpReceiver|
157 void DlDispatcherBase::setDrawStyle(flutter::DlDrawStyle style) {
158 AUTO_DEPTH_WATCHER(0u);
159
160 paint_.style = ToStyle(style);
161 }
162
163 // |flutter::DlOpReceiver|
164 void DlDispatcherBase::setColor(flutter::DlColor color) {
165 AUTO_DEPTH_WATCHER(0u);
166
167 paint_.color = skia_conversions::ToColor(color);
168 }
169
170 // |flutter::DlOpReceiver|
171 void DlDispatcherBase::setStrokeWidth(DlScalar width) {
172 AUTO_DEPTH_WATCHER(0u);
173
174 paint_.stroke_width = width;
175 }
176
177 // |flutter::DlOpReceiver|
178 void DlDispatcherBase::setStrokeMiter(DlScalar limit) {
179 AUTO_DEPTH_WATCHER(0u);
180
181 paint_.stroke_miter = limit;
182 }
183
184 // |flutter::DlOpReceiver|
185 void DlDispatcherBase::setStrokeCap(flutter::DlStrokeCap cap) {
186 AUTO_DEPTH_WATCHER(0u);
187
188 switch (cap) {
189 case flutter::DlStrokeCap::kButt:
190 paint_.stroke_cap = Cap::kButt;
191 break;
192 case flutter::DlStrokeCap::kRound:
193 paint_.stroke_cap = Cap::kRound;
194 break;
195 case flutter::DlStrokeCap::kSquare:
196 paint_.stroke_cap = Cap::kSquare;
197 break;
198 }
199 }
200
201 // |flutter::DlOpReceiver|
202 void DlDispatcherBase::setStrokeJoin(flutter::DlStrokeJoin join) {
203 AUTO_DEPTH_WATCHER(0u);
204
205 switch (join) {
206 case flutter::DlStrokeJoin::kMiter:
207 paint_.stroke_join = Join::kMiter;
208 break;
209 case flutter::DlStrokeJoin::kRound:
210 paint_.stroke_join = Join::kRound;
211 break;
212 case flutter::DlStrokeJoin::kBevel:
213 paint_.stroke_join = Join::kBevel;
214 break;
215 }
216 }
217
218 // |flutter::DlOpReceiver|
219 void DlDispatcherBase::setColorSource(const flutter::DlColorSource* source) {
220 AUTO_DEPTH_WATCHER(0u);
221
222 if (!source || source->type() == flutter::DlColorSourceType::kColor) {
223 paint_.color_source = nullptr;
224 } else {
225 paint_.color_source = source;
226 }
227 }
228
229 // |flutter::DlOpReceiver|
230 void DlDispatcherBase::setColorFilter(const flutter::DlColorFilter* filter) {
231 AUTO_DEPTH_WATCHER(0u);
232
233 paint_.color_filter = filter;
234 }
235
236 // |flutter::DlOpReceiver|
237 void DlDispatcherBase::setInvertColors(bool invert) {
238 AUTO_DEPTH_WATCHER(0u);
239
240 paint_.invert_colors = invert;
241 }
242
243 // |flutter::DlOpReceiver|
244 void DlDispatcherBase::setBlendMode(flutter::DlBlendMode dl_mode) {
245 AUTO_DEPTH_WATCHER(0u);
246
247 paint_.blend_mode = skia_conversions::ToBlendMode(dl_mode);
248 }
249
250 static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style) {
251 switch (blur_style) {
252 case flutter::DlBlurStyle::kNormal:
253 return FilterContents::BlurStyle::kNormal;
254 case flutter::DlBlurStyle::kSolid:
255 return FilterContents::BlurStyle::kSolid;
256 case flutter::DlBlurStyle::kOuter:
257 return FilterContents::BlurStyle::kOuter;
258 case flutter::DlBlurStyle::kInner:
259 return FilterContents::BlurStyle::kInner;
260 }
261 }
262
263 // |flutter::DlOpReceiver|
264 void DlDispatcherBase::setMaskFilter(const flutter::DlMaskFilter* filter) {
265 AUTO_DEPTH_WATCHER(0u);
266
267 // Needs https://github.com/flutter/flutter/issues/95434
268 if (filter == nullptr) {
269 paint_.mask_blur_descriptor = std::nullopt;
270 return;
271 }
272 switch (filter->type()) {
273 case flutter::DlMaskFilterType::kBlur: {
274 auto blur = filter->asBlur();
275
276 paint_.mask_blur_descriptor = {
277 .style = ToBlurStyle(blur->style()),
278 .sigma = Sigma(blur->sigma()),
279 .respect_ctm = blur->respectCTM(),
280 };
281 break;
282 }
283 }
284 }
285
286 // |flutter::DlOpReceiver|
287 void DlDispatcherBase::setImageFilter(const flutter::DlImageFilter* filter) {
288 AUTO_DEPTH_WATCHER(0u);
289
290 paint_.image_filter = filter;
291 }
292
293 // |flutter::DlOpReceiver|
294 void DlDispatcherBase::save(uint32_t total_content_depth) {
295 AUTO_DEPTH_WATCHER(1u);
296
297 GetCanvas().Save(total_content_depth);
298 }
299
300 // |flutter::DlOpReceiver|
301 void DlDispatcherBase::saveLayer(const DlRect& bounds,
302 const flutter::SaveLayerOptions& options,
303 uint32_t total_content_depth,
304 flutter::DlBlendMode max_content_mode,
305 const flutter::DlImageFilter* backdrop) {
306 AUTO_DEPTH_WATCHER(1u);
307
308 auto paint = options.renders_with_attributes() ? paint_ : Paint{};
309 auto promise = options.content_is_clipped()
310 ? ContentBoundsPromise::kMayClipContents
311 : ContentBoundsPromise::kContainsContents;
312 std::optional<Rect> impeller_bounds;
313 // If the content is unbounded but has developer specified bounds, we take
314 // the original bounds so that we clip the content as expected.
315 if (!options.content_is_unbounded() || options.bounds_from_caller()) {
316 impeller_bounds = bounds;
317 }
318
319 GetCanvas().SaveLayer(
320 paint, impeller_bounds, backdrop, promise, total_content_depth,
321 // Unbounded content can still have user specified bounds that require a
322 // saveLayer to be created to perform the clip.
323 options.can_distribute_opacity() && !options.content_is_unbounded());
324 }
325
326 // |flutter::DlOpReceiver|
327 void DlDispatcherBase::restore() {
328 GetCanvas().Restore();
329 }
330
331 // |flutter::DlOpReceiver|
332 void DlDispatcherBase::translate(DlScalar tx, DlScalar ty) {
333 AUTO_DEPTH_WATCHER(0u);
334
335 GetCanvas().Translate({tx, ty, 0.0});
336 }
337
338 // |flutter::DlOpReceiver|
339 void DlDispatcherBase::scale(DlScalar sx, DlScalar sy) {
340 AUTO_DEPTH_WATCHER(0u);
341
342 GetCanvas().Scale({sx, sy, 1.0});
343 }
344
345 // |flutter::DlOpReceiver|
346 void DlDispatcherBase::rotate(DlScalar degrees) {
347 AUTO_DEPTH_WATCHER(0u);
348
349 GetCanvas().Rotate(Degrees{degrees});
350 }
351
352 // |flutter::DlOpReceiver|
353 void DlDispatcherBase::skew(DlScalar sx, DlScalar sy) {
354 AUTO_DEPTH_WATCHER(0u);
355
356 GetCanvas().Skew(sx, sy);
357 }
358
359 // |flutter::DlOpReceiver|
360 void DlDispatcherBase::transform2DAffine(DlScalar mxx,
361 DlScalar mxy,
362 DlScalar mxt,
363 DlScalar myx,
364 DlScalar myy,
365 DlScalar myt) {
366 AUTO_DEPTH_WATCHER(0u);
367
368 // clang-format off
369 transformFullPerspective(
370 mxx, mxy, 0, mxt,
371 myx, myy, 0, myt,
372 0 , 0, 1, 0,
373 0 , 0, 0, 1
374 );
375 // clang-format on
376 }
377
378 // |flutter::DlOpReceiver|
379 void DlDispatcherBase::transformFullPerspective(DlScalar mxx,
380 DlScalar mxy,
381 DlScalar mxz,
382 DlScalar mxt,
383 DlScalar myx,
384 DlScalar myy,
385 DlScalar myz,
386 DlScalar myt,
387 DlScalar mzx,
388 DlScalar mzy,
389 DlScalar mzz,
390 DlScalar mzt,
391 DlScalar mwx,
392 DlScalar mwy,
393 DlScalar mwz,
394 DlScalar mwt) {
395 AUTO_DEPTH_WATCHER(0u);
396
397 // The order of arguments is row-major but Impeller matrices are
398 // column-major.
399 // clang-format off
400 auto transform = Matrix{
401 mxx, myx, mzx, mwx,
402 mxy, myy, mzy, mwy,
403 mxz, myz, mzz, mwz,
404 mxt, myt, mzt, mwt
405 };
406 // clang-format on
407 GetCanvas().Transform(transform);
408 }
409
410 // |flutter::DlOpReceiver|
411 void DlDispatcherBase::transformReset() {
412 AUTO_DEPTH_WATCHER(0u);
413
414 GetCanvas().ResetTransform();
415 GetCanvas().Transform(initial_matrix_);
416 }
417
418 static Entity::ClipOperation ToClipOperation(
419 flutter::DlCanvas::ClipOp clip_op) {
420 switch (clip_op) {
421 case flutter::DlCanvas::ClipOp::kDifference:
422 return Entity::ClipOperation::kDifference;
423 case flutter::DlCanvas::ClipOp::kIntersect:
424 return Entity::ClipOperation::kIntersect;
425 }
426 }
427
428 // |flutter::DlOpReceiver|
429 void DlDispatcherBase::clipRect(const DlRect& rect,
430 ClipOp clip_op,
431 bool is_aa) {
432 AUTO_DEPTH_WATCHER(0u);
433
434 GetCanvas().ClipGeometry(Geometry::MakeRect(rect), ToClipOperation(clip_op));
435 }
436
437 // |flutter::DlOpReceiver|
438 void DlDispatcherBase::clipOval(const DlRect& bounds,
439 ClipOp clip_op,
440 bool is_aa) {
441 AUTO_DEPTH_WATCHER(0u);
442
443 GetCanvas().ClipGeometry(Geometry::MakeOval(bounds),
444 ToClipOperation(clip_op));
445 }
446
447 // |flutter::DlOpReceiver|
448 void DlDispatcherBase::clipRRect(const SkRRect& rrect,
449 ClipOp sk_op,
450 bool is_aa) {
451 AUTO_DEPTH_WATCHER(0u);
452
453 auto clip_op = ToClipOperation(sk_op);
454 if (rrect.isRect()) {
455 GetCanvas().ClipGeometry(
456 Geometry::MakeRect(skia_conversions::ToRect(rrect.rect())), clip_op);
457 } else if (rrect.isOval()) {
458 GetCanvas().ClipGeometry(
459 Geometry::MakeOval(skia_conversions::ToRect(rrect.rect())), clip_op);
460 } else if (rrect.isSimple()) {
461 GetCanvas().ClipGeometry(
462 Geometry::MakeRoundRect(
463 skia_conversions::ToRect(rrect.rect()),
464 skia_conversions::ToSize(rrect.getSimpleRadii())),
465 clip_op);
466 } else {
467 GetCanvas().ClipGeometry(
468 Geometry::MakeFillPath(skia_conversions::ToPath(rrect)), clip_op);
469 }
470 }
471
472 // |flutter::DlOpReceiver|
473 void DlDispatcherBase::clipPath(const DlPath& path, ClipOp sk_op, bool is_aa) {
474 AUTO_DEPTH_WATCHER(0u);
475
476 auto clip_op = ToClipOperation(sk_op);
477
478 DlRect rect;
479 if (path.IsRect(&rect)) {
480 GetCanvas().ClipGeometry(Geometry::MakeRect(rect), clip_op);
481 } else if (path.IsOval(&rect)) {
482 GetCanvas().ClipGeometry(Geometry::MakeOval(rect), clip_op);
483 } else {
484 SkRRect rrect;
485 if (path.IsSkRRect(&rrect) && rrect.isSimple()) {
486 GetCanvas().ClipGeometry(
487 Geometry::MakeRoundRect(
488 skia_conversions::ToRect(rrect.rect()),
489 skia_conversions::ToSize(rrect.getSimpleRadii())),
490 clip_op);
491 } else {
492 GetCanvas().ClipGeometry(Geometry::MakeFillPath(path.GetPath()), clip_op);
493 }
494 }
495 }
496
497 // |flutter::DlOpReceiver|
498 void DlDispatcherBase::drawColor(flutter::DlColor color,
499 flutter::DlBlendMode dl_mode) {
500 AUTO_DEPTH_WATCHER(1u);
501
502 Paint paint;
503 paint.color = skia_conversions::ToColor(color);
504 paint.blend_mode = skia_conversions::ToBlendMode(dl_mode);
505 GetCanvas().DrawPaint(paint);
506 }
507
508 // |flutter::DlOpReceiver|
509 void DlDispatcherBase::drawPaint() {
510 AUTO_DEPTH_WATCHER(1u);
511
512 GetCanvas().DrawPaint(paint_);
513 }
514
515 // |flutter::DlOpReceiver|
516 void DlDispatcherBase::drawLine(const DlPoint& p0, const DlPoint& p1) {
517 AUTO_DEPTH_WATCHER(1u);
518
519 GetCanvas().DrawLine(p0, p1, paint_);
520 }
521
522 void DlDispatcherBase::drawDashedLine(const DlPoint& p0,
523 const DlPoint& p1,
524 DlScalar on_length,
525 DlScalar off_length) {
526 AUTO_DEPTH_WATCHER(1u);
527
528 Scalar length = p0.GetDistance(p1);
529 // Reasons to defer to regular DrawLine:
530 // length is non-positive - drawLine will draw appropriate "dot"
531 // off_length is non-positive - no gaps, drawLine will draw it solid
532 // on_length is negative - invalid dashing
533 // Note that a 0 length "on" dash will draw "dot"s every "off" distance apart
534 if (length > 0.0f && on_length >= 0.0f && off_length > 0.0f) {
535 Point delta = (p1 - p0) / length; // length > 0 already tested
536 PathBuilder builder;
537
538 Scalar consumed = 0.0f;
539 while (consumed < length) {
540 builder.MoveTo(p0 + delta * consumed);
541
542 Scalar dash_end = consumed + on_length;
543 if (dash_end < length) {
544 builder.LineTo(p0 + delta * dash_end);
545 } else {
546 builder.LineTo(p1);
547 // Should happen anyway due to the math, but let's make it explicit
548 // in case of bit errors. We're done with this line.
549 break;
550 }
551
552 consumed = dash_end + off_length;
553 }
554
555 Paint stroke_paint = paint_;
556 stroke_paint.style = Paint::Style::kStroke;
557 GetCanvas().DrawPath(builder.TakePath(), stroke_paint);
558 } else {
559 drawLine(p0, p1);
560 }
561 }
562
563 // |flutter::DlOpReceiver|
564 void DlDispatcherBase::drawRect(const DlRect& rect) {
565 AUTO_DEPTH_WATCHER(1u);
566
567 GetCanvas().DrawRect(rect, paint_);
568 }
569
570 // |flutter::DlOpReceiver|
571 void DlDispatcherBase::drawOval(const DlRect& bounds) {
572 AUTO_DEPTH_WATCHER(1u);
573
574 GetCanvas().DrawOval(bounds, paint_);
575 }
576
577 // |flutter::DlOpReceiver|
578 void DlDispatcherBase::drawCircle(const DlPoint& center, DlScalar radius) {
579 AUTO_DEPTH_WATCHER(1u);
580
581 GetCanvas().DrawCircle(center, radius, paint_);
582 }
583
584 // |flutter::DlOpReceiver|
585 void DlDispatcherBase::drawRRect(const SkRRect& rrect) {
586 AUTO_DEPTH_WATCHER(1u);
587
588 if (skia_conversions::IsNearlySimpleRRect(rrect)) {
589 GetCanvas().DrawRRect(skia_conversions::ToRect(rrect.rect()),
590 skia_conversions::ToSize(rrect.getSimpleRadii()),
591 paint_);
592 } else {
593 GetCanvas().DrawPath(skia_conversions::ToPath(rrect), paint_);
594 }
595 }
596
597 // |flutter::DlOpReceiver|
598 void DlDispatcherBase::drawDRRect(const SkRRect& outer, const SkRRect& inner) {
599 AUTO_DEPTH_WATCHER(1u);
600
601 PathBuilder builder;
602 builder.AddPath(skia_conversions::ToPath(outer));
603 builder.AddPath(skia_conversions::ToPath(inner));
604 GetCanvas().DrawPath(builder.TakePath(FillType::kOdd), paint_);
605 }
606
607 // |flutter::DlOpReceiver|
608 void DlDispatcherBase::drawPath(const DlPath& path) {
609 AUTO_DEPTH_WATCHER(1u);
610
611 SimplifyOrDrawPath(GetCanvas(), path, paint_);
612 }
613
614 void DlDispatcherBase::SimplifyOrDrawPath(Canvas& canvas,
615 const DlPath& path,
616 const Paint& paint) {
617 DlRect rect;
618
619 // We can't "optimize" a path into a rectangle if it's open.
620 bool closed;
621 if (path.IsRect(&rect, &closed) && closed) {
622 canvas.DrawRect(rect, paint);
623 return;
624 }
625
626 SkRRect rrect;
627 if (path.IsSkRRect(&rrect) && rrect.isSimple()) {
628 canvas.DrawRRect(skia_conversions::ToRect(rrect.rect()),
629 skia_conversions::ToSize(rrect.getSimpleRadii()), paint);
630 return;
631 }
632
633 if (path.IsOval(&rect)) {
634 canvas.DrawOval(rect, paint);
635 return;
636 }
637
638 canvas.DrawPath(path.GetPath(), paint);
639 }
640
641 // |flutter::DlOpReceiver|
642 void DlDispatcherBase::drawArc(const DlRect& oval_bounds,
643 DlScalar start_degrees,
644 DlScalar sweep_degrees,
645 bool use_center) {
646 AUTO_DEPTH_WATCHER(1u);
647
648 PathBuilder builder;
649 builder.AddArc(oval_bounds, Degrees(start_degrees), Degrees(sweep_degrees),
650 use_center);
651 GetCanvas().DrawPath(builder.TakePath(), paint_);
652 }
653
654 // |flutter::DlOpReceiver|
655 void DlDispatcherBase::drawPoints(PointMode mode,
656 uint32_t count,
657 const DlPoint points[]) {
658 AUTO_DEPTH_WATCHER(1u);
659
660 Paint paint = paint_;
661 paint.style = Paint::Style::kStroke;
662 switch (mode) {
663 case flutter::DlCanvas::PointMode::kPoints: {
664 // Cap::kButt is also treated as a square.
665 auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound
666 : PointStyle::kSquare;
667 auto radius = paint.stroke_width;
668 if (radius > 0) {
669 radius /= 2.0;
670 }
671 GetCanvas().DrawPoints(skia_conversions::ToPoints(points, count), radius,
672 paint, point_style);
673 } break;
674 case flutter::DlCanvas::PointMode::kLines:
675 for (uint32_t i = 1; i < count; i += 2) {
676 Point p0 = points[i - 1];
677 Point p1 = points[i];
678 GetCanvas().DrawLine(p0, p1, paint, /*reuse_depth=*/i > 1);
679 }
680 break;
681 case flutter::DlCanvas::PointMode::kPolygon:
682 if (count > 1) {
683 Point p0 = points[0];
684 for (uint32_t i = 1; i < count; i++) {
685 Point p1 = points[i];
686 GetCanvas().DrawLine(p0, p1, paint, /*reuse_depth=*/i > 1);
687 p0 = p1;
688 }
689 }
690 break;
691 }
692 }
693
694 void DlDispatcherBase::drawVertices(
695 const std::shared_ptr<flutter::DlVertices>& vertices,
696 flutter::DlBlendMode dl_mode) {}
697
698 // |flutter::DlOpReceiver|
699 void DlDispatcherBase::drawImage(const sk_sp<flutter::DlImage> image,
700 const DlPoint& point,
701 flutter::DlImageSampling sampling,
702 bool render_with_attributes) {
703 AUTO_DEPTH_WATCHER(1u);
704
705 if (!image) {
706 return;
707 }
708
709 auto texture = image->impeller_texture();
710 if (!texture) {
711 return;
712 }
713
714 const auto size = texture->GetSize();
715 const auto src = DlRect::MakeWH(size.width, size.height);
716 const auto dest = DlRect::MakeXYWH(point.x, point.y, size.width, size.height);
717
718 drawImageRect(image, // image
719 src, // source rect
720 dest, // destination rect
721 sampling, // sampling options
722 render_with_attributes, // render with attributes
723 SrcRectConstraint::kStrict // constraint
724 );
725 }
726
727 // |flutter::DlOpReceiver|
728 void DlDispatcherBase::drawImageRect(
729 const sk_sp<flutter::DlImage> image,
730 const DlRect& src,
731 const DlRect& dst,
732 flutter::DlImageSampling sampling,
733 bool render_with_attributes,
734 SrcRectConstraint constraint = SrcRectConstraint::kFast) {
735 AUTO_DEPTH_WATCHER(1u);
736
737 GetCanvas().DrawImageRect(
738 image->impeller_texture(), // image
739 src, // source rect
740 dst, // destination rect
741 render_with_attributes ? paint_ : Paint(), // paint
742 skia_conversions::ToSamplerDescriptor(sampling) // sampling
743 );
744 }
745
746 // |flutter::DlOpReceiver|
747 void DlDispatcherBase::drawImageNine(const sk_sp<flutter::DlImage> image,
748 const DlIRect& center,
749 const DlRect& dst,
750 flutter::DlFilterMode filter,
751 bool render_with_attributes) {
752 AUTO_DEPTH_WATCHER(9u);
753
754 NinePatchConverter converter = {};
755 converter.DrawNinePatch(image->impeller_texture(),
756 Rect::MakeLTRB(center.GetLeft(), center.GetTop(),
757 center.GetRight(), center.GetBottom()),
758 dst, ToSamplerDescriptor(filter), &GetCanvas(),
759 &paint_);
760 }
761
762 // |flutter::DlOpReceiver|
763 void DlDispatcherBase::drawAtlas(const sk_sp<flutter::DlImage> atlas,
764 const SkRSXform xform[],
765 const DlRect tex[],
766 const flutter::DlColor colors[],
767 int count,
768 flutter::DlBlendMode mode,
769 flutter::DlImageSampling sampling,
770 const DlRect* cull_rect,
771 bool render_with_attributes) {
772 AUTO_DEPTH_WATCHER(1u);
773
774 auto geometry =
775 DlAtlasGeometry(atlas->impeller_texture(), //
776 xform, //
777 tex, //
778 colors, //
779 static_cast<size_t>(count), //
780 skia_conversions::ToBlendMode(mode), //
781 skia_conversions::ToSamplerDescriptor(sampling), //
782 skia_conversions::ToRect(cull_rect) //
783 );
784 auto atlas_contents = std::make_shared<AtlasContents>();
785 atlas_contents->SetGeometry(&geometry);
786
787 GetCanvas().DrawAtlas(atlas_contents, paint_);
788 }
789
790 // |flutter::DlOpReceiver|
791 void DlDispatcherBase::drawDisplayList(
792 const sk_sp<flutter::DisplayList> display_list,
793 DlScalar opacity) {
794 AUTO_DEPTH_WATCHER(display_list->total_depth());
795
796 // Save all values that must remain untouched after the operation.
797 Paint saved_paint = paint_;
798 Matrix saved_initial_matrix = initial_matrix_;
799
800 // Establish a new baseline for interpreting the new DL.
801 // Matrix and clip are left untouched, the current
802 // transform is saved as the new base matrix, and paint
803 // values are reset to defaults.
804 initial_matrix_ = GetCanvas().GetCurrentTransform();
805 paint_ = Paint();
806
807 // Handle passed opacity in the most brute-force way by using
808 // a SaveLayer. If the display_list is able to inherit the
809 // opacity, this could also be handled by modulating all of its
810 // attribute settings (for example, color), by the indicated
811 // opacity.
812 int restore_count = GetCanvas().GetSaveCount();
813 if (opacity < SK_Scalar1) {
814 Paint save_paint;
815 save_paint.color = Color(0, 0, 0, opacity);
816 GetCanvas().SaveLayer(
817 save_paint, skia_conversions::ToRect(display_list->bounds()), nullptr,
818 ContentBoundsPromise::kContainsContents, display_list->total_depth(),
819 display_list->can_apply_group_opacity());
820 } else {
821 // The display list may alter the clip, which must be restored to the
822 // current clip at the end of playback.
823 GetCanvas().Save(display_list->total_depth());
824 }
825
826 // TODO(131445): Remove this restriction if we can correctly cull with
827 // perspective transforms.
828 if (display_list->has_rtree() && !initial_matrix_.HasPerspective()) {
829 // The canvas remembers the screen-space culling bounds clipped by
830 // the surface and the history of clip calls. DisplayList can cull
831 // the ops based on a rectangle expressed in its "destination bounds"
832 // so we need the canvas to transform those into the current local
833 // coordinate space into which the DisplayList will be rendered.
834 auto global_culling_bounds = GetCanvas().GetLocalCoverageLimit();
835 if (global_culling_bounds.has_value()) {
836 Rect cull_rect = global_culling_bounds->TransformBounds(
837 GetCanvas().GetCurrentTransform().Invert());
838 display_list->Dispatch(
839 *this, SkRect::MakeLTRB(cull_rect.GetLeft(), cull_rect.GetTop(),
840 cull_rect.GetRight(), cull_rect.GetBottom()));
841 } else {
842 // If the culling bounds are empty, this display list can be skipped
843 // entirely.
844 }
845 } else {
846 display_list->Dispatch(*this);
847 }
848
849 // Restore all saved state back to what it was before we interpreted
850 // the display_list
851 AUTO_DEPTH_CHECK();
852 GetCanvas().RestoreToCount(restore_count);
853 initial_matrix_ = saved_initial_matrix;
854 paint_ = saved_paint;
855 }
856
857 // |flutter::DlOpReceiver|
858 void DlDispatcherBase::drawTextBlob(const sk_sp<SkTextBlob> blob,
859 DlScalar x,
860 DlScalar y) {
861 // When running with Impeller enabled Skia text blobs are converted to
862 // Impeller text frames in paragraph_skia.cc
863 UNIMPLEMENTED;
864 }
865
866 // |flutter::DlOpReceiver|
867 void DlDispatcherBase::drawTextFrame(
868 const std::shared_ptr<TextFrame>& text_frame,
869 DlScalar x,
870 DlScalar y) {
871 AUTO_DEPTH_WATCHER(1u);
872
873 GetCanvas().DrawTextFrame(text_frame, //
874 impeller::Point{x, y}, //
875 paint_ //
876 );
877 }
878
879 // |flutter::DlOpReceiver|
880 void DlDispatcherBase::drawShadow(const DlPath& path,
881 const flutter::DlColor color,
882 const DlScalar elevation,
883 bool transparent_occluder,
884 DlScalar dpr) {
885 AUTO_DEPTH_WATCHER(1u);
886
887 Color spot_color = skia_conversions::ToColor(color);
888 spot_color.alpha *= 0.25;
889
890 // Compute the spot color -- ported from SkShadowUtils::ComputeTonalColors.
891 {
892 Scalar max =
893 std::max(std::max(spot_color.red, spot_color.green), spot_color.blue);
894 Scalar min =
895 std::min(std::min(spot_color.red, spot_color.green), spot_color.blue);
896 Scalar luminance = (min + max) * 0.5;
897
898 Scalar alpha_adjust =
899 (2.6f + (-2.66667f + 1.06667f * spot_color.alpha) * spot_color.alpha) *
900 spot_color.alpha;
901 Scalar color_alpha =
902 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
903 luminance;
904 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
905
906 Scalar greyscale_alpha =
907 std::clamp(spot_color.alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
908
909 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
910 Scalar tonal_alpha = color_scale + greyscale_alpha;
911 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
912 spot_color = Color(unpremul_scale * spot_color.red,
913 unpremul_scale * spot_color.green,
914 unpremul_scale * spot_color.blue, tonal_alpha);
915 }
916
917 Vector3 light_position(0, -1, 1);
918 Scalar occluder_z = dpr * elevation;
919
920 constexpr Scalar kLightRadius = 800 / 600; // Light radius / light height
921
922 Paint paint;
923 paint.style = Paint::Style::kFill;
924 paint.color = spot_color;
925 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
926 .style = FilterContents::BlurStyle::kNormal,
927 .sigma = Radius{kLightRadius * occluder_z /
928 GetCanvas().GetCurrentTransform().GetScale().y},
929 };
930
931 GetCanvas().Save(1u);
932 GetCanvas().PreConcat(
933 Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y)));
934
935 SimplifyOrDrawPath(GetCanvas(), path, paint);
936 AUTO_DEPTH_CHECK();
937
938 GetCanvas().Restore();
939 }
940
941 /// Subclasses
942
943 static bool RequiresReadbackForBlends(
944 const ContentContext& renderer,
945 flutter::DlBlendMode max_root_blend_mode) {
946 return !renderer.GetDeviceCapabilities().SupportsFramebufferFetch() &&
947 skia_conversions::ToBlendMode(max_root_blend_mode) >
948 Entity::kLastPipelineBlendMode;
949 }
950
951 CanvasDlDispatcher::CanvasDlDispatcher(ContentContext& renderer,
952 RenderTarget& render_target,
953 bool has_root_backdrop_filter,
954 flutter::DlBlendMode max_root_blend_mode,
955 IRect cull_rect)
956 : canvas_(renderer,
957 render_target,
958 has_root_backdrop_filter ||
959 RequiresReadbackForBlends(renderer, max_root_blend_mode),
960 cull_rect),
961 renderer_(renderer) {}
962
963 Canvas& CanvasDlDispatcher::GetCanvas() {
964 return canvas_;
965 }
966
967 void CanvasDlDispatcher::drawVertices(
968 const std::shared_ptr<flutter::DlVertices>& vertices,
969 flutter::DlBlendMode dl_mode) {
970 AUTO_DEPTH_WATCHER(1u);
971
972 GetCanvas().DrawVertices(
973 std::make_shared<DlVerticesGeometry>(vertices, renderer_),
974 skia_conversions::ToBlendMode(dl_mode), paint_);
975 }
976
977 //// Text Frame Dispatcher
978
979 TextFrameDispatcher::TextFrameDispatcher(const ContentContext& renderer,
980 const Matrix& initial_matrix,
981 const Rect cull_rect)
982 : renderer_(renderer), matrix_(initial_matrix) {
983 cull_rect_state_.push_back(cull_rect);
984 }
985
986 TextFrameDispatcher::~TextFrameDispatcher() {
987 FML_DCHECK(cull_rect_state_.size() == 1);
988 }
989
990 void TextFrameDispatcher::save() {
991 stack_.emplace_back(matrix_);
992 cull_rect_state_.push_back(cull_rect_state_.back());
993 }
994
995 void TextFrameDispatcher::saveLayer(const DlRect& bounds,
996 const flutter::SaveLayerOptions options,
997 const flutter::DlImageFilter* backdrop) {
998 save();
999
1000 // This dispatcher does not track enough state to accurately compute
1001 // cull rects with image filters.
1002 auto global_cull_rect = cull_rect_state_.back();
1003 if (has_image_filter_ || global_cull_rect.IsMaximum()) {
1004 cull_rect_state_.back() = Rect::MakeMaximum();
1005 } else {
1006 auto global_save_bounds = bounds.TransformBounds(matrix_);
1007 auto new_cull_rect = global_cull_rect.Intersection(global_save_bounds);
1008 if (new_cull_rect.has_value()) {
1009 cull_rect_state_.back() = new_cull_rect.value();
1010 } else {
1011 cull_rect_state_.back() = Rect::MakeLTRB(0, 0, 0, 0);
1012 }
1013 }
1014 }
1015
1016 void TextFrameDispatcher::restore() {
1017 matrix_ = stack_.back();
1018 stack_.pop_back();
1019 cull_rect_state_.pop_back();
1020 }
1021
1022 void TextFrameDispatcher::translate(DlScalar tx, DlScalar ty) {
1023 matrix_ = matrix_.Translate({tx, ty});
1024 }
1025
1026 void TextFrameDispatcher::scale(DlScalar sx, DlScalar sy) {
1027 matrix_ = matrix_.Scale({sx, sy, 1.0f});
1028 }
1029
1030 void TextFrameDispatcher::rotate(DlScalar degrees) {
1031 matrix_ = matrix_ * Matrix::MakeRotationZ(Degrees(degrees));
1032 }
1033
1034 void TextFrameDispatcher::skew(DlScalar sx, DlScalar sy) {
1035 matrix_ = matrix_ * Matrix::MakeSkew(sx, sy);
1036 }
1037
1038 // clang-format off
1039 // 2x3 2D affine subset of a 4x4 transform in row major order
1040 void TextFrameDispatcher::transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt,
1041 DlScalar myx, DlScalar myy, DlScalar myt) {
1042 matrix_ = matrix_ * Matrix::MakeColumn(
1043 mxx, myx, 0.0f, 0.0f,
1044 mxy, myy, 0.0f, 0.0f,
1045 0.0f, 0.0f, 1.0f, 0.0f,
1046 mxt, myt, 0.0f, 1.0f
1047 );
1048 }
1049
1050 // full 4x4 transform in row major order
1051 void TextFrameDispatcher::transformFullPerspective(
1052 DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt,
1053 DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt,
1054 DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt,
1055 DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) {
1056 matrix_ = matrix_ * Matrix::MakeColumn(
1057 mxx, myx, mzx, mwx,
1058 mxy, myy, mzy, mwy,
1059 mxz, myz, mzz, mwz,
1060 mxt, myt, mzt, mwt
1061 );
1062 }
1063 // clang-format on
1064
1065 void TextFrameDispatcher::transformReset() {
1066 matrix_ = Matrix();
1067 }
1068
1069 void TextFrameDispatcher::drawTextFrame(
1070 const std::shared_ptr<impeller::TextFrame>& text_frame,
1071 DlScalar x,
1072 DlScalar y) {
1073 GlyphProperties properties;
1074 if (paint_.style == Paint::Style::kStroke) {
1075 properties.stroke = true;
1076 properties.stroke_cap = paint_.stroke_cap;
1077 properties.stroke_join = paint_.stroke_join;
1078 properties.stroke_miter = paint_.stroke_miter;
1079 properties.stroke_width = paint_.stroke_width;
1080 }
1081 if (text_frame->HasColor()) {
1082 // Alpha is always applied when rendering, remove it here so
1083 // we do not double-apply the alpha.
1084 properties.color = paint_.color.WithAlpha(1.0);
1085 }
1086 auto scale =
1087 (matrix_ * Matrix::MakeTranslation(Point(x, y))).GetMaxBasisLengthXY();
1088 renderer_.GetLazyGlyphAtlas()->AddTextFrame(*text_frame, //
1089 scale, //
1090 Point(x, y), //
1091 properties //
1092 );
1093 }
1094
1095 const Rect TextFrameDispatcher::GetCurrentLocalCullingBounds() const {
1096 auto cull_rect = cull_rect_state_.back();
1097 if (!cull_rect.IsEmpty() && !cull_rect.IsMaximum()) {
1098 Matrix inverse = matrix_.Invert();
1099 cull_rect = cull_rect.TransformBounds(inverse);
1100 }
1101 return cull_rect;
1102 }
1103
1104 void TextFrameDispatcher::drawDisplayList(
1105 const sk_sp<flutter::DisplayList> display_list,
1106 DlScalar opacity) {
1107 [[maybe_unused]] size_t stack_depth = stack_.size();
1108 save();
1109 Paint old_paint = paint_;
1110 paint_ = Paint{};
1111 bool old_has_image_filter = has_image_filter_;
1112 has_image_filter_ = false;
1113
1114 if (matrix_.HasPerspective()) {
1115 display_list->Dispatch(*this);
1116 } else {
1117 Rect local_cull_bounds = GetCurrentLocalCullingBounds();
1118 if (local_cull_bounds.IsMaximum()) {
1119 display_list->Dispatch(*this);
1120 } else if (!local_cull_bounds.IsEmpty()) {
1121 IRect cull_rect = IRect::RoundOut(local_cull_bounds);
1122 display_list->Dispatch(*this, SkIRect::MakeLTRB(cull_rect.GetLeft(), //
1123 cull_rect.GetTop(), //
1124 cull_rect.GetRight(), //
1125 cull_rect.GetBottom() //
1126 ));
1127 }
1128 }
1129
1130 restore();
1131 paint_ = old_paint;
1132 has_image_filter_ = old_has_image_filter;
1133 FML_DCHECK(stack_depth == stack_.size());
1134 }
1135
1136 // |flutter::DlOpReceiver|
1137 void TextFrameDispatcher::setDrawStyle(flutter::DlDrawStyle style) {
1138 paint_.style = ToStyle(style);
1139 }
1140
1141 // |flutter::DlOpReceiver|
1142 void TextFrameDispatcher::setColor(flutter::DlColor color) {
1143 paint_.color = skia_conversions::ToColor(color);
1144 }
1145
1146 // |flutter::DlOpReceiver|
1147 void TextFrameDispatcher::setStrokeWidth(DlScalar width) {
1148 paint_.stroke_width = width;
1149 }
1150
1151 // |flutter::DlOpReceiver|
1152 void TextFrameDispatcher::setStrokeMiter(DlScalar limit) {
1153 paint_.stroke_miter = limit;
1154 }
1155
1156 // |flutter::DlOpReceiver|
1157 void TextFrameDispatcher::setStrokeCap(flutter::DlStrokeCap cap) {
1158 switch (cap) {
1159 case flutter::DlStrokeCap::kButt:
1160 paint_.stroke_cap = Cap::kButt;
1161 break;
1162 case flutter::DlStrokeCap::kRound:
1163 paint_.stroke_cap = Cap::kRound;
1164 break;
1165 case flutter::DlStrokeCap::kSquare:
1166 paint_.stroke_cap = Cap::kSquare;
1167 break;
1168 }
1169 }
1170
1171 // |flutter::DlOpReceiver|
1172 void TextFrameDispatcher::setStrokeJoin(flutter::DlStrokeJoin join) {
1173 switch (join) {
1174 case flutter::DlStrokeJoin::kMiter:
1175 paint_.stroke_join = Join::kMiter;
1176 break;
1177 case flutter::DlStrokeJoin::kRound:
1178 paint_.stroke_join = Join::kRound;
1179 break;
1180 case flutter::DlStrokeJoin::kBevel:
1181 paint_.stroke_join = Join::kBevel;
1182 break;
1183 }
1184 }
1185
1186 // |flutter::DlOpReceiver|
1187 void TextFrameDispatcher::setImageFilter(const flutter::DlImageFilter* filter) {
1188 if (filter == nullptr) {
1189 has_image_filter_ = false;
1190 } else {
1191 has_image_filter_ = true;
1192 }
1193 }
1194
1195 std::shared_ptr<Texture> DisplayListToTexture(
1196 const sk_sp<flutter::DisplayList>& display_list,
1197 ISize size,
1198 AiksContext& context,
1199 bool reset_host_buffer,
1200 bool generate_mips) {
1201 int mip_count = 1;
1202 if (generate_mips) {
1203 mip_count = size.MipCount();
1204 }
1205 // Do not use the render target cache as the lifecycle of this texture
1206 // will outlive a particular frame.
1207 impeller::RenderTargetAllocator render_target_allocator =
1208 impeller::RenderTargetAllocator(
1209 context.GetContext()->GetResourceAllocator());
1210 impeller::RenderTarget target;
1211 if (context.GetContext()->GetCapabilities()->SupportsOffscreenMSAA()) {
1212 target = render_target_allocator.CreateOffscreenMSAA(
1213 *context.GetContext(), // context
1214 size, // size
1215 /*mip_count=*/mip_count,
1216 "Picture Snapshot MSAA", // label
1217 impeller::RenderTarget::
1218 kDefaultColorAttachmentConfigMSAA // color_attachment_config
1219 );
1220 } else {
1221 target = render_target_allocator.CreateOffscreen(
1222 *context.GetContext(), // context
1223 size, // size
1224 /*mip_count=*/mip_count,
1225 "Picture Snapshot", // label
1226 impeller::RenderTarget::
1227 kDefaultColorAttachmentConfig // color_attachment_config
1228 );
1229 }
1230
1231 SkIRect sk_cull_rect = SkIRect::MakeWH(size.width, size.height);
1232 impeller::TextFrameDispatcher collector(
1233 context.GetContentContext(), impeller::Matrix(), Rect::MakeSize(size));
1234 display_list->Dispatch(collector, sk_cull_rect);
1235 impeller::CanvasDlDispatcher impeller_dispatcher(
1236 context.GetContentContext(), //
1237 target, //
1238 display_list->root_has_backdrop_filter(), //
1239 display_list->max_root_blend_mode(), //
1240 impeller::IRect::MakeSize(size) //
1241 );
1242 display_list->Dispatch(impeller_dispatcher, sk_cull_rect);
1243 impeller_dispatcher.FinishRecording();
1244
1245 if (reset_host_buffer) {
1246 context.GetContentContext().GetTransientsBuffer().Reset();
1247 }
1248 context.GetContentContext().GetLazyGlyphAtlas()->ResetTextFrames();
1249
1250 return target.GetRenderTargetTexture();
1251 }
1252
1253 bool RenderToOnscreen(ContentContext& context,
1254 RenderTarget render_target,
1255 const sk_sp<flutter::DisplayList>& display_list,
1256 SkIRect cull_rect,
1257 bool reset_host_buffer) {
1258 Rect ip_cull_rect = Rect::MakeLTRB(cull_rect.left(), cull_rect.top(),
1259 cull_rect.right(), cull_rect.bottom());
1260 TextFrameDispatcher collector(context, impeller::Matrix(), ip_cull_rect);
1261 display_list->Dispatch(collector, cull_rect);
1262
1263 impeller::CanvasDlDispatcher impeller_dispatcher(
1264 context, //
1265 render_target, //
1266 display_list->root_has_backdrop_filter(), //
1267 display_list->max_root_blend_mode(), //
1268 IRect::RoundOut(ip_cull_rect) //
1269 );
1270 display_list->Dispatch(impeller_dispatcher, cull_rect);
1271 impeller_dispatcher.FinishRecording();
1272 if (reset_host_buffer) {
1273 context.GetTransientsBuffer().Reset();
1274 }
1275 context.GetLazyGlyphAtlas()->ResetTextFrames();
1276
1277 return true;
1278 }
1279
1280 } // namespace impeller
impeller::DlDispatcherBase::drawDRRect
void drawDRRect(const SkRRect &outer, const SkRRect &inner) override
Definition: dl_dispatcher.cc:598
AUTO_DEPTH_WATCHER
#define AUTO_DEPTH_WATCHER(d)
Definition: dl_dispatcher.cc:110
impeller::CanvasDlDispatcher
Definition: dl_dispatcher.h:246
impeller::Matrix::MakeSkew
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
Definition: matrix.h:117
impeller::Paint::stroke_cap
Cap stroke_cap
Definition: paint.h:80
impeller::DlDispatcherBase::transformReset
void transformReset() override
Definition: dl_dispatcher.cc:411
impeller::Matrix::HasPerspective
constexpr bool HasPerspective() const
Definition: matrix.h:335
impeller::Canvas::DrawPoints
void DrawPoints(std::vector< Point > points, Scalar radius, const Paint &paint, PointStyle point_style)
Definition: canvas.cc:685
impeller::Entity::ClipOperation::kIntersect
@ kIntersect
impeller::CanvasDlDispatcher::FinishRecording
void FinishRecording()
Definition: dl_dispatcher.h:274
impeller::TextFrameDispatcher::setStrokeWidth
void setStrokeWidth(DlScalar width) override
Definition: dl_dispatcher.cc:1147
impeller::DlDispatcherBase::drawRect
void drawRect(const DlRect &rect) override
Definition: dl_dispatcher.cc:564
impeller::ToClipOperation
static Entity::ClipOperation ToClipOperation(flutter::DlCanvas::ClipOp clip_op)
Definition: dl_dispatcher.cc:418
impeller::Cap::kRound
@ kRound
impeller::Entity::kLastPipelineBlendMode
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:22
impeller::TextFrameDispatcher::scale
void scale(DlScalar sx, DlScalar sy) override
Definition: dl_dispatcher.cc:1026
impeller::RenderTargetAllocator::CreateOffscreen
virtual RenderTarget CreateOffscreen(const Context &context, ISize size, int mip_count, const std::string &label="Offscreen", RenderTarget::AttachmentConfig color_attachment_config=RenderTarget::kDefaultColorAttachmentConfig, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr)
Definition: render_target.cc:259
impeller::Cap::kSquare
@ kSquare
impeller::Canvas::DrawRRect
void DrawRRect(const Rect &rect, const Size &corner_radii, const Paint &paint)
Definition: canvas.cc:607
impeller::skia_conversions::ToPoints
std::vector< Point > ToPoints(const SkPoint points[], int count)
Definition: skia_conversions.cc:64
impeller::Entity::ClipOperation::kDifference
@ kDifference
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Canvas::RestoreToCount
void RestoreToCount(size_t count)
Definition: canvas.cc:378
impeller::AiksContext
Definition: aiks_context.h:19
impeller::DlDispatcherBase::save
void save(uint32_t total_content_depth) override
Definition: dl_dispatcher.cc:294
impeller::DlDispatcherBase::drawColor
void drawColor(flutter::DlColor color, flutter::DlBlendMode mode) override
Definition: dl_dispatcher.cc:498
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:721
impeller::skia_conversions::IsNearlySimpleRRect
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.
Definition: skia_conversions.cc:21
impeller::AiksContext::GetContentContext
ContentContext & GetContentContext() const
Definition: aiks_context.cc:42
impeller::TextFrameDispatcher::setDrawStyle
void setDrawStyle(flutter::DlDrawStyle style) override
Definition: dl_dispatcher.cc:1137
impeller::DlDispatcherBase::drawImageRect
void drawImageRect(const sk_sp< flutter::DlImage > image, const DlRect &src, const DlRect &dst, flutter::DlImageSampling sampling, bool render_with_attributes, SrcRectConstraint constraint) override
Definition: dl_dispatcher.cc:728
geometry.h
impeller::TextFrameDispatcher::TextFrameDispatcher
TextFrameDispatcher(const ContentContext &renderer, const Matrix &initial_matrix, const Rect cull_rect)
Definition: dl_dispatcher.cc:979
impeller::GlyphProperties
Definition: font_glyph_pair.h:20
impeller::Paint::Style::kStroke
@ kStroke
impeller::TextFrameDispatcher::setStrokeJoin
void setStrokeJoin(flutter::DlStrokeJoin join) override
Definition: dl_dispatcher.cc:1172
entity.h
impeller::Paint
Definition: paint.h:26
impeller::FillType::kOdd
@ kOdd
impeller::DlDispatcherBase::setStrokeCap
void setStrokeCap(flutter::DlStrokeCap cap) override
Definition: dl_dispatcher.cc:185
impeller::skia_conversions::ToSize
Size ToSize(const SkPoint &point)
Definition: skia_conversions.cc:102
impeller::DlDispatcherBase::scale
void scale(DlScalar sx, DlScalar sy) override
Definition: dl_dispatcher.cc:339
impeller::Canvas::Skew
void Skew(Scalar sx, Scalar sy)
Definition: canvas.cc:347
impeller::FilterContents::BlurStyle
BlurStyle
Definition: filter_contents.h:26
impeller::Color
Definition: color.h:123
impeller::DlDispatcherBase::saveLayer
void saveLayer(const DlRect &bounds, const flutter::SaveLayerOptions &options, uint32_t total_content_depth, flutter::DlBlendMode max_content_mode, const flutter::DlImageFilter *backdrop) override
Definition: dl_dispatcher.cc:301
impeller::RenderToOnscreen
bool RenderToOnscreen(ContentContext &context, RenderTarget render_target, const sk_sp< flutter::DisplayList > &display_list, SkIRect cull_rect, bool reset_host_buffer)
Render the provided display list to the render target.
Definition: dl_dispatcher.cc:1253
impeller::skia_conversions::ToSamplerDescriptor
impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
Definition: skia_conversions.cc:169
impeller::TextFrameDispatcher::restore
void restore() override
Definition: dl_dispatcher.cc:1016
impeller::Canvas::SaveLayer
void SaveLayer(const Paint &paint, std::optional< Rect > bounds=std::nullopt, const flutter::DlImageFilter *backdrop_filter=nullptr, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, uint32_t total_content_depth=kMaxDepth, bool can_distribute_opacity=false)
Definition: canvas.cc:986
impeller::DlPath
flutter::DlPath DlPath
Definition: dl_dispatcher.h:25
impeller::Paint::color
Color color
Definition: paint.h:74
impeller::TextFrameDispatcher::save
void save() override
Definition: dl_dispatcher.cc:990
impeller::DlDispatcherBase::drawTextFrame
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, DlScalar x, DlScalar y) override
Definition: dl_dispatcher.cc:867
aiks_context.h
impeller::Canvas::DrawTextFrame
void DrawTextFrame(const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint)
Definition: canvas.cc:1313
dl_dispatcher.h
impeller::Canvas
Definition: canvas.h:101
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:466
impeller::PathBuilder::AddPath
PathBuilder & AddPath(const Path &path)
Definition: path_builder.cc:435
impeller::TRect::IsMaximum
constexpr bool IsMaximum() const
Definition: rect.h:308
impeller::PathBuilder
Definition: path_builder.h:14
impeller::TextFrameDispatcher::translate
void translate(DlScalar tx, DlScalar ty) override
Definition: dl_dispatcher.cc:1022
impeller::Paint::MaskBlurDescriptor::style
FilterContents::BlurStyle style
Definition: paint.h:52
impeller::PointStyle::kRound
@ kRound
Points are drawn as squares.
impeller::Vector2
Point Vector2
Definition: point.h:331
impeller::Canvas::ResetTransform
void ResetTransform()
Definition: canvas.cc:323
impeller::Canvas::DrawVertices
void DrawVertices(const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
Definition: canvas.cc:762
path_builder.h
formats.h
impeller::Color::alpha
Scalar alpha
Definition: color.h:142
impeller::Paint::MaskBlurDescriptor
Definition: paint.h:51
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:106
impeller::TextFrameDispatcher::setStrokeCap
void setStrokeCap(flutter::DlStrokeCap cap) override
Definition: dl_dispatcher.cc:1157
impeller::DlDispatcherBase::setColorFilter
void setColorFilter(const flutter::DlColorFilter *filter) override
Definition: dl_dispatcher.cc:230
impeller::Geometry::MakeOval
static std::unique_ptr< Geometry > MakeOval(const Rect &rect)
Definition: geometry.cc:93
impeller::DlDispatcherBase::drawShadow
void drawShadow(const DlPath &path, const flutter::DlColor color, const DlScalar elevation, bool transparent_occluder, DlScalar dpr) override
Definition: dl_dispatcher.cc:880
impeller::TextFrameDispatcher::drawTextFrame
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, DlScalar x, DlScalar y) override
Definition: dl_dispatcher.cc:1069
impeller::GlyphProperties::stroke_miter
Scalar stroke_miter
Definition: font_glyph_pair.h:25
impeller::DlIRect
flutter::DlIRect DlIRect
Definition: dl_dispatcher.h:24
impeller::FilterContents::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.
impeller::DlDispatcherBase::drawCircle
void drawCircle(const DlPoint &center, DlScalar radius) override
Definition: dl_dispatcher.cc:578
impeller::Paint::color_filter
const flutter::DlColorFilter * color_filter
Definition: paint.h:76
impeller::DlDispatcherBase::setStrokeMiter
void setStrokeMiter(DlScalar limit) override
Definition: dl_dispatcher.cc:178
impeller::Cap::kButt
@ kButt
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
AUTO_DEPTH_CHECK
#define AUTO_DEPTH_CHECK()
Definition: dl_dispatcher.cc:111
impeller::Color::green
Scalar green
Definition: color.h:132
impeller::DlDispatcherBase::translate
void translate(DlScalar tx, DlScalar ty) override
Definition: dl_dispatcher.cc:332
impeller::TextFrameDispatcher::setImageFilter
void setImageFilter(const flutter::DlImageFilter *filter) override
Definition: dl_dispatcher.cc:1187
impeller::Canvas::DrawRect
void DrawRect(const Rect &rect, const Paint &paint)
Definition: canvas.cc:559
impeller::Canvas::GetCurrentTransform
const Matrix & GetCurrentTransform() const
Definition: canvas.cc:331
UNIMPLEMENTED
#define UNIMPLEMENTED
Definition: dl_dispatcher.cc:115
impeller::GlyphProperties::color
Color color
Definition: font_glyph_pair.h:21
impeller::skia_conversions::ToBlendMode
BlendMode ToBlendMode(flutter::DlBlendMode mode)
Definition: skia_conversions.cc:204
impeller::DlDispatcherBase::drawLine
void drawLine(const DlPoint &p0, const DlPoint &p1) override
Definition: dl_dispatcher.cc:516
impeller::DlDispatcherBase::drawAtlas
void drawAtlas(const sk_sp< flutter::DlImage > atlas, const SkRSXform xform[], const DlRect tex[], const flutter::DlColor colors[], int count, flutter::DlBlendMode mode, flutter::DlImageSampling sampling, const DlRect *cull_rect, bool render_with_attributes) override
Definition: dl_dispatcher.cc:763
impeller::Join::kMiter
@ kMiter
impeller::DlDispatcherBase::drawVertices
void drawVertices(const std::shared_ptr< flutter::DlVertices > &vertices, flutter::DlBlendMode dl_mode) override
Definition: dl_dispatcher.cc:694
impeller::Paint::stroke_miter
Scalar stroke_miter
Definition: paint.h:82
impeller::TRect::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: rect.h:291
impeller::TRect::RoundOut
RoundOut(const TRect< U > &r)
Definition: rect.h:673
impeller::TextFrameDispatcher::transform2DAffine
void transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
Definition: dl_dispatcher.cc:1040
impeller::MinMagFilter::kNearest
@ kNearest
Select nearest to the sample point. Most widely supported.
impeller::DlAtlasGeometry
A wrapper around data provided by a drawAtlas call.
Definition: dl_atlas_geometry.h:18
impeller::TextFrameDispatcher::setColor
void setColor(flutter::DlColor color) override
Definition: dl_dispatcher.cc:1142
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:30
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::Canvas::GetMaxOpDepth
uint64_t GetMaxOpDepth() const
Definition: canvas.h:221
impeller::TextFrameDispatcher::transformFullPerspective
void transformFullPerspective(DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt, DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt, DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override
Definition: dl_dispatcher.cc:1051
impeller::ToSamplerDescriptor
static impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlFilterMode options)
Definition: dl_dispatcher.cc:118
impeller::TSize
Definition: size.h:19
impeller::PointStyle::kSquare
@ kSquare
Points are drawn as circles.
impeller::SamplerDescriptor::min_filter
MinMagFilter min_filter
Definition: sampler_descriptor.h:16
impeller::TextFrameDispatcher::~TextFrameDispatcher
~TextFrameDispatcher()
Definition: dl_dispatcher.cc:986
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::DlDispatcherBase::drawRRect
void drawRRect(const SkRRect &rrect) override
Definition: dl_dispatcher.cc:585
filter_contents.h
color_filter.h
impeller::RenderTarget::GetRenderTargetTexture
std::shared_ptr< Texture > GetRenderTargetTexture() const
Definition: render_target.cc:144
impeller::TRect::GetLeft
constexpr auto GetLeft() const
Definition: rect.h:345
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:339
impeller::DlDispatcherBase::drawPoints
void drawPoints(PointMode mode, uint32_t count, const DlPoint points[]) override
Definition: dl_dispatcher.cc:655
skia_conversions.h
impeller::DlDispatcherBase::setImageFilter
void setImageFilter(const flutter::DlImageFilter *filter) override
Definition: dl_dispatcher.cc:287
impeller::DlDispatcherBase::clipPath
void clipPath(const DlPath &path, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:473
sigma.h
impeller::DlDispatcherBase::setColorSource
void setColorSource(const flutter::DlColorSource *source) override
Definition: dl_dispatcher.cc:219
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:157
impeller::Matrix::GetScale
constexpr Vector3 GetScale() const
Definition: matrix.h:316
impeller::Canvas::GetLocalCoverageLimit
std::optional< Rect > GetLocalCoverageLimit() const
Return the culling bounds of the current render target, or nullopt if there is no coverage.
Definition: canvas.cc:955
impeller::DlDispatcherBase::setStrokeJoin
void setStrokeJoin(flutter::DlStrokeJoin join) override
Definition: dl_dispatcher.cc:202
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:213
impeller::TextFrameDispatcher::transformReset
void transformReset() override
Definition: dl_dispatcher.cc:1065
impeller::DlDispatcherBase::skew
void skew(DlScalar sx, DlScalar sy) override
Definition: dl_dispatcher.cc:353
impeller::MinMagFilter::kLinear
@ kLinear
impeller::Paint::style
Style style
Definition: paint.h:83
impeller::Color::WithAlpha
constexpr Color WithAlpha(Scalar new_alpha) const
Definition: color.h:277
impeller::Paint::Style::kFill
@ kFill
impeller::DlRect
flutter::DlRect DlRect
Definition: dl_dispatcher.h:23
impeller::CanvasDlDispatcher::drawVertices
void drawVertices(const std::shared_ptr< flutter::DlVertices > &vertices, flutter::DlBlendMode dl_mode) override
Definition: dl_dispatcher.cc:967
impeller::Canvas::DrawCircle
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition: canvas.cc:632
impeller::ToStyle
static Paint::Style ToStyle(flutter::DlDrawStyle style)
Definition: dl_dispatcher.cc:143
impeller::Matrix::Translate
constexpr Matrix Translate(const Vector3 &t) const
Definition: matrix.h:240
impeller::Paint::color_source
const flutter::DlColorSource * color_source
Definition: paint.h:75
impeller::Color::red
Scalar red
Definition: color.h:127
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:55
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::TextFrameDispatcher::rotate
void rotate(DlScalar degrees) override
Definition: dl_dispatcher.cc:1030
impeller::DlDispatcherBase::setAntiAlias
void setAntiAlias(bool aa) override
Definition: dl_dispatcher.cc:137
impeller::Canvas::Restore
bool Restore()
Definition: canvas.cc:1138
impeller::Paint::image_filter
const flutter::DlImageFilter * image_filter
Definition: paint.h:77
impeller::CanvasDlDispatcher::CanvasDlDispatcher
CanvasDlDispatcher(ContentContext &renderer, RenderTarget &render_target, bool has_root_backdrop_filter, flutter::DlBlendMode max_root_blend_mode, IRect cull_rect)
Definition: dl_dispatcher.cc:951
impeller::RenderTarget
Definition: render_target.h:38
impeller::GlyphProperties::stroke_join
Join stroke_join
Definition: font_glyph_pair.h:24
impeller::Canvas::DrawPath
void DrawPath(const Path &path, const Paint &paint)
Definition: canvas.cc:386
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:24
impeller::Canvas::DrawPaint
void DrawPaint(const Paint &paint)
Definition: canvas.cc:401
impeller::GlyphProperties::stroke
bool stroke
Definition: font_glyph_pair.h:26
filter_input.h
impeller::NinePatchConverter
Definition: nine_patch_converter.h:17
impeller::ToBlurStyle
static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style)
Definition: dl_dispatcher.cc:250
impeller::Canvas::GetSaveCount
size_t GetSaveCount() const
Definition: canvas.cc:370
impeller::Join::kRound
@ kRound
impeller::Canvas::DrawImageRect
void DrawImageRect(const std::shared_ptr< Texture > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
Definition: canvas.cc:716
impeller::DlDispatcherBase::drawPath
void drawPath(const DlPath &path) override
Definition: dl_dispatcher.cc:608
impeller::Vector3::y
Scalar y
Definition: vector.h:24
impeller::FilterContents::BlurStyle::kInner
@ kInner
Blurred inside, nothing outside.
dl_atlas_geometry.h
impeller::RenderTargetAllocator::CreateOffscreenMSAA
virtual RenderTarget CreateOffscreenMSAA(const Context &context, ISize size, int mip_count, const std::string &label="Offscreen MSAA", RenderTarget::AttachmentConfigMSAA color_attachment_config=RenderTarget::kDefaultColorAttachmentConfigMSAA, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_msaa_texture=nullptr, const std::shared_ptr< Texture > &existing_color_resolve_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr)
Definition: render_target.cc:313
impeller::Geometry::MakeRoundRect
static std::unique_ptr< Geometry > MakeRoundRect(const Rect &rect, const Size &radii)
Definition: geometry.cc:115
impeller::DlDispatcherBase::GetCanvas
virtual Canvas & GetCanvas()=0
impeller::RenderTargetAllocator
a wrapper around the impeller [Allocator] instance that can be used to provide caching of allocated r...
Definition: render_target.h:142
impeller::DlDispatcherBase::drawImageNine
void drawImageNine(const sk_sp< flutter::DlImage > image, const DlIRect &center, const DlRect &dst, flutter::DlFilterMode filter, bool render_with_attributes) override
Definition: dl_dispatcher.cc:747
impeller::TSize::width
Type width
Definition: size.h:22
impeller::Matrix::Invert
Matrix Invert() const
Definition: matrix.cc:97
impeller::GlyphProperties::stroke_width
Scalar stroke_width
Definition: font_glyph_pair.h:22
dl_vertices_geometry.h
impeller::DlDispatcherBase::clipRRect
void clipRRect(const SkRRect &rrect, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:448
impeller::Canvas::DrawAtlas
void DrawAtlas(const std::shared_ptr< AtlasContents > &atlas_contents, const Paint &paint)
Definition: canvas.cc:872
impeller::TextFrameDispatcher::saveLayer
void saveLayer(const DlRect &bounds, const flutter::SaveLayerOptions options, const flutter::DlImageFilter *backdrop) override
Definition: dl_dispatcher.cc:995
impeller::Canvas::ClipGeometry
void ClipGeometry(std::unique_ptr< Geometry > geometry, Entity::ClipOperation clip_op)
Definition: canvas.cc:655
impeller::DlDispatcherBase::SimplifyOrDrawPath
static void SimplifyOrDrawPath(Canvas &canvas, const DlPath &cache, const Paint &paint)
Definition: dl_dispatcher.cc:614
impeller::Canvas::GetOpDepth
uint64_t GetOpDepth() const
Definition: canvas.h:219
scalar.h
impeller::DlDispatcherBase::drawDashedLine
void drawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length) override
Definition: dl_dispatcher.cc:522
impeller::Canvas::PreConcat
void PreConcat(const Matrix &transform)
Definition: canvas.cc:319
impeller::DlDispatcherBase::drawDisplayList
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, DlScalar opacity) override
Definition: dl_dispatcher.cc:791
impeller::DlDispatcherBase::drawArc
void drawArc(const DlRect &oval_bounds, DlScalar start_degrees, DlScalar sweep_degrees, bool use_center) override
Definition: dl_dispatcher.cc:642
impeller::AiksContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: aiks_context.cc:38
impeller::Geometry::MakeRect
static std::unique_ptr< Geometry > MakeRect(const Rect &rect)
Definition: geometry.cc:89
atlas_contents.h
impeller::Join::kBevel
@ kBevel
impeller::TextFrameDispatcher::drawDisplayList
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, DlScalar opacity) override
Definition: dl_dispatcher.cc:1104
impeller::Canvas::DrawOval
void DrawOval(const Rect &rect, const Paint &paint)
Definition: canvas.cc:577
content_context.h
impeller::FilterContents::BlurStyle::kOuter
@ kOuter
Nothing inside, blurred outside.
impeller::TRect::GetRight
constexpr auto GetRight() const
Definition: rect.h:349
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:244
impeller::ContentContext::GetDeviceCapabilities
const Capabilities & GetDeviceCapabilities() const
Definition: content_context.cc:554
impeller::GlyphProperties::stroke_cap
Cap stroke_cap
Definition: font_glyph_pair.h:23
impeller::Canvas::Rotate
void Rotate(Radians radians)
Definition: canvas.cc:351
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150
impeller::TextFrameDispatcher::setStrokeMiter
void setStrokeMiter(DlScalar limit) override
Definition: dl_dispatcher.cc:1152
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:22
impeller::HostBuffer::Reset
void Reset()
Resets the contents of the HostBuffer to nothing so it can be reused.
Definition: host_buffer.cc:208
impeller::TPoint< Scalar >
impeller::TRect< Scalar >::MakeMaximum
constexpr static TRect MakeMaximum()
Definition: rect.h:178
impeller::Canvas::Transform
void Transform(const Matrix &transform)
Definition: canvas.cc:327
impeller::DlDispatcherBase::paint_
Paint paint_
Definition: dl_dispatcher.h:238
impeller::Canvas::DrawLine
void DrawLine(const Point &p0, const Point &p1, const Paint &paint, bool reuse_depth=false)
Definition: canvas.cc:546
impeller::PathBuilder::MoveTo
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:36
impeller::Geometry::MakeFillPath
static std::unique_ptr< Geometry > MakeFillPath(const Path &path, std::optional< Rect > inner_rect=std::nullopt)
Definition: geometry.cc:60
impeller::DlDispatcherBase::transform2DAffine
void transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
Definition: dl_dispatcher.cc:360
impeller::Paint::invert_colors
bool invert_colors
Definition: paint.h:85
impeller::Canvas::Save
void Save(uint32_t total_content_depth=kMaxDepth)
Definition: canvas.cc:938
impeller::TextFrameDispatcher::skew
void skew(DlScalar sx, DlScalar sy) override
Definition: dl_dispatcher.cc:1034
impeller::DlDispatcherBase::setColor
void setColor(flutter::DlColor color) override
Definition: dl_dispatcher.cc:164
impeller::SamplerDescriptor::label
std::string label
Definition: sampler_descriptor.h:24
impeller::Entity::ClipOperation
ClipOperation
Definition: entity.h:61
impeller::DlDispatcherBase::setStrokeWidth
void setStrokeWidth(DlScalar width) override
Definition: dl_dispatcher.cc:171
impeller::TRect::GetBottom
constexpr auto GetBottom() const
Definition: rect.h:351
impeller::Degrees
Definition: scalar.h:51
color.h
impeller::Paint::Style
Style
Definition: paint.h:46
color
DlColor color
Definition: dl_golden_blur_unittests.cc:24
impeller::DisplayListToTexture
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips)
Render the provided display list to a texture with the given size.
Definition: dl_dispatcher.cc:1195
impeller::skia_conversions::ToPath
Path ToPath(const SkRRect &rrect)
Definition: skia_conversions.cc:90
impeller::TSize::height
Type height
Definition: size.h:23
impeller::DlDispatcherBase::restore
void restore() override
Definition: dl_dispatcher.cc:327
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::NinePatchConverter::DrawNinePatch
void DrawNinePatch(const std::shared_ptr< Texture > &image, Rect center, Rect dst, const SamplerDescriptor &sampler, Canvas *canvas, Paint *paint)
Definition: nine_patch_converter.cc:60
impeller::DlDispatcherBase::initial_matrix_
Matrix initial_matrix_
Definition: dl_dispatcher.h:239
impeller::DlDispatcherBase::drawPaint
void drawPaint() override
Definition: dl_dispatcher.cc:509
impeller::TextFrameDispatcher
Performs a first pass over the display list to collect all text frames.
Definition: dl_dispatcher.h:288
nine_patch_converter.h
path.h
impeller::TSize::MipCount
constexpr size_t MipCount() const
Definition: size.h:115
impeller::DlDispatcherBase::drawOval
void drawOval(const DlRect &bounds) override
Definition: dl_dispatcher.cc:571
impeller::Color::blue
Scalar blue
Definition: color.h:137
impeller::DlDispatcherBase::clipRect
void clipRect(const DlRect &rect, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:429
impeller::DlDispatcherBase::setMaskFilter
void setMaskFilter(const flutter::DlMaskFilter *filter) override
Definition: dl_dispatcher.cc:264
impeller::DlDispatcherBase::clipOval
void clipOval(const DlRect &bounds, ClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:438
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:237
impeller::DlScalar
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:21
impeller
Definition: allocation.cc:12
impeller::Paint::mask_blur_descriptor
std::optional< MaskBlurDescriptor > mask_blur_descriptor
Definition: paint.h:87
impeller::ContentContext
Definition: content_context.h:366
impeller::TRect::GetTop
constexpr auto GetTop() const
Definition: rect.h:347
impeller::Paint::stroke_width
Scalar stroke_width
Definition: paint.h:79
impeller::TRect< Scalar >
impeller::DlDispatcherBase::transformFullPerspective
void transformFullPerspective(DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt, DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt, DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override
Definition: dl_dispatcher.cc:379
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:323
impeller::Vector3
Definition: vector.h:20
impeller::RequiresReadbackForBlends
static bool RequiresReadbackForBlends(const ContentContext &renderer, flutter::DlBlendMode max_root_blend_mode)
Subclasses.
Definition: dl_dispatcher.cc:943
impeller::DlDispatcherBase::drawImage
void drawImage(const sk_sp< flutter::DlImage > image, const DlPoint &point, flutter::DlImageSampling sampling, bool render_with_attributes) override
Definition: dl_dispatcher.cc:699
impeller::Paint::blend_mode
BlendMode blend_mode
Definition: paint.h:84
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:753
impeller::Matrix::Scale
constexpr Matrix Scale(const Vector3 &s) const
Definition: matrix.h:252
impeller::Paint::stroke_join
Join stroke_join
Definition: paint.h:81
impeller::Canvas::Translate
void Translate(const Vector3 &offset)
Definition: canvas.cc:335
impeller::DlDispatcherBase::rotate
void rotate(DlScalar degrees) override
Definition: dl_dispatcher.cc:346
impeller::DlDispatcherBase::drawTextBlob
void drawTextBlob(const sk_sp< SkTextBlob > blob, DlScalar x, DlScalar y) override
Definition: dl_dispatcher.cc:858