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)
 
bool Restore ()
 
size_t GetSaveCount () const
 
void RestoreToCount (size_t count)
 
const MatrixGetCurrentTransformation () const
 
const std::optional< RectGetCurrentLocalCullingBounds () const
 
void ResetTransform ()
 
void Transform (const Matrix &xformation)
 
void Concat (const Matrix &xformation)
 
void PreConcat (const Matrix &xformation)
 
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 DrawRect (Rect rect, const Paint &paint)
 
void DrawRRect (Rect rect, Scalar corner_radius, const Paint &paint)
 
void DrawCircle (Point center, Scalar radius, const Paint &paint)
 
void DrawPoints (std::vector< Point >, 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={})
 
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 ClipRRect (const Rect &rect, Scalar corner_radius, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
 
void DrawPicture (const Picture &picture)
 
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 50 of file canvas.h.

Constructor & Destructor Documentation

◆ Canvas() [1/3]

impeller::Canvas::Canvas ( )

Definition at line 26 of file canvas.cc.

26  {
27  Initialize(std::nullopt);
28 }

◆ Canvas() [2/3]

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

Definition at line 30 of file canvas.cc.

30  {
31  Initialize(cull_rect);
32 }

◆ Canvas() [3/3]

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

Definition at line 34 of file canvas.cc.

34  {
35  Initialize(Rect::MakeLTRB(cull_rect.GetLeft(), cull_rect.GetTop(),
36  cull_rect.GetRight(), cull_rect.GetBottom()));
37 }

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

◆ ClipPath()

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

Definition at line 290 of file canvas.cc.

290  {
291  ClipGeometry(Geometry::MakeFillPath(path), clip_op);
292  if (clip_op == Entity::ClipOperation::kIntersect) {
293  auto bounds = path.GetBoundingBox();
294  if (bounds.has_value()) {
295  IntersectCulling(bounds.value());
296  }
297  }
298 }

References impeller::Path::GetBoundingBox(), impeller::Entity::kIntersect, and impeller::Geometry::MakeFillPath().

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 300 of file canvas.cc.

300  {
301  auto geometry = Geometry::MakeRect(rect);
302  auto& cull_rect = xformation_stack_.back().cull_rect;
303  if (clip_op == Entity::ClipOperation::kIntersect && //
304  cull_rect.has_value() && //
305  geometry->CoversArea(xformation_stack_.back().xformation, *cull_rect) //
306  ) {
307  return; // This clip will do nothing, so skip it.
308  }
309 
310  ClipGeometry(std::move(geometry), clip_op);
311  switch (clip_op) {
313  IntersectCulling(rect);
314  break;
316  SubtractCulling(rect);
317  break;
318  }
319 }

References impeller::Entity::kDifference, impeller::Entity::kIntersect, and impeller::Geometry::MakeRect().

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

◆ ClipRRect()

void impeller::Canvas::ClipRRect ( const Rect rect,
Scalar  corner_radius,
Entity::ClipOperation  clip_op = Entity::ClipOperation::kIntersect 
)

Definition at line 321 of file canvas.cc.

323  {
324  auto path = PathBuilder{}
325  .SetConvexity(Convexity::kConvex)
326  .AddRoundedRect(rect, corner_radius)
327  .TakePath();
328 
329  std::optional<Rect> inner_rect = (corner_radius * 2 < rect.size.width &&
330  corner_radius * 2 < rect.size.height)
331  ? rect.Expand(-corner_radius)
332  : std::make_optional<Rect>();
333  auto geometry = Geometry::MakeFillPath(path, inner_rect);
334  auto& cull_rect = xformation_stack_.back().cull_rect;
335  if (clip_op == Entity::ClipOperation::kIntersect && //
336  cull_rect.has_value() && //
337  geometry->CoversArea(xformation_stack_.back().xformation, *cull_rect) //
338  ) {
339  return; // This clip will do nothing, so skip it.
340  }
341 
342  ClipGeometry(std::move(geometry), clip_op);
343  switch (clip_op) {
345  IntersectCulling(rect);
346  break;
348  if (corner_radius <= 0) {
349  SubtractCulling(rect);
350  } else {
351  // We subtract the inner "tall" and "wide" rectangle pieces
352  // that fit inside the corners which cover the greatest area
353  // without involving the curved corners
354  // Since this is a subtract operation, we can subtract each
355  // rectangle piece individually without fear of interference.
356  if (corner_radius * 2 < rect.size.width) {
357  SubtractCulling(Rect::MakeLTRB(
358  rect.GetLeft() + corner_radius, rect.GetTop(),
359  rect.GetRight() - corner_radius, rect.GetBottom()));
360  }
361  if (corner_radius * 2 < rect.size.height) {
362  SubtractCulling(Rect::MakeLTRB(
363  rect.GetLeft(), rect.GetTop() + corner_radius, //
364  rect.GetRight(), rect.GetBottom() - corner_radius));
365  }
366  }
367  break;
368  }
369 }

References impeller::PathBuilder::AddRoundedRect(), impeller::TRect< T >::Expand(), impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TSize< T >::height, impeller::kConvex, impeller::Entity::kDifference, impeller::Entity::kIntersect, impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::PathBuilder::SetConvexity(), impeller::TRect< T >::size, impeller::PathBuilder::TakePath(), and impeller::TSize< T >::width.

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

◆ Concat()

void impeller::Canvas::Concat ( const Matrix xformation)

Definition at line 113 of file canvas.cc.

113  {
114  xformation_stack_.back().xformation = GetCurrentTransformation() * xformation;
115 }

References GetCurrentTransformation().

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 667 of file canvas.cc.

674  {
675  if (!atlas) {
676  return;
677  }
678 
679  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
680  contents->SetColors(std::move(colors));
681  contents->SetTransforms(std::move(transforms));
682  contents->SetTextureCoordinates(std::move(texture_coordinates));
683  contents->SetTexture(atlas->GetTexture());
684  contents->SetSamplerDescriptor(std::move(sampler));
685  contents->SetBlendMode(blend_mode);
686  contents->SetCullRect(cull_rect);
687  contents->SetAlpha(paint.color.alpha);
688 
689  Entity entity;
690  entity.SetTransformation(GetCurrentTransformation());
691  entity.SetStencilDepth(GetStencilDepth());
692  entity.SetBlendMode(paint.blend_mode);
693  entity.SetContents(paint.WithFilters(contents));
694 
695  GetCurrentPass().AddEntity(entity);
696 }

References impeller::EntityPass::AddEntity(), impeller::Color::alpha, impeller::Paint::blend_mode, impeller::Paint::color, GetCurrentTransformation(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetStencilDepth(), impeller::Entity::SetTransformation(), and impeller::Paint::WithFilters().

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

◆ DrawCircle()

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

Definition at line 277 of file canvas.cc.

277  {
278  Size half_size(radius, radius);
279  if (AttemptDrawBlurredRRect(Rect(center - half_size, half_size * 2), radius,
280  paint)) {
281  return;
282  }
283  auto circle_path = PathBuilder{}
284  .AddCircle(center, radius)
285  .SetConvexity(Convexity::kConvex)
286  .TakePath();
287  DrawPath(circle_path, paint);
288 }

References impeller::PathBuilder::AddCircle(), DrawPath(), impeller::kConvex, impeller::PathBuilder::SetConvexity(), and impeller::PathBuilder::TakePath().

Referenced by impeller::DlDispatcher::drawCircle(), impeller::DlDispatcher::drawOval(), impeller::DlDispatcher::drawPath(), impeller::DlDispatcher::drawShadow(), 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 473 of file canvas.cc.

476  {
477  if (!image) {
478  return;
479  }
480 
481  const auto source = Rect::MakeSize(image->GetSize());
482  const auto dest =
483  Rect::MakeXYWH(offset.x, offset.y, source.size.width, source.size.height);
484 
485  DrawImageRect(image, source, dest, paint, std::move(sampler));
486 }

References DrawImageRect(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

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 = {} 
)

Definition at line 488 of file canvas.cc.

492  {
493  if (!image || source.size.IsEmpty() || dest.size.IsEmpty()) {
494  return;
495  }
496 
497  auto size = image->GetSize();
498 
499  if (size.IsEmpty()) {
500  return;
501  }
502 
503  auto contents = TextureContents::MakeRect(dest);
504  contents->SetTexture(image->GetTexture());
505  contents->SetSourceRect(source);
506  contents->SetSamplerDescriptor(std::move(sampler));
507  contents->SetOpacity(paint.color.alpha);
508  contents->SetDeferApplyingOpacity(paint.HasColorFilter());
509 
510  Entity entity;
511  entity.SetBlendMode(paint.blend_mode);
512  entity.SetStencilDepth(GetStencilDepth());
513  entity.SetContents(paint.WithFilters(contents));
514  entity.SetTransformation(GetCurrentTransformation());
515 
516  GetCurrentPass().AddEntity(entity);
517 }

References impeller::EntityPass::AddEntity(), impeller::Color::alpha, impeller::Paint::blend_mode, impeller::Paint::color, GetCurrentTransformation(), impeller::Paint::HasColorFilter(), impeller::TSize< T >::IsEmpty(), impeller::TextureContents::MakeRect(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetStencilDepth(), impeller::Entity::SetTransformation(), impeller::TRect< T >::size, and impeller::Paint::WithFilters().

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

◆ DrawPaint()

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

Definition at line 184 of file canvas.cc.

184  {
185  Entity entity;
186  entity.SetTransformation(GetCurrentTransformation());
187  entity.SetStencilDepth(GetStencilDepth());
188  entity.SetBlendMode(paint.blend_mode);
189  entity.SetContents(paint.CreateContentsForEntity({}, true));
190 
191  GetCurrentPass().AddEntity(entity);
192 }

References impeller::EntityPass::AddEntity(), impeller::Paint::blend_mode, impeller::Paint::CreateContentsForEntity(), GetCurrentTransformation(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetStencilDepth(), and impeller::Entity::SetTransformation().

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

◆ DrawPath()

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

◆ DrawPicture()

void impeller::Canvas::DrawPicture ( const Picture picture)

Definition at line 443 of file canvas.cc.

443  {
444  if (!picture.pass) {
445  return;
446  }
447 
448  // Clone the base pass and account for the CTM updates.
449  auto pass = picture.pass->Clone();
450 
451  pass->IterateAllElements([&](auto& element) -> bool {
452  if (auto entity = std::get_if<Entity>(&element)) {
453  entity->IncrementStencilDepth(GetStencilDepth());
454  entity->SetTransformation(GetCurrentTransformation() *
455  entity->GetTransformation());
456  return true;
457  }
458 
459  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
460  subpass->get()->SetStencilDepth(subpass->get()->GetStencilDepth() +
461  GetStencilDepth());
462  return true;
463  }
464 
465  FML_UNREACHABLE();
466  });
467 
468  GetCurrentPass().AddSubpassInline(std::move(pass));
469 
470  RestoreClip();
471 }

References impeller::EntityPass::AddSubpassInline(), GetCurrentTransformation(), and impeller::Picture::pass.

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

◆ DrawPoints()

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

Definition at line 424 of file canvas.cc.

427  {
428  if (radius <= 0) {
429  return;
430  }
431 
432  Entity entity;
433  entity.SetTransformation(GetCurrentTransformation());
434  entity.SetStencilDepth(GetStencilDepth());
435  entity.SetBlendMode(paint.blend_mode);
436  entity.SetContents(paint.WithFilters(paint.CreateContentsForGeometry(
437  Geometry::MakePointField(std::move(points), radius,
438  /*round=*/point_style == PointStyle::kRound))));
439 
440  GetCurrentPass().AddEntity(entity);
441 }

References impeller::EntityPass::AddEntity(), impeller::Paint::blend_mode, impeller::Paint::CreateContentsForGeometry(), GetCurrentTransformation(), impeller::kRound, impeller::Geometry::MakePointField(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetStencilDepth(), impeller::Entity::SetTransformation(), and impeller::Paint::WithFilters().

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

◆ DrawRect()

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

Definition at line 235 of file canvas.cc.

235  {
236  if (paint.style == Paint::Style::kStroke) {
237  DrawPath(PathBuilder{}.AddRect(rect).TakePath(), paint);
238  return;
239  }
240 
241  if (AttemptDrawBlurredRRect(rect, 0, paint)) {
242  return;
243  }
244 
245  Entity entity;
246  entity.SetTransformation(GetCurrentTransformation());
247  entity.SetStencilDepth(GetStencilDepth());
248  entity.SetBlendMode(paint.blend_mode);
249  entity.SetContents(paint.WithFilters(
250  paint.CreateContentsForGeometry(Geometry::MakeRect(rect))));
251 
252  GetCurrentPass().AddEntity(entity);
253 }

References impeller::EntityPass::AddEntity(), impeller::PathBuilder::AddRect(), impeller::Paint::blend_mode, impeller::Paint::CreateContentsForGeometry(), DrawPath(), GetCurrentTransformation(), impeller::Paint::kStroke, impeller::Geometry::MakeRect(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetStencilDepth(), impeller::Entity::SetTransformation(), impeller::Paint::style, and impeller::Paint::WithFilters().

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

◆ DrawRRect()

void impeller::Canvas::DrawRRect ( Rect  rect,
Scalar  corner_radius,
const Paint paint 
)

Definition at line 255 of file canvas.cc.

255  {
256  if (AttemptDrawBlurredRRect(rect, corner_radius, paint)) {
257  return;
258  }
259  auto path = PathBuilder{}
260  .SetConvexity(Convexity::kConvex)
261  .AddRoundedRect(rect, corner_radius)
262  .TakePath();
263  if (paint.style == Paint::Style::kFill) {
264  Entity entity;
265  entity.SetTransformation(GetCurrentTransformation());
266  entity.SetStencilDepth(GetStencilDepth());
267  entity.SetBlendMode(paint.blend_mode);
268  entity.SetContents(paint.WithFilters(
269  paint.CreateContentsForGeometry(Geometry::MakeFillPath(path))));
270 
271  GetCurrentPass().AddEntity(entity);
272  return;
273  }
274  DrawPath(path, paint);
275 }

References impeller::EntityPass::AddEntity(), impeller::PathBuilder::AddRoundedRect(), impeller::Paint::blend_mode, impeller::Paint::CreateContentsForGeometry(), DrawPath(), GetCurrentTransformation(), impeller::kConvex, impeller::Paint::kFill, impeller::Geometry::MakeFillPath(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::PathBuilder::SetConvexity(), impeller::Entity::SetStencilDepth(), impeller::Entity::SetTransformation(), impeller::Paint::style, impeller::PathBuilder::TakePath(), and impeller::Paint::WithFilters().

Referenced by impeller::DlDispatcher::drawPath(), impeller::DlDispatcher::drawRRect(), impeller::DlDispatcher::drawShadow(), 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 563 of file canvas.cc.

565  {
566  Entity entity;
567  entity.SetStencilDepth(GetStencilDepth());
568  entity.SetBlendMode(paint.blend_mode);
569 
570  auto text_contents = std::make_shared<TextContents>();
571  text_contents->SetTextFrame(text_frame);
572  text_contents->SetColor(paint.color);
573 
574  entity.SetTransformation(GetCurrentTransformation() *
575  Matrix::MakeTranslation(position));
576 
577  // TODO(bdero): This mask blur application is a hack. It will always wind up
578  // doing a gaussian blur that affects the color source itself
579  // instead of just the mask. The color filter text support
580  // needs to be reworked in order to interact correctly with
581  // mask filters.
582  // https://github.com/flutter/flutter/issues/133297
583  entity.SetContents(
584  paint.WithFilters(paint.WithMaskBlur(std::move(text_contents), true)));
585 
586  GetCurrentPass().AddEntity(entity);
587 }

References impeller::EntityPass::AddEntity(), impeller::Paint::blend_mode, impeller::Paint::color, GetCurrentTransformation(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetStencilDepth(), impeller::Entity::SetTransformation(), 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 606 of file canvas.cc.

608  {
609  // Override the blend mode with kDestination in order to match the behavior
610  // of Skia's SK_LEGACY_IGNORE_DRAW_VERTICES_BLEND_WITH_NO_SHADER flag, which
611  // is enabled when the Flutter engine builds Skia.
612  if (paint.color_source.GetType() == ColorSource::Type::kColor) {
613  blend_mode = BlendMode::kDestination;
614  }
615 
616  Entity entity;
617  entity.SetTransformation(GetCurrentTransformation());
618  entity.SetStencilDepth(GetStencilDepth());
619  entity.SetBlendMode(paint.blend_mode);
620 
621  // If there are no vertex color or texture coordinates. Or if there
622  // are vertex coordinates then only if the contents are an image.
623  if (UseColorSourceContents(vertices, paint)) {
624  auto contents = paint.CreateContentsForGeometry(vertices);
625  entity.SetContents(paint.WithFilters(std::move(contents)));
626  GetCurrentPass().AddEntity(entity);
627  return;
628  }
629 
630  auto src_paint = paint;
631  src_paint.color = paint.color.WithAlpha(1.0);
632 
633  std::shared_ptr<Contents> src_contents =
634  src_paint.CreateContentsForGeometry(vertices);
635  if (vertices->HasTextureCoordinates()) {
636  // If the color source has an intrinsic size, then we use that to
637  // create the src contents as a simplification. Otherwise we use
638  // the extent of the texture coordinates to determine how large
639  // the src contents should be. If neither has a value we fall back
640  // to using the geometry coverage data.
641  Rect src_coverage;
642  auto size = src_contents->GetColorSourceSize();
643  if (size.has_value()) {
644  src_coverage = Rect::MakeXYWH(0, 0, size->width, size->height);
645  } else {
646  auto cvg = vertices->GetCoverage(Matrix{});
647  FML_CHECK(cvg.has_value());
648  src_coverage =
649  // Covered by FML_CHECK.
650  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
651  vertices->GetTextureCoordinateCoverge().value_or(cvg.value());
652  }
653  src_contents =
654  src_paint.CreateContentsForGeometry(Geometry::MakeRect(src_coverage));
655  }
656 
657  auto contents = std::make_shared<VerticesContents>();
658  contents->SetAlpha(paint.color.alpha);
659  contents->SetBlendMode(blend_mode);
660  contents->SetGeometry(vertices);
661  contents->SetSourceContents(std::move(src_contents));
662  entity.SetContents(paint.WithFilters(std::move(contents)));
663 
664  GetCurrentPass().AddEntity(entity);
665 }

References impeller::EntityPass::AddEntity(), impeller::Color::alpha, impeller::Paint::blend_mode, impeller::Paint::color, impeller::Paint::color_source, impeller::Paint::CreateContentsForGeometry(), GetCurrentTransformation(), impeller::ColorSource::GetType(), impeller::ColorSource::kColor, impeller::kDestination, impeller::Geometry::MakeRect(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetStencilDepth(), impeller::Entity::SetTransformation(), 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 519 of file canvas.cc.

519  {
520  Picture picture;
521  picture.pass = std::move(base_pass_);
522 
523  Reset();
524  Initialize(initial_cull_rect_);
525 
526  return picture;
527 }

References impeller::Picture::pass.

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

◆ GetCurrentLocalCullingBounds()

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

Definition at line 133 of file canvas.cc.

133  {
134  auto cull_rect = xformation_stack_.back().cull_rect;
135  if (cull_rect.has_value()) {
136  Matrix inverse = xformation_stack_.back().xformation.Invert();
137  cull_rect = cull_rect.value().TransformBounds(inverse);
138  }
139  return cull_rect;
140 }

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

◆ GetCurrentTransformation()

const Matrix & impeller::Canvas::GetCurrentTransformation ( ) const

◆ GetSaveCount()

size_t impeller::Canvas::GetSaveCount ( ) const

Definition at line 162 of file canvas.cc.

162  {
163  return xformation_stack_.size();
164 }

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

◆ PreConcat()

void impeller::Canvas::PreConcat ( const Matrix xformation)

Definition at line 117 of file canvas.cc.

117  {
118  xformation_stack_.back().xformation = xformation * GetCurrentTransformation();
119 }

References GetCurrentTransformation().

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

◆ ResetTransform()

void impeller::Canvas::ResetTransform ( )

Definition at line 121 of file canvas.cc.

121  {
122  xformation_stack_.back().xformation = {};
123 }

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

◆ Restore()

bool impeller::Canvas::Restore ( )

Definition at line 92 of file canvas.cc.

92  {
93  FML_DCHECK(xformation_stack_.size() > 0);
94  if (xformation_stack_.size() == 1) {
95  return false;
96  }
97  if (xformation_stack_.back().rendering_mode ==
99  current_pass_ = GetCurrentPass().GetSuperpass();
100  FML_DCHECK(current_pass_);
101  }
102 
103  bool contains_clips = xformation_stack_.back().contains_clips;
104  xformation_stack_.pop_back();
105 
106  if (contains_clips) {
107  RestoreClip();
108  }
109 
110  return true;
111 }

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

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 166 of file canvas.cc.

166  {
167  while (GetSaveCount() > count) {
168  if (!Restore()) {
169  return;
170  }
171  }
172 }

References GetSaveCount(), and Restore().

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

◆ Rotate()

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

Definition at line 158 of file canvas.cc.

158  {
159  Concat(Matrix::MakeRotationZ(radians));
160 }

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

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

◆ Save()

◆ SaveLayer()

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

Definition at line 538 of file canvas.cc.

540  {
541  Save(true, paint.blend_mode, backdrop_filter);
542 
543  // The DisplayList bounds/rtree doesn't account for filters applied to parent
544  // layers, and so sub-DisplayLists are getting culled as if no filters are
545  // applied.
546  // See also: https://github.com/flutter/flutter/issues/139294
547  if (paint.image_filter) {
548  xformation_stack_.back().cull_rect = std::nullopt;
549  }
550 
551  auto& new_layer_pass = GetCurrentPass();
552  new_layer_pass.SetBoundsLimit(bounds);
553 
554  // Only apply opacity peephole on default blending.
555  if (paint.blend_mode == BlendMode::kSourceOver) {
556  new_layer_pass.SetDelegate(
557  std::make_shared<OpacityPeepholePassDelegate>(paint));
558  } else {
559  new_layer_pass.SetDelegate(std::make_shared<PaintPassDelegate>(paint));
560  }
561 }

References impeller::Paint::blend_mode, impeller::Paint::image_filter, impeller::kSourceOver, and Save().

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 150 of file canvas.cc.

150  {
151  Concat(Matrix::MakeScale(scale));
152 }

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

◆ Skew()

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

Definition at line 154 of file canvas.cc.

154  {
155  Concat(Matrix::MakeSkew(sx, sy));
156 }

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

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

◆ Transform()

void impeller::Canvas::Transform ( const Matrix xformation)

Definition at line 125 of file canvas.cc.

125  {
126  Concat(xformation);
127 }

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:116
impeller::EntityPass::AddSubpassInline
void AddSubpassInline(std::unique_ptr< EntityPass > pass)
Merges a given pass into this pass. Useful for drawing pre-recorded pictures that don't require rende...
Definition: entity_pass.cc:245
impeller::Entity::ClipOperation::kIntersect
@ kIntersect
impeller::Entity::ClipOperation::kDifference
@ kDifference
impeller::Paint::Style::kStroke
@ kStroke
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:47
impeller::PointStyle::kRound
@ kRound
Points are drawn as squares.
impeller::Geometry::MakeRect
static std::unique_ptr< Geometry > MakeRect(Rect rect)
Definition: geometry.cc:142
impeller::Size
TSize< Scalar > Size
Definition: size.h:135
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:94
impeller::UseColorSourceContents
static bool UseColorSourceContents(const std::shared_ptr< VerticesGeometry > &vertices, const Paint &paint)
Definition: canvas.cc:589
impeller::Canvas::DrawImageRect
void DrawImageRect(const std::shared_ptr< Image > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={})
Definition: canvas.cc:488
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::EntityPass::GetSuperpass
EntityPass * GetSuperpass() const
Definition: entity_pass.cc:222
impeller::BlendMode::kDestination
@ kDestination
impeller::Canvas::Save
void Save()
Definition: canvas.cc:56
impeller::Paint::Style::kFill
@ kFill
impeller::Canvas::Restore
bool Restore()
Definition: canvas.cc:92
impeller::Canvas::DrawPath
void DrawPath(const Path &path, const Paint &paint)
Definition: canvas.cc:174
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:306
impeller::Canvas::GetSaveCount
size_t GetSaveCount() const
Definition: canvas.cc:162
impeller::Entity::RenderingMode::kSubpass
@ kSubpass
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:208
impeller::Geometry::MakePointField
static std::unique_ptr< Geometry > MakePointField(std::vector< Point > points, Scalar radius, bool round)
Definition: geometry.cc:119
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:52
impeller::Canvas::GetCurrentTransformation
const Matrix & GetCurrentTransformation() const
Definition: canvas.cc:129
impeller::Geometry::MakeFillPath
static std::unique_ptr< Geometry > MakeFillPath(const Path &path, std::optional< Rect > inner_rect=std::nullopt)
Definition: geometry.cc:113
impeller::Canvas::Concat
void Concat(const Matrix &xformation)
Definition: canvas.cc:113
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:40
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:28
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:103
impeller::ColorSource::Type::kColor
@ kColor
impeller::EntityPass::AddEntity
void AddEntity(Entity entity)
Definition: entity_pass.cc:77