| 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 <vector>
12
13 #include "display_list/dl_sampling_options.h"
14 #include "display_list/effects/dl_image_filter.h"
15 #include "flutter/fml/logging.h"
16 #include "fml/closure.h"
17 #include "impeller/core/formats.h"
18 #include "impeller/display_list/aiks_context.h"
19 #include "impeller/display_list/canvas.h"
20 #include "impeller/display_list/dl_atlas_geometry.h"
21 #include "impeller/display_list/dl_vertices_geometry.h"
22 #include "impeller/display_list/nine_patch_converter.h"
23 #include "impeller/display_list/skia_conversions.h"
24 #include "impeller/entity/contents/atlas_contents.h"
25 #include "impeller/entity/contents/content_context.h"
26 #include "impeller/entity/contents/filters/filter_contents.h"
27 #include "impeller/entity/contents/filters/inputs/filter_input.h"
28 #include "impeller/entity/entity.h"
29 #include "impeller/entity/geometry/ellipse_geometry.h"
30 #include "impeller/entity/geometry/fill_path_geometry.h"
31 #include "impeller/entity/geometry/rect_geometry.h"
32 #include "impeller/entity/geometry/round_rect_geometry.h"
33 #include "impeller/entity/geometry/round_superellipse_geometry.h"
34 #include "impeller/geometry/color.h"
35 #include "impeller/geometry/scalar.h"
36 #include "impeller/geometry/sigma.h"
37 #include "impeller/typographer/font_glyph_pair.h"
38
39 namespace impeller {
40
41 #if !defined(NDEBUG)
42 #define USE_DEPTH_WATCHER true
43 #else
44 #define USE_DEPTH_WATCHER false
45 #endif // !defined(NDEBUG)
46
47 #if USE_DEPTH_WATCHER
48
49 // Invoke this macro at the top of any DlOpReceiver dispatch function
50 // using a number indicating the maximum depth that the operation is
51 // expected to consume in the Canvas. Most rendering ops consume 1
52 // except for DrawImageNine that currently consumes 1 per section (i.e. 9).
53 // Attribute, clip and transform ops do not consume depth but this
54 // macro can still be used with an argument of 0 to verify that expectation.
55 //
56 // The watchdog object allocated here will automatically double-check
57 // the depth usage at any exit point to the function, or any other
58 // point at which it falls out of scope.
59 #define AUTO_DEPTH_WATCHER(d) \
60 DepthWatcher _watcher(__FILE__, __LINE__, GetCanvas(), \
61 paint_.mask_blur_descriptor.has_value(), d)
62
63 // While the AUTO_DEPTH_WATCHER macro will check the depth usage at
64 // any exit point from the dispatch function, sometimes the dispatch
65 // functions are somewhat compounded and result in multiple Canvas
66 // calls.
67 //
68 // Invoke this macro at any key points in the middle of a dispatch
69 // function to verify that you still haven't exceeded the maximum
70 // allowed depth. This is especially useful if the function does
71 // an implicit save/restore where the restore call might assert the
72 // depth constraints in a function in Canvas that can't be as easily
73 // traced back to a given dispatch function as these macros can.
74 #define AUTO_DEPTH_CHECK() _watcher.check(__FILE__, __LINE__)
75
76 // Helper class, use the AUTO_DEPTH_WATCHER macros to access it
77 struct DepthWatcher {
78 DepthWatcher(const std::string& file,
79 int line,
80 const impeller::Canvas& canvas,
81 bool has_mask_blur,
82 int allowed)
83 : file_(file),
84 line_(line),
85 canvas_(canvas),
86 allowed_(has_mask_blur ? allowed + 1 : allowed),
87 old_depth_(canvas.GetOpDepth()),
88 old_max_(canvas.GetMaxOpDepth()) {}
89
90 ~DepthWatcher() { check(file_, line_); }
91
92 void check(const std::string& file, int line) {
93 FML_CHECK(canvas_.GetOpDepth() <= (old_depth_ + allowed_) &&
94 canvas_.GetOpDepth() <= old_max_)
95 << std::endl
96 << "from " << file << ":" << line << std::endl
97 << "old/allowed/current/max = " << old_depth_ << "/" << allowed_ << "/"
98 << canvas_.GetOpDepth() << "/" << old_max_;
99 }
100
101 private:
102 const std::string file_;
103 const int line_;
104
105 const impeller::Canvas& canvas_;
106 const uint64_t allowed_;
107 const uint64_t old_depth_;
108 const uint64_t old_max_;
109 };
110
111 #else // USE_DEPTH_WATCHER
112
113 #define AUTO_DEPTH_WATCHER(d)
114 #define AUTO_DEPTH_CHECK()
115
116 #endif // USE_DEPTH_WATCHER
117
118 #define UNIMPLEMENTED \
119 FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
120
121 static impeller::SamplerDescriptor ToSamplerDescriptor(
122 const flutter::DlFilterMode options) {
123 impeller::SamplerDescriptor desc;
124 switch (options) {
125 case flutter::DlFilterMode::kNearest:
126 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
127 desc.label = "Nearest Sampler";
128 break;
129 case flutter::DlFilterMode::kLinear:
130 desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
131 desc.label = "Linear Sampler";
132 break;
133 default:
134 break;
135 }
136 return desc;
137 }
138
139 static std::optional<const Rect> ToOptRect(const flutter::DlRect* rect) {
140 if (rect == nullptr) {
141 return std::nullopt;
142 }
143 return *rect;
144 }
145
146 // |flutter::DlOpReceiver|
147 void DlDispatcherBase::setAntiAlias(bool aa) {
148 AUTO_DEPTH_WATCHER(0u);
149
150 // Nothing to do because AA is implicit.
151 }
152
153 static Paint::Style ToStyle(flutter::DlDrawStyle style) {
154 switch (style) {
155 case flutter::DlDrawStyle::kFill:
156 return Paint::Style::kFill;
157 case flutter::DlDrawStyle::kStroke:
158 return Paint::Style::kStroke;
159 case flutter::DlDrawStyle::kStrokeAndFill:
160 UNIMPLEMENTED;
161 break;
162 }
163 return Paint::Style::kFill;
164 }
165
166 // |flutter::DlOpReceiver|
167 void DlDispatcherBase::setDrawStyle(flutter::DlDrawStyle style) {
168 AUTO_DEPTH_WATCHER(0u);
169
170 paint_.style = ToStyle(style);
171 }
172
173 // |flutter::DlOpReceiver|
174 void DlDispatcherBase::setColor(flutter::DlColor color) {
175 AUTO_DEPTH_WATCHER(0u);
176
177 paint_.color = skia_conversions::ToColor(color);
178 }
179
180 // |flutter::DlOpReceiver|
181 void DlDispatcherBase::setStrokeWidth(DlScalar width) {
182 AUTO_DEPTH_WATCHER(0u);
183
184 paint_.stroke.width = width;
185 }
186
187 // |flutter::DlOpReceiver|
188 void DlDispatcherBase::setStrokeMiter(DlScalar limit) {
189 AUTO_DEPTH_WATCHER(0u);
190
191 paint_.stroke.miter_limit = limit;
192 }
193
194 // |flutter::DlOpReceiver|
195 void DlDispatcherBase::setStrokeCap(flutter::DlStrokeCap cap) {
196 AUTO_DEPTH_WATCHER(0u);
197
198 switch (cap) {
199 case flutter::DlStrokeCap::kButt:
200 paint_.stroke.cap = Cap::kButt;
201 break;
202 case flutter::DlStrokeCap::kRound:
203 paint_.stroke.cap = Cap::kRound;
204 break;
205 case flutter::DlStrokeCap::kSquare:
206 paint_.stroke.cap = Cap::kSquare;
207 break;
208 }
209 }
210
211 // |flutter::DlOpReceiver|
212 void DlDispatcherBase::setStrokeJoin(flutter::DlStrokeJoin join) {
213 AUTO_DEPTH_WATCHER(0u);
214
215 switch (join) {
216 case flutter::DlStrokeJoin::kMiter:
217 paint_.stroke.join = Join::kMiter;
218 break;
219 case flutter::DlStrokeJoin::kRound:
220 paint_.stroke.join = Join::kRound;
221 break;
222 case flutter::DlStrokeJoin::kBevel:
223 paint_.stroke.join = Join::kBevel;
224 break;
225 }
226 }
227
228 // |flutter::DlOpReceiver|
229 void DlDispatcherBase::setColorSource(const flutter::DlColorSource* source) {
230 AUTO_DEPTH_WATCHER(0u);
231
232 paint_.color_source = source;
233 }
234
235 // |flutter::DlOpReceiver|
236 void DlDispatcherBase::setColorFilter(const flutter::DlColorFilter* filter) {
237 AUTO_DEPTH_WATCHER(0u);
238
239 paint_.color_filter = filter;
240 }
241
242 // |flutter::DlOpReceiver|
243 void DlDispatcherBase::setInvertColors(bool invert) {
244 AUTO_DEPTH_WATCHER(0u);
245
246 paint_.invert_colors = invert;
247 }
248
249 // |flutter::DlOpReceiver|
250 void DlDispatcherBase::setBlendMode(flutter::DlBlendMode dl_mode) {
251 AUTO_DEPTH_WATCHER(0u);
252
253 paint_.blend_mode = dl_mode;
254 }
255
256 static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style) {
257 switch (blur_style) {
258 case flutter::DlBlurStyle::kNormal:
259 return FilterContents::BlurStyle::kNormal;
260 case flutter::DlBlurStyle::kSolid:
261 return FilterContents::BlurStyle::kSolid;
262 case flutter::DlBlurStyle::kOuter:
263 return FilterContents::BlurStyle::kOuter;
264 case flutter::DlBlurStyle::kInner:
265 return FilterContents::BlurStyle::kInner;
266 }
267 }
268
269 // |flutter::DlOpReceiver|
270 void DlDispatcherBase::setMaskFilter(const flutter::DlMaskFilter* filter) {
271 AUTO_DEPTH_WATCHER(0u);
272
273 // Needs https://github.com/flutter/flutter/issues/95434
274 if (filter == nullptr) {
275 paint_.mask_blur_descriptor = std::nullopt;
276 return;
277 }
278 switch (filter->type()) {
279 case flutter::DlMaskFilterType::kBlur: {
280 auto blur = filter->asBlur();
281
282 paint_.mask_blur_descriptor = {
283 .style = ToBlurStyle(blur->style()),
284 .sigma = Sigma(blur->sigma()),
285 .respect_ctm = blur->respectCTM(),
286 };
287 break;
288 }
289 }
290 }
291
292 // |flutter::DlOpReceiver|
293 void DlDispatcherBase::setImageFilter(const flutter::DlImageFilter* filter) {
294 AUTO_DEPTH_WATCHER(0u);
295
296 paint_.image_filter = filter;
297 }
298
299 // |flutter::DlOpReceiver|
300 void DlDispatcherBase::save(uint32_t total_content_depth) {
301 AUTO_DEPTH_WATCHER(1u);
302
303 GetCanvas().Save(total_content_depth);
304 }
305
306 // |flutter::DlOpReceiver|
307 void DlDispatcherBase::saveLayer(const DlRect& bounds,
308 const flutter::SaveLayerOptions& options,
309 uint32_t total_content_depth,
310 flutter::DlBlendMode max_content_mode,
311 const flutter::DlImageFilter* backdrop,
312 std::optional<int64_t> backdrop_id) {
313 AUTO_DEPTH_WATCHER(1u);
314
315 auto paint = options.renders_with_attributes() ? paint_ : Paint{};
316 auto promise = options.content_is_clipped()
317 ? ContentBoundsPromise::kMayClipContents
318 : ContentBoundsPromise::kContainsContents;
319 std::optional<Rect> impeller_bounds;
320 // If the content is unbounded but has developer specified bounds, we take
321 // the original bounds so that we clip the content as expected.
322 if (!options.content_is_unbounded() || options.bounds_from_caller()) {
323 impeller_bounds = bounds;
324 }
325
326 GetCanvas().SaveLayer(
327 paint, impeller_bounds, backdrop, promise, total_content_depth,
328 // Unbounded content can still have user specified bounds that require a
329 // saveLayer to be created to perform the clip.
330 options.can_distribute_opacity() && !options.content_is_unbounded(),
331 backdrop_id //
332 );
333 }
334
335 // |flutter::DlOpReceiver|
336 void DlDispatcherBase::restore() {
337 GetCanvas().Restore();
338 }
339
340 // |flutter::DlOpReceiver|
341 void DlDispatcherBase::translate(DlScalar tx, DlScalar ty) {
342 AUTO_DEPTH_WATCHER(0u);
343
344 GetCanvas().Translate({tx, ty, 0.0});
345 }
346
347 // |flutter::DlOpReceiver|
348 void DlDispatcherBase::scale(DlScalar sx, DlScalar sy) {
349 AUTO_DEPTH_WATCHER(0u);
350
351 GetCanvas().Scale({sx, sy, 1.0});
352 }
353
354 // |flutter::DlOpReceiver|
355 void DlDispatcherBase::rotate(DlScalar degrees) {
356 AUTO_DEPTH_WATCHER(0u);
357
358 GetCanvas().Rotate(Degrees{degrees});
359 }
360
361 // |flutter::DlOpReceiver|
362 void DlDispatcherBase::skew(DlScalar sx, DlScalar sy) {
363 AUTO_DEPTH_WATCHER(0u);
364
365 GetCanvas().Skew(sx, sy);
366 }
367
368 // |flutter::DlOpReceiver|
369 void DlDispatcherBase::transform2DAffine(DlScalar mxx,
370 DlScalar mxy,
371 DlScalar mxt,
372 DlScalar myx,
373 DlScalar myy,
374 DlScalar myt) {
375 AUTO_DEPTH_WATCHER(0u);
376
377 // clang-format off
378 transformFullPerspective(
379 mxx, mxy, 0, mxt,
380 myx, myy, 0, myt,
381 0 , 0, 1, 0,
382 0 , 0, 0, 1
383 );
384 // clang-format on
385 }
386
387 // |flutter::DlOpReceiver|
388 void DlDispatcherBase::transformFullPerspective(DlScalar mxx,
389 DlScalar mxy,
390 DlScalar mxz,
391 DlScalar mxt,
392 DlScalar myx,
393 DlScalar myy,
394 DlScalar myz,
395 DlScalar myt,
396 DlScalar mzx,
397 DlScalar mzy,
398 DlScalar mzz,
399 DlScalar mzt,
400 DlScalar mwx,
401 DlScalar mwy,
402 DlScalar mwz,
403 DlScalar mwt) {
404 AUTO_DEPTH_WATCHER(0u);
405
406 // The order of arguments is row-major but Impeller matrices are
407 // column-major.
408 // clang-format off
409 auto transform = Matrix{
410 mxx, myx, mzx, mwx,
411 mxy, myy, mzy, mwy,
412 mxz, myz, mzz, mwz,
413 mxt, myt, mzt, mwt
414 };
415 // clang-format on
416 GetCanvas().Transform(transform);
417 }
418
419 // |flutter::DlOpReceiver|
420 void DlDispatcherBase::transformReset() {
421 AUTO_DEPTH_WATCHER(0u);
422
423 GetCanvas().ResetTransform();
424 GetCanvas().Transform(initial_matrix_);
425 }
426
427 static Entity::ClipOperation ToClipOperation(flutter::DlClipOp clip_op) {
428 switch (clip_op) {
429 case flutter::DlClipOp::kDifference:
430 return Entity::ClipOperation::kDifference;
431 case flutter::DlClipOp::kIntersect:
432 return Entity::ClipOperation::kIntersect;
433 }
434 }
435
436 // |flutter::DlOpReceiver|
437 void DlDispatcherBase::clipRect(const DlRect& rect,
438 flutter::DlClipOp clip_op,
439 bool is_aa) {
440 AUTO_DEPTH_WATCHER(0u);
441
442 FillRectGeometry geom(rect);
443 GetCanvas().ClipGeometry(geom, ToClipOperation(clip_op), /*is_aa=*/is_aa);
444 }
445
446 // |flutter::DlOpReceiver|
447 void DlDispatcherBase::clipOval(const DlRect& bounds,
448 flutter::DlClipOp clip_op,
449 bool is_aa) {
450 AUTO_DEPTH_WATCHER(0u);
451
452 EllipseGeometry geom(bounds);
453 GetCanvas().ClipGeometry(geom, ToClipOperation(clip_op));
454 }
455
456 // |flutter::DlOpReceiver|
457 void DlDispatcherBase::clipRoundRect(const DlRoundRect& rrect,
458 flutter::DlClipOp sk_op,
459 bool is_aa) {
460 AUTO_DEPTH_WATCHER(0u);
461
462 auto clip_op = ToClipOperation(sk_op);
463 if (rrect.IsRect()) {
464 FillRectGeometry geom(rrect.GetBounds());
465 GetCanvas().ClipGeometry(geom, clip_op, /*is_aa=*/is_aa);
466 } else if (rrect.IsOval()) {
467 EllipseGeometry geom(rrect.GetBounds());
468 GetCanvas().ClipGeometry(geom, clip_op);
469 } else if (rrect.GetRadii().AreAllCornersSame()) {
470 RoundRectGeometry geom(rrect.GetBounds(), rrect.GetRadii().top_left);
471 GetCanvas().ClipGeometry(geom, clip_op);
472 } else {
473 FillRoundRectGeometry geom(rrect);
474 GetCanvas().ClipGeometry(geom, clip_op);
475 }
476 }
477
478 // |flutter::DlOpReceiver|
479 void DlDispatcherBase::clipRoundSuperellipse(const DlRoundSuperellipse& rse,
480 flutter::DlClipOp sk_op,
481 bool is_aa) {
482 AUTO_DEPTH_WATCHER(0u);
483
484 auto clip_op = ToClipOperation(sk_op);
485 if (rse.IsRect()) {
486 FillRectGeometry geom(rse.GetBounds());
487 GetCanvas().ClipGeometry(geom, clip_op, /*is_aa=*/is_aa);
488 } else if (rse.IsOval()) {
489 EllipseGeometry geom(rse.GetBounds());
490 GetCanvas().ClipGeometry(geom, clip_op);
491 } else {
492 RoundSuperellipseGeometry geom(rse.GetBounds(), rse.GetRadii());
493 GetCanvas().ClipGeometry(geom, clip_op);
494 }
495 }
496
497 // |flutter::DlOpReceiver|
498 void DlDispatcherBase::clipPath(const DlPath& path,
499 flutter::DlClipOp sk_op,
500 bool is_aa) {
501 AUTO_DEPTH_WATCHER(0u);
502
503 auto clip_op = ToClipOperation(sk_op);
504
505 DlRect rect;
506 if (path.IsRect(&rect)) {
507 FillRectGeometry geom(rect);
508 GetCanvas().ClipGeometry(geom, clip_op, /*is_aa=*/is_aa);
509 } else if (path.IsOval(&rect)) {
510 EllipseGeometry geom(rect);
511 GetCanvas().ClipGeometry(geom, clip_op);
512 } else {
513 DlRoundRect rrect;
514 if (path.IsRoundRect(&rrect) && rrect.GetRadii().AreAllCornersSame()) {
515 RoundRectGeometry geom(rrect.GetBounds(), rrect.GetRadii().top_left);
516 GetCanvas().ClipGeometry(geom, clip_op);
517 } else {
518 FillPathGeometry geom(path);
519 GetCanvas().ClipGeometry(geom, clip_op);
520 }
521 }
522 }
523
524 // |flutter::DlOpReceiver|
525 void DlDispatcherBase::drawColor(flutter::DlColor color,
526 flutter::DlBlendMode dl_mode) {
527 AUTO_DEPTH_WATCHER(1u);
528
529 Paint paint;
530 paint.color = skia_conversions::ToColor(color);
531 paint.blend_mode = dl_mode;
532 GetCanvas().DrawPaint(paint);
533 }
534
535 // |flutter::DlOpReceiver|
536 void DlDispatcherBase::drawPaint() {
537 AUTO_DEPTH_WATCHER(1u);
538
539 GetCanvas().DrawPaint(paint_);
540 }
541
542 // |flutter::DlOpReceiver|
543 void DlDispatcherBase::drawLine(const DlPoint& p0, const DlPoint& p1) {
544 AUTO_DEPTH_WATCHER(1u);
545
546 GetCanvas().DrawLine(p0, p1, paint_);
547 }
548
549 // |flutter::DlOpReceiver|
550 void DlDispatcherBase::drawDashedLine(const DlPoint& p0,
551 const DlPoint& p1,
552 DlScalar on_length,
553 DlScalar off_length) {
554 AUTO_DEPTH_WATCHER(1u);
555
556 GetCanvas().DrawDashedLine(p0, p1, on_length, off_length, paint_);
557 }
558
559 // |flutter::DlOpReceiver|
560 void DlDispatcherBase::drawRect(const DlRect& rect) {
561 AUTO_DEPTH_WATCHER(1u);
562
563 GetCanvas().DrawRect(rect, paint_);
564 }
565
566 // |flutter::DlOpReceiver|
567 void DlDispatcherBase::drawOval(const DlRect& bounds) {
568 AUTO_DEPTH_WATCHER(1u);
569
570 GetCanvas().DrawOval(bounds, paint_);
571 }
572
573 // |flutter::DlOpReceiver|
574 void DlDispatcherBase::drawCircle(const DlPoint& center, DlScalar radius) {
575 AUTO_DEPTH_WATCHER(1u);
576
577 GetCanvas().DrawCircle(center, radius, paint_);
578 }
579
580 // |flutter::DlOpReceiver|
581 void DlDispatcherBase::drawRoundRect(const DlRoundRect& rrect) {
582 AUTO_DEPTH_WATCHER(1u);
583
584 GetCanvas().DrawRoundRect(rrect, paint_);
585 }
586
587 // |flutter::DlOpReceiver|
588 void DlDispatcherBase::drawDiffRoundRect(const DlRoundRect& outer,
589 const DlRoundRect& inner) {
590 AUTO_DEPTH_WATCHER(1u);
591
592 GetCanvas().DrawDiffRoundRect(outer, inner, paint_);
593 }
594
595 // |flutter::DlOpReceiver|
596 void DlDispatcherBase::drawRoundSuperellipse(const DlRoundSuperellipse& rse) {
597 AUTO_DEPTH_WATCHER(1u);
598
599 GetCanvas().DrawRoundSuperellipse(rse, paint_);
600 }
601
602 // |flutter::DlOpReceiver|
603 void DlDispatcherBase::drawPath(const DlPath& path) {
604 AUTO_DEPTH_WATCHER(1u);
605
606 SimplifyOrDrawPath(GetCanvas(), path, paint_);
607 }
608
609 void DlDispatcherBase::SimplifyOrDrawPath(Canvas& canvas,
610 const DlPath& path,
611 const Paint& paint) {
612 DlRect rect;
613
614 // We can't "optimize" a path into a rectangle if it's open.
615 bool closed;
616 if (path.IsRect(&rect, &closed) && closed) {
617 canvas.DrawRect(rect, paint);
618 return;
619 }
620
621 DlRoundRect rrect;
622 if (path.IsRoundRect(&rrect) && rrect.GetRadii().AreAllCornersSame()) {
623 canvas.DrawRoundRect(rrect, paint);
624 return;
625 }
626
627 if (path.IsOval(&rect)) {
628 canvas.DrawOval(rect, paint);
629 return;
630 }
631
632 DlPoint start;
633 DlPoint end;
634 if (path.IsLine(&start, &end)) {
635 canvas.DrawLine(start, end, paint);
636 return;
637 }
638
639 canvas.DrawPath(path, paint);
640 }
641
642 // |flutter::DlOpReceiver|
643 void DlDispatcherBase::drawArc(const DlRect& oval_bounds,
644 DlScalar start_degrees,
645 DlScalar sweep_degrees,
646 bool use_center) {
647 AUTO_DEPTH_WATCHER(1u);
648
649 GetCanvas().DrawArc(Arc(oval_bounds, Degrees(start_degrees),
650 Degrees(sweep_degrees), use_center),
651 paint_);
652 }
653
654 // |flutter::DlOpReceiver|
655 void DlDispatcherBase::drawPoints(flutter::DlPointMode 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::DlPointMode::kPoints: {
664 // Cap::kButt is also treated as a square.
665 PointStyle point_style = paint.stroke.cap == Cap::kRound
666 ? PointStyle::kRound
667 : PointStyle::kSquare;
668 Scalar radius = paint.stroke.width;
669 if (radius > 0) {
670 radius /= 2.0;
671 }
672 GetCanvas().DrawPoints(points, count, radius, paint, point_style);
673 } break;
674 case flutter::DlPointMode::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::DlPointMode::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 flutter::DlSrcRectConstraint::kStrict // constraint
724 );
725 }
726
727 // |flutter::DlOpReceiver|
728 void DlDispatcherBase::drawImageRect(const sk_sp<flutter::DlImage> image,
729 const DlRect& src,
730 const DlRect& dst,
731 flutter::DlImageSampling sampling,
732 bool render_with_attributes,
733 flutter::DlSrcRectConstraint constraint =
734 flutter::DlSrcRectConstraint::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 RSTransform 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 mode, //
781 skia_conversions::ToSamplerDescriptor(sampling), //
782 ToOptRect(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(save_paint, display_list->GetBounds(), nullptr,
817 ContentBoundsPromise::kContainsContents,
818 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(*this, cull_rect);
839 } else {
840 // If the culling bounds are empty, this display list can be skipped
841 // entirely.
842 }
843 } else {
844 display_list->Dispatch(*this);
845 }
846
847 // Restore all saved state back to what it was before we interpreted
848 // the display_list
849 AUTO_DEPTH_CHECK();
850 GetCanvas().RestoreToCount(restore_count);
851 initial_matrix_ = saved_initial_matrix;
852 paint_ = saved_paint;
853 }
854
855 // |flutter::DlOpReceiver|
856 void DlDispatcherBase::drawTextBlob(const sk_sp<SkTextBlob> blob,
857 DlScalar x,
858 DlScalar y) {
859 // When running with Impeller enabled Skia text blobs are converted to
860 // Impeller text frames in paragraph_skia.cc
861 UNIMPLEMENTED;
862 }
863
864 // |flutter::DlOpReceiver|
865 void DlDispatcherBase::drawTextFrame(
866 const std::shared_ptr<TextFrame>& text_frame,
867 DlScalar x,
868 DlScalar y) {
869 AUTO_DEPTH_WATCHER(1u);
870
871 GetCanvas().DrawTextFrame(text_frame, //
872 impeller::Point{x, y}, //
873 paint_ //
874 );
875 }
876
877 // |flutter::DlOpReceiver|
878 void DlDispatcherBase::drawShadow(const DlPath& path,
879 const flutter::DlColor color,
880 const DlScalar elevation,
881 bool transparent_occluder,
882 DlScalar dpr) {
883 AUTO_DEPTH_WATCHER(1u);
884
885 Color spot_color = skia_conversions::ToColor(color);
886 spot_color.alpha *= 0.25;
887
888 // Compute the spot color -- ported from SkShadowUtils::ComputeTonalColors.
889 {
890 Scalar max =
891 std::max(std::max(spot_color.red, spot_color.green), spot_color.blue);
892 Scalar min =
893 std::min(std::min(spot_color.red, spot_color.green), spot_color.blue);
894 Scalar luminance = (min + max) * 0.5;
895
896 Scalar alpha_adjust =
897 (2.6f + (-2.66667f + 1.06667f * spot_color.alpha) * spot_color.alpha) *
898 spot_color.alpha;
899 Scalar color_alpha =
900 (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) *
901 luminance;
902 color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f);
903
904 Scalar greyscale_alpha =
905 std::clamp(spot_color.alpha * (1 - 0.4f * luminance), 0.0f, 1.0f);
906
907 Scalar color_scale = color_alpha * (1 - greyscale_alpha);
908 Scalar tonal_alpha = color_scale + greyscale_alpha;
909 Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0;
910 spot_color = Color(unpremul_scale * spot_color.red,
911 unpremul_scale * spot_color.green,
912 unpremul_scale * spot_color.blue, tonal_alpha);
913 }
914
915 Vector3 light_position(0, -1, 1);
916 Scalar occluder_z = dpr * elevation;
917
918 constexpr Scalar kLightRadius = 800 / 600; // Light radius / light height
919
920 Paint paint;
921 paint.style = Paint::Style::kFill;
922 paint.color = spot_color;
923 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
924 .style = FilterContents::BlurStyle::kNormal,
925 .sigma = Radius{kLightRadius * occluder_z /
926 GetCanvas().GetCurrentTransform().GetScale().y},
927 };
928
929 GetCanvas().Save(1u);
930 GetCanvas().PreConcat(
931 Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y)));
932
933 SimplifyOrDrawPath(GetCanvas(), path, paint);
934 AUTO_DEPTH_CHECK();
935
936 GetCanvas().Restore();
937 }
938
939 /// Subclasses
940
941 static bool RequiresReadbackForBlends(
942 const ContentContext& renderer,
943 flutter::DlBlendMode max_root_blend_mode) {
944 return !renderer.GetDeviceCapabilities().SupportsFramebufferFetch() &&
945 max_root_blend_mode > Entity::kLastPipelineBlendMode;
946 }
947
948 CanvasDlDispatcher::CanvasDlDispatcher(ContentContext& renderer,
949 RenderTarget& render_target,
950 bool is_onscreen,
951 bool has_root_backdrop_filter,
952 flutter::DlBlendMode max_root_blend_mode,
953 IRect32 cull_rect)
954 : canvas_(renderer,
955 render_target,
956 is_onscreen,
957 has_root_backdrop_filter ||
958 RequiresReadbackForBlends(renderer, max_root_blend_mode),
959 cull_rect),
960 renderer_(renderer) {}
961
962 Canvas& CanvasDlDispatcher::GetCanvas() {
963 return canvas_;
964 }
965
966 void CanvasDlDispatcher::drawVertices(
967 const std::shared_ptr<flutter::DlVertices>& vertices,
968 flutter::DlBlendMode dl_mode) {
969 AUTO_DEPTH_WATCHER(1u);
970
971 GetCanvas().DrawVertices(
972 std::make_shared<DlVerticesGeometry>(vertices, renderer_), dl_mode,
973 paint_);
974 }
975
976 void CanvasDlDispatcher::SetBackdropData(
977 std::unordered_map<int64_t, BackdropData> backdrop,
978 size_t backdrop_count) {
979 GetCanvas().SetBackdropData(std::move(backdrop), backdrop_count);
980 }
981
982 //// Text Frame Dispatcher
983
984 FirstPassDispatcher::FirstPassDispatcher(const ContentContext& renderer,
985 const Matrix& initial_matrix,
986 const Rect cull_rect)
987 : renderer_(renderer), matrix_(initial_matrix) {
988 cull_rect_state_.push_back(cull_rect);
989 }
990
991 FirstPassDispatcher::~FirstPassDispatcher() {
992 FML_DCHECK(cull_rect_state_.size() == 1);
993 }
994
995 void FirstPassDispatcher::save() {
996 stack_.emplace_back(matrix_);
997 cull_rect_state_.push_back(cull_rect_state_.back());
998 }
999
1000 void FirstPassDispatcher::saveLayer(const DlRect& bounds,
1001 const flutter::SaveLayerOptions options,
1002 const flutter::DlImageFilter* backdrop,
1003 std::optional<int64_t> backdrop_id) {
1004 save();
1005
1006 backdrop_count_ += (backdrop == nullptr ? 0 : 1);
1007 if (backdrop != nullptr && backdrop_id.has_value()) {
1008 std::shared_ptr<flutter::DlImageFilter> shared_backdrop =
1009 backdrop->shared();
1010 std::unordered_map<int64_t, BackdropData>::iterator existing =
1011 backdrop_data_.find(backdrop_id.value());
1012 if (existing == backdrop_data_.end()) {
1013 backdrop_data_[backdrop_id.value()] =
1014 BackdropData{.backdrop_count = 1, .last_backdrop = shared_backdrop};
1015 } else {
1016 BackdropData& data = existing->second;
1017 data.backdrop_count++;
1018 if (data.all_filters_equal) {
1019 data.all_filters_equal = (*data.last_backdrop == *shared_backdrop);
1020 data.last_backdrop = shared_backdrop;
1021 }
1022 }
1023 }
1024
1025 // This dispatcher does not track enough state to accurately compute
1026 // cull rects with image filters.
1027 auto global_cull_rect = cull_rect_state_.back();
1028 if (has_image_filter_ || global_cull_rect.IsMaximum()) {
1029 cull_rect_state_.back() = Rect::MakeMaximum();
1030 } else {
1031 auto global_save_bounds = bounds.TransformBounds(matrix_);
1032 auto new_cull_rect = global_cull_rect.Intersection(global_save_bounds);
1033 if (new_cull_rect.has_value()) {
1034 cull_rect_state_.back() = new_cull_rect.value();
1035 } else {
1036 cull_rect_state_.back() = Rect::MakeLTRB(0, 0, 0, 0);
1037 }
1038 }
1039 }
1040
1041 void FirstPassDispatcher::restore() {
1042 matrix_ = stack_.back();
1043 stack_.pop_back();
1044 cull_rect_state_.pop_back();
1045 }
1046
1047 void FirstPassDispatcher::translate(DlScalar tx, DlScalar ty) {
1048 matrix_ = matrix_.Translate({tx, ty});
1049 }
1050
1051 void FirstPassDispatcher::scale(DlScalar sx, DlScalar sy) {
1052 matrix_ = matrix_.Scale({sx, sy, 1.0f});
1053 }
1054
1055 void FirstPassDispatcher::rotate(DlScalar degrees) {
1056 matrix_ = matrix_ * Matrix::MakeRotationZ(Degrees(degrees));
1057 }
1058
1059 void FirstPassDispatcher::skew(DlScalar sx, DlScalar sy) {
1060 matrix_ = matrix_ * Matrix::MakeSkew(sx, sy);
1061 }
1062
1063 // clang-format off
1064 // 2x3 2D affine subset of a 4x4 transform in row major order
1065 void FirstPassDispatcher::transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt,
1066 DlScalar myx, DlScalar myy, DlScalar myt) {
1067 matrix_ = matrix_ * Matrix::MakeColumn(
1068 mxx, myx, 0.0f, 0.0f,
1069 mxy, myy, 0.0f, 0.0f,
1070 0.0f, 0.0f, 1.0f, 0.0f,
1071 mxt, myt, 0.0f, 1.0f
1072 );
1073 }
1074
1075 // full 4x4 transform in row major order
1076 void FirstPassDispatcher::transformFullPerspective(
1077 DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt,
1078 DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt,
1079 DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt,
1080 DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) {
1081 matrix_ = matrix_ * Matrix::MakeColumn(
1082 mxx, myx, mzx, mwx,
1083 mxy, myy, mzy, mwy,
1084 mxz, myz, mzz, mwz,
1085 mxt, myt, mzt, mwt
1086 );
1087 }
1088 // clang-format on
1089
1090 void FirstPassDispatcher::transformReset() {
1091 matrix_ = Matrix();
1092 }
1093
1094 void FirstPassDispatcher::drawTextFrame(
1095 const std::shared_ptr<impeller::TextFrame>& text_frame,
1096 DlScalar x,
1097 DlScalar y) {
1098 GlyphProperties properties;
1099 if (paint_.style == Paint::Style::kStroke) {
1100 properties.stroke = paint_.stroke;
1101 }
1102 if (text_frame->HasColor()) {
1103 // Alpha is always applied when rendering, remove it here so
1104 // we do not double-apply the alpha.
1105 properties.color = paint_.color.WithAlpha(1.0);
1106 }
1107 auto scale = TextFrame::RoundScaledFontSize(
1108 (matrix_ * Matrix::MakeTranslation(Point(x, y))).GetMaxBasisLengthXY());
1109
1110 renderer_.GetLazyGlyphAtlas()->AddTextFrame(
1111 text_frame, //
1112 scale, //
1113 Point(x, y), //
1114 matrix_,
1115 (properties.stroke.has_value() || text_frame->HasColor()) //
1116 ? std::optional<GlyphProperties>(properties) //
1117 : std::nullopt //
1118 );
1119 }
1120
1121 const Rect FirstPassDispatcher::GetCurrentLocalCullingBounds() const {
1122 auto cull_rect = cull_rect_state_.back();
1123 if (!cull_rect.IsEmpty() && !cull_rect.IsMaximum()) {
1124 Matrix inverse = matrix_.Invert();
1125 cull_rect = cull_rect.TransformBounds(inverse);
1126 }
1127 return cull_rect;
1128 }
1129
1130 void FirstPassDispatcher::drawDisplayList(
1131 const sk_sp<flutter::DisplayList> display_list,
1132 DlScalar opacity) {
1133 [[maybe_unused]] size_t stack_depth = stack_.size();
1134 save();
1135 Paint old_paint = paint_;
1136 paint_ = Paint{};
1137 bool old_has_image_filter = has_image_filter_;
1138 has_image_filter_ = false;
1139
1140 if (matrix_.HasPerspective()) {
1141 display_list->Dispatch(*this);
1142 } else {
1143 Rect local_cull_bounds = GetCurrentLocalCullingBounds();
1144 if (local_cull_bounds.IsMaximum()) {
1145 display_list->Dispatch(*this);
1146 } else if (!local_cull_bounds.IsEmpty()) {
1147 DlIRect cull_rect = DlIRect::RoundOut(local_cull_bounds);
1148 display_list->Dispatch(*this, cull_rect);
1149 }
1150 }
1151
1152 restore();
1153 paint_ = old_paint;
1154 has_image_filter_ = old_has_image_filter;
1155 FML_DCHECK(stack_depth == stack_.size());
1156 }
1157
1158 // |flutter::DlOpReceiver|
1159 void FirstPassDispatcher::setDrawStyle(flutter::DlDrawStyle style) {
1160 paint_.style = ToStyle(style);
1161 }
1162
1163 // |flutter::DlOpReceiver|
1164 void FirstPassDispatcher::setColor(flutter::DlColor color) {
1165 paint_.color = skia_conversions::ToColor(color);
1166 }
1167
1168 // |flutter::DlOpReceiver|
1169 void FirstPassDispatcher::setStrokeWidth(DlScalar width) {
1170 paint_.stroke.width = width;
1171 }
1172
1173 // |flutter::DlOpReceiver|
1174 void FirstPassDispatcher::setStrokeMiter(DlScalar limit) {
1175 paint_.stroke.miter_limit = limit;
1176 }
1177
1178 // |flutter::DlOpReceiver|
1179 void FirstPassDispatcher::setStrokeCap(flutter::DlStrokeCap cap) {
1180 switch (cap) {
1181 case flutter::DlStrokeCap::kButt:
1182 paint_.stroke.cap = Cap::kButt;
1183 break;
1184 case flutter::DlStrokeCap::kRound:
1185 paint_.stroke.cap = Cap::kRound;
1186 break;
1187 case flutter::DlStrokeCap::kSquare:
1188 paint_.stroke.cap = Cap::kSquare;
1189 break;
1190 }
1191 }
1192
1193 // |flutter::DlOpReceiver|
1194 void FirstPassDispatcher::setStrokeJoin(flutter::DlStrokeJoin join) {
1195 switch (join) {
1196 case flutter::DlStrokeJoin::kMiter:
1197 paint_.stroke.join = Join::kMiter;
1198 break;
1199 case flutter::DlStrokeJoin::kRound:
1200 paint_.stroke.join = Join::kRound;
1201 break;
1202 case flutter::DlStrokeJoin::kBevel:
1203 paint_.stroke.join = Join::kBevel;
1204 break;
1205 }
1206 }
1207
1208 // |flutter::DlOpReceiver|
1209 void FirstPassDispatcher::setImageFilter(const flutter::DlImageFilter* filter) {
1210 if (filter == nullptr) {
1211 has_image_filter_ = false;
1212 } else {
1213 has_image_filter_ = true;
1214 }
1215 }
1216
1217 std::pair<std::unordered_map<int64_t, BackdropData>, size_t>
1218 FirstPassDispatcher::TakeBackdropData() {
1219 std::unordered_map<int64_t, BackdropData> temp;
1220 std::swap(temp, backdrop_data_);
1221 return std::make_pair(temp, backdrop_count_);
1222 }
1223
1224 std::shared_ptr<Texture> DisplayListToTexture(
1225 const sk_sp<flutter::DisplayList>& display_list,
1226 ISize size,
1227 AiksContext& context,
1228 bool reset_host_buffer,
1229 bool generate_mips) {
1230 int mip_count = 1;
1231 if (generate_mips) {
1232 mip_count = size.MipCount();
1233 }
1234 // Do not use the render target cache as the lifecycle of this texture
1235 // will outlive a particular frame.
1236 impeller::RenderTargetAllocator render_target_allocator =
1237 impeller::RenderTargetAllocator(
1238 context.GetContext()->GetResourceAllocator());
1239 impeller::RenderTarget target;
1240 if (context.GetContext()->GetCapabilities()->SupportsOffscreenMSAA()) {
1241 target = render_target_allocator.CreateOffscreenMSAA(
1242 *context.GetContext(), // context
1243 size, // size
1244 /*mip_count=*/mip_count,
1245 "Picture Snapshot MSAA", // label
1246 impeller::RenderTarget::
1247 kDefaultColorAttachmentConfigMSAA // color_attachment_config
1248 );
1249 } else {
1250 target = render_target_allocator.CreateOffscreen(
1251 *context.GetContext(), // context
1252 size, // size
1253 /*mip_count=*/mip_count,
1254 "Picture Snapshot", // label
1255 impeller::RenderTarget::
1256 kDefaultColorAttachmentConfig // color_attachment_config
1257 );
1258 }
1259 if (!target.IsValid()) {
1260 return nullptr;
1261 }
1262
1263 DlIRect cull_rect = DlIRect::MakeWH(size.width, size.height);
1264 impeller::FirstPassDispatcher collector(
1265 context.GetContentContext(), impeller::Matrix(), Rect::MakeSize(size));
1266 display_list->Dispatch(collector, cull_rect);
1267 impeller::CanvasDlDispatcher impeller_dispatcher(
1268 context.GetContentContext(), //
1269 target, //
1270 /*is_onscreen=*/false, //
1271 display_list->root_has_backdrop_filter(), //
1272 display_list->max_root_blend_mode(), //
1273 impeller::IRect32::MakeSize(size) //
1274 );
1275 const auto& [data, count] = collector.TakeBackdropData();
1276 impeller_dispatcher.SetBackdropData(data, count);
1277 context.GetContentContext().GetTextShadowCache().MarkFrameStart();
1278 fml::ScopedCleanupClosure cleanup([&] {
1279 if (reset_host_buffer) {
1280 context.GetContentContext().GetTransientsBuffer().Reset();
1281 }
1282 context.GetContentContext().GetTextShadowCache().MarkFrameEnd();
1283 context.GetContentContext().GetLazyGlyphAtlas()->ResetTextFrames();
1284 context.GetContext()->DisposeThreadLocalCachedResources();
1285 });
1286
1287 display_list->Dispatch(impeller_dispatcher, cull_rect);
1288 impeller_dispatcher.FinishRecording();
1289
1290 return target.GetRenderTargetTexture();
1291 }
1292
1293 bool RenderToTarget(ContentContext& context,
1294 RenderTarget render_target,
1295 const sk_sp<flutter::DisplayList>& display_list,
1296 Rect cull_rect,
1297 bool reset_host_buffer,
1298 bool is_onscreen) {
1299 FirstPassDispatcher collector(context, impeller::Matrix(), cull_rect);
1300 display_list->Dispatch(collector, cull_rect);
1301
1302 impeller::CanvasDlDispatcher impeller_dispatcher(
1303 context, //
1304 render_target, //
1305 /*is_onscreen=*/is_onscreen, //
1306 display_list->root_has_backdrop_filter(), //
1307 display_list->max_root_blend_mode(), //
1308 IRect32::RoundOut(cull_rect) //
1309 );
1310 const auto& [data, count] = collector.TakeBackdropData();
1311 impeller_dispatcher.SetBackdropData(data, count);
1312 context.GetTextShadowCache().MarkFrameStart();
1313 fml::ScopedCleanupClosure cleanup([&] {
1314 if (reset_host_buffer) {
1315 context.GetTransientsBuffer().Reset();
1316 }
1317 context.GetTextShadowCache().MarkFrameEnd();
1318 });
1319
1320 display_list->Dispatch(impeller_dispatcher, cull_rect);
1321 impeller_dispatcher.FinishRecording();
1322 context.GetLazyGlyphAtlas()->ResetTextFrames();
1323
1324 return true;
1325 }
1326
1327 } // namespace impeller
aiks_context.h
use_center
bool use_center
Definition: aiks_dl_basic_unittests.cc:764
atlas_contents.h
canvas.h
impeller::AiksContext
Definition: aiks_context.h:19
impeller::AiksContext::GetContentContext
ContentContext & GetContentContext() const
Definition: aiks_context.cc:42
impeller::AiksContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: aiks_context.cc:38
impeller::CanvasDlDispatcher
Definition: dl_dispatcher.h:268
impeller::CanvasDlDispatcher::FinishRecording
void FinishRecording()
Definition: dl_dispatcher.h:301
impeller::CanvasDlDispatcher::CanvasDlDispatcher
CanvasDlDispatcher(ContentContext &renderer, RenderTarget &render_target, bool is_onscreen, bool has_root_backdrop_filter, flutter::DlBlendMode max_root_blend_mode, IRect32 cull_rect)
Definition: dl_dispatcher.cc:948
impeller::CanvasDlDispatcher::drawVertices
void drawVertices(const std::shared_ptr< flutter::DlVertices > &vertices, flutter::DlBlendMode dl_mode) override
Definition: dl_dispatcher.cc:966
impeller::CanvasDlDispatcher::SetBackdropData
void SetBackdropData(std::unordered_map< int64_t, BackdropData > backdrop, size_t backdrop_count)
Definition: dl_dispatcher.cc:976
impeller::Canvas
Definition: canvas.h:120
impeller::Canvas::ClipGeometry
void ClipGeometry(const Geometry &geometry, Entity::ClipOperation clip_op, bool is_aa=true)
Definition: canvas.cc:827
impeller::Canvas::SetBackdropData
void SetBackdropData(std::unordered_map< int64_t, BackdropData > backdrop_data, size_t backdrop_count)
Update the backdrop data used to group together backdrop filters within the same layer.
Definition: canvas.cc:1889
impeller::Canvas::DrawRoundSuperellipse
void DrawRoundSuperellipse(const RoundSuperellipse &rse, const Paint &paint)
Definition: canvas.cc:782
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:1201
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, std::optional< int64_t > backdrop_id=std::nullopt)
Definition: canvas.cc:1238
impeller::Canvas::GetCurrentTransform
const Matrix & GetCurrentTransform() const
Definition: canvas.cc:272
impeller::Canvas::DrawVertices
void DrawVertices(const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
Definition: canvas.cc:1005
impeller::Canvas::DrawOval
void DrawOval(const Rect &rect, const Paint &paint)
Definition: canvas.cc:650
impeller::Canvas::DrawImageRect
void DrawImageRect(const std::shared_ptr< Texture > &image, Rect source, Rect dest, const Paint &paint, const SamplerDescriptor &sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
Definition: canvas.cc:940
impeller::Canvas::RestoreToCount
void RestoreToCount(size_t count)
Definition: canvas.cc:319
impeller::Canvas::Restore
bool Restore()
Definition: canvas.cc:1476
impeller::Canvas::GetSaveCount
size_t GetSaveCount() const
Definition: canvas.cc:311
impeller::Canvas::Transform
void Transform(const Matrix &transform)
Definition: canvas.cc:268
impeller::Canvas::GetMaxOpDepth
uint64_t GetMaxOpDepth() const
Definition: canvas.h:263
impeller::Canvas::DrawDashedLine
void DrawDashedLine(const Point &p0, const Point &p1, Scalar on_length, Scalar off_length, const Paint &paint)
Definition: canvas.cc:606
impeller::Canvas::DrawDiffRoundRect
void DrawDiffRoundRect(const RoundRect &outer, const RoundRect &inner, const Paint &paint)
Definition: canvas.cc:766
impeller::Canvas::DrawPath
void DrawPath(const flutter::DlPath &path, const Paint &paint)
Definition: canvas.cc:327
impeller::Canvas::PreConcat
void PreConcat(const Matrix &transform)
Definition: canvas.cc:260
impeller::Canvas::Rotate
void Rotate(Radians radians)
Definition: canvas.cc:292
impeller::Canvas::DrawPoints
void DrawPoints(const Point points[], uint32_t count, Scalar radius, const Paint &paint, PointStyle point_style)
Definition: canvas.cc:908
impeller::Canvas::ResetTransform
void ResetTransform()
Definition: canvas.cc:264
impeller::Canvas::DrawTextFrame
void DrawTextFrame(const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint)
Definition: canvas.cc:1667
impeller::Canvas::DrawPaint
void DrawPaint(const Paint &paint)
Definition: canvas.cc:341
impeller::Canvas::DrawRoundRect
void DrawRoundRect(const RoundRect &rect, const Paint &paint)
Definition: canvas.cc:734
impeller::Canvas::Skew
void Skew(Scalar sx, Scalar sy)
Definition: canvas.cc:288
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:280
impeller::Canvas::GetOpDepth
uint64_t GetOpDepth() const
Definition: canvas.h:261
impeller::Canvas::Save
void Save(uint32_t total_content_depth=kMaxDepth)
Definition: canvas.cc:1184
impeller::Canvas::DrawRect
void DrawRect(const Rect &rect, const Paint &paint)
Definition: canvas.cc:632
impeller::Canvas::DrawAtlas
void DrawAtlas(const std::shared_ptr< AtlasContents > &atlas_contents, const Paint &paint)
Definition: canvas.cc:1118
impeller::Canvas::DrawLine
void DrawLine(const Point &p0, const Point &p1, const Paint &paint, bool reuse_depth=false)
Definition: canvas.cc:584
impeller::Canvas::Translate
void Translate(const Vector3 &offset)
Definition: canvas.cc:276
impeller::Canvas::DrawCircle
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition: canvas.cc:804
impeller::Canvas::DrawArc
void DrawArc(const Arc &arc, const Paint &paint)
Definition: canvas.cc:679
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::ContentContext
Definition: content_context.h:138
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:297
impeller::ContentContext::GetLazyGlyphAtlas
const std::shared_ptr< LazyGlyphAtlas > & GetLazyGlyphAtlas() const
Definition: content_context.h:265
impeller::ContentContext::GetDeviceCapabilities
const Capabilities & GetDeviceCapabilities() const
Definition: content_context.cc:943
impeller::ContentContext::GetTextShadowCache
TextShadowCache & GetTextShadowCache() const
Definition: content_context.h:299
impeller::DlAtlasGeometry
A wrapper around data provided by a drawAtlas call.
Definition: dl_atlas_geometry.h:17
impeller::DlDispatcherBase::drawLine
void drawLine(const DlPoint &p0, const DlPoint &p1) override
Definition: dl_dispatcher.cc:543
impeller::DlDispatcherBase::drawAtlas
void drawAtlas(const sk_sp< flutter::DlImage > atlas, const RSTransform 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::DlDispatcherBase::drawPoints
void drawPoints(flutter::DlPointMode mode, uint32_t count, const DlPoint points[]) override
Definition: dl_dispatcher.cc:655
impeller::DlDispatcherBase::GetCanvas
virtual Canvas & GetCanvas()=0
impeller::DlDispatcherBase::drawDashedLine
void drawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length) override
Definition: dl_dispatcher.cc:550
impeller::DlDispatcherBase::drawOval
void drawOval(const DlRect &bounds) override
Definition: dl_dispatcher.cc:567
impeller::DlDispatcherBase::setImageFilter
void setImageFilter(const flutter::DlImageFilter *filter) override
Definition: dl_dispatcher.cc:293
impeller::DlDispatcherBase::drawPath
void drawPath(const DlPath &path) override
Definition: dl_dispatcher.cc:603
impeller::DlDispatcherBase::setStrokeCap
void setStrokeCap(flutter::DlStrokeCap cap) override
Definition: dl_dispatcher.cc:195
impeller::DlDispatcherBase::clipOval
void clipOval(const DlRect &bounds, flutter::DlClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:447
impeller::DlDispatcherBase::drawRoundSuperellipse
void drawRoundSuperellipse(const DlRoundSuperellipse &rse) override
Definition: dl_dispatcher.cc:596
impeller::DlDispatcherBase::clipRoundRect
void clipRoundRect(const DlRoundRect &rrect, flutter::DlClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:457
impeller::DlDispatcherBase::initial_matrix_
Matrix initial_matrix_
Definition: dl_dispatcher.h:261
impeller::DlDispatcherBase::skew
void skew(DlScalar sx, DlScalar sy) override
Definition: dl_dispatcher.cc:362
impeller::DlDispatcherBase::clipRect
void clipRect(const DlRect &rect, flutter::DlClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:437
impeller::DlDispatcherBase::setAntiAlias
void setAntiAlias(bool aa) override
Definition: dl_dispatcher.cc:147
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:388
impeller::DlDispatcherBase::setStrokeWidth
void setStrokeWidth(DlScalar width) override
Definition: dl_dispatcher.cc:181
impeller::DlDispatcherBase::paint_
Paint paint_
Definition: dl_dispatcher.h:260
impeller::DlDispatcherBase::drawDiffRoundRect
void drawDiffRoundRect(const DlRoundRect &outer, const DlRoundRect &inner) override
Definition: dl_dispatcher.cc:588
impeller::DlDispatcherBase::drawRoundRect
void drawRoundRect(const DlRoundRect &rrect) override
Definition: dl_dispatcher.cc:581
impeller::DlDispatcherBase::drawPaint
void drawPaint() override
Definition: dl_dispatcher.cc:536
impeller::DlDispatcherBase::setStrokeJoin
void setStrokeJoin(flutter::DlStrokeJoin join) override
Definition: dl_dispatcher.cc:212
impeller::DlDispatcherBase::drawTextBlob
void drawTextBlob(const sk_sp< SkTextBlob > blob, DlScalar x, DlScalar y) override
Definition: dl_dispatcher.cc:856
impeller::DlDispatcherBase::rotate
void rotate(DlScalar degrees) override
Definition: dl_dispatcher.cc:355
impeller::DlDispatcherBase::setColorFilter
void setColorFilter(const flutter::DlColorFilter *filter) override
Definition: dl_dispatcher.cc:236
impeller::DlDispatcherBase::scale
void scale(DlScalar sx, DlScalar sy) override
Definition: dl_dispatcher.cc:348
impeller::DlDispatcherBase::setDrawStyle
void setDrawStyle(flutter::DlDrawStyle style) override
Definition: dl_dispatcher.cc:167
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:878
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::DlDispatcherBase::clipPath
void clipPath(const DlPath &path, flutter::DlClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:498
impeller::DlDispatcherBase::drawImageRect
void drawImageRect(const sk_sp< flutter::DlImage > image, const DlRect &src, const DlRect &dst, flutter::DlImageSampling sampling, bool render_with_attributes, flutter::DlSrcRectConstraint constraint) override
Definition: dl_dispatcher.cc:728
impeller::DlDispatcherBase::clipRoundSuperellipse
void clipRoundSuperellipse(const DlRoundSuperellipse &rse, flutter::DlClipOp clip_op, bool is_aa) override
Definition: dl_dispatcher.cc:479
impeller::DlDispatcherBase::drawArc
void drawArc(const DlRect &oval_bounds, DlScalar start_degrees, DlScalar sweep_degrees, bool use_center) override
Definition: dl_dispatcher.cc:643
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, std::optional< int64_t > backdrop_id) override
Definition: dl_dispatcher.cc:307
impeller::DlDispatcherBase::drawDisplayList
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, DlScalar opacity) override
Definition: dl_dispatcher.cc:791
impeller::DlDispatcherBase::transform2DAffine
void transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
Definition: dl_dispatcher.cc:369
impeller::DlDispatcherBase::setInvertColors
void setInvertColors(bool invert) override
Definition: dl_dispatcher.cc:243
impeller::DlDispatcherBase::setColor
void setColor(flutter::DlColor color) override
Definition: dl_dispatcher.cc:174
impeller::DlDispatcherBase::save
void save(uint32_t total_content_depth) override
Definition: dl_dispatcher.cc:300
impeller::DlDispatcherBase::setStrokeMiter
void setStrokeMiter(DlScalar limit) override
Definition: dl_dispatcher.cc:188
impeller::DlDispatcherBase::translate
void translate(DlScalar tx, DlScalar ty) override
Definition: dl_dispatcher.cc:341
impeller::DlDispatcherBase::drawVertices
void drawVertices(const std::shared_ptr< flutter::DlVertices > &vertices, flutter::DlBlendMode dl_mode) override
Definition: dl_dispatcher.cc:694
impeller::DlDispatcherBase::drawCircle
void drawCircle(const DlPoint &center, DlScalar radius) override
Definition: dl_dispatcher.cc:574
impeller::DlDispatcherBase::drawTextFrame
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, DlScalar x, DlScalar y) override
Definition: dl_dispatcher.cc:865
impeller::DlDispatcherBase::setMaskFilter
void setMaskFilter(const flutter::DlMaskFilter *filter) override
Definition: dl_dispatcher.cc:270
impeller::DlDispatcherBase::restore
void restore() override
Definition: dl_dispatcher.cc:336
impeller::DlDispatcherBase::setColorSource
void setColorSource(const flutter::DlColorSource *source) override
Definition: dl_dispatcher.cc:229
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::DlDispatcherBase::transformReset
void transformReset() override
Definition: dl_dispatcher.cc:420
impeller::DlDispatcherBase::setBlendMode
void setBlendMode(flutter::DlBlendMode mode) override
Definition: dl_dispatcher.cc:250
impeller::DlDispatcherBase::drawColor
void drawColor(flutter::DlColor color, flutter::DlBlendMode mode) override
Definition: dl_dispatcher.cc:525
impeller::DlDispatcherBase::drawRect
void drawRect(const DlRect &rect) override
Definition: dl_dispatcher.cc:560
impeller::DlDispatcherBase::SimplifyOrDrawPath
static void SimplifyOrDrawPath(Canvas &canvas, const DlPath &cache, const Paint &paint)
Definition: dl_dispatcher.cc:609
impeller::EllipseGeometry
A Geometry class that can directly generate vertices (with or without texture coordinates) for filled...
Definition: ellipse_geometry.h:21
impeller::Entity::kLastPipelineBlendMode
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:28
impeller::Entity::ClipOperation
ClipOperation
Definition: entity.h:67
impeller::Entity::ClipOperation::kIntersect
@ kIntersect
impeller::Entity::ClipOperation::kDifference
@ kDifference
impeller::FillPathGeometry
A Geometry that produces fillable vertices from a |DlPath| object using the |FillPathSourceGeometry| ...
Definition: fill_path_geometry.h:55
impeller::FillRectGeometry
Definition: rect_geometry.h:13
impeller::FillRoundRectGeometry
A Geometry class that produces fillable vertices from any |RoundRect| object regardless of radii unif...
Definition: round_rect_geometry.h:59
impeller::FilterContents::BlurStyle
BlurStyle
Definition: filter_contents.h:28
impeller::FilterContents::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.
impeller::FilterContents::BlurStyle::kOuter
@ kOuter
Nothing inside, blurred outside.
impeller::FilterContents::BlurStyle::kInner
@ kInner
Blurred inside, nothing outside.
impeller::FilterContents::BlurStyle::kSolid
@ kSolid
Solid inside, blurred outside.
impeller::FirstPassDispatcher
Definition: dl_dispatcher.h:318
impeller::FirstPassDispatcher::setColor
void setColor(flutter::DlColor color) override
Definition: dl_dispatcher.cc:1164
impeller::FirstPassDispatcher::setStrokeCap
void setStrokeCap(flutter::DlStrokeCap cap) override
Definition: dl_dispatcher.cc:1179
impeller::FirstPassDispatcher::saveLayer
void saveLayer(const DlRect &bounds, const flutter::SaveLayerOptions options, const flutter::DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
Definition: dl_dispatcher.cc:1000
impeller::FirstPassDispatcher::setDrawStyle
void setDrawStyle(flutter::DlDrawStyle style) override
Definition: dl_dispatcher.cc:1159
impeller::FirstPassDispatcher::save
void save() override
Definition: dl_dispatcher.cc:995
impeller::FirstPassDispatcher::restore
void restore() override
Definition: dl_dispatcher.cc:1041
impeller::FirstPassDispatcher::TakeBackdropData
std::pair< std::unordered_map< int64_t, BackdropData >, size_t > TakeBackdropData()
Definition: dl_dispatcher.cc:1218
impeller::FirstPassDispatcher::rotate
void rotate(DlScalar degrees) override
Definition: dl_dispatcher.cc:1055
impeller::FirstPassDispatcher::drawTextFrame
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, DlScalar x, DlScalar y) override
Definition: dl_dispatcher.cc:1094
impeller::FirstPassDispatcher::setImageFilter
void setImageFilter(const flutter::DlImageFilter *filter) override
Definition: dl_dispatcher.cc:1209
impeller::FirstPassDispatcher::setStrokeMiter
void setStrokeMiter(DlScalar limit) override
Definition: dl_dispatcher.cc:1174
impeller::FirstPassDispatcher::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:1076
impeller::FirstPassDispatcher::scale
void scale(DlScalar sx, DlScalar sy) override
Definition: dl_dispatcher.cc:1051
impeller::FirstPassDispatcher::translate
void translate(DlScalar tx, DlScalar ty) override
Definition: dl_dispatcher.cc:1047
impeller::FirstPassDispatcher::skew
void skew(DlScalar sx, DlScalar sy) override
Definition: dl_dispatcher.cc:1059
impeller::FirstPassDispatcher::FirstPassDispatcher
FirstPassDispatcher(const ContentContext &renderer, const Matrix &initial_matrix, const Rect cull_rect)
Definition: dl_dispatcher.cc:984
impeller::FirstPassDispatcher::drawDisplayList
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, DlScalar opacity) override
Definition: dl_dispatcher.cc:1130
impeller::FirstPassDispatcher::setStrokeWidth
void setStrokeWidth(DlScalar width) override
Definition: dl_dispatcher.cc:1169
impeller::FirstPassDispatcher::setStrokeJoin
void setStrokeJoin(flutter::DlStrokeJoin join) override
Definition: dl_dispatcher.cc:1194
impeller::FirstPassDispatcher::~FirstPassDispatcher
~FirstPassDispatcher()
Definition: dl_dispatcher.cc:991
impeller::FirstPassDispatcher::transformReset
void transformReset() override
Definition: dl_dispatcher.cc:1090
impeller::FirstPassDispatcher::transform2DAffine
void transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
Definition: dl_dispatcher.cc:1065
impeller::NinePatchConverter
Definition: nine_patch_converter.h:17
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::RenderTargetAllocator
a wrapper around the impeller [Allocator] instance that can be used to provide caching of allocated r...
Definition: render_target.h:149
impeller::RenderTargetAllocator::CreateOffscreenMSAA
virtual RenderTarget CreateOffscreenMSAA(const Context &context, ISize size, int mip_count, std::string_view 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:376
impeller::RenderTargetAllocator::CreateOffscreen
virtual RenderTarget CreateOffscreen(const Context &context, ISize size, int mip_count, std::string_view 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:322
impeller::RenderTarget
Definition: render_target.h:38
impeller::RenderTarget::GetRenderTargetTexture
std::shared_ptr< Texture > GetRenderTargetTexture() const
Definition: render_target.cc:176
impeller::RenderTarget::IsValid
bool IsValid() const
Definition: render_target.cc:23
impeller::RoundRectGeometry
A Geometry class that generates fillable vertices (with or without texture coordinates) directly from...
Definition: round_rect_geometry.h:25
impeller::RoundSuperellipseGeometry
A Geometry class that generates fillable vertices (with or without texture coordinates) directly from...
Definition: round_superellipse_geometry.h:30
impeller::TextFrame::RoundScaledFontSize
static Rational RoundScaledFontSize(Scalar scale)
Definition: text_frame.cc:55
impeller::TextShadowCache::MarkFrameStart
void MarkFrameStart()
Mark all glyph textures as unused this frame.
Definition: text_shadow_cache.cc:30
color.h
content_context.h
formats.h
dl_atlas_geometry.h
AUTO_DEPTH_WATCHER
#define AUTO_DEPTH_WATCHER(d)
Definition: dl_dispatcher.cc:113
UNIMPLEMENTED
#define UNIMPLEMENTED
Definition: dl_dispatcher.cc:118
AUTO_DEPTH_CHECK
#define AUTO_DEPTH_CHECK()
Definition: dl_dispatcher.cc:114
dl_dispatcher.h
x
int32_t x
Definition: dl_golden_unittests.cc:458
dl_vertices_geometry.h
ellipse_geometry.h
entity.h
fill_path_geometry.h
filter_contents.h
filter_input.h
font_glyph_pair.h
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:214
impeller::skia_conversions::ToSamplerDescriptor
impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
Definition: skia_conversions.cc:24
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:13
impeller
Definition: allocation.cc:12
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:1224
impeller::Join::kRound
@ kRound
impeller::Join::kMiter
@ kMiter
impeller::Join::kBevel
@ kBevel
impeller::Vector2
Point Vector2
Definition: point.h:331
impeller::DlRect
flutter::DlRect DlRect
Definition: dl_dispatcher.h:25
impeller::Scalar
float Scalar
Definition: scalar.h:19
impeller::DlIRect
flutter::DlIRect DlIRect
Definition: dl_dispatcher.h:26
impeller::ToStyle
static Paint::Style ToStyle(flutter::DlDrawStyle style)
Definition: dl_dispatcher.cc:153
impeller::DlRoundRect
flutter::DlRoundRect DlRoundRect
Definition: dl_dispatcher.h:27
impeller::ToOptRect
static std::optional< const Rect > ToOptRect(const flutter::DlRect *rect)
Definition: dl_dispatcher.cc:139
impeller::PointStyle
PointStyle
Definition: canvas.h:65
impeller::PointStyle::kRound
@ kRound
Points are drawn as squares.
impeller::PointStyle::kSquare
@ kSquare
Points are drawn as circles.
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::ToClipOperation
static Entity::ClipOperation ToClipOperation(flutter::DlClipOp clip_op)
Definition: dl_dispatcher.cc:427
impeller::Cap::kRound
@ kRound
impeller::Cap::kButt
@ kButt
impeller::Cap::kSquare
@ kSquare
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24
impeller::DlRoundSuperellipse
flutter::DlRoundSuperellipse DlRoundSuperellipse
Definition: dl_dispatcher.h:28
impeller::RequiresReadbackForBlends
static bool RequiresReadbackForBlends(const ContentContext &renderer, flutter::DlBlendMode max_root_blend_mode)
Subclasses.
Definition: dl_dispatcher.cc:941
impeller::ToSamplerDescriptor
static impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlFilterMode options)
Definition: dl_dispatcher.cc:121
impeller::DlPath
flutter::DlPath DlPath
Definition: dl_dispatcher.h:29
impeller::ContentBoundsPromise::kMayClipContents
@ kMayClipContents
The caller claims the bounds are a subset of an estimate of the reasonably tight bounds but likely cl...
impeller::ContentBoundsPromise::kContainsContents
@ kContainsContents
The caller claims the bounds are a reasonably tight estimate of the coverage of the contents and shou...
impeller::RenderToTarget
bool RenderToTarget(ContentContext &context, RenderTarget render_target, const sk_sp< flutter::DisplayList > &display_list, Rect cull_rect, bool reset_host_buffer, bool is_onscreen)
Render the provided display list to the render target.
Definition: dl_dispatcher.cc:1293
impeller::MinMagFilter::kLinear
@ kLinear
impeller::MinMagFilter::kNearest
@ kNearest
Select nearest to the sample point. Most widely supported.
impeller::DlScalar
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:23
impeller::ToBlurStyle
static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style)
Definition: dl_dispatcher.cc:256
nine_patch_converter.h
rect_geometry.h
round_rect_geometry.h
round_superellipse_geometry.h
scalar.h
sigma.h
skia_conversions.h
impeller::Arc
Definition: arc.h:13
impeller::BackdropData
Definition: canvas.h:40
impeller::BackdropData::backdrop_count
size_t backdrop_count
Definition: canvas.h:41
impeller::Color
Definition: color.h:124
impeller::Color::blue
Scalar blue
Definition: color.h:138
impeller::Color::alpha
Scalar alpha
Definition: color.h:143
impeller::Color::WithAlpha
constexpr Color WithAlpha(Scalar new_alpha) const
Definition: color.h:278
impeller::Color::red
Scalar red
Definition: color.h:128
impeller::Color::green
Scalar green
Definition: color.h:133
impeller::Degrees
Definition: scalar.h:76
impeller::GlyphProperties
Definition: font_glyph_pair.h:19
impeller::GlyphProperties::color
Color color
Definition: font_glyph_pair.h:20
impeller::GlyphProperties::stroke
std::optional< StrokeParameters > stroke
Definition: font_glyph_pair.h:21
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Matrix::Translate
constexpr Matrix Translate(const Vector3 &t) const
Definition: matrix.h:263
impeller::Matrix::Invert
Matrix Invert() const
Definition: matrix.cc:99
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::Matrix::GetScale
Vector3 GetScale() const
Definition: matrix.h:394
impeller::Matrix::MakeSkew
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
Definition: matrix.h:127
impeller::Matrix::Scale
constexpr Matrix Scale(const Vector3 &s) const
Definition: matrix.h:275
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:223
impeller::Matrix::HasPerspective
constexpr bool HasPerspective() const
Definition: matrix.h:418
impeller::Paint::MaskBlurDescriptor
Definition: paint.h:52
impeller::Paint::MaskBlurDescriptor::style
FilterContents::BlurStyle style
Definition: paint.h:53
impeller::Paint
Definition: paint.h:27
impeller::Paint::color_filter
const flutter::DlColorFilter * color_filter
Definition: paint.h:77
impeller::Paint::color_source
const flutter::DlColorSource * color_source
Definition: paint.h:76
impeller::Paint::Style
Style
Definition: paint.h:47
impeller::Paint::Style::kStroke
@ kStroke
impeller::Paint::Style::kFill
@ kFill
impeller::Paint::image_filter
const flutter::DlImageFilter * image_filter
Definition: paint.h:78
impeller::Paint::style
Style style
Definition: paint.h:81
impeller::Paint::invert_colors
bool invert_colors
Definition: paint.h:83
impeller::Paint::mask_blur_descriptor
std::optional< MaskBlurDescriptor > mask_blur_descriptor
Definition: paint.h:85
impeller::Paint::color
Color color
Definition: paint.h:75
impeller::Paint::blend_mode
BlendMode blend_mode
Definition: paint.h:82
impeller::Paint::stroke
StrokeParameters stroke
Definition: paint.h:80
impeller::RSTransform
Definition: rstransform.h:20
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::SamplerDescriptor
Definition: sampler_descriptor.h:14
impeller::SamplerDescriptor::mag_filter
MinMagFilter mag_filter
Definition: sampler_descriptor.h:16
impeller::SamplerDescriptor::label
std::string_view label
Definition: sampler_descriptor.h:23
impeller::SamplerDescriptor::min_filter
MinMagFilter min_filter
Definition: sampler_descriptor.h:15
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::StrokeParameters::cap
Cap cap
Definition: stroke_parameters.h:30
impeller::StrokeParameters::join
Join join
Definition: stroke_parameters.h:31
impeller::StrokeParameters::miter_limit
Scalar miter_limit
Definition: stroke_parameters.h:32
impeller::StrokeParameters::width
Scalar width
Definition: stroke_parameters.h:29
impeller::TPoint< Scalar >
impeller::TRect< Scalar >
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:476
impeller::TRect::IsMaximum
constexpr bool IsMaximum() const
Definition: rect.h:318
impeller::TRect::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: rect.h:301
impeller::TRect::RoundOut
RoundOut(const TRect< U > &r)
Definition: rect.h:683
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::TRect< Scalar >::MakeMaximum
constexpr static TRect MakeMaximum()
Definition: rect.h:188
impeller::TSize
Definition: size.h:25
impeller::TSize::height
Type height
Definition: size.h:29
impeller::TSize::width
Type width
Definition: size.h:28
impeller::TSize::MipCount
constexpr size_t MipCount() const
Return the mip count of the texture.
Definition: size.h:137
impeller::Vector3
Definition: vector.h:20
impeller::Vector3::y
Scalar y
Definition: vector.h:24
start
const size_t start
Definition: tessellator_libtess.cc:62
end
const size_t end
Definition: tessellator_libtess.cc:63
points
std::vector< Point > points
Definition: tessellator_libtess.cc:76
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:68