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

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

◆ Canvas() [2/3]

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

Definition at line 29 of file canvas.cc.

29  {
30  Initialize(cull_rect);
31 }

◆ Canvas() [3/3]

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

Definition at line 33 of file canvas.cc.

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

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

284  {
285  ClipGeometry(Geometry::MakeFillPath(path), clip_op);
286  if (clip_op == Entity::ClipOperation::kIntersect) {
287  auto bounds = path.GetBoundingBox();
288  if (bounds.has_value()) {
289  IntersectCulling(bounds.value());
290  }
291  }
292 }

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

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

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

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

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

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

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

660  {
661  if (!atlas) {
662  return;
663  }
664 
665  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
666  contents->SetColors(std::move(colors));
667  contents->SetTransforms(std::move(transforms));
668  contents->SetTextureCoordinates(std::move(texture_coordinates));
669  contents->SetTexture(atlas->GetTexture());
670  contents->SetSamplerDescriptor(std::move(sampler));
671  contents->SetBlendMode(blend_mode);
672  contents->SetCullRect(cull_rect);
673  contents->SetAlpha(paint.color.alpha);
674 
675  Entity entity;
676  entity.SetTransformation(GetCurrentTransformation());
677  entity.SetStencilDepth(GetStencilDepth());
678  entity.SetBlendMode(paint.blend_mode);
679  entity.SetContents(paint.WithFilters(contents));
680 
681  GetCurrentPass().AddEntity(entity);
682 }

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

271  {
272  Size half_size(radius, radius);
273  if (AttemptDrawBlurredRRect(Rect(center - half_size, half_size * 2), radius,
274  paint)) {
275  return;
276  }
277  auto circle_path = PathBuilder{}
278  .AddCircle(center, radius)
279  .SetConvexity(Convexity::kConvex)
280  .TakePath();
281  DrawPath(circle_path, paint);
282 }

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

470  {
471  if (!image) {
472  return;
473  }
474 
475  const auto source = Rect::MakeSize(image->GetSize());
476  const auto dest =
477  Rect::MakeXYWH(offset.x, offset.y, source.size.width, source.size.height);
478 
479  DrawImageRect(image, source, dest, paint, std::move(sampler));
480 }

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

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

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

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

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

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

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

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

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

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

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

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

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

551  {
552  Entity entity;
553  entity.SetStencilDepth(GetStencilDepth());
554  entity.SetBlendMode(paint.blend_mode);
555 
556  auto text_contents = std::make_shared<TextContents>();
557  text_contents->SetTextFrame(text_frame);
558  text_contents->SetColor(paint.color);
559 
560  entity.SetTransformation(GetCurrentTransformation() *
561  Matrix::MakeTranslation(position));
562 
563  // TODO(bdero): This mask blur application is a hack. It will always wind up
564  // doing a gaussian blur that affects the color source itself
565  // instead of just the mask. The color filter text support
566  // needs to be reworked in order to interact correctly with
567  // mask filters.
568  // https://github.com/flutter/flutter/issues/133297
569  entity.SetContents(
570  paint.WithFilters(paint.WithMaskBlur(std::move(text_contents), true)));
571 
572  GetCurrentPass().AddEntity(entity);
573 }

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

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

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

513  {
514  Picture picture;
515  picture.pass = std::move(base_pass_);
516 
517  Reset();
518  Initialize(initial_cull_rect_);
519 
520  return picture;
521 }

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

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

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

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

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

◆ PreConcat()

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

Definition at line 116 of file canvas.cc.

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

References GetCurrentTransformation().

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

◆ ResetTransform()

void impeller::Canvas::ResetTransform ( )

Definition at line 120 of file canvas.cc.

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

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

◆ Restore()

bool impeller::Canvas::Restore ( )

Definition at line 91 of file canvas.cc.

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

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

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

◆ RestoreToCount()

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

Definition at line 165 of file canvas.cc.

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

References GetSaveCount(), and Restore().

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

◆ Rotate()

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

Definition at line 157 of file canvas.cc.

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

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 
)

Definition at line 532 of file canvas.cc.

534  {
535  Save(true, paint.blend_mode, backdrop_filter);
536 
537  auto& new_layer_pass = GetCurrentPass();
538  new_layer_pass.SetBoundsLimit(bounds);
539 
540  // Only apply opacity peephole on default blending.
541  if (paint.blend_mode == BlendMode::kSourceOver) {
542  new_layer_pass.SetDelegate(
543  std::make_shared<OpacityPeepholePassDelegate>(paint));
544  } else {
545  new_layer_pass.SetDelegate(std::make_shared<PaintPassDelegate>(paint));
546  }
547 }

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

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

◆ Scale() [1/2]

◆ Scale() [2/2]

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

Definition at line 149 of file canvas.cc.

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

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

◆ Skew()

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

Definition at line 153 of file canvas.cc.

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

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

124  {
125  Concat(xformation);
126 }

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:575
impeller::Canvas::DrawImageRect
void DrawImageRect(const std::shared_ptr< Image > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={})
Definition: canvas.cc:482
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:55
impeller::Paint::Style::kFill
@ kFill
impeller::Canvas::Restore
bool Restore()
Definition: canvas.cc:91
impeller::Canvas::DrawPath
void DrawPath(const Path &path, const Paint &paint)
Definition: canvas.cc:173
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:306
impeller::Canvas::GetSaveCount
size_t GetSaveCount() const
Definition: canvas.cc:161
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:128
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:112
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