Flutter Impeller
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 
12 #include "impeller/core/formats.h"
15 #include "impeller/geometry/arc.h"
19 #include "impeller/geometry/trig.h"
20 
21 namespace impeller {
22 
23 /// The size of the point arena buffer stored on the tessellator.
24 [[maybe_unused]]
25 static constexpr size_t kPointArenaSize = 4096u;
26 
27 //------------------------------------------------------------------------------
28 /// @brief A utility that generates triangles of the specified fill type
29 /// given a polyline. This happens on the CPU.
30 ///
31 /// Also contains functionality for optimized generation of circles
32 /// and ellipses.
33 ///
34 /// This object is not thread safe, and its methods must not be
35 /// called from multiple threads.
36 ///
37 class Tessellator {
38  public:
39  /// Essentially just a vector of Trig objects, but supports storing a
40  /// reference to either a cached vector or a locally generated vector.
41  /// The constructor will fill the vector with quarter circular samples
42  /// for the indicated number of equal divisions if the vector is new.
43  ///
44  /// A given instance of Trigs will always contain at least 2 entries
45  /// which is the minimum number of samples to traverse a quarter circle
46  /// in a single step. The first sample will always be (0, 1) and the last
47  /// sample will always be (1, 0).
48  class Trigs {
49  public:
50  explicit Trigs(Scalar pixel_radius);
51 
52  // Utility forwards of the indicated vector methods.
53  size_t inline size() const { return trigs_.size(); }
54  std::vector<Trig>::iterator inline begin() const { return trigs_.begin(); }
55  std::vector<Trig>::iterator inline end() const { return trigs_.end(); }
56  const inline Trig& operator[](size_t index) const { return trigs_[index]; }
57 
58  size_t inline GetSteps() const { return trigs_.size() - 1u; }
59 
60  private:
61  friend class Tessellator;
62 
63  explicit Trigs(std::vector<Trig>& trigs, size_t divisions) : trigs_(trigs) {
64  FML_DCHECK(divisions >= 1);
65  init(divisions);
66  FML_DCHECK(trigs_.size() == divisions + 1);
67  }
68 
69  explicit Trigs(size_t divisions)
70  : local_storage_(std::make_unique<std::vector<Trig>>()),
71  trigs_(*local_storage_) {
72  FML_DCHECK(divisions >= 1);
73  init(divisions);
74  FML_DCHECK(trigs_.size() == divisions + 1);
75  }
76 
77  // nullptr if a cached vector is used, otherwise the actual storage
78  std::unique_ptr<std::vector<Trig>> local_storage_;
79 
80  // Whether or not a cached vector or the local storage is used, this
81  // this reference will always be valid
82  std::vector<Trig>& trigs_;
83 
84  // Fill the vector with the indicated number of equal divisions of
85  // trigonometric values if it is empty.
86  void init(size_t divisions);
87  };
88 
89  enum class Result {
90  kSuccess,
93  };
94 
95  /// @brief A callback function for a |VertexGenerator| to deliver
96  /// the vertices it computes as |Point| objects.
97  using TessellatedVertexProc = std::function<void(const Point& p)>;
98 
99  /// @brief An object which produces a list of vertices as |Point|s that
100  /// tessellate a previously provided shape and delivers the vertices
101  /// through a |TessellatedVertexProc| callback.
102  ///
103  /// The object can also provide advance information on how many
104  /// vertices it will generate.
105  ///
106  /// @see |Tessellator::FilledCircle|
107  /// @see |Tessellator::StrokedCircle|
108  /// @see |Tessellator::RoundCapLine|
109  /// @see |Tessellator::FilledEllipse|
111  public:
112  /// @brief Returns the |PrimitiveType| that describes the relationship
113  /// among the list of vertices produced by the |GenerateVertices|
114  /// method.
115  ///
116  /// Most generators will deliver |kTriangleStrip| triangles
117  virtual PrimitiveType GetTriangleType() const = 0;
118 
119  /// @brief Returns the number of vertices that the generator plans to
120  /// produce, if known.
121  ///
122  /// This value is advisory only and can be used to reserve space
123  /// where the vertices will be placed, but the count may be an
124  /// estimate.
125  ///
126  /// Implementations are encouraged to avoid overestimating
127  /// the count by too large a number and to provide a best
128  /// guess so as to minimize potential buffer reallocations
129  /// as the vertices are delivered.
130  virtual size_t GetVertexCount() const = 0;
131 
132  /// @brief Generate the vertices and deliver them in the necessary
133  /// order (as required by the PrimitiveType) to the given
134  /// callback function.
135  virtual void GenerateVertices(const TessellatedVertexProc& proc) const = 0;
136  };
137 
138  /// @brief The |VertexGenerator| implementation common to all shapes
139  /// that are based on a polygonal representation of an ellipse.
141  public:
142  /// |VertexGenerator|
143  PrimitiveType GetTriangleType() const override {
145  }
146 
147  /// |VertexGenerator|
148  size_t GetVertexCount() const override {
149  return trigs_.size() * vertices_per_trig_;
150  }
151 
152  /// |VertexGenerator|
153  void GenerateVertices(const TessellatedVertexProc& proc) const override {
154  impl_(trigs_, data_, proc);
155  }
156 
157  private:
158  friend class Tessellator;
159 
160  struct Data {
161  // Circles and Ellipses only use one of these points.
162  // RoundCapLines use both as the endpoints of the unexpanded line.
163  // A round rect can specify its interior rectangle by using the
164  // 2 points as opposing corners.
165  const Point reference_centers[2];
166  // Circular shapes have the same value in radii.width and radii.height
167  const Size radii;
168  // half_width is only used in cases where the generator will be
169  // generating 2 different outlines, such as StrokedCircle
170  const Scalar half_width;
171  };
172 
173  typedef void GeneratorProc(const Trigs& trigs,
174  const Data& data,
175  const TessellatedVertexProc& proc);
176 
177  GeneratorProc& impl_;
178  const Trigs trigs_;
179  const Data data_;
180  const size_t vertices_per_trig_;
181 
182  EllipticalVertexGenerator(GeneratorProc& generator,
183  Trigs&& trigs,
184  PrimitiveType triangle_type,
185  size_t vertices_per_trig,
186  Data&& data);
187  };
188 
189  /// @brief The |VertexGenerator| implementation common to all shapes
190  /// that are based on a polygonal representation of an ellipse.
191  class ArcVertexGenerator : public virtual VertexGenerator {
192  public:
193  /// |VertexGenerator|
194  PrimitiveType GetTriangleType() const override;
195 
196  /// |VertexGenerator|
197  size_t GetVertexCount() const override;
198 
199  /// |VertexGenerator|
200  void GenerateVertices(const TessellatedVertexProc& proc) const override;
201 
202  static ArcVertexGenerator MakeFilled(const Arc::Iteration& iteration,
203  Trigs&& trigs,
204  const Rect& oval_bounds,
205  bool use_center,
206  bool supports_triangle_fans);
207 
209  const Arc::Iteration& iteration,
210  Trigs&& trigs,
211  const Rect& oval_bounds,
212  Scalar half_width,
213  Cap cap,
214  std::unique_ptr<Trigs> round_cap_trigs);
215 
216  private:
217  friend class Tessellator;
218 
219  const Arc::Iteration iteration_;
220  const Trigs trigs_;
221  const Rect oval_bounds_;
222 
223  // Used only in filled arcs.
224  const bool use_center_;
225  const bool supports_triangle_fans_;
226 
227  // Used only in stroked arcs. half_width_ is set to -1.0f for filled arcs.
228  const Scalar half_width_;
229  const Cap cap_;
230  const std::unique_ptr<Trigs> round_cap_trigs_;
231 
232  ArcVertexGenerator(const Arc::Iteration& iteration,
233  Trigs&& trigs,
234  const Rect& oval_bounds,
235  bool use_center,
236  bool supports_triangle_fans,
237  Scalar half_width,
238  Cap cap,
239  std::unique_ptr<Trigs> round_cap_trigs);
240  };
241 
242  explicit Tessellator(bool supports_32bit_primitive_indices = true);
243 
244  virtual ~Tessellator();
245 
246  //----------------------------------------------------------------------------
247  /// @brief Given a convex path, create a triangle fan structure.
248  ///
249  /// @param[in] path The path to tessellate.
250  /// @param[in] host_buffer The host buffer for allocation of vertices/index
251  /// data.
252  /// @param[in] tolerance The tolerance value for conversion of the path to
253  /// a polyline. This value is often derived from the
254  /// Matrix::GetMaxBasisLengthXY of the CTM applied to
255  /// the path for rendering.
256  ///
257  /// @return A vertex buffer containing all data from the provided curve.
259  HostBuffer& data_host_buffer,
260  HostBuffer& indexes_host_buffer,
261  Scalar tolerance,
262  bool supports_primitive_restart = false,
263  bool supports_triangle_fan = false);
264 
265  /// Visible for testing.
266  ///
267  /// This method only exists for the ease of benchmarking without using the
268  /// real allocator needed by the [host_buffer].
269  static void TessellateConvexInternal(const PathSource& path,
270  std::vector<Point>& point_buffer,
271  std::vector<uint16_t>& index_buffer,
272  Scalar tolerance);
273 
274  //----------------------------------------------------------------------------
275  /// @brief The pixel tolerance used by the algorighm to determine how
276  /// many divisions to create for a circle.
277  ///
278  /// No point on the polygon of vertices should deviate from the
279  /// true circle by more than this tolerance.
280  static constexpr Scalar kCircleTolerance = 0.1f;
281 
282  /// @brief Create a |VertexGenerator| that can produce vertices for
283  /// a filled circle of the given radius around the given center
284  /// with enough polygon sub-divisions to provide reasonable
285  /// fidelity when viewed under the given view transform.
286  ///
287  /// Note that the view transform is only used to choose the
288  /// number of sample points to use per quarter circle and the
289  /// returned points are not transformed by it, instead they are
290  /// relative to the coordinate space of the center point.
291  EllipticalVertexGenerator FilledCircle(const Matrix& view_transform,
292  const Point& center,
293  Scalar radius);
294 
295  /// @brief Create a |VertexGenerator| that can produce vertices for
296  /// a stroked circle of the given radius and half_width around
297  /// the given shared center with enough polygon sub-divisions
298  /// to provide reasonable fidelity when viewed under the given
299  /// view transform. The outer edge of the stroked circle is
300  /// generated at (radius + half_width) and the inner edge is
301  /// generated at (radius - half_width).
302  ///
303  /// Note that the view transform is only used to choose the
304  /// number of sample points to use per quarter circle and the
305  /// returned points are not transformed by it, instead they are
306  /// relative to the coordinate space of the center point.
307  EllipticalVertexGenerator StrokedCircle(const Matrix& view_transform,
308  const Point& center,
309  Scalar radius,
310  Scalar half_width);
311 
312  /// @brief Create a |VertexGenerator| that can produce vertices for
313  /// a stroked arc inscribed within the given oval_bounds with
314  /// the given stroke half_width with enough polygon sub-divisions
315  /// to provide reasonable fidelity when viewed under the given
316  /// view transform. The outer edge of the stroked arc is
317  /// generated at (radius + half_width) and the inner edge is
318  /// generated at (radius - half_width).
319  ///
320  /// Note that the view transform is only used to choose the
321  /// number of sample points to use per quarter circle and the
322  /// returned points are not transformed by it, instead they are
323  /// relative to the coordinate space of the oval bounds.
324  ArcVertexGenerator FilledArc(const Matrix& view_transform,
325  const Arc& arc,
326  bool supports_triangle_fans);
327 
328  /// @brief Create a |VertexGenerator| that can produce vertices for
329  /// a stroked arc inscribed within the given oval_bounds with
330  /// the given stroke half_width with enough polygon sub-divisions
331  /// to provide reasonable fidelity when viewed under the given
332  /// view transform. The outer edge of the stroked arc is
333  /// generated at (radius + half_width) and the inner edge is
334  /// generated at (radius - half_width).
335  ///
336  /// Note that the arc may not include the center and its bounds
337  /// must be a perfect circle (width == height)
338  ///
339  /// Note that the view transform is only used to choose the
340  /// number of sample points to use per quarter circle and the
341  /// returned points are not transformed by it, instead they are
342  /// relative to the coordinate space of the oval bounds.
343  ArcVertexGenerator StrokedArc(const Matrix& view_transform,
344  const Arc& arc,
345  Cap cap,
346  Scalar half_width);
347 
348  /// @brief Create a |VertexGenerator| that can produce vertices for
349  /// a line with round end caps of the given radius with enough
350  /// polygon sub-divisions to provide reasonable fidelity when
351  /// viewed under the given view transform.
352  ///
353  /// Note that the view transform is only used to choose the
354  /// number of sample points to use per quarter circle and the
355  /// returned points are not transformed by it, instead they are
356  /// relative to the coordinate space of the two points.
357  EllipticalVertexGenerator RoundCapLine(const Matrix& view_transform,
358  const Point& p0,
359  const Point& p1,
360  Scalar radius);
361 
362  /// @brief Create a |VertexGenerator| that can produce vertices for
363  /// a filled ellipse inscribed within the given bounds with
364  /// enough polygon sub-divisions to provide reasonable
365  /// fidelity when viewed under the given view transform.
366  ///
367  /// Note that the view transform is only used to choose the
368  /// number of sample points to use per quarter circle and the
369  /// returned points are not transformed by it, instead they are
370  /// relative to the coordinate space of the bounds.
371  EllipticalVertexGenerator FilledEllipse(const Matrix& view_transform,
372  const Rect& bounds);
373 
374  /// @brief Create a |VertexGenerator| that can produce vertices for
375  /// a filled round rect within the given bounds and corner radii
376  /// with enough polygon sub-divisions to provide reasonable
377  /// fidelity when viewed under the given view transform.
378  ///
379  /// Note that the view transform is only used to choose the
380  /// number of sample points to use per quarter circle and the
381  /// returned points are not transformed by it, instead they are
382  /// relative to the coordinate space of the bounds.
383  EllipticalVertexGenerator FilledRoundRect(const Matrix& view_transform,
384  const Rect& bounds,
385  const Size& radii);
386 
387  /// Retrieve a pre-allocated arena of kPointArenaSize points.
388  std::vector<Point>& GetStrokePointCache();
389 
390  /// Return a vector of Trig (cos, sin pairs) structs for a 90 degree
391  /// circle quadrant of the specified pixel radius
392  Trigs GetTrigsForDeviceRadius(Scalar pixel_radius);
393 
394  private:
395  class ConvexTessellator {
396  public:
397  virtual ~ConvexTessellator() = default;
398  virtual VertexBuffer TessellateConvex(const PathSource& path,
399  HostBuffer& data_host_buffer,
400  HostBuffer& indexes_host_buffer,
401  Scalar tolerance,
402  bool supports_primitive_restart,
403  bool supports_triangle_fan) = 0;
404  };
405  template <typename IndexT>
406  friend class ConvexTessellatorImpl;
407 
408  /// Used for polyline generation.
409  std::unique_ptr<ConvexTessellator> convex_tessellator_;
410 
411  /// Used for stroke path generation.
412  std::vector<Point> stroke_points_;
413 
414  // Data for various Circle/EllipseGenerator classes, cached per
415  // Tessellator instance which is usually the foreground life of an app
416  // if not longer.
417  static constexpr size_t kCachedTrigCount = 300;
418  std::vector<Trig> precomputed_trigs_[kCachedTrigCount];
419 
420  Trigs GetTrigsForDivisions(size_t divisions);
421 
422  static void GenerateFilledCircle(const Trigs& trigs,
423  const EllipticalVertexGenerator::Data& data,
424  const TessellatedVertexProc& proc);
425 
426  static void GenerateStrokedCircle(const Trigs& trigs,
427  const EllipticalVertexGenerator::Data& data,
428  const TessellatedVertexProc& proc);
429 
430  static void GenerateFilledArcFan(const Trigs& trigs,
431  const Arc::Iteration& iteration,
432  const Rect& oval_bounds,
433  bool use_center,
434  const TessellatedVertexProc& proc);
435 
436  static void GenerateFilledArcStrip(const Trigs& trigs,
437  const Arc::Iteration& iteration,
438  const Rect& oval_bounds,
439  bool use_center,
440  const TessellatedVertexProc& proc);
441 
442  static void GenerateStrokedArc(const Trigs& trigs,
443  const Arc::Iteration& iteration,
444  const Rect& oval_bounds,
445  Scalar half_width,
446  Cap cap,
447  const std::unique_ptr<Trigs>& round_cap_trigs,
448  const TessellatedVertexProc& proc);
449 
450  static void GenerateRoundCapLine(const Trigs& trigs,
451  const EllipticalVertexGenerator::Data& data,
452  const TessellatedVertexProc& proc);
453 
454  static void GenerateFilledEllipse(const Trigs& trigs,
455  const EllipticalVertexGenerator::Data& data,
456  const TessellatedVertexProc& proc);
457 
458  static void GenerateFilledRoundRect(
459  const Trigs& trigs,
460  const EllipticalVertexGenerator::Data& data,
461  const TessellatedVertexProc& proc);
462 
463  // Generates vertices for the start round cap of a stroke.
464  //
465  // The perpendicular input points 90 degrees clockwise to the direction the
466  // stroke is traveling and is the length of half of the stroke width.
467  //
468  // The start round cap covers a semicircle formed by sweeping the
469  // perpendicular input clockwise 180 degrees about point p. This sweeps a
470  // semicircle with a curve facing away from the stroke's direction of travel.
471  //
472  // The first generated vertex is the midpoint of the semicircle's curve,
473  // directly opposite the semicircle's straight diameter. Vertices progress
474  // in the stroke's direction of travel, ending with two vertices at
475  // (p + perpendicular) and (p - perpendicular) that form the semicircle's
476  // diameter.
477  static void GenerateStartRoundCap(const Point& p,
478  const Vector2& perpendicular,
479  const Trigs& trigs,
480  const TessellatedVertexProc& proc);
481 
482  // Generates vertices for the end round cap of a stroke.
483  //
484  // The perpendicular input points 90 degrees clockwise to the direction the
485  // stroke is traveling and is the length of half of the stroke width.
486  //
487  // The end round cap covers a semicircle formed by sweeping the
488  // perpendicular input counterclockwise 180 degrees about point p. This sweeps
489  // a semicircle with a curve facing toward the stroke's direction of travel.
490  //
491  // The generated vertices begin with two vertices at (p + perpendicular) and
492  // (p - perpendicular) which form the semicircle's diameter. Vertices progress
493  // in the stroke's direction of travel, ending with the vertex at the midpoint
494  // of the semicircle's curve.
495  static void GenerateEndRoundCap(const Point& p,
496  const Vector2& perpendicular,
497  const Trigs& trigs,
498  const TessellatedVertexProc& proc);
499 
500  Tessellator(const Tessellator&) = delete;
501 
502  Tessellator& operator=(const Tessellator&) = delete;
503 };
504 
505 } // namespace impeller
506 
507 #endif // FLUTTER_IMPELLER_TESSELLATOR_TESSELLATOR_H_
bool use_center
The |VertexGenerator| implementation common to all shapes that are based on a polygonal representatio...
Definition: tessellator.h:191
static ArcVertexGenerator MakeStroked(const Arc::Iteration &iteration, Trigs &&trigs, const Rect &oval_bounds, Scalar half_width, Cap cap, std::unique_ptr< Trigs > round_cap_trigs)
Definition: tessellator.cc:536
size_t GetVertexCount() const override
|VertexGenerator|
Definition: tessellator.cc:570
PrimitiveType GetTriangleType() const override
|VertexGenerator|
Definition: tessellator.cc:564
static ArcVertexGenerator MakeFilled(const Arc::Iteration &iteration, Trigs &&trigs, const Rect &oval_bounds, bool use_center, bool supports_triangle_fans)
Definition: tessellator.cc:525
void GenerateVertices(const TessellatedVertexProc &proc) const override
|VertexGenerator|
Definition: tessellator.cc:597
The |VertexGenerator| implementation common to all shapes that are based on a polygonal representatio...
Definition: tessellator.h:140
PrimitiveType GetTriangleType() const override
|VertexGenerator|
Definition: tessellator.h:143
size_t GetVertexCount() const override
|VertexGenerator|
Definition: tessellator.h:148
void GenerateVertices(const TessellatedVertexProc &proc) const override
|VertexGenerator|
Definition: tessellator.h:153
std::vector< Trig >::iterator begin() const
Definition: tessellator.h:54
std::vector< Trig >::iterator end() const
Definition: tessellator.h:55
Trigs(Scalar pixel_radius)
Definition: tessellator.cc:447
const Trig & operator[](size_t index) const
Definition: tessellator.h:56
An object which produces a list of vertices as |Point|s that tessellate a previously provided shape a...
Definition: tessellator.h:110
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:37
Trigs GetTrigsForDeviceRadius(Scalar pixel_radius)
Definition: tessellator.cc:425
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...
Definition: tessellator.cc:645
std::vector< Point > & GetStrokePointCache()
Retrieve a pre-allocated arena of kPointArenaSize points.
Definition: tessellator.cc:421
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 ...
Definition: tessellator.cc:689
static constexpr Scalar kCircleTolerance
The pixel tolerance used by the algorighm to determine how many divisions to create for a circle.
Definition: tessellator.h:280
VertexBuffer TessellateConvex(const PathSource &path, HostBuffer &data_host_buffer, HostBuffer &indexes_host_buffer, Scalar tolerance, bool supports_primitive_restart=false, bool supports_triangle_fan=false)
Given a convex path, create a triangle fan structure.
Definition: tessellator.cc:429
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:488
ArcVertexGenerator StrokedArc(const Matrix &view_transform, const Arc &arc, Cap cap, Scalar half_width)
Create a |VertexGenerator| that can produce vertices for a stroked arc inscribed within the given ova...
Definition: tessellator.cc:623
static void TessellateConvexInternal(const PathSource &path, std::vector< Point > &point_buffer, std::vector< uint16_t > &index_buffer, Scalar tolerance)
Definition: tessellator.cc:440
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...
Definition: tessellator.cc:504
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:668
Tessellator(bool supports_32bit_primitive_indices=true)
Definition: tessellator.cc:410
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:97
ArcVertexGenerator FilledArc(const Matrix &view_transform, const Arc &arc, bool supports_triangle_fans)
Create a |VertexGenerator| that can produce vertices for a stroked arc inscribed within the given ova...
Definition: tessellator.cc:612
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:355
float Scalar
Definition: scalar.h:19
Cap
An enum that describes ways to decorate the end of a path contour.
Tessellator::ArcVertexGenerator ArcVertexGenerator
Definition: tessellator.cc:475
static constexpr size_t kPointArenaSize
The size of the point arena buffer stored on the tessellator.
Definition: tessellator.h:25
Definition: comparable.h:95
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
A structure to store the sine and cosine of an angle.
Definition: trig.h:16
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:69