Flutter Engine
 
Loading...
Searching...
No Matches
impeller::TessellatorLibtess Class Reference

An extended tessellator that offers arbitrary/concave tessellation via the libtess2 library. More...

#include <tessellator_libtess.h>

Public Types

enum class  Result {
  kSuccess ,
  kInputError ,
  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.
 

Public Member Functions

 TessellatorLibtess ()
 
 ~TessellatorLibtess ()
 
TessellatorLibtess::Result Tessellate (const PathSource &source, Scalar tolerance, const BuilderCallback &callback)
 Generates filled triangles from the path. A callback is invoked once for the entire tessellation.
 

Detailed Description

An extended tessellator that offers arbitrary/concave tessellation via the libtess2 library.

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

Definition at line 29 of file tessellator_libtess.h.

Member Typedef Documentation

◆ BuilderCallback

using impeller::TessellatorLibtess::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 45 of file tessellator_libtess.h.

Member Enumeration Documentation

◆ Result

Enumerator
kSuccess 
kInputError 
kTessellationError 

Definition at line 35 of file tessellator_libtess.h.

Constructor & Destructor Documentation

◆ TessellatorLibtess()

impeller::TessellatorLibtess::TessellatorLibtess ( )

Definition at line 35 of file tessellator_libtess.cc.

36 : c_tessellator_(nullptr, &DestroyTessellator) {
37 TESSalloc alloc = kAlloc;
38 {
39 // libTess2 copies the TESSalloc despite the non-const argument.
40 CTessellator tessellator(::tessNewTess(&alloc), &DestroyTessellator);
41 c_tessellator_ = std::move(tessellator);
42 }
43}
void DestroyTessellator(TESStesselator *tessellator)
std::unique_ptr< TESStesselator, decltype(&DestroyTessellator)> CTessellator
static const TESSalloc kAlloc

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

◆ ~TessellatorLibtess()

impeller::TessellatorLibtess::~TessellatorLibtess ( )
default

Member Function Documentation

◆ Tessellate()

TessellatorLibtess::Result impeller::TessellatorLibtess::Tessellate ( const PathSource source,
Scalar  tolerance,
const BuilderCallback callback 
)

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

Parameters
[in]sourceThe path source to tessellate.
[in]toleranceThe 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.
[in]callbackThe 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 85 of file tessellator_libtess.cc.

88 {
89 if (!callback) {
91 }
92
93 Polyline polyline;
94 PathTessellator::PathToFilledVertices(source, polyline, tolerance);
95
96 auto fill_type = source.GetFillType();
97
98 if (polyline.points.empty()) {
100 }
101
102 auto tessellator = c_tessellator_.get();
103 if (!tessellator) {
105 }
106
107 constexpr int kVertexSize = 2;
108 constexpr int kPolygonSize = 3;
109
110 //----------------------------------------------------------------------------
111 /// Feed contour information to the tessellator.
112 ///
113 static_assert(sizeof(Point) == 2 * sizeof(float));
114 for (auto contour : polyline.contours) {
115 ::tessAddContour(tessellator, // the C tessellator
116 kVertexSize, //
117 polyline.points.data() + contour.start, //
118 sizeof(Point), //
119 contour.size() //
120 );
121 }
122
123 //----------------------------------------------------------------------------
124 /// Let's tessellate.
125 ///
126 auto result = ::tessTesselate(tessellator, // tessellator
127 ToTessWindingRule(fill_type), // winding
128 TESS_POLYGONS, // element type
129 kPolygonSize, // polygon size
130 kVertexSize, // vertex size
131 nullptr // normal (null is automatic)
132 );
133
134 if (result != 1) {
136 }
137
138 int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
139
140 // We default to using a 16bit index buffer, but in cases where we generate
141 // more tessellated data than this can contain we need to fall back to
142 // dropping the index buffer entirely. Instead code could instead switch to
143 // a uint32 index buffer, but this is done for simplicity with the other
144 // fast path above.
145 if (element_item_count < USHRT_MAX) {
146 int vertex_item_count = tessGetVertexCount(tessellator);
147 auto vertices = tessGetVertices(tessellator);
148 auto elements = tessGetElements(tessellator);
149
150 // libtess uses an int index internally due to usage of -1 as a sentinel
151 // value.
152 std::vector<uint16_t> indices(element_item_count);
153 for (int i = 0; i < element_item_count; i++) {
154 indices[i] = static_cast<uint16_t>(elements[i]);
155 }
156 if (!callback(vertices, vertex_item_count, indices.data(),
157 element_item_count)) {
159 }
160 } else {
161 std::vector<Point> points;
162 std::vector<float> data;
163
164 int vertex_item_count = tessGetVertexCount(tessellator) * kVertexSize;
165 auto vertices = tessGetVertices(tessellator);
166 points.reserve(vertex_item_count);
167 for (int i = 0; i < vertex_item_count; i += 2) {
168 points.emplace_back(vertices[i], vertices[i + 1]);
169 }
170
171 int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
172 auto elements = tessGetElements(tessellator);
173 data.reserve(element_item_count);
174 for (int i = 0; i < element_item_count; i++) {
175 data.emplace_back(points[elements[i]].x);
176 data.emplace_back(points[elements[i]].y);
177 }
178 if (!callback(data.data(), element_item_count, nullptr, 0u)) {
180 }
181 }
182
184}
static void PathToFilledVertices(const PathSource &source, VertexWriter &writer, Scalar scale)
int32_t x
FlutterDesktopBinaryReply callback
double y
TPoint< Scalar > Point
Definition point.h:327
static int ToTessWindingRule(FillType fill_type)
std::vector< Point > points
std::vector< Contour > contours
std::shared_ptr< const fml::Mapping > data

References callback, data, impeller::PathSource::GetFillType(), i, kInputError, kSuccess, kTessellationError, impeller::PathTessellator::PathToFilledVertices(), points, impeller::ToTessWindingRule(), x, and y.

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


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