Flutter Engine
The Flutter Engine
tessellator_libtess.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include "third_party/libtess2/Include/tesselator.h"
8
9namespace impeller {
10
11static void* HeapAlloc(void* userData, unsigned int size) {
12 return malloc(size);
13}
14
15static void* HeapRealloc(void* userData, void* ptr, unsigned int size) {
16 return realloc(ptr, size);
17}
18
19static void HeapFree(void* userData, void* ptr) {
20 free(ptr);
21}
22
23// Note: these units are "number of entities" for bucket size and not in KB.
24static const TESSalloc kAlloc = {
25 HeapAlloc, HeapRealloc, HeapFree, 0, /* =userData */
26 16, /* =meshEdgeBucketSize */
27 16, /* =meshVertexBucketSize */
28 16, /* =meshFaceBucketSize */
29 16, /* =dictNodeBucketSize */
30 16, /* =regionBucketSize */
31 0 /* =extraVertices */
32};
33
35 : c_tessellator_(nullptr, &DestroyTessellator) {
36 TESSalloc alloc = kAlloc;
37 {
38 // libTess2 copies the TESSalloc despite the non-const argument.
39 CTessellator tessellator(::tessNewTess(&alloc), &DestroyTessellator);
40 c_tessellator_ = std::move(tessellator);
41 }
42}
43
45
46static int ToTessWindingRule(FillType fill_type) {
47 switch (fill_type) {
48 case FillType::kOdd:
49 return TESS_WINDING_ODD;
51 return TESS_WINDING_NONZERO;
52 }
53 return TESS_WINDING_ODD;
54}
55
57 const Path& path,
58 Scalar tolerance,
60 if (!callback) {
62 }
63
64 std::unique_ptr<std::vector<Point>> point_buffer =
65 std::make_unique<std::vector<Point>>();
66 auto polyline = path.CreatePolyline(tolerance, std::move(point_buffer));
67
68 auto fill_type = path.GetFillType();
69
70 if (polyline.points->empty()) {
72 }
73
74 auto tessellator = c_tessellator_.get();
75 if (!tessellator) {
77 }
78
79 constexpr int kVertexSize = 2;
80 constexpr int kPolygonSize = 3;
81
82 //----------------------------------------------------------------------------
83 /// Feed contour information to the tessellator.
84 ///
85 static_assert(sizeof(Point) == 2 * sizeof(float));
86 for (size_t contour_i = 0; contour_i < polyline.contours.size();
87 contour_i++) {
88 size_t start_point_index, end_point_index;
89 std::tie(start_point_index, end_point_index) =
90 polyline.GetContourPointBounds(contour_i);
91
92 ::tessAddContour(tessellator, // the C tessellator
93 kVertexSize, //
94 polyline.points->data() + start_point_index, //
95 sizeof(Point), //
96 end_point_index - start_point_index //
97 );
98 }
99
100 //----------------------------------------------------------------------------
101 /// Let's tessellate.
102 ///
103 auto result = ::tessTesselate(tessellator, // tessellator
104 ToTessWindingRule(fill_type), // winding
105 TESS_POLYGONS, // element type
106 kPolygonSize, // polygon size
107 kVertexSize, // vertex size
108 nullptr // normal (null is automatic)
109 );
110
111 if (result != 1) {
113 }
114
115 int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
116
117 // We default to using a 16bit index buffer, but in cases where we generate
118 // more tessellated data than this can contain we need to fall back to
119 // dropping the index buffer entirely. Instead code could instead switch to
120 // a uint32 index buffer, but this is done for simplicity with the other
121 // fast path above.
122 if (element_item_count < USHRT_MAX) {
123 int vertex_item_count = tessGetVertexCount(tessellator);
124 auto vertices = tessGetVertices(tessellator);
125 auto elements = tessGetElements(tessellator);
126
127 // libtess uses an int index internally due to usage of -1 as a sentinel
128 // value.
129 std::vector<uint16_t> indices(element_item_count);
130 for (int i = 0; i < element_item_count; i++) {
131 indices[i] = static_cast<uint16_t>(elements[i]);
132 }
133 if (!callback(vertices, vertex_item_count, indices.data(),
134 element_item_count)) {
136 }
137 } else {
138 std::vector<Point> points;
139 std::vector<float> data;
140
141 int vertex_item_count = tessGetVertexCount(tessellator) * kVertexSize;
142 auto vertices = tessGetVertices(tessellator);
143 points.reserve(vertex_item_count);
144 for (int i = 0; i < vertex_item_count; i += 2) {
145 points.emplace_back(vertices[i], vertices[i + 1]);
146 }
147
148 int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
149 auto elements = tessGetElements(tessellator);
150 data.reserve(element_item_count);
151 for (int i = 0; i < element_item_count; i++) {
152 data.emplace_back(points[elements[i]].x);
153 data.emplace_back(points[elements[i]].y);
154 }
155 if (!callback(data.data(), element_item_count, nullptr, 0u)) {
157 }
158 }
159
161}
162
163void DestroyTessellator(TESStesselator* tessellator) {
164 if (tessellator != nullptr) {
165 ::tessDeleteTess(tessellator);
166 }
167}
168
169} // namespace impeller
static const int points[]
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
std::function< bool(const float *vertices, size_t vertices_count, const uint16_t *indices, size_t indices_count)> BuilderCallback
A callback that returns the results of the tessellation.
TessellatorLibtess::Result Tessellate(const Path &path, Scalar tolerance, const BuilderCallback &callback)
Generates filled triangles from the path. A callback is invoked once for the entire tessellation.
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
GAsyncResult * result
double y
double x
void * malloc(size_t size)
Definition: allocation.cc:19
void * realloc(void *ptr, size_t size)
Definition: allocation.cc:27
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
float Scalar
Definition: scalar.h:18
void DestroyTessellator(TESStesselator *tessellator)
FillType
Definition: path.h:30
TPoint< Scalar > Point
Definition: point.h:322
static void * HeapRealloc(void *userData, void *ptr, unsigned int size)
static void * HeapAlloc(void *userData, unsigned int size)
std::unique_ptr< TESStesselator, decltype(&DestroyTessellator)> CTessellator
static int ToTessWindingRule(FillType fill_type)
static void HeapFree(void *userData, void *ptr)
static const TESSalloc kAlloc
const Path::Polyline & polyline
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63