Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
tessellator.h
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
5#ifndef FLUTTER_IMPELLER_TESSELLATOR_TESSELLATOR_H_
6#define FLUTTER_IMPELLER_TESSELLATOR_TESSELLATOR_H_
7
8#include <functional>
9#include <memory>
10#include <vector>
11
16
17namespace impeller {
18
19//------------------------------------------------------------------------------
20/// @brief A utility that generates triangles of the specified fill type
21/// given a polyline. This happens on the CPU.
22///
23/// Also contains functionality for optimized generation of circles
24/// and ellipses.
25///
26/// This object is not thread safe, and its methods must not be
27/// called from multiple threads.
28///
30 private:
31 /// Essentially just a vector of Trig objects, but supports storing a
32 /// reference to either a cached vector or a locally generated vector.
33 /// The constructor will fill the vector with quarter circular samples
34 /// for the indicated number of equal divisions if the vector is new.
35 class Trigs {
36 public:
37 explicit Trigs(std::vector<Trig>& trigs, size_t divisions) : trigs_(trigs) {
38 init(divisions);
39 FML_DCHECK(trigs_.size() == divisions + 1);
40 }
41
42 explicit Trigs(size_t divisions)
43 : local_storage_(std::make_unique<std::vector<Trig>>()),
44 trigs_(*local_storage_) {
45 init(divisions);
46 FML_DCHECK(trigs_.size() == divisions + 1);
47 }
48
49 // Utility forwards of the indicated vector methods.
50 auto inline size() const { return trigs_.size(); }
51 auto inline begin() const { return trigs_.begin(); }
52 auto inline end() const { return trigs_.end(); }
53
54 private:
55 // nullptr if a cached vector is used, otherwise the actual storage
56 std::unique_ptr<std::vector<Trig>> local_storage_;
57
58 // Whether or not a cached vector or the local storage is used, this
59 // this reference will always be valid
60 std::vector<Trig>& trigs_;
61
62 // Fill the vector with the indicated number of equal divisions of
63 // trigonometric values if it is empty.
64 void init(size_t divisions);
65 };
66
67 public:
68 enum class Result {
72 };
73
74 /// @brief A callback function for a |VertexGenerator| to deliver
75 /// the vertices it computes as |Point| objects.
76 using TessellatedVertexProc = std::function<void(const Point& p)>;
77
78 /// @brief An object which produces a list of vertices as |Point|s that
79 /// tessellate a previously provided shape and delivers the vertices
80 /// through a |TessellatedVertexProc| callback.
81 ///
82 /// The object can also provide advance information on how many
83 /// vertices it will generate.
84 ///
85 /// @see |Tessellator::FilledCircle|
86 /// @see |Tessellator::StrokedCircle|
87 /// @see |Tessellator::RoundCapLine|
88 /// @see |Tessellator::FilledEllipse|
90 public:
91 /// @brief Returns the |PrimitiveType| that describes the relationship
92 /// among the list of vertices produced by the |GenerateVertices|
93 /// method.
94 ///
95 /// Most generators will deliver |kTriangleStrip| triangles
96 virtual PrimitiveType GetTriangleType() const = 0;
97
98 /// @brief Returns the number of vertices that the generator plans to
99 /// produce, if known.
100 ///
101 /// This value is advisory only and can be used to reserve space
102 /// where the vertices will be placed, but the count may be an
103 /// estimate.
104 ///
105 /// Implementations are encouraged to avoid overestimating
106 /// the count by too large a number and to provide a best
107 /// guess so as to minimize potential buffer reallocations
108 /// as the vertices are delivered.
109 virtual size_t GetVertexCount() const = 0;
110
111 /// @brief Generate the vertices and deliver them in the necessary
112 /// order (as required by the PrimitiveType) to the given
113 /// callback function.
114 virtual void GenerateVertices(const TessellatedVertexProc& proc) const = 0;
115 };
116
117 /// @brief The |VertexGenerator| implementation common to all shapes
118 /// that are based on a polygonal representation of an ellipse.
120 public:
121 /// |VertexGenerator|
124 }
125
126 /// |VertexGenerator|
127 size_t GetVertexCount() const override {
128 return trigs_.size() * vertices_per_trig_;
129 }
130
131 /// |VertexGenerator|
132 void GenerateVertices(const TessellatedVertexProc& proc) const override {
133 impl_(trigs_, data_, proc);
134 }
135
136 private:
137 friend class Tessellator;
138
139 struct Data {
140 // Circles and Ellipses only use one of these points.
141 // RoundCapLines use both as the endpoints of the unexpanded line.
142 // A round rect can specify its interior rectangle by using the
143 // 2 points as opposing corners.
144 const Point reference_centers[2];
145 // Circular shapes have the same value in radii.width and radii.height
146 const Size radii;
147 // half_width is only used in cases where the generator will be
148 // generating 2 different outlines, such as StrokedCircle
149 const Scalar half_width;
150 };
151
152 typedef void GeneratorProc(const Trigs& trigs,
153 const Data& data,
154 const TessellatedVertexProc& proc);
155
156 GeneratorProc& impl_;
157 const Trigs trigs_;
158 const Data data_;
159 const size_t vertices_per_trig_;
160
161 EllipticalVertexGenerator(GeneratorProc& generator,
162 Trigs&& trigs,
163 PrimitiveType triangle_type,
164 size_t vertices_per_trig,
165 Data&& data);
166 };
167
168 Tessellator();
169
170 virtual ~Tessellator();
171
172 //----------------------------------------------------------------------------
173 /// @brief Given a convex path, create a triangle fan structure.
174 ///
175 /// @param[in] path The path to tessellate.
176 /// @param[in] tolerance The tolerance value for conversion of the path to
177 /// a polyline. This value is often derived from the
178 /// Matrix::GetMaxBasisLength of the CTM applied to the
179 /// path for rendering.
180 ///
181 /// @return A point vector containing the vertices in triangle strip format.
182 ///
183 std::vector<Point> TessellateConvex(const Path& path, Scalar tolerance);
184
185 //----------------------------------------------------------------------------
186 /// @brief Create a temporary polyline. Only one per-process can exist at
187 /// a time.
188 ///
189 /// The tessellator itself is not a thread safe class and should
190 /// only be used from the raster thread.
191 Path::Polyline CreateTempPolyline(const Path& path, Scalar tolerance);
192
193 /// @brief The pixel tolerance used by the algorighm to determine how
194 /// many divisions to create for a circle.
195 ///
196 /// No point on the polygon of vertices should deviate from the
197 /// true circle by more than this tolerance.
198 static constexpr Scalar kCircleTolerance = 0.1f;
199
200 /// @brief Create a |VertexGenerator| that can produce vertices for
201 /// a filled circle of the given radius around the given center
202 /// with enough polygon sub-divisions to provide reasonable
203 /// fidelity when viewed under the given view transform.
204 ///
205 /// Note that the view transform is only used to choose the
206 /// number of sample points to use per quarter circle and the
207 /// returned points are not transformed by it, instead they are
208 /// relative to the coordinate space of the center point.
209 EllipticalVertexGenerator FilledCircle(const Matrix& view_transform,
210 const Point& center,
211 Scalar radius);
212
213 /// @brief Create a |VertexGenerator| that can produce vertices for
214 /// a stroked circle of the given radius and half_width around
215 /// the given shared center with enough polygon sub-divisions
216 /// to provide reasonable fidelity when viewed under the given
217 /// view transform. The outer edge of the stroked circle is
218 /// generated at (radius + half_width) and the inner edge is
219 /// generated at (radius - half_width).
220 ///
221 /// Note that the view transform is only used to choose the
222 /// number of sample points to use per quarter circle and the
223 /// returned points are not transformed by it, instead they are
224 /// relative to the coordinate space of the center point.
225 EllipticalVertexGenerator StrokedCircle(const Matrix& view_transform,
226 const Point& center,
227 Scalar radius,
228 Scalar half_width);
229
230 /// @brief Create a |VertexGenerator| that can produce vertices for
231 /// a line with round end caps of the given radius with enough
232 /// polygon sub-divisions to provide reasonable fidelity when
233 /// viewed under the given view transform.
234 ///
235 /// Note that the view transform is only used to choose the
236 /// number of sample points to use per quarter circle and the
237 /// returned points are not transformed by it, instead they are
238 /// relative to the coordinate space of the two points.
239 EllipticalVertexGenerator RoundCapLine(const Matrix& view_transform,
240 const Point& p0,
241 const Point& p1,
242 Scalar radius);
243
244 /// @brief Create a |VertexGenerator| that can produce vertices for
245 /// a filled ellipse inscribed within the given bounds with
246 /// enough polygon sub-divisions to provide reasonable
247 /// fidelity when viewed under the given view transform.
248 ///
249 /// Note that the view transform is only used to choose the
250 /// number of sample points to use per quarter circle and the
251 /// returned points are not transformed by it, instead they are
252 /// relative to the coordinate space of the bounds.
253 EllipticalVertexGenerator FilledEllipse(const Matrix& view_transform,
254 const Rect& bounds);
255
256 /// @brief Create a |VertexGenerator| that can produce vertices for
257 /// a filled round rect within the given bounds and corner radii
258 /// with enough polygon sub-divisions to provide reasonable
259 /// fidelity when viewed under the given view transform.
260 ///
261 /// Note that the view transform is only used to choose the
262 /// number of sample points to use per quarter circle and the
263 /// returned points are not transformed by it, instead they are
264 /// relative to the coordinate space of the bounds.
266 const Rect& bounds,
267 const Size& radii);
268
269 protected:
270 /// Used for polyline generation.
271 std::unique_ptr<std::vector<Point>> point_buffer_;
272
273 private:
274 // Data for variouos Circle/EllipseGenerator classes, cached per
275 // Tessellator instance which is usually the foreground life of an app
276 // if not longer.
277 static constexpr size_t kCachedTrigCount = 300;
278 std::vector<Trig> precomputed_trigs_[kCachedTrigCount];
279
280 Trigs GetTrigsForDivisions(size_t divisions);
281
282 static void GenerateFilledCircle(const Trigs& trigs,
283 const EllipticalVertexGenerator::Data& data,
284 const TessellatedVertexProc& proc);
285
286 static void GenerateStrokedCircle(const Trigs& trigs,
287 const EllipticalVertexGenerator::Data& data,
288 const TessellatedVertexProc& proc);
289
290 static void GenerateRoundCapLine(const Trigs& trigs,
291 const EllipticalVertexGenerator::Data& data,
292 const TessellatedVertexProc& proc);
293
294 static void GenerateFilledEllipse(const Trigs& trigs,
295 const EllipticalVertexGenerator::Data& data,
296 const TessellatedVertexProc& proc);
297
298 static void GenerateFilledRoundRect(
299 const Trigs& trigs,
300 const EllipticalVertexGenerator::Data& data,
301 const TessellatedVertexProc& proc);
302
303 Tessellator(const Tessellator&) = delete;
304
305 Tessellator& operator=(const Tessellator&) = delete;
306};
307
308} // namespace impeller
309
310#endif // FLUTTER_IMPELLER_TESSELLATOR_TESSELLATOR_H_
static SkScalar center(float pos0, float pos1)
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition path.h:51
The |VertexGenerator| implementation common to all shapes that are based on a polygonal representatio...
PrimitiveType GetTriangleType() const override
|VertexGenerator|
size_t GetVertexCount() const override
|VertexGenerator|
void GenerateVertices(const TessellatedVertexProc &proc) const override
|VertexGenerator|
An object which produces a list of vertices as |Point|s that tessellate a previously provided shape a...
Definition tessellator.h:89
virtual size_t GetVertexCount() const =0
Returns the number of vertices that the generator plans to produce, if known.
virtual PrimitiveType GetTriangleType() const =0
Returns the |PrimitiveType| that describes the relationship among the list of vertices produced by th...
virtual void GenerateVertices(const TessellatedVertexProc &proc) const =0
Generate the vertices and deliver them in the necessary order (as required by the PrimitiveType) to t...
A utility that generates triangles of the specified fill type given a polyline. This happens on the C...
Definition tessellator.h:29
std::vector< Point > TessellateConvex(const Path &path, Scalar tolerance)
Given a convex path, create a triangle fan structure.
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 radi...
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 ...
static constexpr Scalar kCircleTolerance
The pixel tolerance used by the algorighm to determine how many divisions to create for a circle.
Path::Polyline CreateTempPolyline(const Path &path, Scalar tolerance)
Create a temporary polyline. Only one per-process can exist at a time.
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...
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 hal...
std::unique_ptr< std::vector< Point > > point_buffer_
Used for polyline generation.
EllipticalVertexGenerator FilledEllipse(const Matrix &view_transform, const Rect &bounds)
Create a |VertexGenerator| that can produce vertices for a filled ellipse inscribed within the given ...
std::function< void(const Point &p)> TessellatedVertexProc
A callback function for a |VertexGenerator| to deliver the vertices it computes as |Point| objects.
Definition tessellator.h:76
glong glong end
#define FML_DCHECK(condition)
Definition logging.h:103
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition formats.h:353
float Scalar
Definition scalar.h:18
A 4x4 matrix using column-major storage.
Definition matrix.h:37