| Flutter Impeller |

Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Attributes | 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 | EllipticalVertexGenerator
| The |VertexGenerator| implementation common to all shapes that are based on a polygonal representation of an ellipse. More...
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 | Result { Result::kSuccess, Result::kInputError, Result::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 ()
virtual | ~Tessellator ()
VertexBuffer | TessellateConvex (const Path &path, HostBuffer &host_buffer, Scalar tolerance)
| Given a convex path, create a triangle fan structure. More...
Path::Polyline | CreateTempPolyline (const Path &path, Scalar tolerance)
| Create a temporary polyline. Only one per-process can exist at a time. 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...
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...

## Static Public Member Functions
static void | TessellateConvexInternal (const Path &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...

## Protected Attributes
std::unique_ptr< std::vector< Point > > | point_buffer_
| Used for polyline generation. More...
std::unique_ptr< std::vector< uint16_t > > | index_buffer_

## 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 31 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 78 of file tessellator.h.

## Member Enumeration Documentation

## ◆ Result

enum impeller::Tessellator::Result
| strong

Enumerator
kSuccess |
kInputError |
kTessellationError |

Definition at line 70 of file tessellator.h.

70 {
71 kSuccess,
72 kInputError,
73 kTessellationError,
74 };

## Constructor & Destructor Documentation

## ◆ Tessellator()

impeller::Tessellator::Tessellator | ( |  | ) |

Definition at line 9 of file tessellator.cc.

10 : point_buffer_(std::make_unique<std::vector<Point>>()),
11 index_buffer_(std::make_unique<std::vector<uint16_t>>()) {
12 point_buffer_->reserve(2048);
13 index_buffer_->reserve(2048);
14 }

References index_buffer_, and point_buffer_.

## ◆ ~Tessellator()

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

## Member Function Documentation

## ◆ CreateTempPolyline()

Path::Polyline impeller::Tessellator::CreateTempPolyline | ( | const Path & | path,
|  | Scalar | tolerance
| ) |  |

Create a temporary polyline. Only one per-process can exist at a time.

The tessellator itself is not a thread safe class and should only be used from the raster thread.

Definition at line 18 of file tessellator.cc.

19 {
20 FML_DCHECK(point_buffer_);
21 point_buffer_->clear();
22 auto polyline =
23 path.CreatePolyline(tolerance, std::move(point_buffer_),
24 [this](Path::Polyline::PointBufferPtr point_buffer) {
25 point_buffer_ = std::move(point_buffer);
26 });
27 return polyline;
28 }

References impeller::Path::CreatePolyline(), point_buffer_, and polyline.

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

240 {
241 auto divisions =
242 ComputeQuadrantDivisions(view_transform.GetMaxBasisLength() * radius);
243 return EllipticalVertexGenerator(Tessellator::GenerateFilledCircle,
244 GetTrigsForDivisions(divisions),
245 PrimitiveType::kTriangleStrip, 4,
246 {
247 .reference_centers = {center, center},
248 .radii = {radius, radius},
249 .half_width = -1.0f,
250 });
251 }

References impeller::ComputeQuadrantDivisions(), and impeller::Matrix::GetMaxBasisLength().

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

299 {
300 if (bounds.IsSquare()) {
301 return FilledCircle(view_transform, bounds.GetCenter(),
302 bounds.GetWidth() * 0.5f);
303 }
304 auto max_radius = bounds.GetSize().MaxDimension();
305 auto divisions =
306 ComputeQuadrantDivisions(view_transform.GetMaxBasisLength() * max_radius);
307 auto center = bounds.GetCenter();
308 return EllipticalVertexGenerator(Tessellator::GenerateFilledEllipse,
309 GetTrigsForDivisions(divisions),
310 PrimitiveType::kTriangleStrip, 4,
311 {
312 .reference_centers = {center, center},
313 .radii = bounds.GetSize() * 0.5f,
314 .half_width = -1.0f,
315 });
316 }

References impeller::ComputeQuadrantDivisions(), impeller::TRect< T >::GetCenter(), impeller::Matrix::GetMaxBasisLength(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), and impeller::TRect< T >::IsSquare().

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

321 {
322 if (radii.width * 2 < bounds.GetWidth() ||
323 radii.height * 2 < bounds.GetHeight()) {
324 auto max_radius = radii.MaxDimension();
325 auto divisions = ComputeQuadrantDivisions(
326 view_transform.GetMaxBasisLength() * max_radius);
327 auto upper_left = bounds.GetLeftTop() + radii;
328 auto lower_right = bounds.GetRightBottom() - radii;
329 return EllipticalVertexGenerator(Tessellator::GenerateFilledRoundRect,
330 GetTrigsForDivisions(divisions),
331 PrimitiveType::kTriangleStrip, 4,
332 {
333 .reference_centers =
334 {
335 upper_left,
336 lower_right,
337 },
338 .radii = radii,
339 .half_width = -1.0f,
340 });
341 } else {
342 return FilledEllipse(view_transform, bounds);
343 }
344 }

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

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

278 {
279 auto along = p1 - p0;
280 auto length = along.GetLength();
281 if (length > kEhCloseEnough) {
282 auto divisions =
283 ComputeQuadrantDivisions(view_transform.GetMaxBasisLength() * radius);
284 return EllipticalVertexGenerator(Tessellator::GenerateRoundCapLine,
285 GetTrigsForDivisions(divisions),
286 PrimitiveType::kTriangleStrip, 4,
287 {
288 .reference_centers = {p0, p1},
289 .radii = {radius, radius},
290 .half_width = -1.0f,
291 });
292 } else {
293 return FilledCircle(view_transform, p0, radius);
294 }
295 }

References impeller::ComputeQuadrantDivisions(), impeller::TPoint< T >::GetLength(), impeller::Matrix::GetMaxBasisLength(), and impeller::kEhCloseEnough.

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

257 {
258 if (half_width > 0) {
259 auto divisions = ComputeQuadrantDivisions(
260 view_transform.GetMaxBasisLength() * radius + half_width);
261 return EllipticalVertexGenerator(Tessellator::GenerateStrokedCircle,
262 GetTrigsForDivisions(divisions),
263 PrimitiveType::kTriangleStrip, 8,
264 {
265 .reference_centers = {center, center},
266 .radii = {radius, radius},
267 .half_width = half_width,
268 });
269 } else {
270 return FilledCircle(view_transform, center, radius);
271 }
272 }

References impeller::ComputeQuadrantDivisions(), and impeller::Matrix::GetMaxBasisLength().

## ◆ TessellateConvex()

VertexBuffer impeller::Tessellator::TessellateConvex | ( | const Path & | path,
|  | HostBuffer & | host_buffer,
|  | Scalar | tolerance
| ) |  |

Given a convex path, create a triangle fan structure.

Parameters

  [in] | path | The path to tessellate.
  [in] | tolerance | The tolerance value for conversion of the path to a polyline. This value is often derived from the Matrix::GetMaxBasisLength of the CTM applied to the path for rendering.

Returns
  A point vector containing the vertices in triangle strip format.

Parameters

  [in] | host_buffer | The host buffer for allocation of vertices/index data.

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

Definition at line 30 of file tessellator.cc.

32 {
33 FML_DCHECK(point_buffer_);
34 FML_DCHECK(index_buffer_);
35 TessellateConvexInternal(path, *point_buffer_, *index_buffer_, tolerance);
36
37 if (point_buffer_->empty()) {
38 return VertexBuffer{
39 .vertex_buffer = {},
40 .index_buffer = {},
41 .vertex_count = 0u,
42 .index_type = IndexType::k16bit,
43 };
44 }
45
46 BufferView vertex_buffer = host_buffer.Emplace(
47 point_buffer_->data(), sizeof(Point) * point_buffer_->size(),
48 alignof(Point));
49
50 BufferView index_buffer = host_buffer.Emplace(
51 index_buffer_->data(), sizeof(uint16_t) * index_buffer_->size(),
52 alignof(uint16_t));
53
54 return VertexBuffer{
55 .vertex_buffer = std::move(vertex_buffer),
56 .index_buffer = std::move(index_buffer),
57 .vertex_count = index_buffer_->size(),
58 .index_type = IndexType::k16bit,
59 };
60 }

References impeller::HostBuffer::Emplace(), index_buffer_, impeller::k16bit, point_buffer_, TessellateConvexInternal(), and impeller::VertexBuffer::vertex_buffer.

## ◆ TessellateConvexInternal()

void impeller::Tessellator::TessellateConvexInternal | ( | const Path & | 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 62 of file tessellator.cc.

65 {
66 point_buffer.clear();
67 index_buffer.clear();
68
69 VertexWriter writer(point_buffer, index_buffer);
70
71 path.WritePolyline(tolerance, writer);
72 }

References impeller::Path::WritePolyline().

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

## Member Data Documentation

## ◆ index_buffer_

std::unique_ptr<std::vector<uint16_t> > impeller::Tessellator::index_buffer_
| protected

Definition at line 288 of file tessellator.h.

Referenced by TessellateConvex(), and Tessellator().

## ◆ 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 214 of file tessellator.h.

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

## ◆ point_buffer_

std::unique_ptr<std::vector<Point> > impeller::Tessellator::point_buffer_
| protected

Used for polyline generation.

Definition at line 287 of file tessellator.h.

Referenced by CreateTempPolyline(), TessellateConvex(), and Tessellator().

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

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

impeller::EllipticalVertexGenerator
Tessellator::EllipticalVertexGenerator EllipticalVertexGenerator
Definition: tessellator.cc:224
polyline
const Path::Polyline & polyline
Definition: stroke_path_geometry.cc:303
impeller::IndexType::k16bit
@ k16bit
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:56
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:237
impeller::ComputeQuadrantDivisions
static size_t ComputeQuadrantDivisions(Scalar pixel_radius)
Definition: tessellator.cc:144
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::Point
TPoint< Scalar > Point
Definition: point.h:322
impeller::Tessellator::point_buffer_
std::unique_ptr< std::vector< Point > > point_buffer_
Used for polyline generation.
Definition: tessellator.h:287
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:297
impeller::Tessellator::TessellateConvexInternal
static void TessellateConvexInternal(const Path &path, std::vector< Point > &point_buffer, std::vector< uint16_t > &index_buffer, Scalar tolerance)
Definition: tessellator.cc:62
impeller::Tessellator::index_buffer_
std::unique_ptr< std::vector< uint16_t > > index_buffer_
Definition: tessellator.h:288
impeller::Path::Polyline::PointBufferPtr
std::unique_ptr< std::vector< Point > > PointBufferPtr
Definition: path.h:98