77
88#include " src/gpu/tessellate/GrPathParser.h"
99
10+ #include " include/private/SkTArray.h"
1011#include " src/core/SkPathPriv.h"
1112
12- namespace GrPathParser {
13-
1413static SkPoint lerp (const SkPoint& a, const SkPoint& b, float T) {
1514 SkASSERT (1 != T); // The below does not guarantee lerp(a, b, 1) === b.
1615 return (b - a) * T + a;
@@ -25,7 +24,7 @@ static SkPoint write_line_as_cubic(SkPoint* data, const SkPoint& p0, const SkPoi
2524}
2625
2726static SkPoint write_quadratic_as_cubic (SkPoint* data, const SkPoint& p0, const SkPoint& p1,
28- const SkPoint& p2) {
27+ const SkPoint& p2) {
2928 data[0 ] = p0;
3029 data[1 ] = lerp (p0, p1, 2 /3 .f );
3130 data[2 ] = lerp (p1, p2, 1 /3 .f );
@@ -77,7 +76,7 @@ class MidpointContourParser : public SkTPathContourParser<MidpointContourParser>
7776 int fMidpointWeight ;
7877};
7978
80- int EmitCenterWedges (const SkPath& path, SkPoint* patchData) {
79+ int GrPathParser::EmitCenterWedgePatches (const SkPath& path, SkPoint* patchData) {
8180 int vertexCount = 0 ;
8281 MidpointContourParser parser (path);
8382 while (parser.parseNextContour ()) {
@@ -122,8 +121,112 @@ int EmitCenterWedges(const SkPath& path, SkPoint* patchData) {
122121 }
123122 }
124123
125- SkASSERT (vertexCount <= MaxPossibleWedgeVertices (path));
124+ SkASSERT (vertexCount <= MaxWedgeVertices (path));
125+ return vertexCount;
126+ }
127+
128+ // Triangulates the polygon defined by the points in the range [first..last] inclusive.
129+ // Called by InnerPolygonContourParser::emitInnerPolygon() (and recursively).
130+ static int emit_subpolygon (const SkPoint* points, int first, int last, SkPoint* vertexData) {
131+ if (last - first < 2 ) {
132+ return 0 ;
133+ }
134+
135+ // For sub-polygons we subdivide the points in two and connect the endpoints.
136+ int mid = (first + last) / 2 ;
137+ vertexData[0 ] = points[first];
138+ vertexData[1 ] = points[mid];
139+ vertexData[2 ] = points[last];
140+
141+ // Emit the sub-polygon at each outer-edge of our new triangle.
142+ int vertexCount = 3 ;
143+ vertexCount += emit_subpolygon (points, first, mid, vertexData + vertexCount);
144+ vertexCount += emit_subpolygon (points, mid, last, vertexData + vertexCount);
145+ return vertexCount;
146+ }
147+
148+ class InnerPolygonContourParser : public SkTPathContourParser <InnerPolygonContourParser> {
149+ public:
150+ InnerPolygonContourParser (const SkPath& path) : SkTPathContourParser(path) {
151+ fPolyPoints .reserve (GrPathParser::MaxInnerPolygonVertices (path));
152+ }
153+
154+ int emitInnerPolygon (SkPoint* vertexData) {
155+ if (fPolyPoints .size () < 3 ) {
156+ return 0 ;
157+ }
158+
159+ // For the first triangle in the polygon, subdivide our points into thirds.
160+ int i1 = fPolyPoints .size () / 3 ;
161+ int i2 = (2 * fPolyPoints .size ()) / 3 ;
162+ vertexData[0 ] = fPolyPoints [0 ];
163+ vertexData[1 ] = fPolyPoints [i1];
164+ vertexData[2 ] = fPolyPoints [i2];
165+
166+ // Emit the sub-polygons at all three edges of our first triangle.
167+ int vertexCount = 3 ;
168+ vertexCount += emit_subpolygon (fPolyPoints .begin (), 0 , i1, vertexData + vertexCount);
169+ vertexCount += emit_subpolygon (fPolyPoints .begin (), i1, i2, vertexData + vertexCount);
170+ int i3 = fPolyPoints .size ();
171+ fPolyPoints .push_back (fPolyPoints .front ());
172+ vertexCount += emit_subpolygon (fPolyPoints .begin (), i2, i3, vertexData + vertexCount);
173+ fPolyPoints .pop_back ();
174+
175+ return vertexCount;
176+ }
177+
178+ int numCurves () const { return fNumCurves ; }
179+
180+ private:
181+ friend class SkTPathContourParser <InnerPolygonContourParser>;
182+
183+ void resetGeometry (const SkPoint& startPoint) {
184+ fPolyPoints .pop_back_n (fPolyPoints .count ());
185+ fPolyPoints .push_back (startPoint);
186+ fNumCurves = 0 ;
187+ }
188+
189+ void geometryTo (SkPathVerb verb, const SkPoint& endpoint) {
190+ fPolyPoints .push_back (endpoint);
191+ if (SkPathVerb::kLine != verb) {
192+ ++fNumCurves ;
193+ }
194+ }
195+
196+ SkSTArray<128 , SkPoint> fPolyPoints ;
197+ int fNumCurves ;
198+ };
199+
200+ int GrPathParser::EmitInnerPolygonTriangles (const SkPath& path, SkPoint* vertexData,
201+ int * numCurves) {
202+ *numCurves = 0 ;
203+ int vertexCount = 0 ;
204+ InnerPolygonContourParser parser (path);
205+ while (parser.parseNextContour ()) {
206+ vertexCount += parser.emitInnerPolygon (vertexData + vertexCount);
207+ *numCurves += parser.numCurves ();
208+ }
209+
210+ SkASSERT (vertexCount <= MaxInnerPolygonVertices (path));
126211 return vertexCount;
127212}
128213
129- } // namespace
214+ int GrPathParser::EmitCubicInstances (const SkPath& path, SkPoint* vertexData) {
215+ int instanceCount = 0 ;
216+ SkPath::Iter iter (path, false );
217+ SkPath::Verb verb;
218+ SkPoint pts[4 ];
219+ while ((verb = iter.next (pts)) != SkPath::kDone_Verb ) {
220+ if (SkPath::kQuad_Verb == verb) {
221+ write_quadratic_as_cubic (vertexData + (instanceCount * 4 ), pts[0 ], pts[1 ], pts[2 ]);
222+ ++instanceCount;
223+ continue ;
224+ }
225+ if (SkPath::kCubic_Verb == verb) {
226+ write_cubic (vertexData + (instanceCount * 4 ), pts[0 ], pts[1 ], pts[2 ], pts[3 ]);
227+ ++instanceCount;
228+ continue ;
229+ }
230+ }
231+ return instanceCount;
232+ }
0 commit comments