Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(392)

Side by Side Diff: src/gpu/GrAAConvexTessellator.h

Issue 1084943003: Add GrAAConvexTessellator class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix more warnings as errors Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gyp/gpu.gypi ('k') | src/gpu/GrAAConvexTessellator.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #ifndef GrAAConvexTessellator_DEFINED
9 #define GrAAConvexTessellator_DEFINED
10
11 #include "SkColor.h"
12 #include "SkPoint.h"
13 #include "SkScalar.h"
14 #include "SkTDArray.h"
15
16 class SkCanvas;
17 class SkMatrix;
18 class SkPath;
19
20 //#define GR_AA_CONVEX_TESSELLATOR_VIZ 1
21
22 class GrAAConvexTessellator;
23
24 // The AAConvexTessellator holds the global pool of points and the triangulation
25 // that connects them. It also drives the tessellation process.
26 // The outward facing normals of the original polygon are stored (in 'fNorms') t o service
27 // computeDepthFromEdge requests.
28 class GrAAConvexTessellator {
29 public:
30 GrAAConvexTessellator(SkScalar targetDepth = 0.5f)
31 : fSide(SkPoint::kOn_Side)
32 , fTargetDepth(targetDepth) {
33 }
34
35 void setTargetDepth(SkScalar targetDepth) { fTargetDepth = targetDepth; }
36 SkScalar targetDepth() const { return fTargetDepth; }
37
38 SkPoint::Side side() const { return fSide; }
39
40 bool tessellate(const SkMatrix& m, const SkPath& path);
41
42 // The next five should only be called after tessellate to extract the resul t
43 int numPts() const { return fPts.count(); }
44 int numIndices() const { return fIndices.count(); }
45
46 const SkPoint& lastPoint() const { return fPts.top(); }
47 const SkPoint& point(int index) const { return fPts[index]; }
48 int index(int index) const { return fIndices[index]; }
49 SkScalar depth(int index) const {return fDepths[index]; }
50
51 #if GR_AA_CONVEX_TESSELLATOR_VIZ
52 void draw(SkCanvas* canvas) const;
53 #endif
54
55 // The tessellator can be reused for multiple paths by rewinding in between
56 void rewind();
57
58 private:
59 // CandidateVerts holds the vertices for the next ring while they are
60 // being generated. Its main function is to de-dup the points.
61 class CandidateVerts {
62 public:
63 void setReserve(int numPts) { fPts.setReserve(numPts); }
64 void rewind() { fPts.rewind(); }
65
66 int numPts() const { return fPts.count(); }
67
68 const SkPoint& lastPoint() const { return fPts.top().fPt; }
69 const SkPoint& firstPoint() const { return fPts[0].fPt; }
70 const SkPoint& point(int index) const { return fPts[index].fPt; }
71
72 int originatingIdx(int index) const { return fPts[index].fOriginatingIdx ; }
73 int origEdge(int index) const { return fPts[index].fOrigEdgeId; }
74 bool needsToBeNew(int index) const { return fPts[index].fNeedsToBeNew; }
75
76 int addNewPt(const SkPoint& newPt, int originatingIdx, int origEdge, boo l needsToBeNew) {
77 struct PointData* pt = fPts.push();
78 pt->fPt = newPt;
79 pt->fOrigEdgeId = origEdge;
80 pt->fOriginatingIdx = originatingIdx;
81 pt->fNeedsToBeNew = needsToBeNew;
82 return fPts.count() - 1;
83 }
84
85 int fuseWithPrior(int origEdgeId) {
86 fPts.top().fOrigEdgeId = origEdgeId;
87 fPts.top().fOriginatingIdx = -1;
88 fPts.top().fNeedsToBeNew = true;
89 return fPts.count() - 1;
90 }
91
92 int fuseWithNext() {
93 fPts[0].fOriginatingIdx = -1;
94 fPts[0].fNeedsToBeNew = true;
95 return 0;
96 }
97
98 int fuseWithBoth() {
99 if (fPts.count() > 1) {
100 fPts.pop();
101 }
102
103 fPts[0].fOriginatingIdx = -1;
104 fPts[0].fNeedsToBeNew = true;
105 return 0;
106 }
107
108 private:
109 struct PointData {
110 SkPoint fPt;
111 int fOriginatingIdx;
112 int fOrigEdgeId;
113 bool fNeedsToBeNew;
114 };
115
116 SkTDArray<struct PointData> fPts;
117 };
118
119 // The Ring holds a set of indices into the global pool that together define
120 // a single polygon inset.
121 class Ring {
122 public:
123 void setReserve(int numPts) { fPts.setReserve(numPts); }
124 void rewind() { fPts.rewind(); }
125
126 int numPts() const { return fPts.count(); }
127
128 void addIdx(int index, int origEdgeId) {
129 struct PointData* pt = fPts.push();
130 pt->fIndex = index;
131 pt->fOrigEdgeId = origEdgeId;
132 }
133
134 // init should be called after all the indices have been added (via addI dx)
135 void init(const GrAAConvexTessellator& tess);
136 void init(const SkTDArray<SkVector>& norms, const SkTDArray<SkVector>& b isectors);
137
138 const SkPoint& norm(int index) const { return fPts[index].fNorm; }
139 const SkPoint& bisector(int index) const { return fPts[index].fBisector; }
140 int index(int index) const { return fPts[index].fIndex; }
141 int origEdgeID(int index) const { return fPts[index].fOrigEdgeId; }
142
143 #if GR_AA_CONVEX_TESSELLATOR_VIZ
144 void draw(SkCanvas* canvas, const GrAAConvexTessellator& tess) const;
145 #endif
146
147 private:
148 void computeNormals(const GrAAConvexTessellator& result);
149 void computeBisectors();
150
151 SkDEBUGCODE(bool isConvex(const GrAAConvexTessellator& tess) const;)
152
153 struct PointData {
154 SkPoint fNorm;
155 SkPoint fBisector;
156 int fIndex;
157 int fOrigEdgeId;
158 };
159
160 SkTDArray<PointData> fPts;
161 };
162
163 bool movable(int index) const { return fMovable[index]; }
164
165 // Movable points are those that can be slid along their bisector.
166 // Basically, a point is immovable if it is part of the original
167 // polygon or it results from the fusing of two bisectors.
168 int addPt(const SkPoint& pt, SkScalar depth, bool movable);
169 void popLastPt();
170 void popFirstPtShuffle();
171
172 void updatePt(int index, const SkPoint& pt, SkScalar depth);
173
174 void addTri(int i0, int i1, int i2);
175
176 void reservePts(int count) {
177 fPts.setReserve(count);
178 fDepths.setReserve(count);
179 fMovable.setReserve(count);
180 }
181
182 SkScalar computeDepthFromEdge(int edgeIdx, const SkPoint& p) const;
183
184 bool computePtAlongBisector(int startIdx, const SkPoint& bisector,
185 int edgeIdx, SkScalar desiredDepth,
186 SkPoint* result) const;
187
188 void terminate(const Ring& lastRing);
189
190 // return false on failure/degenerate path
191 bool extractFromPath(const SkMatrix& m, const SkPath& path);
192 void computeBisectors();
193
194 void fanRing(const Ring& ring);
195 void createOuterRing();
196
197 Ring* getNextRing(Ring* lastRing);
198
199 bool createInsetRing(const Ring& lastRing, Ring* nextRing);
200
201 void validate() const;
202
203
204 #ifdef SK_DEBUG
205 SkScalar computeRealDepth(const SkPoint& p) const;
206 void checkAllDepths() const;
207 #endif
208
209 // fPts, fWeights & fMovable should always have the same # of elements
210 SkTDArray<SkPoint> fPts;
211 SkTDArray<SkScalar> fDepths;
212 // movable points are those that can be slid further along their bisector
213 SkTDArray<bool> fMovable;
214
215 // The outward facing normals for the original polygon
216 SkTDArray<SkVector> fNorms;
217 // The inward facing bisector at each point in the original polygon. Only
218 // needed for exterior ring creation and then handed off to the initial ring .
219 SkTDArray<SkVector> fBisectors;
220 SkPoint::Side fSide; // winding of the original polygon
221
222 // The triangulation of the points
223 SkTDArray<int> fIndices;
224
225 Ring fInitialRing;
226 #if GR_AA_CONVEX_TESSELLATOR_VIZ
227 // When visualizing save all the rings
228 SkTDArray<Ring*> fRings;
229 #else
230 Ring fRings[2];
231 #endif
232 CandidateVerts fCandidateVerts;
233
234 SkScalar fTargetDepth;
235
236 // If some goes wrong with the inset computation the tessellator will
237 // truncate the creation of the inset polygon. In this case the depth
238 // check will complain.
239 SkDEBUGCODE(bool fShouldCheckDepths;)
240 };
241
242
243 #endif
244
OLDNEW
« no previous file with comments | « gyp/gpu.gypi ('k') | src/gpu/GrAAConvexTessellator.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698