| Flutter Impeller |

Classes | Public Member Functions | Public Attributes | List of all members
impeller::Canvas Class Reference

`#include <canvas.h>`

## Classes
struct | DebugOptions

## Public Member Functions
| Canvas ()
| Canvas (Rect cull_rect)
| Canvas (IRect cull_rect)
| ~Canvas ()
void | Save ()
void | SaveLayer (const Paint &paint, std::optional< Rect > bounds=std::nullopt, const std::shared_ptr< ImageFilter > &backdrop_filter=nullptr, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown)
bool | Restore ()
size_t | GetSaveCount () const
void | RestoreToCount (size_t count)
const Matrix & | GetCurrentTransform () const
const std::optional< Rect > | GetCurrentLocalCullingBounds () const
void | ResetTransform ()
void | Transform (const Matrix &transform)
void | Concat (const Matrix &transform)
void | PreConcat (const Matrix &transform)
void | Translate (const Vector3 &offset)
void | Scale (const Vector2 &scale)
void | Scale (const Vector3 &scale)
void | Skew (Scalar sx, Scalar sy)
void | Rotate (Radians radians)
void | DrawPath (const Path &path, const Paint &paint)
void | DrawPaint (const Paint &paint)
void | DrawLine (const Point &p0, const Point &p1, const Paint &paint)
void | DrawRect (const Rect &rect, const Paint &paint)
void | DrawOval (const Rect &rect, const Paint &paint)
void | DrawRRect (const Rect &rect, const Size &corner_radii, const Paint &paint)
void | DrawCircle (const Point &center, Scalar radius, const Paint &paint)
void | DrawPoints (std::vector< Point > points, Scalar radius, const Paint &paint, PointStyle point_style)
void | DrawImage (const std::shared_ptr< Image > &image, Point offset, const Paint &paint, SamplerDescriptor sampler={})
void | DrawImageRect (const std::shared_ptr< Image > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
void | ClipPath (const Path &path, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
void | ClipRect (const Rect &rect, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
void | ClipOval (const Rect &bounds, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
void | ClipRRect (const Rect &rect, const Size &corner_radii, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
void | DrawTextFrame (const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint)
void | DrawVertices (const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
void | DrawAtlas (const std::shared_ptr< Image > &atlas, std::vector< Matrix > transforms, std::vector< Rect > texture_coordinates, std::vector< Color > colors, BlendMode blend_mode, SamplerDescriptor sampler, std::optional< Rect > cull_rect, const Paint &paint)
Picture | EndRecordingAsPicture ()

## Public Attributes
struct impeller::Canvas::DebugOptions | debug_options

## Detailed Description

Definition at line 58 of file canvas.h.

## Constructor & Destructor Documentation

## ◆ Canvas() [1/3]

impeller::Canvas::Canvas | ( |  | ) |

Definition at line 104 of file canvas.cc.

104 {
105 Initialize(std::nullopt);
106 }

## ◆ Canvas() [2/3]

impeller::Canvas::Canvas | ( | Rect | cull_rect | ) |
| explicit

Definition at line 108 of file canvas.cc.

108 {
109 Initialize(cull_rect);
110 }

## ◆ Canvas() [3/3]

impeller::Canvas::Canvas | ( | IRect | cull_rect | ) |
| explicit

Definition at line 112 of file canvas.cc.

112 {
113 Initialize(Rect::MakeLTRB(cull_rect.GetLeft(), cull_rect.GetTop(),
114 cull_rect.GetRight(), cull_rect.GetBottom()));
115 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), and impeller::TRect< Scalar >::MakeLTRB().

## ◆ ~Canvas()

impeller::Canvas::~Canvas | ( |  | ) |
| default

## Member Function Documentation

## ◆ ClipOval()

void impeller::Canvas::ClipOval | ( | const Rect & | bounds,
|  | Entity::ClipOperation | clip_op = `Entity::ClipOperation::kIntersect`
| ) |  |

Definition at line 570 of file canvas.cc.

570 {
571 auto geometry = Geometry::MakeOval(bounds);
572 auto& cull_rect = transform_stack_.back().cull_rect;
573 if (clip_op == Entity::ClipOperation::kIntersect && //
574 cull_rect.has_value() && //
575 geometry->CoversArea(transform_stack_.back().transform, *cull_rect) //
576 ) {
577 return; // This clip will do nothing, so skip it.
578 }
579
580 ClipGeometry(geometry, clip_op);
581 switch (clip_op) {
582 case Entity::ClipOperation::kIntersect:
583 IntersectCulling(bounds);
584 break;
585 case Entity::ClipOperation::kDifference:
586 break;
587 }
588 }

Referenced by impeller::DlDispatcher::clipPath(), impeller::DlDispatcher::clipRRect(), and impeller::testing::TEST_P().

## ◆ ClipPath()

void impeller::Canvas::ClipPath | ( | const Path & | path,
|  | Entity::ClipOperation | clip_op = `Entity::ClipOperation::kIntersect`
| ) |  |

Definition at line 539 of file canvas.cc.

539 {
540 auto bounds = path.GetBoundingBox();
541 ClipGeometry(Geometry::MakeFillPath(path), clip_op);
542 if (clip_op == Entity::ClipOperation::kIntersect) {
543 if (bounds.has_value()) {
544 IntersectCulling(bounds.value());
545 }
546 }
547 }

References impeller::Path::GetBoundingBox().

Referenced by impeller::DlDispatcher::clipPath(), impeller::DlDispatcher::clipRRect(), impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ ClipRect()

void impeller::Canvas::ClipRect | ( | const Rect & | rect,
|  | Entity::ClipOperation | clip_op = `Entity::ClipOperation::kIntersect`
| ) |  |

Definition at line 549 of file canvas.cc.

549 {
550 auto geometry = Geometry::MakeRect(rect);
551 auto& cull_rect = transform_stack_.back().cull_rect;
552 if (clip_op == Entity::ClipOperation::kIntersect && //
553 cull_rect.has_value() && //
554 geometry->CoversArea(transform_stack_.back().transform, *cull_rect) //
555 ) {
556 return; // This clip will do nothing, so skip it.
557 }
558
559 ClipGeometry(geometry, clip_op);
560 switch (clip_op) {
561 case Entity::ClipOperation::kIntersect:
562 IntersectCulling(rect);
563 break;
564 case Entity::ClipOperation::kDifference:
565 SubtractCulling(rect);
566 break;
567 }
568 }

Referenced by impeller::DlDispatcher::clipPath(), impeller::DlDispatcher::clipRect(), impeller::DlDispatcher::clipRRect(), impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ ClipRRect()

void impeller::Canvas::ClipRRect | ( | const Rect & | rect,
|  | const Size & | corner_radii,
|  | Entity::ClipOperation | clip_op = `Entity::ClipOperation::kIntersect`
| ) |  |

Definition at line 590 of file canvas.cc.

592 {
593 // Does the rounded rect have a flat part on the top/bottom or left/right?
594 bool flat_on_TB = corner_radii.width * 2 < rect.GetWidth();
595 bool flat_on_LR = corner_radii.height * 2 < rect.GetHeight();
596 auto geometry = Geometry::MakeRoundRect(rect, corner_radii);
597 auto& cull_rect = transform_stack_.back().cull_rect;
598 if (clip_op == Entity::ClipOperation::kIntersect && //
599 cull_rect.has_value() && //
600 geometry->CoversArea(transform_stack_.back().transform, *cull_rect) //
601 ) {
602 return; // This clip will do nothing, so skip it.
603 }
604
605 ClipGeometry(geometry, clip_op);
606 switch (clip_op) {
607 case Entity::ClipOperation::kIntersect:
608 IntersectCulling(rect);
609 break;
610 case Entity::ClipOperation::kDifference:
611 if (corner_radii.IsEmpty()) {
612 SubtractCulling(rect);
613 } else {
614 // We subtract the inner "tall" and "wide" rectangle pieces
615 // that fit inside the corners which cover the greatest area
616 // without involving the curved corners
617 // Since this is a subtract operation, we can subtract each
618 // rectangle piece individually without fear of interference.
619 if (flat_on_TB) {
620 SubtractCulling(rect.Expand(Size{-corner_radii.width, 0.0}));
621 }
622 if (flat_on_LR) {
623 SubtractCulling(rect.Expand(Size{0.0, -corner_radii.height}));
624 }
625 }
626 break;
627 }
628 }

References impeller::TRect< T >::Expand(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TSize< T >::height, impeller::TSize< T >::IsEmpty(), and impeller::TSize< T >::width.

Referenced by impeller::DlDispatcher::clipPath(), impeller::DlDispatcher::clipRRect(), impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ Concat()

void impeller::Canvas::Concat | ( | const Matrix & | transform | ) |

Definition at line 231 of file canvas.cc.

231 {
232 transform_stack_.back().transform = GetCurrentTransform() * transform;
233 }

References GetCurrentTransform().

Referenced by Rotate(), Scale(), Skew(), impeller::testing::TEST_P(), Transform(), and Translate().

## ◆ DrawAtlas()

void impeller::Canvas::DrawAtlas | ( | const std::shared_ptr< Image > & | atlas,
|  | std::vector< Matrix > | transforms,
|  | std::vector< Rect > | texture_coordinates,
|  | std::vector< Color > | colors,
|  | BlendMode | blend_mode,
|  | SamplerDescriptor | sampler,
|  | std::optional< Rect > | cull_rect,
|  | const Paint & | paint
| ) |  |

Definition at line 925 of file canvas.cc.

932 {
933 if (!atlas) {
934 return;
935 }
936
937 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
938 contents->SetColors(std::move(colors));
939 contents->SetTransforms(std::move(transforms));
940 contents->SetTextureCoordinates(std::move(texture_coordinates));
941 contents->SetTexture(atlas->GetTexture());
942 contents->SetSamplerDescriptor(std::move(sampler));
943 contents->SetBlendMode(blend_mode);
944 contents->SetCullRect(cull_rect);
945 contents->SetAlpha(paint.color.alpha);
946
947 Entity entity;
948 entity.SetTransform(GetCurrentTransform());
949 entity.SetClipDepth(GetClipDepth());
950 entity.SetBlendMode(paint.blend_mode);
951 entity.SetContents(paint.WithFilters(contents));
952
953 AddEntityToCurrentPass(std::move(entity));
954 }

References impeller::Color::alpha, impeller::Paint::blend_mode, impeller::Paint::color, impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::Paint::WithFilters().

Referenced by impeller::DlDispatcher::drawAtlas(), and impeller::testing::TEST_P().

## ◆ DrawCircle()

void impeller::Canvas::DrawCircle | ( | const Point & | center,
|  | Scalar | radius,
|  | const Paint & | paint
| ) |  |

Definition at line 515 of file canvas.cc.

517 {
518 Size half_size(radius, radius);
519 if (AttemptDrawBlurredRRect(
520 Rect::MakeOriginSize(center - half_size, half_size * 2),
521 {radius, radius}, paint)) {
522 return;
523 }
524
525 Entity entity;
526 entity.SetTransform(GetCurrentTransform());
527 entity.SetClipDepth(GetClipDepth());
528 entity.SetBlendMode(paint.blend_mode);
529 auto geometry =
530 paint.style == Paint::Style::kStroke
531 ? Geometry::MakeStrokedCircle(center, radius, paint.stroke_width)
532 : Geometry::MakeCircle(center, radius);
533 entity.SetContents(
534 CreateContentsForGeometryWithFilters(paint, std::move(geometry)));
535
536 AddEntityToCurrentPass(std::move(entity));
537 }

References impeller::Paint::blend_mode, impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::Paint::stroke_width, and impeller::Paint::style.

Referenced by impeller::DlDispatcher::drawCircle(), impeller::testing::MaskBlurVariantTest(), and impeller::testing::TEST_P().

## ◆ DrawImage()

void impeller::Canvas::DrawImage | ( | const std::shared_ptr< Image > & | image,
|  | Point | offset,
|  | const Paint & | paint,
|  | SamplerDescriptor | sampler = `{}`
| ) |  |

Definition at line 703 of file canvas.cc.

706 {
707 if (!image) {
708 return;
709 }
710
711 const auto source = Rect::MakeSize(image->GetSize());
712 const auto dest = source.Shift(offset);
713
714 DrawImageRect(image, source, dest, paint, std::move(sampler));
715 }

References offset.

Referenced by impeller::testing::TEST_P().

## ◆ DrawImageRect()

void impeller::Canvas::DrawImageRect | ( | const std::shared_ptr< Image > & | image,
|  | Rect | source,
|  | Rect | dest,
|  | const Paint & | paint,
|  | SamplerDescriptor | sampler = `{}`,
|  | SourceRectConstraint | src_rect_constraint = `SourceRectConstraint::kFast`
| ) |  |

Definition at line 717 of file canvas.cc.

722 {
723 if (!image || source.IsEmpty() || dest.IsEmpty()) {
724 return;
725 }
726
727 auto size = image->GetSize();
728
729 if (size.IsEmpty()) {
730 return;
731 }
732
733 auto texture_contents = TextureContents::MakeRect(dest);
734 texture_contents->SetTexture(image->GetTexture());
735 texture_contents->SetSourceRect(source);
736 texture_contents->SetStrictSourceRect(src_rect_constraint ==
737 SourceRectConstraint::kStrict);
738 texture_contents->SetSamplerDescriptor(std::move(sampler));
739 texture_contents->SetOpacity(paint.color.alpha);
740 texture_contents->SetDeferApplyingOpacity(paint.HasColorFilter());
741
742 std::shared_ptr<Contents> contents = texture_contents;
743 if (paint.mask_blur_descriptor.has_value()) {
744 contents = paint.mask_blur_descriptor->CreateMaskBlur(texture_contents);
745 }
746
747 Entity entity;
748 entity.SetBlendMode(paint.blend_mode);
749 entity.SetClipDepth(GetClipDepth());
750 entity.SetContents(paint.WithFilters(contents));
751 entity.SetTransform(GetCurrentTransform());
752
753 AddEntityToCurrentPass(std::move(entity));
754 }

References impeller::Color::alpha, impeller::Paint::blend_mode, impeller::Paint::color, impeller::Paint::HasColorFilter(), impeller::TRect< T >::IsEmpty(), impeller::Paint::mask_blur_descriptor, impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::Paint::WithFilters().

Referenced by impeller::DlDispatcher::drawImageRect(), impeller::NinePatchConverter::DrawNinePatch(), and impeller::testing::TEST_P().

## ◆ DrawLine()

void impeller::Canvas::DrawLine | ( | const Point & | p0,
|  | const Point & | p1,
|  | const Paint & | paint
| ) |  |

Definition at line 430 of file canvas.cc.

430 {
431 Entity entity;
432 entity.SetTransform(GetCurrentTransform());
433 entity.SetClipDepth(GetClipDepth());
434 entity.SetBlendMode(paint.blend_mode);
435 entity.SetContents(CreateContentsForGeometryWithFilters(
436 paint, Geometry::MakeLine(p0, p1, paint.stroke_width, paint.stroke_cap)));
437
438 AddEntityToCurrentPass(std::move(entity));
439 }

References impeller::Paint::blend_mode, impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::Paint::stroke_cap, and impeller::Paint::stroke_width.

Referenced by impeller::DlDispatcher::drawLine(), impeller::DlDispatcher::drawPoints(), and impeller::testing::TEST_P().

## ◆ DrawOval()

void impeller::Canvas::DrawOval | ( | const Rect & | rect,
|  | const Paint & | paint
| ) |  |

Definition at line 461 of file canvas.cc.

461 {
462 if (rect.IsSquare()) {
463 // Circles have slightly less overhead and can do stroking
464 DrawCircle(rect.GetCenter(), rect.GetWidth() * 0.5f, paint);
465 return;
466 }
467
468 if (paint.style == Paint::Style::kStroke) {
469 // No stroked ellipses yet
470 DrawPath(PathBuilder{}.AddOval(rect).TakePath(), paint);
471 return;
472 }
473
474 if (AttemptDrawBlurredRRect(rect, rect.GetSize() * 0.5f, paint)) {
475 return;
476 }
477
478 Entity entity;
479 entity.SetTransform(GetCurrentTransform());
480 entity.SetClipDepth(GetClipDepth());
481 entity.SetBlendMode(paint.blend_mode);
482 entity.SetContents(
483 CreateContentsForGeometryWithFilters(paint, Geometry::MakeOval(rect)));
484
485 AddEntityToCurrentPass(std::move(entity));
486 }

References impeller::PathBuilder::AddOval(), impeller::Paint::blend_mode, impeller::TRect< T >::GetCenter(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::IsSquare(), impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::Paint::style.

Referenced by impeller::DlDispatcher::drawOval(), impeller::testing::MaskBlurVariantTest(), and impeller::testing::TEST_P().

## ◆ DrawPaint()

void impeller::Canvas::DrawPaint | ( | const Paint & | paint | ) |

Definition at line 302 of file canvas.cc.

302 {
303 Entity entity;
304 entity.SetTransform(GetCurrentTransform());
305 entity.SetClipDepth(GetClipDepth());
306 entity.SetBlendMode(paint.blend_mode);
307 entity.SetContents(CreateCoverContentsWithFilters(paint));
308
309 AddEntityToCurrentPass(std::move(entity));
310 }

References impeller::Paint::blend_mode, GetCurrentTransform(), impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

Referenced by impeller::testing::BlendModeTest(), impeller::DlDispatcher::drawColor(), impeller::DlDispatcher::drawPaint(), impeller::testing::MaskBlurVariantTest(), and impeller::testing::TEST_P().

## ◆ DrawPath()

void impeller::Canvas::DrawPath | ( | const Path & | path,
|  | const Paint & | paint
| ) |  |

Definition at line 292 of file canvas.cc.

292 {
293 Entity entity;
294 entity.SetTransform(GetCurrentTransform());
295 entity.SetClipDepth(GetClipDepth());
296 entity.SetBlendMode(paint.blend_mode);
297 entity.SetContents(CreatePathContentsWithFilters(paint, path));
298
299 AddEntityToCurrentPass(std::move(entity));
300 }

References impeller::Paint::blend_mode, GetCurrentTransform(), impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

Referenced by impeller::DlDispatcher::drawArc(), impeller::DlDispatcher::drawDRRect(), impeller::DlDispatcher::drawRRect(), impeller::testing::MaskBlurVariantTest(), and impeller::testing::TEST_P().

## ◆ DrawPoints()

void impeller::Canvas::DrawPoints | ( | std::vector< Point > | points,
|  | Scalar | radius,
|  | const Paint & | paint,
|  | PointStyle | point_style
| ) |  |

Definition at line 683 of file canvas.cc.

686 {
687 if (radius <= 0) {
688 return;
689 }
690
691 Entity entity;
692 entity.SetTransform(GetCurrentTransform());
693 entity.SetClipDepth(GetClipDepth());
694 entity.SetBlendMode(paint.blend_mode);
695 entity.SetContents(CreateContentsForGeometryWithFilters(
696 paint,
697 Geometry::MakePointField(std::move(points), radius,
698 /*round=*/point_style == PointStyle::kRound)));
699
700 AddEntityToCurrentPass(std::move(entity));
701 }

References impeller::Paint::blend_mode, impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

Referenced by impeller::DlDispatcher::drawPoints(), and impeller::testing::TEST_P().

## ◆ DrawRect()

void impeller::Canvas::DrawRect | ( | const Rect & | rect,
|  | const Paint & | paint
| ) |  |

Definition at line 441 of file canvas.cc.

441 {
442 if (paint.style == Paint::Style::kStroke) {
443 DrawPath(PathBuilder{}.AddRect(rect).TakePath(), paint);
444 return;
445 }
446
447 if (AttemptDrawBlurredRRect(rect, {}, paint)) {
448 return;
449 }
450
451 Entity entity;
452 entity.SetTransform(GetCurrentTransform());
453 entity.SetClipDepth(GetClipDepth());
454 entity.SetBlendMode(paint.blend_mode);
455 entity.SetContents(
456 CreateContentsForGeometryWithFilters(paint, Geometry::MakeRect(rect)));
457
458 AddEntityToCurrentPass(std::move(entity));
459 }

References impeller::PathBuilder::AddRect(), impeller::Paint::blend_mode, impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::Paint::style.

Referenced by impeller::testing::CanRenderConicalGradientWithDithering(), impeller::testing::CanRenderLinearGradientWithDithering(), impeller::testing::CanRenderRadialGradientWithDithering(), impeller::testing::CanRenderSweepGradientWithDithering(), impeller::DlDispatcher::drawRect(), impeller::testing::MaskBlurVariantTest(), impeller::testing::TEST_F(), and impeller::testing::TEST_P().

## ◆ DrawRRect()

void impeller::Canvas::DrawRRect | ( | const Rect & | rect,
|  | const Size & | corner_radii,
|  | const Paint & | paint
| ) |  |

Definition at line 488 of file canvas.cc.

490 {
491 if (AttemptDrawBlurredRRect(rect, corner_radii, paint)) {
492 return;
493 }
494
495 if (paint.style == Paint::Style::kFill) {
496 Entity entity;
497 entity.SetTransform(GetCurrentTransform());
498 entity.SetClipDepth(GetClipDepth());
499 entity.SetBlendMode(paint.blend_mode);
500 entity.SetContents(CreateContentsForGeometryWithFilters(
501 paint, Geometry::MakeRoundRect(rect, corner_radii)));
502
503 AddEntityToCurrentPass(std::move(entity));
504 return;
505 }
506
507 auto path = PathBuilder{}
508 .SetConvexity(Convexity::kConvex)
509 .AddRoundedRect(rect, corner_radii)
510 .SetBounds(rect)
511 .TakePath();
512 DrawPath(path, paint);
513 }

References impeller::PathBuilder::AddRoundedRect(), impeller::Paint::blend_mode, impeller::Entity::SetBlendMode(), impeller::PathBuilder::SetBounds(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::PathBuilder::SetConvexity(), impeller::Entity::SetTransform(), impeller::Paint::style, and impeller::PathBuilder::TakePath().

Referenced by impeller::DlDispatcher::drawRRect(), impeller::testing::MaskBlurVariantTest(), and impeller::testing::TEST_P().

## ◆ DrawTextFrame()

void impeller::Canvas::DrawTextFrame | ( | const std::shared_ptr< TextFrame > & | text_frame,
|  | Point | position,
|  | const Paint & | paint
| ) |  |

Definition at line 821 of file canvas.cc.

823 {
824 Entity entity;
825 entity.SetClipDepth(GetClipDepth());
826 entity.SetBlendMode(paint.blend_mode);
827
828 auto text_contents = std::make_shared<TextContents>();
829 text_contents->SetTextFrame(text_frame);
830 text_contents->SetColor(paint.color);
831 text_contents->SetForceTextColor(paint.mask_blur_descriptor.has_value());
832
833 entity.SetTransform(GetCurrentTransform() *
834 Matrix::MakeTranslation(position));
835
836 // TODO(bdero): This mask blur application is a hack. It will always wind up
837 // doing a gaussian blur that affects the color source itself
838 // instead of just the mask. The color filter text support
839 // needs to be reworked in order to interact correctly with
840 // mask filters.
841 // https://github.com/flutter/flutter/issues/133297
842 entity.SetContents(
843 paint.WithFilters(paint.WithMaskBlur(std::move(text_contents), true)));
844
845 AddEntityToCurrentPass(std::move(entity));
846 }

References impeller::Paint::blend_mode, impeller::Paint::color, impeller::Paint::mask_blur_descriptor, impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::Paint::WithFilters(), and impeller::Paint::WithMaskBlur().

Referenced by impeller::DlDispatcher::drawTextFrame(), and impeller::testing::TEST_P().

## ◆ DrawVertices()

void impeller::Canvas::DrawVertices | ( | const std::shared_ptr< VerticesGeometry > & | vertices,
|  | BlendMode | blend_mode,
|  | const Paint & | paint
| ) |  |

Definition at line 865 of file canvas.cc.

867 {
868 // Override the blend mode with kDestination in order to match the behavior
869 // of Skia's SK_LEGACY_IGNORE_DRAW_VERTICES_BLEND_WITH_NO_SHADER flag, which
870 // is enabled when the Flutter engine builds Skia.
871 if (paint.color_source.GetType() == ColorSource::Type::kColor) {
872 blend_mode = BlendMode::kDestination;
873 }
874
875 Entity entity;
876 entity.SetTransform(GetCurrentTransform());
877 entity.SetClipDepth(GetClipDepth());
878 entity.SetBlendMode(paint.blend_mode);
879
880 // If there are no vertex color or texture coordinates. Or if there
881 // are vertex coordinates then only if the contents are an image.
882 if (UseColorSourceContents(vertices, paint)) {
883 entity.SetContents(CreateContentsForGeometryWithFilters(paint, vertices));
884 AddEntityToCurrentPass(std::move(entity));
885 return;
886 }
887
888 auto src_paint = paint;
889 src_paint.color = paint.color.WithAlpha(1.0);
890
891 std::shared_ptr<Contents> src_contents =
892 src_paint.CreateContentsForGeometry(vertices);
893 if (vertices->HasTextureCoordinates()) {
894 // If the color source has an intrinsic size, then we use that to
895 // create the src contents as a simplification. Otherwise we use
896 // the extent of the texture coordinates to determine how large
897 // the src contents should be. If neither has a value we fall back
898 // to using the geometry coverage data.
899 Rect src_coverage;
900 auto size = src_contents->GetColorSourceSize();
901 if (size.has_value()) {
902 src_coverage = Rect::MakeXYWH(0, 0, size->width, size->height);
903 } else {
904 auto cvg = vertices->GetCoverage(Matrix{});
905 FML_CHECK(cvg.has_value());
906 src_coverage =
907 // Covered by FML_CHECK.
908 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
909 vertices->GetTextureCoordinateCoverge().value_or(cvg.value());
910 }
911 src_contents =
912 src_paint.CreateContentsForGeometry(Geometry::MakeRect(src_coverage));
913 }
914
915 auto contents = std::make_shared<VerticesContents>();
916 contents->SetAlpha(paint.color.alpha);
917 contents->SetBlendMode(blend_mode);
918 contents->SetGeometry(vertices);
919 contents->SetSourceContents(std::move(src_contents));
920 entity.SetContents(paint.WithFilters(std::move(contents)));
921
922 AddEntityToCurrentPass(std::move(entity));
923 }

References impeller::Color::alpha, impeller::Paint::blend_mode, impeller::Paint::color, impeller::Paint::color_source, impeller::ColorSource::GetType(), impeller::kColor, impeller::Entity::SetBlendMode(), impeller::Entity::SetClipDepth(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::UseColorSourceContents(), impeller::Color::WithAlpha(), and impeller::Paint::WithFilters().

Referenced by impeller::DlDispatcher::drawVertices(), and impeller::testing::TEST_P().

## ◆ EndRecordingAsPicture()

Picture impeller::Canvas::EndRecordingAsPicture | ( |  | ) |

Definition at line 756 of file canvas.cc.

756 {
757 // Assign clip depths to any outstanding clip entities.
758 while (current_pass_ != nullptr) {
759 current_pass_->PopAllClips(current_depth_);
760 current_pass_ = current_pass_->GetSuperpass();
761 }
762
763 Picture picture;
764 picture.pass = std::move(base_pass_);
765
766 Reset();
767 Initialize(initial_cull_rect_);
768
769 return picture;
770 }

References impeller::Picture::pass.

Referenced by impeller::testing::CanRenderConicalGradientWithDithering(), impeller::testing::CanRenderLinearGradientWithDithering(), impeller::testing::CanRenderRadialGradientWithDithering(), impeller::testing::CanRenderSweepGradientWithDithering(), impeller::DlDispatcher::EndRecordingAsPicture(), impeller::testing::MaskBlurVariantTest(), impeller::testing::TEST_F(), and impeller::testing::TEST_P().

## ◆ GetCurrentLocalCullingBounds()

const std::optional< Rect > impeller::Canvas::GetCurrentLocalCullingBounds | ( |  | ) | const

Definition at line 251 of file canvas.cc.

251 {
252 auto cull_rect = transform_stack_.back().cull_rect;
253 if (cull_rect.has_value()) {
254 Matrix inverse = transform_stack_.back().transform.Invert();
255 cull_rect = cull_rect.value().TransformBounds(inverse);
256 }
257 return cull_rect;
258 }

Referenced by impeller::DlDispatcher::drawDisplayList(), and impeller::testing::TEST().

## ◆ GetCurrentTransform()

const Matrix & impeller::Canvas::GetCurrentTransform | ( |  | ) | const

Definition at line 247 of file canvas.cc.

247 {
248 return transform_stack_.back().transform;
249 }

Referenced by Concat(), impeller::DlDispatcher::drawDisplayList(), DrawPaint(), DrawPath(), impeller::DlDispatcher::drawShadow(), PreConcat(), and impeller::testing::TEST_P().

## ◆ GetSaveCount()

size_t impeller::Canvas::GetSaveCount | ( |  | ) | const

Definition at line 280 of file canvas.cc.

280 {
281 return transform_stack_.size();
282 }

Referenced by impeller::DlDispatcher::drawDisplayList(), RestoreToCount(), and impeller::testing::TEST_P().

## ◆ PreConcat()

void impeller::Canvas::PreConcat | ( | const Matrix & | transform | ) |

Definition at line 235 of file canvas.cc.

235 {
236 transform_stack_.back().transform = transform * GetCurrentTransform();
237 }

References GetCurrentTransform().

Referenced by impeller::DlDispatcher::drawShadow().

## ◆ ResetTransform()

void impeller::Canvas::ResetTransform | ( |  | ) |

Definition at line 239 of file canvas.cc.

239 {
240 transform_stack_.back().transform = {};
241 }

Referenced by impeller::DlDispatcher::transformReset().

## ◆ Restore()

bool impeller::Canvas::Restore | ( |  | ) |

Definition at line 208 of file canvas.cc.

208 {
209 FML_DCHECK(transform_stack_.size() > 0);
210 if (transform_stack_.size() == 1) {
211 return false;
212 }
213 size_t num_clips = transform_stack_.back().num_clips;
214 current_pass_->PopClips(num_clips, current_depth_);
215
216 if (transform_stack_.back().rendering_mode ==
217 Entity::RenderingMode::kSubpass) {
218 current_pass_->SetNewClipDepth(++current_depth_);
219 current_pass_ = GetCurrentPass().GetSuperpass();
220 FML_DCHECK(current_pass_);
221 }
222
223 transform_stack_.pop_back();
224 if (num_clips > 0) {
225 RestoreClip();
226 }
227
228 return true;
229 }

References impeller::EntityPass::GetSuperpass(), impeller::Entity::kSubpass, impeller::EntityPass::PopClips(), and impeller::EntityPass::SetNewClipDepth().

Referenced by impeller::DlDispatcher::drawShadow(), impeller::DlDispatcher::restore(), RestoreToCount(), impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ RestoreToCount()

void impeller::Canvas::RestoreToCount | ( | size_t | count | ) |

Definition at line 284 of file canvas.cc.

284 {
285 while (GetSaveCount() > count) {
286 if (!Restore()) {
287 return;
288 }
289 }
290 }

References GetSaveCount(), and Restore().

Referenced by impeller::DlDispatcher::drawDisplayList().

## ◆ Rotate()

void impeller::Canvas::Rotate | ( | Radians | radians | ) |

Definition at line 276 of file canvas.cc.

276 {
277 Concat(Matrix::MakeRotationZ(radians));
278 }

References Concat(), and impeller::Matrix::MakeRotationZ().

Referenced by impeller::DlDispatcher::rotate(), and impeller::testing::TEST_P().

## ◆ Save()

void impeller::Canvas::Save | ( |  | ) |

Definition at line 136 of file canvas.cc.

136 {
137 Save(false);
138 }

Referenced by impeller::DlDispatcher::drawDisplayList(), impeller::DlDispatcher::drawShadow(), impeller::DlDispatcher::save(), impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ SaveLayer()

void impeller::Canvas::SaveLayer | ( | const Paint & | paint,
|  | std::optional< Rect > | bounds = `std::nullopt`,
|  | const std::shared_ptr< ImageFilter > & | backdrop_filter = `nullptr`,
|  | ContentBoundsPromise | bounds_promise = `ContentBoundsPromise::kUnknown`
| ) |  |

Definition at line 786 of file canvas.cc.

789 {
790 TRACE_EVENT0("flutter", "Canvas::saveLayer");
791 Save(true, paint.blend_mode, backdrop_filter);
792
793 // The DisplayList bounds/rtree doesn't account for filters applied to parent
794 // layers, and so sub-DisplayLists are getting culled as if no filters are
795 // applied.
796 // See also: https://github.com/flutter/flutter/issues/139294
797 if (paint.image_filter) {
798 transform_stack_.back().cull_rect = std::nullopt;
799 }
800
801 auto& new_layer_pass = GetCurrentPass();
802 if (bounds) {
803 new_layer_pass.SetBoundsLimit(bounds, bounds_promise);
804 }
805
806 if (paint.image_filter) {
807 MipCountVisitor mip_count_visitor;
808 paint.image_filter->Visit(mip_count_visitor);
809 new_layer_pass.SetRequiredMipCount(mip_count_visitor.GetRequiredMipCount());
810 }
811
812 // Only apply opacity peephole on default blending.
813 if (paint.blend_mode == BlendMode::kSourceOver) {
814 new_layer_pass.SetDelegate(
815 std::make_shared<OpacityPeepholePassDelegate>(paint));
816 } else {
817 new_layer_pass.SetDelegate(std::make_shared<PaintPassDelegate>(paint));
818 }
819 }

References impeller::Paint::blend_mode, and impeller::Paint::image_filter.

Referenced by impeller::DlDispatcher::drawDisplayList(), impeller::DlDispatcher::saveLayer(), impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ Scale() [1/2]

void impeller::Canvas::Scale | ( | const Vector2 & | scale | ) |

Definition at line 264 of file canvas.cc.

264 {
265 Concat(Matrix::MakeScale(scale));
266 }

References Concat(), impeller::Matrix::MakeScale(), and scale.

Referenced by impeller::testing::CanRenderConicalGradientWithDithering(), impeller::testing::CanRenderSweepGradientWithDithering(), impeller::testing::MaskBlurVariantTest(), impeller::DlDispatcher::scale(), impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ Scale() [2/2]

void impeller::Canvas::Scale | ( | const Vector3 & | scale | ) |

Definition at line 268 of file canvas.cc.

268 {
269 Concat(Matrix::MakeScale(scale));
270 }

References Concat(), impeller::Matrix::MakeScale(), and scale.

## ◆ Skew()

void impeller::Canvas::Skew | ( | Scalar | sx,
|  | Scalar | sy
| ) |  |

Definition at line 272 of file canvas.cc.

272 {
273 Concat(Matrix::MakeSkew(sx, sy));
274 }

References Concat(), and impeller::Matrix::MakeSkew().

Referenced by impeller::DlDispatcher::skew(), and impeller::testing::TEST_P().

## ◆ Transform()

void impeller::Canvas::Transform | ( | const Matrix & | transform | ) |

Definition at line 243 of file canvas.cc.

243 {
244 Concat(transform);
245 }

References Concat().

Referenced by impeller::testing::TEST_P(), impeller::DlDispatcher::transformFullPerspective(), and impeller::DlDispatcher::transformReset().

## ◆ Translate()

void impeller::Canvas::Translate | ( | const Vector3 & | offset | ) |

Definition at line 260 of file canvas.cc.

260 {
261 Concat(Matrix::MakeTranslation(offset));
262 }

References Concat(), impeller::Matrix::MakeTranslation(), and offset.

Referenced by impeller::testing::CanRenderConicalGradientWithDithering(), impeller::testing::CanRenderLinearGradientWithDithering(), impeller::testing::CanRenderRadialGradientWithDithering(), impeller::testing::CanRenderSweepGradientWithDithering(), impeller::testing::TEST(), impeller::testing::TEST_P(), and impeller::DlDispatcher::translate().

## Member Data Documentation

## ◆ debug_options

struct impeller::Canvas::DebugOptions impeller::Canvas::debug_options

Referenced by impeller::testing::TEST_P().

The documentation for this class was generated from the following files:

- impeller/aiks/canvas.h
- impeller/aiks/canvas.cc

impeller::Matrix::MakeSkew
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
Definition: matrix.h:117
impeller::Entity::ClipOperation::kIntersect
@ kIntersect
impeller::Geometry::MakePointField
static std::shared_ptr< Geometry > MakePointField(std::vector< Point > points, Scalar radius, bool round)
Definition: geometry.cc:181
impeller::Geometry::MakeStrokedCircle
static std::shared_ptr< Geometry > MakeStrokedCircle(const Point &center, Scalar radius, Scalar stroke_width)
Definition: geometry.cc:224
impeller::Entity::ClipOperation::kDifference
@ kDifference
impeller::EntityPass::PopAllClips
void PopAllClips(uint64_t depth)
Definition: entity_pass.cc:141
impeller::Canvas::DrawImageRect
void DrawImageRect(const std::shared_ptr< Image > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
Definition: canvas.cc:717
impeller::Geometry::MakeRoundRect
static std::shared_ptr< Geometry > MakeRoundRect(const Rect &rect, const Size &radii)
Definition: geometry.cc:230
impeller::Paint::Style::kStroke
@ kStroke
impeller::EntityPass::SetNewClipDepth
void SetNewClipDepth(size_t clip_depth)
Definition: entity_pass.cc:1170
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:136
impeller::BlendMode::kDestination
@ kDestination
impeller::PointStyle::kRound
@ kRound
Points are drawn as squares.
impeller::Size
TSize< Scalar > Size
Definition: size.h:137
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Canvas::GetCurrentTransform
const Matrix & GetCurrentTransform() const
Definition: canvas.cc:247
impeller::Geometry::MakeOval
static std::shared_ptr< Geometry > MakeOval(const Rect &rect)
Definition: geometry.cc:208
impeller::Canvas::Concat
void Concat(const Matrix &transform)
Definition: canvas.cc:231
impeller::UseColorSourceContents
static bool UseColorSourceContents(const std::shared_ptr< VerticesGeometry > &vertices, const Paint &paint)
Definition: canvas.cc:848
impeller::SourceRectConstraint::kStrict
@ kStrict
Sample only within the source rectangle. May be slower.
impeller::Geometry::MakeFillPath
static std::shared_ptr< Geometry > MakeFillPath(const Path &path, std::optional< Rect > inner_rect=std::nullopt)
Definition: geometry.cc:175
impeller::EntityPass::GetSuperpass
EntityPass * GetSuperpass() const
Definition: entity_pass.cc:268
impeller::Canvas::Save
void Save()
Definition: canvas.cc:136
impeller::Paint::Style::kFill
@ kFill
impeller::TRect< Scalar >::MakeOriginSize
constexpr static TRect MakeOriginSize(const TPoint< Type > &origin, const TSize< Type > &size)
Definition: rect.h:140
impeller::Canvas::DrawCircle
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition: canvas.cc:515
impeller::Canvas::Restore
bool Restore()
Definition: canvas.cc:208
impeller::Canvas::DrawPath
void DrawPath(const Path &path, const Paint &paint)
Definition: canvas.cc:292
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:661
impeller::Canvas::GetSaveCount
size_t GetSaveCount() const
Definition: canvas.cc:280
impeller::Entity::RenderingMode::kSubpass
@ kSubpass
impeller::Geometry::MakeRect
static std::shared_ptr< Geometry > MakeRect(const Rect &rect)
Definition: geometry.cc:204
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:209
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:146
impeller::EntityPass::PopClips
void PopClips(size_t num_clips, uint64_t depth)
Definition: entity_pass.cc:123
scale
const Scalar scale
Definition: stroke_path_geometry.cc:297
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
offset
Point offset
Definition: stroke_path_geometry.cc:300
impeller::Convexity::kConvex
@ kConvex
impeller::TextureContents::MakeRect
static std::shared_ptr< TextureContents > MakeRect(Rect destination)
A common case factory that marks the texture contents as having a destination rectangle....
Definition: texture_contents.cc:27
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104
impeller::ColorSource::Type::kColor
@ kColor
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::Geometry::MakeLine
static std::shared_ptr< Geometry > MakeLine(const Point &p0, const Point &p1, Scalar width, Cap cap)
Definition: geometry.cc:212