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