| Flutter Impeller |

Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Friends | List of all members
impeller::Tessellator Class Reference

A utility that generates triangles of the specified fill type given a polyline. This happens on the CPU. More...

`#include <tessellator.h>`

## Classes
class | ArcVertexGenerator
| The |VertexGenerator| implementation common to all shapes that are based on a polygonal representation of an ellipse. More...
class | EllipticalVertexGenerator
| The |VertexGenerator| implementation common to all shapes that are based on a polygonal representation of an ellipse. More...
class | Trigs
class | VertexGenerator
| An object which produces a list of vertices as |Point|s that tessellate a previously provided shape and delivers the vertices through a |TessellatedVertexProc| callback. More...

## Public Types
enum class | Result { kSuccess , kInputError , kTessellationError }
using | TessellatedVertexProc = std::function< void(const Point &p)>
| A callback function for a |VertexGenerator| to deliver the vertices it computes as |Point| objects. More...

## Public Member Functions
| Tessellator (bool supports_32bit_primitive_indices=true)
virtual | ~Tessellator ()
VertexBuffer | TessellateConvex (const PathSource &path, HostBuffer &data_host_buffer, HostBuffer &indexes_host_buffer, Scalar tolerance, bool supports_primitive_restart=false, bool supports_triangle_fan=false)
| Given a convex path, create a triangle fan structure. More...
EllipticalVertexGenerator | FilledCircle (const Matrix &view_transform, const Point &center, Scalar radius)
| Create a |VertexGenerator| that can produce vertices for a filled circle of the given radius around the given center with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. More...
EllipticalVertexGenerator | StrokedCircle (const Matrix &view_transform, const Point &center, Scalar radius, Scalar half_width)
| Create a |VertexGenerator| that can produce vertices for a stroked circle of the given radius and half_width around the given shared center with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. The outer edge of the stroked circle is generated at (radius + half_width) and the inner edge is generated at (radius - half_width). More...
ArcVertexGenerator | FilledArc (const Matrix &view_transform, const Arc &arc, bool supports_triangle_fans)
| Create a |VertexGenerator| that can produce vertices for a stroked arc inscribed within the given oval_bounds with the given stroke half_width with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. The outer edge of the stroked arc is generated at (radius + half_width) and the inner edge is generated at (radius - half_width). More...
ArcVertexGenerator | StrokedArc (const Matrix &view_transform, const Arc &arc, Cap cap, Scalar half_width)
| Create a |VertexGenerator| that can produce vertices for a stroked arc inscribed within the given oval_bounds with the given stroke half_width with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. The outer edge of the stroked arc is generated at (radius + half_width) and the inner edge is generated at (radius - half_width). More...
EllipticalVertexGenerator | RoundCapLine (const Matrix &view_transform, const Point &p0, const Point &p1, Scalar radius)
| Create a |VertexGenerator| that can produce vertices for a line with round end caps of the given radius with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. More...
EllipticalVertexGenerator | FilledEllipse (const Matrix &view_transform, const Rect &bounds)
| Create a |VertexGenerator| that can produce vertices for a filled ellipse inscribed within the given bounds with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. More...
EllipticalVertexGenerator | FilledRoundRect (const Matrix &view_transform, const Rect &bounds, const Size &radii)
| Create a |VertexGenerator| that can produce vertices for a filled round rect within the given bounds and corner radii with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. More...
std::vector< Point > & | GetStrokePointCache ()
| Retrieve a pre-allocated arena of kPointArenaSize points. More...
Trigs | GetTrigsForDeviceRadius (Scalar pixel_radius)

## Static Public Member Functions
static void | TessellateConvexInternal (const PathSource &path, std::vector< Point > &point_buffer, std::vector< uint16_t > &index_buffer, Scalar tolerance)

## Static Public Attributes
static constexpr Scalar | kCircleTolerance = 0.1f
| The pixel tolerance used by the algorighm to determine how many divisions to create for a circle. More...

## Friends
template<typename IndexT >
class | ConvexTessellatorImpl

## Detailed Description

A utility that generates triangles of the specified fill type given a polyline. This happens on the CPU.

Also contains functionality for optimized generation of circles and ellipses.

This object is not thread safe, and its methods must not be called from multiple threads.

Definition at line 37 of file tessellator.h.

## Member Typedef Documentation

## ◆ TessellatedVertexProc

using impeller::Tessellator::TessellatedVertexProc = std::function<void(const Point& p)>

A callback function for a |VertexGenerator| to deliver the vertices it computes as |Point| objects.

Definition at line 97 of file tessellator.h.

## Member Enumeration Documentation

## ◆ Result

enum impeller::Tessellator::Result
| strong

Enumerator
kSuccess |
kInputError |
kTessellationError |

Definition at line 89 of file tessellator.h.

89 {
90 kSuccess,
91 kInputError,
92 kTessellationError,
93 };

## Constructor & Destructor Documentation

## ◆ Tessellator()

impeller::Tessellator::Tessellator | ( | bool | supports_32bit_primitive_indices = `true` | ) |
| explicit

Definition at line 410 of file tessellator.cc.

411 : stroke_points_(kPointArenaSize) {
412 if (supports_32bit_primitive_indices) {
413 convex_tessellator_ = std::make_unique<ConvexTessellatorImpl<uint32_t>>();
414 } else {
415 convex_tessellator_ = std::make_unique<ConvexTessellatorImpl<uint16_t>>();
416 }
417 }
impeller::kPointArenaSize
static constexpr size_t kPointArenaSize
The size of the point arena buffer stored on the tessellator.
Definition: tessellator.h:25

## ◆ ~Tessellator()

impeller::Tessellator::~Tessellator | ( |  | ) |
| virtual default

## Member Function Documentation

## ◆ FilledArc()

ArcVertexGenerator impeller::Tessellator::FilledArc | ( | const Matrix & | view_transform,
|  | const Arc & | arc,
|  | bool | supports_triangle_fans
| ) |  |

Create a |VertexGenerator| that can produce vertices for a stroked arc inscribed within the given oval_bounds with the given stroke half_width with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. The outer edge of the stroked arc is generated at (radius + half_width) and the inner edge is generated at (radius - half_width).

Note that the view transform is only used to choose the number of sample points to use per quarter circle and the returned points are not transformed by it, instead they are relative to the coordinate space of the oval bounds.

Definition at line 612 of file tessellator.cc.

614 {
615 size_t divisions = ComputeQuadrantDivisions(
616 view_transform.GetMaxBasisLengthXY() * arc.GetOvalSize().MaxDimension());
617
618 return ArcVertexGenerator::MakeFilled(
619 arc.ComputeIterations(divisions), GetTrigsForDivisions(divisions),
620 arc.GetOvalBounds(), arc.IncludeCenter(), supports_triangle_fans);
621 };
impeller::Tessellator::ArcVertexGenerator::MakeFilled
static ArcVertexGenerator MakeFilled(const Arc::Iteration &iteration, Trigs &&trigs, const Rect &oval_bounds, bool use_center, bool supports_triangle_fans)
Definition: tessellator.cc:525

References impeller::Arc::ComputeIterations(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::Arc::GetOvalBounds(), impeller::Arc::GetOvalSize(), impeller::Arc::IncludeCenter(), impeller::Tessellator::ArcVertexGenerator::MakeFilled(), and impeller::TSize< T >::MaxDimension().

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

## ◆ FilledCircle()

EllipticalVertexGenerator impeller::Tessellator::FilledCircle | ( | const Matrix & | view_transform,
|  | const Point & | center,
|  | Scalar | radius
| ) |  |

Create a |VertexGenerator| that can produce vertices for a filled circle of the given radius around the given center with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform.

Note that the view transform is only used to choose the number of sample points to use per quarter circle and the returned points are not transformed by it, instead they are relative to the coordinate space of the center point.

Definition at line 488 of file tessellator.cc.

491 {
492 size_t divisions =
493 ComputeQuadrantDivisions(view_transform.GetMaxBasisLengthXY() * radius);
494 return EllipticalVertexGenerator(Tessellator::GenerateFilledCircle,
495 GetTrigsForDivisions(divisions),
496 PrimitiveType::kTriangleStrip, 4,
497 {
498 .reference_centers = {center, center},
499 .radii = {radius, radius},
500 .half_width = -1.0f,
501 });
502 }
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::EllipticalVertexGenerator
Tessellator::EllipticalVertexGenerator EllipticalVertexGenerator
Definition: tessellator.cc:474

References impeller::Matrix::GetMaxBasisLengthXY().

Referenced by FilledEllipse(), RoundCapLine(), and impeller::testing::TEST().

## ◆ FilledEllipse()

EllipticalVertexGenerator impeller::Tessellator::FilledEllipse | ( | const Matrix & | view_transform,
|  | const Rect & | bounds
| ) |  |

Create a |VertexGenerator| that can produce vertices for a filled ellipse inscribed within the given bounds with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform.

Note that the view transform is only used to choose the number of sample points to use per quarter circle and the returned points are not transformed by it, instead they are relative to the coordinate space of the bounds.

Definition at line 668 of file tessellator.cc.

670 {
671 if (bounds.IsSquare()) {
672 return FilledCircle(view_transform, bounds.GetCenter(),
673 bounds.GetWidth() * 0.5f);
674 }
675 auto max_radius = bounds.GetSize().MaxDimension();
676 auto divisions = ComputeQuadrantDivisions(
677 view_transform.GetMaxBasisLengthXY() * max_radius);
678 auto center = bounds.GetCenter();
679 return EllipticalVertexGenerator(Tessellator::GenerateFilledEllipse,
680 GetTrigsForDivisions(divisions),
681 PrimitiveType::kTriangleStrip, 4,
682 {
683 .reference_centers = {center, center},
684 .radii = bounds.GetSize() * 0.5f,
685 .half_width = -1.0f,
686 });
687 }
impeller::Tessellator::FilledCircle
EllipticalVertexGenerator FilledCircle(const Matrix &view_transform, const Point &center, Scalar radius)
Create a |VertexGenerator| that can produce vertices for a filled circle of the given radius around t...
Definition: tessellator.cc:488

References FilledCircle(), impeller::TRect< T >::GetCenter(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::IsSquare(), and impeller::kTriangleStrip.

Referenced by FilledRoundRect(), and impeller::testing::TEST().

## ◆ FilledRoundRect()

EllipticalVertexGenerator impeller::Tessellator::FilledRoundRect | ( | const Matrix & | view_transform,
|  | const Rect & | bounds,
|  | const Size & | radii
| ) |  |

Create a |VertexGenerator| that can produce vertices for a filled round rect within the given bounds and corner radii with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform.

Note that the view transform is only used to choose the number of sample points to use per quarter circle and the returned points are not transformed by it, instead they are relative to the coordinate space of the bounds.

Definition at line 689 of file tessellator.cc.

692 {
693 if (radii.width * 2 < bounds.GetWidth() ||
694 radii.height * 2 < bounds.GetHeight()) {
695 auto max_radius = radii.MaxDimension();
696 auto divisions = ComputeQuadrantDivisions(
697 view_transform.GetMaxBasisLengthXY() * max_radius);
698 auto upper_left = bounds.GetLeftTop() + radii;
699 auto lower_right = bounds.GetRightBottom() - radii;
700 return EllipticalVertexGenerator(Tessellator::GenerateFilledRoundRect,
701 GetTrigsForDivisions(divisions),
702 PrimitiveType::kTriangleStrip, 4,
703 {
704 .reference_centers =
705 {
706 upper_left,
707 lower_right,
708 },
709 .radii = radii,
710 .half_width = -1.0f,
711 });
712 } else {
713 return FilledEllipse(view_transform, bounds);
714 }
715 }
impeller::Tessellator::FilledEllipse
EllipticalVertexGenerator FilledEllipse(const Matrix &view_transform, const Rect &bounds)
Create a |VertexGenerator| that can produce vertices for a filled ellipse inscribed within the given ...
Definition: tessellator.cc:668

References FilledEllipse(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeftTop(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::TRect< T >::GetRightBottom(), impeller::TRect< T >::GetWidth(), impeller::TSize< T >::height, impeller::kTriangleStrip, impeller::TSize< T >::MaxDimension(), and impeller::TSize< T >::width.

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

## ◆ GetStrokePointCache()

std::vector< Point > & impeller::Tessellator::GetStrokePointCache | ( |  | ) |

Retrieve a pre-allocated arena of kPointArenaSize points.

Definition at line 421 of file tessellator.cc.

421 {
422 return stroke_points_;
423 }

## ◆ GetTrigsForDeviceRadius()

Tessellator::Trigs impeller::Tessellator::GetTrigsForDeviceRadius | ( | Scalar | pixel_radius | ) |

Return a vector of Trig (cos, sin pairs) structs for a 90 degree circle quadrant of the specified pixel radius

Definition at line 425 of file tessellator.cc.

425 {
426 return GetTrigsForDivisions(ComputeQuadrantDivisions(pixel_radius));
427 }

Referenced by impeller::ArcStrokeGeometry::Dispatch(), impeller::StrokeRectGeometry::GetPositionBuffer(), impeller::ShadowPathGeometry::MakeAmbientShadowVertices(), impeller::StrokePathSegmentReceiver::RecordArc(), StrokedArc(), and impeller::testing::TEST().

## ◆ RoundCapLine()

EllipticalVertexGenerator impeller::Tessellator::RoundCapLine | ( | const Matrix & | view_transform,
|  | const Point & | p0,
|  | const Point & | p1,
|  | Scalar | radius
| ) |  |

Create a |VertexGenerator| that can produce vertices for a line with round end caps of the given radius with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform.

Note that the view transform is only used to choose the number of sample points to use per quarter circle and the returned points are not transformed by it, instead they are relative to the coordinate space of the two points.

Definition at line 645 of file tessellator.cc.

649 {
650 auto along = p1 - p0;
651 auto length = along.GetLength();
652 if (length > kEhCloseEnough) {
653 auto divisions =
654 ComputeQuadrantDivisions(view_transform.GetMaxBasisLengthXY() * radius);
655 return EllipticalVertexGenerator(Tessellator::GenerateRoundCapLine,
656 GetTrigsForDivisions(divisions),
657 PrimitiveType::kTriangleStrip, 4,
658 {
659 .reference_centers = {p0, p1},
660 .radii = {radius, radius},
661 .half_width = -1.0f,
662 });
663 } else {
664 return FilledCircle(view_transform, p0, radius);
665 }
666 }
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:57

References FilledCircle(), impeller::TPoint< T >::GetLength(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::kEhCloseEnough, and impeller::kTriangleStrip.

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

## ◆ StrokedArc()

ArcVertexGenerator impeller::Tessellator::StrokedArc | ( | const Matrix & | view_transform,
|  | const Arc & | arc,
|  | Cap | cap,
|  | Scalar | half_width
| ) |  |

Create a |VertexGenerator| that can produce vertices for a stroked arc inscribed within the given oval_bounds with the given stroke half_width with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. The outer edge of the stroked arc is generated at (radius + half_width) and the inner edge is generated at (radius - half_width).

Note that the arc may not include the center and its bounds must be a perfect circle (width == height)

Note that the view transform is only used to choose the number of sample points to use per quarter circle and the returned points are not transformed by it, instead they are relative to the coordinate space of the oval bounds.

Definition at line 623 of file tessellator.cc.

626 {
627 FML_DCHECK(half_width > 0);
628 FML_DCHECK(arc.IsPerfectCircle());
629 FML_DCHECK(!arc.IncludeCenter());
630 size_t divisions =
631 ComputeQuadrantDivisions(view_transform.GetMaxBasisLengthXY() *
632 (arc.GetOvalSize().MaxDimension() + half_width));
633
634 std::unique_ptr<Trigs> round_cap_trigs;
635 if (cap == Cap::kRound) {
636 round_cap_trigs = std::make_unique<Trigs>(GetTrigsForDeviceRadius(
637 view_transform.GetMaxBasisLengthXY() * half_width));
638 }
639
640 return ArcVertexGenerator::MakeStroked(
641 arc.ComputeIterations(divisions), GetTrigsForDivisions(divisions),
642 arc.GetOvalBounds(), half_width, cap, std::move(round_cap_trigs));
643 }
impeller::Tessellator::ArcVertexGenerator::MakeStroked
static ArcVertexGenerator MakeStroked(const Arc::Iteration &iteration, Trigs &&trigs, const Rect &oval_bounds, Scalar half_width, Cap cap, std::unique_ptr< Trigs > round_cap_trigs)
Definition: tessellator.cc:536
impeller::Tessellator::GetTrigsForDeviceRadius
Trigs GetTrigsForDeviceRadius(Scalar pixel_radius)
Definition: tessellator.cc:425
impeller::Cap::kRound
@ kRound

References impeller::Arc::ComputeIterations(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::Arc::GetOvalBounds(), impeller::Arc::GetOvalSize(), GetTrigsForDeviceRadius(), impeller::Arc::IncludeCenter(), impeller::Arc::IsPerfectCircle(), impeller::kRound, impeller::Tessellator::ArcVertexGenerator::MakeStroked(), and impeller::TSize< T >::MaxDimension().

## ◆ StrokedCircle()

EllipticalVertexGenerator impeller::Tessellator::StrokedCircle | ( | const Matrix & | view_transform,
|  | const Point & | center,
|  | Scalar | radius,
|  | Scalar | half_width
| ) |  |

Create a |VertexGenerator| that can produce vertices for a stroked circle of the given radius and half_width around the given shared center with enough polygon sub-divisions to provide reasonable fidelity when viewed under the given view transform. The outer edge of the stroked circle is generated at (radius + half_width) and the inner edge is generated at (radius - half_width).

Note that the view transform is only used to choose the number of sample points to use per quarter circle and the returned points are not transformed by it, instead they are relative to the coordinate space of the center point.

Definition at line 504 of file tessellator.cc.

508 {
509 if (half_width > 0) {
510 auto divisions = ComputeQuadrantDivisions(
511 view_transform.GetMaxBasisLengthXY() * radius + half_width);
512 return EllipticalVertexGenerator(Tessellator::GenerateStrokedCircle,
513 GetTrigsForDivisions(divisions),
514 PrimitiveType::kTriangleStrip, 8,
515 {
516 .reference_centers = {center, center},
517 .radii = {radius, radius},
518 .half_width = half_width,
519 });
520 } else {
521 return FilledCircle(view_transform, center, radius);
522 }
523 }

References impeller::Matrix::GetMaxBasisLengthXY().

Referenced by impeller::CircleGeometry::GetPositionBuffer(), and impeller::testing::TEST().

## ◆ TessellateConvex()

VertexBuffer impeller::Tessellator::TessellateConvex | ( | const PathSource & | path,
|  | HostBuffer & | data_host_buffer,
|  | HostBuffer & | indexes_host_buffer,
|  | Scalar | tolerance,
|  | bool | supports_primitive_restart = `false`,
|  | bool | supports_triangle_fan = `false`
| ) |  |

Given a convex path, create a triangle fan structure.

Parameters

  [in] | path | The path to tessellate.
  [in] | host_buffer | The host buffer for allocation of vertices/index data.
  [in] | tolerance | The tolerance value for conversion of the path to a polyline. This value is often derived from the Matrix::GetMaxBasisLengthXY of the CTM applied to the path for rendering.

Returns
  A vertex buffer containing all data from the provided curve.

Definition at line 429 of file tessellator.cc.

434 {
435 return convex_tessellator_->TessellateConvex(
436 path, data_host_buffer, indexes_host_buffer, tolerance,
437 supports_primitive_restart, supports_triangle_fan);
438 }

## ◆ TessellateConvexInternal()

void impeller::Tessellator::TessellateConvexInternal | ( | const PathSource & | path,
|  | std::vector< Point > & | point_buffer,
|  | std::vector< uint16_t > & | index_buffer,
|  | Scalar | tolerance
| ) |  |
| static

Visible for testing.

This method only exists for the ease of benchmarking without using the real allocator needed by the [host_buffer].

Definition at line 440 of file tessellator.cc.

443 {
444 DoTessellateConvexInternal(path, point_buffer, index_buffer, tolerance);
445 }

Referenced by impeller::BM_Convex(), and impeller::testing::TEST().

## Friends And Related Function Documentation

## ◆ ConvexTessellatorImpl

template<typename IndexT >

friend class ConvexTessellatorImpl
| friend

Definition at line 406 of file tessellator.h.

## Member Data Documentation

## ◆ kCircleTolerance

constexpr Scalar impeller::Tessellator::kCircleTolerance = 0.1f
| static constexpr

The pixel tolerance used by the algorighm to determine how many divisions to create for a circle.

No point on the polygon of vertices should deviate from the true circle by more than this tolerance.

Definition at line 280 of file tessellator.h.

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

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

- impeller/tessellator/tessellator.h
- impeller/tessellator/tessellator.cc