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

Side by Side Diff: src/core/SkEdgeBuilder.cpp

Issue 2388213003: Revert of Analytic AntiAlias for Convex Shapes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 2 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 | « src/core/SkEdgeBuilder.h ('k') | src/core/SkScan.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 #include "SkEdgeBuilder.h" 7 #include "SkEdgeBuilder.h"
8 #include "SkPath.h" 8 #include "SkPath.h"
9 #include "SkEdge.h" 9 #include "SkEdge.h"
10 #include "SkAnalyticEdge.h"
11 #include "SkEdgeClipper.h" 10 #include "SkEdgeClipper.h"
12 #include "SkLineClipper.h" 11 #include "SkLineClipper.h"
13 #include "SkGeometry.h" 12 #include "SkGeometry.h"
14 13
15 template <typename T> static T* typedAllocThrow(SkChunkAlloc& alloc) { 14 template <typename T> static T* typedAllocThrow(SkChunkAlloc& alloc) {
16 return static_cast<T*>(alloc.allocThrow(sizeof(T))); 15 return static_cast<T*>(alloc.allocThrow(sizeof(T)));
17 } 16 }
18 17
19 /////////////////////////////////////////////////////////////////////////////// 18 ///////////////////////////////////////////////////////////////////////////////
20 19
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 return kPartial_Combine; 55 return kPartial_Combine;
57 } 56 }
58 last->fLastY = last->fFirstY - 1; 57 last->fLastY = last->fFirstY - 1;
59 last->fFirstY = edge->fFirstY; 58 last->fFirstY = edge->fFirstY;
60 last->fWinding = edge->fWinding; 59 last->fWinding = edge->fWinding;
61 return kPartial_Combine; 60 return kPartial_Combine;
62 } 61 }
63 return kNo_Combine; 62 return kNo_Combine;
64 } 63 }
65 64
66 SkEdgeBuilder::Combine SkEdgeBuilder::CombineVertical( 65 static bool vertical_line(const SkEdge* edge) {
67 const SkAnalyticEdge* edge, SkAnalyticEdge* last) {
68 SkASSERT(fAnalyticAA);
69 if (last->fCurveCount || last->fDX || edge->fX != last->fX) {
70 return kNo_Combine;
71 }
72 if (edge->fWinding == last->fWinding) {
73 if (edge->fLowerY == last->fUpperY) {
74 last->fUpperY = edge->fUpperY;
75 last->fY = last->fUpperY;
76 return kPartial_Combine;
77 }
78 if (edge->fUpperY == last->fLowerY) {
79 last->fLowerY = edge->fLowerY;
80 return kPartial_Combine;
81 }
82 return kNo_Combine;
83 }
84 if (edge->fUpperY == last->fUpperY) {
85 if (edge->fLowerY == last->fLowerY) {
86 return kTotal_Combine;
87 }
88 if (edge->fLowerY < last->fLowerY) {
89 last->fUpperY = edge->fLowerY;
90 last->fY = last->fUpperY;
91 return kPartial_Combine;
92 }
93 last->fUpperY = last->fLowerY;
94 last->fY = last->fUpperY;
95 last->fLowerY = edge->fLowerY;
96 last->fWinding = edge->fWinding;
97 return kPartial_Combine;
98 }
99 if (edge->fLowerY == last->fLowerY) {
100 if (edge->fUpperY > last->fUpperY) {
101 last->fLowerY = edge->fUpperY;
102 return kPartial_Combine;
103 }
104 last->fLowerY = last->fUpperY;
105 last->fUpperY = edge->fUpperY;
106 last->fY = last->fUpperY;
107 last->fWinding = edge->fWinding;
108 return kPartial_Combine;
109 }
110 return kNo_Combine;
111 }
112
113 bool SkEdgeBuilder::vertical_line(const SkEdge* edge) {
114 return !edge->fDX && !edge->fCurveCount;
115 }
116
117 bool SkEdgeBuilder::vertical_line(const SkAnalyticEdge* edge) {
118 SkASSERT(fAnalyticAA);
119 return !edge->fDX && !edge->fCurveCount; 66 return !edge->fDX && !edge->fCurveCount;
120 } 67 }
121 68
122 void SkEdgeBuilder::addLine(const SkPoint pts[]) { 69 void SkEdgeBuilder::addLine(const SkPoint pts[]) {
123 if (fAnalyticAA) { 70 SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc);
124 SkAnalyticEdge* edge = typedAllocThrow<SkAnalyticEdge>(fAlloc); 71 if (edge->setLine(pts[0], pts[1], fShiftUp)) {
125 if (edge->setLine(pts[0], pts[1])) { 72 if (vertical_line(edge) && fList.count()) {
126 if (vertical_line(edge) && fList.count()) { 73 Combine combine = CombineVertical(edge, *(fList.end() - 1));
127 Combine combine = CombineVertical(edge, (SkAnalyticEdge*)*(fList .end() - 1)); 74 if (kNo_Combine != combine) {
128 if (kNo_Combine != combine) { 75 if (kTotal_Combine == combine) {
129 if (kTotal_Combine == combine) { 76 fList.pop();
130 fList.pop();
131 }
132 goto unallocate_analytic_edge;
133 } 77 }
78 goto unallocate_edge;
134 } 79 }
135 fList.push(edge);
136 } else {
137 unallocate_analytic_edge:
138 ;
139 // TODO: unallocate edge from storage...
140 } 80 }
81 fList.push(edge);
141 } else { 82 } else {
142 SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc);
143 if (edge->setLine(pts[0], pts[1], fShiftUp)) {
144 if (vertical_line(edge) && fList.count()) {
145 Combine combine = CombineVertical(edge, (SkEdge*)*(fList.end() - 1));
146 if (kNo_Combine != combine) {
147 if (kTotal_Combine == combine) {
148 fList.pop();
149 }
150 goto unallocate_edge;
151 }
152 }
153 fList.push(edge);
154 } else {
155 unallocate_edge: 83 unallocate_edge:
156 ; 84 ;
157 // TODO: unallocate edge from storage... 85 // TODO: unallocate edge from storage...
158 }
159 } 86 }
160 } 87 }
161 88
162 void SkEdgeBuilder::addQuad(const SkPoint pts[]) { 89 void SkEdgeBuilder::addQuad(const SkPoint pts[]) {
163 if (fAnalyticAA) { 90 SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc);
164 SkAnalyticQuadraticEdge* edge = typedAllocThrow<SkAnalyticQuadraticEdge> (fAlloc); 91 if (edge->setQuadratic(pts, fShiftUp)) {
165 if (edge->setQuadratic(pts)) { 92 fList.push(edge);
166 fList.push(edge);
167 } else {
168 // TODO: unallocate edge from storage...
169 }
170 } else { 93 } else {
171 SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc); 94 // TODO: unallocate edge from storage...
172 if (edge->setQuadratic(pts, fShiftUp)) {
173 fList.push(edge);
174 } else {
175 // TODO: unallocate edge from storage...
176 }
177 } 95 }
178 } 96 }
179 97
180 void SkEdgeBuilder::addCubic(const SkPoint pts[]) { 98 void SkEdgeBuilder::addCubic(const SkPoint pts[]) {
181 if (fAnalyticAA) { 99 SkCubicEdge* edge = typedAllocThrow<SkCubicEdge>(fAlloc);
182 SkAnalyticCubicEdge* edge = typedAllocThrow<SkAnalyticCubicEdge>(fAlloc) ; 100 if (edge->setCubic(pts, fShiftUp)) {
183 if (edge->setCubic(pts)) { 101 fList.push(edge);
184 fList.push(edge);
185 } else {
186 // TODO: unallocate edge from storage...
187 }
188 } else { 102 } else {
189 SkCubicEdge* edge = typedAllocThrow<SkCubicEdge>(fAlloc); 103 // TODO: unallocate edge from storage...
190 if (edge->setCubic(pts, fShiftUp)) {
191 fList.push(edge);
192 } else {
193 // TODO: unallocate edge from storage...
194 }
195 } 104 }
196 } 105 }
197 106
198 void SkEdgeBuilder::addClipper(SkEdgeClipper* clipper) { 107 void SkEdgeBuilder::addClipper(SkEdgeClipper* clipper) {
199 SkPoint pts[4]; 108 SkPoint pts[4];
200 SkPath::Verb verb; 109 SkPath::Verb verb;
201 110
202 while ((verb = clipper->next(pts)) != SkPath::kDone_Verb) { 111 while ((verb = clipper->next(pts)) != SkPath::kDone_Verb) {
203 switch (verb) { 112 switch (verb) {
204 case SkPath::kLine_Verb: 113 case SkPath::kLine_Verb:
(...skipping 14 matching lines...) Expand all
219 /////////////////////////////////////////////////////////////////////////////// 128 ///////////////////////////////////////////////////////////////////////////////
220 129
221 static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) { 130 static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) {
222 dst->set(SkIntToScalar(src.fLeft >> shift), 131 dst->set(SkIntToScalar(src.fLeft >> shift),
223 SkIntToScalar(src.fTop >> shift), 132 SkIntToScalar(src.fTop >> shift),
224 SkIntToScalar(src.fRight >> shift), 133 SkIntToScalar(src.fRight >> shift),
225 SkIntToScalar(src.fBottom >> shift)); 134 SkIntToScalar(src.fBottom >> shift));
226 } 135 }
227 136
228 SkEdgeBuilder::Combine SkEdgeBuilder::checkVertical(const SkEdge* edge, SkEdge** edgePtr) { 137 SkEdgeBuilder::Combine SkEdgeBuilder::checkVertical(const SkEdge* edge, SkEdge** edgePtr) {
229 return !vertical_line(edge) || edgePtr <= (SkEdge**)fEdgeList ? kNo_Combine : 138 return !vertical_line(edge) || edgePtr <= fEdgeList ? kNo_Combine :
230 CombineVertical(edge, edgePtr[-1]); 139 CombineVertical(edge, edgePtr[-1]);
231 } 140 }
232 141
233 SkEdgeBuilder::Combine SkEdgeBuilder::checkVertical(const SkAnalyticEdge* edge,
234 SkAnalyticEdge** edgePtr) {
235 SkASSERT(fAnalyticAA);
236 return !vertical_line(edge) || edgePtr <= (SkAnalyticEdge**)fEdgeList ? kNo_ Combine :
237 CombineVertical(edge, edgePtr[-1]);
238 }
239
240 int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift Up, 142 int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift Up,
241 bool canCullToTheRight) { 143 bool canCullToTheRight) {
242 SkPath::Iter iter(path, true); 144 SkPath::Iter iter(path, true);
243 SkPoint pts[4]; 145 SkPoint pts[4];
244 SkPath::Verb verb; 146 SkPath::Verb verb;
245 147
246 int maxEdgeCount = path.countPoints(); 148 int maxEdgeCount = path.countPoints();
247 if (iclip) { 149 if (iclip) {
248 // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since 150 // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since
249 // we turn portions that are clipped out on the left/right into vertical 151 // we turn portions that are clipped out on the left/right into vertical
250 // segments. 152 // segments.
251 maxEdgeCount *= SkLineClipper::kMaxClippedLineSegments; 153 maxEdgeCount *= SkLineClipper::kMaxClippedLineSegments;
252 } 154 }
253 size_t edgeSize = fAnalyticAA ? sizeof(SkAnalyticEdge) : sizeof(SkEdge); 155 size_t maxEdgeSize = maxEdgeCount * sizeof(SkEdge);
254 size_t maxEdgeSize = maxEdgeCount * edgeSize; 156 size_t maxEdgePtrSize = maxEdgeCount * sizeof(SkEdge*);
255 size_t maxEdgePtrSize = maxEdgeCount * sizeof(char*);
256 157
257 // lets store the edges and their pointers in the same block 158 // lets store the edges and their pointers in the same block
258 char* storage = (char*)fAlloc.allocThrow(maxEdgeSize + maxEdgePtrSize); 159 char* storage = (char*)fAlloc.allocThrow(maxEdgeSize + maxEdgePtrSize);
259 char* edge = (char*)storage; 160 SkEdge* edge = reinterpret_cast<SkEdge*>(storage);
260 char** edgePtr = (char**)(storage + maxEdgeSize); 161 SkEdge** edgePtr = reinterpret_cast<SkEdge**>(storage + maxEdgeSize);
261 // Record the beginning of our pointers, so we can return them to the caller 162 // Record the beginning of our pointers, so we can return them to the caller
262 fEdgeList = (void**)edgePtr; 163 fEdgeList = edgePtr;
263 164
264 if (iclip) { 165 if (iclip) {
265 SkRect clip; 166 SkRect clip;
266 setShiftedClip(&clip, *iclip, shiftUp); 167 setShiftedClip(&clip, *iclip, shiftUp);
267 168
268 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { 169 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
269 switch (verb) { 170 switch (verb) {
270 case SkPath::kMove_Verb: 171 case SkPath::kMove_Verb:
271 case SkPath::kClose_Verb: 172 case SkPath::kClose_Verb:
272 // we ignore these, and just get the whole segment from 173 // we ignore these, and just get the whole segment from
273 // the corresponding line/quad/cubic verbs 174 // the corresponding line/quad/cubic verbs
274 break; 175 break;
275 case SkPath::kLine_Verb: { 176 case SkPath::kLine_Verb: {
276 SkPoint lines[SkLineClipper::kMaxPoints]; 177 SkPoint lines[SkLineClipper::kMaxPoints];
277 int lineCount = SkLineClipper::ClipLine(pts, clip, lines, ca nCullToTheRight); 178 int lineCount = SkLineClipper::ClipLine(pts, clip, lines, ca nCullToTheRight);
278 SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments ); 179 SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments );
279 for (int i = 0; i < lineCount; i++) { 180 for (int i = 0; i < lineCount; i++) {
280 bool setLineResult = fAnalyticAA ? 181 if (edge->setLine(lines[i], lines[i + 1], shiftUp)) {
281 ((SkAnalyticEdge*)edge)->setLine(lines[i], lines [i + 1]) : 182 Combine combine = checkVertical(edge, edgePtr);
282 ((SkEdge*)edge)->setLine(lines[i], lines[i + 1], shiftUp);
283 if (setLineResult) {
284 Combine combine = fAnalyticAA ?
285 checkVertical((SkAnalyticEdge*)edge, (SkAnal yticEdge**)edgePtr) :
286 checkVertical((SkEdge*)edge, (SkEdge**)edgeP tr);
287 if (kNo_Combine == combine) { 183 if (kNo_Combine == combine) {
288 *edgePtr++ = edge; 184 *edgePtr++ = edge++;
289 edge += edgeSize;
290 } else if (kTotal_Combine == combine) { 185 } else if (kTotal_Combine == combine) {
291 --edgePtr; 186 --edgePtr;
292 } 187 }
293 } 188 }
294 } 189 }
295 break; 190 break;
296 } 191 }
297 default: 192 default:
298 SkDEBUGFAIL("unexpected verb"); 193 SkDEBUGFAIL("unexpected verb");
299 break; 194 break;
300 } 195 }
301 } 196 }
302 } else { 197 } else {
303 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { 198 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
304 switch (verb) { 199 switch (verb) {
305 case SkPath::kMove_Verb: 200 case SkPath::kMove_Verb:
306 case SkPath::kClose_Verb: 201 case SkPath::kClose_Verb:
307 // we ignore these, and just get the whole segment from 202 // we ignore these, and just get the whole segment from
308 // the corresponding line/quad/cubic verbs 203 // the corresponding line/quad/cubic verbs
309 break; 204 break;
310 case SkPath::kLine_Verb: { 205 case SkPath::kLine_Verb:
311 bool setLineResult = fAnalyticAA ? 206 if (edge->setLine(pts[0], pts[1], shiftUp)) {
312 ((SkAnalyticEdge*)edge)->setLine(pts[0], pts[1]) : 207 Combine combine = checkVertical(edge, edgePtr);
313 ((SkEdge*)edge)->setLine(pts[0], pts[1], shiftUp);
314 if (setLineResult) {
315 Combine combine = fAnalyticAA ?
316 checkVertical((SkAnalyticEdge*)edge, (SkAnalytic Edge**)edgePtr) :
317 checkVertical((SkEdge*)edge, (SkEdge**)edgePtr);
318 if (kNo_Combine == combine) { 208 if (kNo_Combine == combine) {
319 *edgePtr++ = edge; 209 *edgePtr++ = edge++;
320 edge += edgeSize;
321 } else if (kTotal_Combine == combine) { 210 } else if (kTotal_Combine == combine) {
322 --edgePtr; 211 --edgePtr;
323 } 212 }
324 } 213 }
325 break; 214 break;
326 }
327 default: 215 default:
328 SkDEBUGFAIL("unexpected verb"); 216 SkDEBUGFAIL("unexpected verb");
329 break; 217 break;
330 } 218 }
331 } 219 }
332 } 220 }
333 SkASSERT((char*)edge <= (char*)fEdgeList); 221 SkASSERT((char*)edge <= (char*)fEdgeList);
334 SkASSERT(edgePtr - (char**)fEdgeList <= maxEdgeCount); 222 SkASSERT(edgePtr - fEdgeList <= maxEdgeCount);
335 return SkToInt(edgePtr - (char**)fEdgeList); 223 return SkToInt(edgePtr - fEdgeList);
336 } 224 }
337 225
338 static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) { 226 static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) {
339 SkPoint monoX[5]; 227 SkPoint monoX[5];
340 int n = SkChopQuadAtYExtrema(pts, monoX); 228 int n = SkChopQuadAtYExtrema(pts, monoX);
341 for (int i = 0; i <= n; i++) { 229 for (int i = 0; i <= n; i++) {
342 builder->addQuad(&monoX[i * 2]); 230 builder->addQuad(&monoX[i * 2]);
343 } 231 }
344 } 232 }
345 233
346 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp, 234 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
347 bool canCullToTheRight, bool analyticAA) { 235 bool canCullToTheRight) {
348 fAlloc.reset(); 236 fAlloc.reset();
349 fList.reset(); 237 fList.reset();
350 fShiftUp = shiftUp; 238 fShiftUp = shiftUp;
351 fAnalyticAA = analyticAA;
352 239
353 if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) { 240 if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) {
354 return this->buildPoly(path, iclip, shiftUp, canCullToTheRight); 241 return this->buildPoly(path, iclip, shiftUp, canCullToTheRight);
355 } 242 }
356 243
357 SkAutoConicToQuads quadder; 244 SkAutoConicToQuads quadder;
358 const SkScalar conicTol = SK_Scalar1 / 4; 245 const SkScalar conicTol = SK_Scalar1 / 4;
359 246
360 SkPath::Iter iter(path, true); 247 SkPath::Iter iter(path, true);
361 SkPoint pts[4]; 248 SkPoint pts[4];
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 } 326 }
440 default: 327 default:
441 SkDEBUGFAIL("unexpected verb"); 328 SkDEBUGFAIL("unexpected verb");
442 break; 329 break;
443 } 330 }
444 } 331 }
445 } 332 }
446 fEdgeList = fList.begin(); 333 fEdgeList = fList.begin();
447 return fList.count(); 334 return fList.count();
448 } 335 }
OLDNEW
« no previous file with comments | « src/core/SkEdgeBuilder.h ('k') | src/core/SkScan.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698