Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | List of all members
skgpu::tess::LinearTolerances Class Reference

#include <LinearTolerances.h>

Public Member Functions

float numParametricSegments_p4 () const
 
float numRadialSegmentsPerRadian () const
 
int numEdgesInJoins () const
 
int requiredResolveLevel () const
 
int requiredStrokeEdges () const
 
void setParametricSegments (float n4)
 
void setStroke (const StrokeParams &strokeParams, float maxScale)
 
void accumulate (const LinearTolerances &tolerances)
 

Detailed Description

LinearTolerances stores state to approximate the final device-space transform applied to curves, and uses that to calculate segmentation levels for both the parametric curves and radial components (when stroking, where you have to represent the offset of a curve). These tolerances determine the worst-case number of parametric and radial segments required to accurately linearize curves.

The tolerance values and decisions are estimated in the local path space, although PatchWriter uses a 2x2 vector transform that approximates the scale/skew (as-best-as-possible) of the full local-to-device transform applied in the vertex shader.

The properties tracked in LinearTolerances can be used to compute the final segmentation factor for filled paths (the resolve level) or stroked paths (the number of edges).

Definition at line 38 of file LinearTolerances.h.

Member Function Documentation

◆ accumulate()

void skgpu::tess::LinearTolerances::accumulate ( const LinearTolerances tolerances)
inline

Definition at line 109 of file LinearTolerances.h.

109 {
110 if (tolerances.fNumParametricSegments_p4 > fNumParametricSegments_p4) {
111 fNumParametricSegments_p4 = tolerances.fNumParametricSegments_p4;
112 }
113 if (tolerances.fNumRadialSegmentsPerRadian > fNumRadialSegmentsPerRadian) {
114 fNumRadialSegmentsPerRadian = tolerances.fNumRadialSegmentsPerRadian;
115 }
116 if (tolerances.fEdgesInJoins > fEdgesInJoins) {
117 fEdgesInJoins = tolerances.fEdgesInJoins;
118 }
119 }

◆ numEdgesInJoins()

int skgpu::tess::LinearTolerances::numEdgesInJoins ( ) const
inline

Definition at line 42 of file LinearTolerances.h.

42{ return fEdgesInJoins; }

◆ numParametricSegments_p4()

float skgpu::tess::LinearTolerances::numParametricSegments_p4 ( ) const
inline

Definition at line 40 of file LinearTolerances.h.

40{ return fNumParametricSegments_p4; }

◆ numRadialSegmentsPerRadian()

float skgpu::tess::LinearTolerances::numRadialSegmentsPerRadian ( ) const
inline

Definition at line 41 of file LinearTolerances.h.

41{ return fNumRadialSegmentsPerRadian; }

◆ requiredResolveLevel()

int skgpu::tess::LinearTolerances::requiredResolveLevel ( ) const
inline

Definition at line 45 of file LinearTolerances.h.

45 {
46 // log16(n^4) == log2(n)
47 return wangs_formula::nextlog16(fNumParametricSegments_p4);
48 }
AI int nextlog16(float x)

◆ requiredStrokeEdges()

int skgpu::tess::LinearTolerances::requiredStrokeEdges ( ) const
inline

Definition at line 50 of file LinearTolerances.h.

50 {
51 // The maximum rotation we can have in a stroke is 180 degrees (SK_ScalarPI radians).
52 int maxRadialSegmentsInStroke =
53 std::max(SkScalarCeilToInt(fNumRadialSegmentsPerRadian * SK_ScalarPI), 1);
54
55 int maxParametricSegmentsInStroke =
56 SkScalarCeilToInt(wangs_formula::root4(fNumParametricSegments_p4));
57 SkASSERT(maxParametricSegmentsInStroke >= 1);
58
59 // Now calculate the maximum number of edges we will need in the stroke portion of the
60 // instance. The first and last edges in a stroke are shared by both the parametric and
61 // radial sets of edges, so the total number of edges is:
62 //
63 // numCombinedEdges = numParametricEdges + numRadialEdges - 2
64 //
65 // It's important to differentiate between the number of edges and segments in a strip:
66 //
67 // numSegments = numEdges - 1
68 //
69 // So the total number of combined edges in the stroke is:
70 //
71 // numEdgesInStroke = numParametricSegments + 1 + numRadialSegments + 1 - 2
72 // = numParametricSegments + numRadialSegments
73 //
74 int maxEdgesInStroke = maxRadialSegmentsInStroke + maxParametricSegmentsInStroke;
75
76 // Each triangle strip has two sections: It starts with a join then transitions to a
77 // stroke. The number of edges in an instance is the sum of edges from the join and
78 // stroke sections both.
79 // NOTE: The final join edge and the first stroke edge are co-located, however we still
80 // need to emit both because the join's edge is half-width and the stroke is full-width.
81 return fEdgesInJoins + maxEdgesInStroke;
82 }
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SkScalarCeilToInt(x)
Definition SkScalar.h:36
#define SK_ScalarPI
Definition SkScalar.h:21
AI float root4(float x)

◆ setParametricSegments()

void skgpu::tess::LinearTolerances::setParametricSegments ( float  n4)
inline

Definition at line 84 of file LinearTolerances.h.

84 {
85 SkASSERT(n4 >= 0.f);
86 fNumParametricSegments_p4 = n4;
87 }

◆ setStroke()

void skgpu::tess::LinearTolerances::setStroke ( const StrokeParams strokeParams,
float  maxScale 
)
inline

Definition at line 89 of file LinearTolerances.h.

89 {
90 float approxDeviceStrokeRadius;
91 if (strokeParams.fRadius == 0.f) {
92 // Hairlines are always 1 px wide
93 approxDeviceStrokeRadius = 0.5f;
94 } else {
95 // Approximate max scale * local stroke width / 2
96 approxDeviceStrokeRadius = strokeParams.fRadius * maxScale;
97 }
98
99 fNumRadialSegmentsPerRadian = CalcNumRadialSegmentsPerRadian(approxDeviceStrokeRadius);
100
101 fEdgesInJoins = NumFixedEdgesInJoin(strokeParams);
102 if (strokeParams.fJoinType < 0.f && fNumRadialSegmentsPerRadian > 0.f) {
103 // For round joins we need to count the radial edges on our own. Account for a
104 // worst-case join of 180 degrees (SK_ScalarPI radians).
105 fEdgesInJoins += SkScalarCeilToInt(fNumRadialSegmentsPerRadian * SK_ScalarPI) - 1;
106 }
107 }
float CalcNumRadialSegmentsPerRadian(float approxDevStrokeRadius)
constexpr int NumFixedEdgesInJoin(SkPaint::Join joinType)

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