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

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: Created 5 years, 8 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
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 GrAAConvexTessellator holds the global pool of vertices. The GrRing
25 // holds a set of indices into that global pool that together define a
26 // single polygon inset.
27 class GrRing {
bsalomon 2015/04/24 15:44:44 Seems like Ring should be a nested class of GrAACT
robertphillips 2015/05/05 15:21:33 Done. The GrAACT does need to know the size but I
28 public:
29 GrRing() : fSide(SkPoint::kOn_Side) {}
30
31 void setSide(SkPoint::Side side) { fSide = side; }
32 SkPoint::Side side() const { return fSide; }
33
34 void setReserve(int numPts);
35 void rewind();
36
37 int numPts0() const { return fIndices.count(); }
38
39 void addIdx1(int index, int origEdgeId) {
40 *fIndices.push() = index;
41 *fOrigEdgeIds.push() = origEdgeId;
42 }
43
44 // init should be called after all the indices have been added (via addIdx)
45 void init(const GrAAConvexTessellator& tess);
46
47 const SkPoint& norm1(int index) const { return fNorms[index]; }
48 const SkPoint& bisector(int index) const { return fBisectors[index]; }
49 int index(int index) const { return fIndices[index]; }
50 int origEdgeID(int index) const { return fOrigEdgeIds[index]; }
51
52 // only call after 'init'
53 SkScalar computeDepthFromEdge(GrAAConvexTessellator& tess,
54 int edgeIdx, const SkPoint& p) const;
55
56 #if GR_AA_CONVEX_TESSELLATOR_VIZ
57 void draw(SkCanvas* canvas, const GrAAConvexTessellator& tess) const;
58 #endif
59
60 int numPts2() const { return fPts2.count(); }
61
62 const SkPoint& lastPoint() const { return fPts2[fPts2.count()-1];}
63 const SkPoint& firstPoint() const { return fPts2[0]; }
64 const SkPoint& point(int index) const { return fPts2[index]; }
65
66 int originatingIdx(int index) const {
67 return fOriginatingIdx2[index];
68 }
69
70 int origEdge2(int index) const {
71 return fOrigEdgeIds2[index];
72 }
73
74 bool needsToBeNew(int index) const {
75 return fNeedsToBeNew2[index];
76 }
77
78 int addNewPt(const SkPoint& newPt, int originatingIdx, int origEdge, bool ne edsToBeNew) {
79 *fPts2.push() = newPt;
80 *fOrigEdgeIds2.push() = origEdge;
81 *fOriginatingIdx2.push() = originatingIdx;
82 *fNeedsToBeNew2.push() = needsToBeNew;
83 return fPts2.count() - 1;
84 }
85
86 int fuseWithPrior(int origEdgeId) {
87 this->validate();
88
89 fOrigEdgeIds2[fOrigEdgeIds2.count()-1] = origEdgeId;
90 fOriginatingIdx2[fOriginatingIdx2.count()-1] = -1;
91 fNeedsToBeNew2[fNeedsToBeNew2.count()-1] = true;
92 return fPts2.count() - 1;
93 }
94
95 int fuseWithNext() {
96 this->validate();
97
98 fOriginatingIdx2[0] = -1;
99 fNeedsToBeNew2[0] = true;
100 return 0;
101 }
102
103 int fuseWithBoth() {
104 this->validate();
105
106 if (fPts2.count() > 1) {
107 fPts2.pop();
108 fOriginatingIdx2.pop();
109 fOrigEdgeIds2.pop();
110 fNeedsToBeNew2.pop();
111 }
112
113 this->validate();
114
115 fOriginatingIdx2[0] = -1;
116 fNeedsToBeNew2[0] = true;
117 return 0;
118 }
119
120 private:
121 void validate() const;
122 void computeNormals(const GrAAConvexTessellator& result);
123 void computeBisectors();
124
125 bool isConvex(const GrAAConvexTessellator& tess) const;
126
127 // TODO: the ring operates in two modes: a construction phase and
128 // an information phase. The data used by the two phases is almost completel y
129 // disjoint but of equal size. We could reuse the memory between the
130 // two phases.
131 #if 0
132 enum RingMode {
133 InProgress_RingMode,
134 Finished_RingMode,
135 FinishedWithInfo_RingMode
136 };
137
138 typedef struct {
139 SkPoint fPt; // new ring point not yet in the global pool
140 int fOriginatingIdx; // Index of the vert that was slid along the bisector for this
141 // point. Set to -1 if this point was fused with another.
142 int fOrigEdgeId; // The closest edge in fInitialRing
143 bool fNeedsToBeNew;
144 } InProgressInfo;
145
146 typedef struct {
147 SkPoint fNorm;
148 SkPoint fBisector;
149 int fIndex; // index of the point in the global pool
150 int fOrigEdgeId; // The closest edge in fInitialRing
151 } FinishedInfo;
152
153 RingMode fMode;
154
155 typedef union {
156 InProgressInfo fIPI;
157 FinishedInfo fFI;
158 } SingleEntry;
159
160 SkTDArray<SingleEntry> fVertInfo;
161 #endif
162
163 SkPoint::Side fSide;
164
165 SkTDArray<SkPoint> fPts2;
166 SkTDArray<int> fOriginatingIdx2;
167 SkTDArray<int> fOrigEdgeIds2;
168 SkTDArray<bool> fNeedsToBeNew2;
169
170 SkTDArray<SkPoint> fNorms;
171 SkTDArray<SkPoint> fBisectors;
172 SkTDArray<int> fIndices;
173 SkTDArray<int> fOrigEdgeIds;
174
175 };
176
177
178 class GrAAConvexTessellator {
179 public:
180 GrAAConvexTessellator(SkScalar targetDepth = 0.5f) : fTargetDepth(targetDept h) { }
181
182 void setTargetDepth(SkScalar targetDepth) { fTargetDepth = targetDepth; }
183 SkScalar targetDepth() const { return fTargetDepth; }
184
185 bool tessellate(const SkMatrix& m, const SkPath& path);
186
187 // The next five should only be called after tessellate
188 int numPts() const { return fPts.count(); }
189 int numIndices() const { return fIndices.count(); }
190
191 const SkPoint& point(int index) const { return fPts[index]; }
192 int index(int index) const { return fIndices[index]; }
193
194 #if GR_AA_CONVEX_TESSELLATOR_VIZ
195 void draw(SkCanvas* canvas) const;
196 #endif
197
198 private:
199 const SkPoint& lastPoint() const { return fPts.top(); }
200 SkScalar depth(int index) const { return fDepths[index]; }
201 bool movable(int index) const { return fMovable[index]; }
202
203 int addPt(const SkPoint& pt, SkScalar depth, bool movable);
bsalomon 2015/04/24 15:44:44 comment about what movable means?
robertphillips 2015/05/05 15:21:33 Done.
204 void popLastPt();
205 void popFirstPtShuffle();
206
207 void updatePt(int index, const SkPoint& pt, SkScalar depth);
208
209 void addTri(int i0, int i1, int i2);
210
211 void reservePts(int count) {
212 fPts.setReserve(count);
213 fDepths.setReserve(count);
214 fMovable.setReserve(count);
215 }
216
217 SkPoint computePtAlongBisector(int startIdx, const SkPoint& bisector,
218 int edgeIdx, SkScalar desiredDepth) const;
219
220 // return false on failure/degenerate path
221 bool extractFromPath(const SkMatrix& m, const SkPath& path);
222
223 void fanRing(const GrRing& ring);
224 void createOuterRing(const GrRing& ring);
225
226 GrRing* getNextRing(GrRing* lastRing);
227
228 bool createInsetRing(const GrRing& lastRing, GrRing* nextRing);
229
230 void validate() const;
231
232 #ifdef SK_DEBUG
233 SkScalar computeRealDepth(const SkPoint& p) const;
234 void checkAllDepths() const;
235 #endif
236
237 // fPts, fWeights & fMovable should always have the same # of elements
238 SkTDArray<SkPoint> fPts;
239 SkTDArray<SkScalar> fDepths;
240 // movable points are those that can be slid further along their bisector
241 SkTDArray<bool> fMovable;
242
243 SkTDArray<int> fIndices;
244
245 GrRing fInitialRing;
246 #if GR_AA_CONVEX_TESSELLATOR_VIZ
247 // When visualizing save all the rings
248 SkTDArray<GrRing*> fRings;
249 #else
250 GrRing fRings[2];
251 #endif
252
253 SkScalar fTargetDepth;
254 };
255
256
257 #endif
258
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698