Flutter Impeller
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 MatrixGetCurrentTransform () const
 
const std::optional< RectGetCurrentLocalCullingBounds () 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) {
583  IntersectCulling(bounds);
584  break;
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) {
562  IntersectCulling(rect);
563  break;
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) {
608  IntersectCulling(rect);
609  break;
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 ==
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 ==
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 ( )

◆ 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]

◆ Scale() [2/2]

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

Definition at line 268 of file canvas.cc.

268  {
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()

Member Data Documentation

◆ debug_options

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

The documentation for this class was generated from the following files:
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