| Flutter Impeller |

Public Types | Public Member Functions | 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>`

## Public Types
enum | Result { Result::kSuccess, Result::kInputError, Result::kTessellationError }
using | BuilderCallback = std::function< bool(const float *vertices, size_t vertices_count, const uint16_t *indices, size_t indices_count)>
| A callback that returns the results of the tessellation. More...

## Public Member Functions
| Tessellator ()
| ~Tessellator ()
Tessellator::Result | Tessellate (FillType fill_type, const Path::Polyline &polyline, const BuilderCallback &callback) const
| Generates filled triangles from the polyline. A callback is invoked once for the entire tessellation. More...

## Detailed Description

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

Definition at line 35 of file tessellator.h.

## Member Typedef Documentation

## ◆ BuilderCallback

using impeller::Tessellator::BuilderCallback = std::function<bool(const float* vertices, size_t vertices_count, const uint16_t* indices, size_t indices_count)>

A callback that returns the results of the tessellation.

       The index buffer may not be populated, in which case [indices] will
       be nullptr and indices_count will be 0.

Definition at line 54 of file tessellator.h.

## Member Enumeration Documentation

## ◆ Result

enum impeller::Tessellator::Result
| strong

Enumerator
kSuccess |
kInputError |
kTessellationError |

Definition at line 37 of file tessellator.h.

37 {
38 kSuccess,
39 kInputError,
40 kTessellationError,
41 };

## Constructor & Destructor Documentation

## ◆ Tessellator()

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

Definition at line 34 of file tessellator.cc.

34 : c_tessellator_(nullptr, &DestroyTessellator) {
35 TESSalloc alloc = kAlloc;
36 {
37 // libTess2 copies the TESSalloc despite the non-const argument.
38 CTessellator tessellator(::tessNewTess(&alloc), &DestroyTessellator);
39 c_tessellator_ = std::move(tessellator);
40 }
41 }

References impeller::DestroyTessellator(), and impeller::kAlloc.

## ◆ ~Tessellator()

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

## Member Function Documentation

## ◆ Tessellate()

Tessellator::Result impeller::Tessellator::Tessellate | ( | FillType | fill_type,
|  | const Path::Polyline & | polyline,
|  | const BuilderCallback & | callback
| ) |  | const

Generates filled triangles from the polyline. A callback is invoked once for the entire tessellation.

Parameters

  [in] | fill_type | The fill rule to use when filling.
  [in] | polyline | The polyline
  [in] | callback | The callback, return false to indicate failure.

Returns
  The result status of the tessellation.

Feed contour information to the tessellator.

Let's tessellate.

Definition at line 61 of file tessellator.cc.

64 {
65 if (!callback) {
66 return Result::kInputError;
67 }
68
69 if (polyline.points.empty()) {
70 return Result::kInputError;
71 }
72
73 auto tessellator = c_tessellator_.get();
74 if (!tessellator) {
75 return Result::kTessellationError;
76 }
77
78 constexpr int kVertexSize = 2;
79 constexpr int kPolygonSize = 3;
80
81 //----------------------------------------------------------------------------
82 /// Feed contour information to the tessellator.
83 ///
84 static_assert(sizeof(Point) == 2 * sizeof(float));
85 for (size_t contour_i = 0; contour_i < polyline.contours.size();
86 contour_i++) {
87 size_t start_point_index, end_point_index;
88 std::tie(start_point_index, end_point_index) =
89 polyline.GetContourPointBounds(contour_i);
90
91 ::tessAddContour(tessellator, // the C tessellator
92 kVertexSize, //
93 polyline.points.data() + start_point_index, //
94 sizeof(Point), //
95 end_point_index - start_point_index //
96 );
97 }
98
99 //----------------------------------------------------------------------------
100 /// Let's tessellate.
101 ///
102 auto result = ::tessTesselate(tessellator, // tessellator
103 ToTessWindingRule(fill_type), // winding
104 TESS_POLYGONS, // element type
105 kPolygonSize, // polygon size
106 kVertexSize, // vertex size
107 nullptr // normal (null is automatic)
108 );
109
110 if (result != 1) {
111 return Result::kTessellationError;
112 }
113
114 int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
115
116 // We default to using a 16bit index buffer, but in cases where we generate
117 // more tessellated data than this can contain we need to fall back to
118 // dropping the index buffer entirely. Instead code could instead switch to
119 // a uint32 index buffer, but this is done for simplicity with the other
120 // fast path above.
121 if (element_item_count < USHRT_MAX) {
122 int vertex_item_count = tessGetVertexCount(tessellator);
123 auto vertices = tessGetVertices(tessellator);
124 auto elements = tessGetElements(tessellator);
125
126 // libtess uses an int index internally due to usage of -1 as a sentinel
127 // value.
128 std::vector<uint16_t> indices(element_item_count);
129 for (int i = 0; i < element_item_count; i++) {
130 indices[i] = static_cast<uint16_t>(elements[i]);
131 }
132 if (!callback(vertices, vertex_item_count, indices.data(),
133 element_item_count)) {
134 return Result::kInputError;
135 }
136 } else {
137 std::vector<Point> points;
138 std::vector<float> data;
139
140 int vertex_item_count = tessGetVertexCount(tessellator) * kVertexSize;
141 auto vertices = tessGetVertices(tessellator);
142 points.reserve(vertex_item_count);
143 for (int i = 0; i < vertex_item_count; i += 2) {
144 points.emplace_back(vertices[i], vertices[i + 1]);
145 }
146
147 int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
148 auto elements = tessGetElements(tessellator);
149 data.reserve(element_item_count);
150 for (int i = 0; i < element_item_count; i++) {
151 data.emplace_back(points[elements[i]].x);
152 data.emplace_back(points[elements[i]].y);
153 }
154 if (!callback(data.data(), element_item_count, nullptr, 0u)) {
155 return Result::kInputError;
156 }
157 }
158
159 return Result::kSuccess;
160 }

References impeller::Path::Polyline::contours, impeller::Path::Polyline::GetContourPointBounds(), kInputError, kSuccess, kTessellationError, impeller::Path::Polyline::points, and impeller::ToTessWindingRule().

Referenced by impeller::BM_Polyline(), impeller::Tessellate(), impeller::testing::TEST(), and impeller::testing::TEST_P().

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

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

impeller::kAlloc
static const TESSalloc kAlloc
Definition: tessellator.cc:24
impeller::Tessellator::Result::kInputError
@ kInputError
impeller::Point
TPoint< Scalar > Point
Definition: point.h:306
impeller::Tessellator::Result::kTessellationError
@ kTessellationError
impeller::DestroyTessellator
void DestroyTessellator(TESStesselator *tessellator)
Definition: tessellator.cc:162
impeller::Tessellator::Result::kSuccess
@ kSuccess
impeller::ToTessWindingRule
static int ToTessWindingRule(FillType fill_type)
Definition: tessellator.cc:45
impeller::CTessellator
std::unique_ptr< TESStesselator, decltype(&DestroyTessellator)> CTessellator
Definition: tessellator.h:22