Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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.
 

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.
 
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.
 
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).
 
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).
 
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).
 
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.
 
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.
 
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.
 
std::vector< Point > & GetStrokePointCache ()
 Retrieve a pre-allocated arena of kPointArenaSize points.
 
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.
 

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 class impeller::Tessellator::Result
strong
Enumerator
kSuccess 
kInputError 
kTessellationError 

Definition at line 89 of file tessellator.h.

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}
static constexpr size_t kPointArenaSize
The size of the point arena buffer stored on the tessellator.
Definition tessellator.h:25

◆ ~Tessellator()

impeller::Tessellator::~Tessellator ( )
virtualdefault

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 610 of file tessellator.cc.

612 {
613 size_t divisions = ComputeQuadrantDivisions(
614 view_transform.GetMaxBasisLengthXY() * arc.GetOvalSize().MaxDimension());
615
617 arc.ComputeIterations(divisions), GetTrigsForDivisions(divisions),
618 arc.GetOvalBounds(), arc.IncludeCenter(), supports_triangle_fans);
619};
static ArcVertexGenerator MakeFilled(const Arc::Iteration &iteration, Trigs &&trigs, const Rect &oval_bounds, bool use_center, bool supports_triangle_fans)

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().

◆ 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),
497 {
498 .reference_centers = {center, center},
499 .radii = {radius, radius},
500 .half_width = -1.0f,
501 });
502}

References impeller::Matrix::GetMaxBasisLengthXY(), and impeller::kTriangleStrip.

Referenced by FilledEllipse(), RoundCapLine(), and StrokedCircle().

◆ 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 666 of file tessellator.cc.

668 {
669 if (bounds.IsSquare()) {
670 return FilledCircle(view_transform, bounds.GetCenter(),
671 bounds.GetWidth() * 0.5f);
672 }
673 auto max_radius = bounds.GetSize().MaxDimension();
674 auto divisions = ComputeQuadrantDivisions(
675 view_transform.GetMaxBasisLengthXY() * max_radius);
676 auto center = bounds.GetCenter();
677 return EllipticalVertexGenerator(Tessellator::GenerateFilledEllipse,
678 GetTrigsForDivisions(divisions),
680 {
681 .reference_centers = {center, center},
682 .radii = bounds.GetSize() * 0.5f,
683 .half_width = -1.0f,
684 });
685}
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...

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().

◆ 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 687 of file tessellator.cc.

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

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.

◆ 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::StrokePathSegmentReceiver::RecordArc(), StrokedArc(), impeller::testing::TEST(), impeller::testing::TEST(), 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 643 of file tessellator.cc.

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

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

◆ 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 621 of file tessellator.cc.

624 {
625 FML_DCHECK(half_width > 0);
626 FML_DCHECK(arc.IsPerfectCircle());
627 FML_DCHECK(!arc.IncludeCenter());
628 size_t divisions =
629 ComputeQuadrantDivisions(view_transform.GetMaxBasisLengthXY() *
630 (arc.GetOvalSize().MaxDimension() + half_width));
631
632 std::unique_ptr<Trigs> round_cap_trigs;
633 if (cap == Cap::kRound) {
634 round_cap_trigs = std::make_unique<Trigs>(GetTrigsForDeviceRadius(
635 view_transform.GetMaxBasisLengthXY() * half_width));
636 }
637
639 arc.ComputeIterations(divisions), GetTrigsForDivisions(divisions),
640 arc.GetOvalBounds(), half_width, cap, std::move(round_cap_trigs));
641}
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)
Trigs GetTrigsForDeviceRadius(Scalar pixel_radius)
#define FML_DCHECK(condition)
Definition logging.h:122

References impeller::Arc::ComputeIterations(), FML_DCHECK, 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),
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 FilledCircle(), impeller::Matrix::GetMaxBasisLengthXY(), and impeller::kTriangleStrip.

Referenced by impeller::CircleGeometry::GetPositionBuffer().

◆ 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]pathThe path to tessellate.
[in]host_bufferThe host buffer for allocation of vertices/index data.
[in]toleranceThe 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(), impeller::testing::TEST(), impeller::testing::TEST(), and impeller::testing::TEST().

Friends And Related Symbol 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
staticconstexpr

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: