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

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

Issue 692583002: WIP: GPU-accelerated trapezoidal path renderer. Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rename GrTrapezoidalPathRenderer -> GrAAConcavePathRenderer; swap MSAA support for a coverage ramp. Created 5 years, 3 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/SkStroke.h ('k') | src/gpu/GrAAConcavePathRenderer.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 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
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 7
8 #include "SkStrokerPriv.h" 8 #include "SkStrokerPriv.h"
9 #include "SkGeometry.h" 9 #include "SkGeometry.h"
10 #include "SkPathPriv.h" 10 #include "SkPathPriv.h"
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 fTangentEnd = parent->fTangentEnd; 112 fTangentEnd = parent->fTangentEnd;
113 fEndSet = true; 113 fEndSet = true;
114 return true; 114 return true;
115 } 115 }
116 }; 116 };
117 117
118 class SkPathStroker { 118 class SkPathStroker {
119 public: 119 public:
120 SkPathStroker(const SkPath& src, 120 SkPathStroker(const SkPath& src,
121 SkScalar radius, SkScalar miterLimit, SkPaint::Cap, 121 SkScalar radius, SkScalar miterLimit, SkPaint::Cap,
122 SkPaint::Join, SkScalar resScale); 122 SkPaint::Join, SkScalar resScale, bool autoClose, bool reverse Inner);
123 123
124 bool hasOnlyMoveTo() const { return 0 == fSegmentCount; } 124 bool hasOnlyMoveTo() const { return 0 == fSegmentCount; }
125 SkPoint moveToPt() const { return fFirstPt; } 125 SkPoint moveToPt() const { return fFirstPt; }
126 126
127 void moveTo(const SkPoint&); 127 void moveTo(const SkPoint&);
128 void lineTo(const SkPoint&); 128 void lineTo(const SkPoint&);
129 void quadTo(const SkPoint&, const SkPoint&); 129 void quadTo(const SkPoint&, const SkPoint&);
130 void conicTo(const SkPoint&, const SkPoint&, SkScalar weight); 130 void conicTo(const SkPoint&, const SkPoint&, SkScalar weight);
131 void cubicTo(const SkPoint&, const SkPoint&, const SkPoint&); 131 void cubicTo(const SkPoint&, const SkPoint&, const SkPoint&);
132 void close(bool isLine) { this->finishContour(true, isLine); } 132 void close(bool isLine) { this->finishContour(true, isLine); }
133 133
134 void done(SkPath* dst, bool isLine) { 134 void done(SkPath* dst, bool isLine) {
135 this->finishContour(false, isLine); 135 this->finishContour(fAutoClose, isLine);
136 fOuter.addPath(fExtra); 136 fOuter.addPath(fExtra);
137 dst->swap(fOuter); 137 dst->swap(fOuter);
138 } 138 }
139 139
140 SkScalar getResScale() const { return fResScale; } 140 SkScalar getResScale() const { return fResScale; }
141 141
142 private: 142 private:
143 SkScalar fRadius; 143 SkScalar fRadius;
144 SkScalar fInvMiterLimit; 144 SkScalar fInvMiterLimit;
145 SkScalar fResScale; 145 SkScalar fResScale;
146 SkScalar fInvResScale; 146 SkScalar fInvResScale;
147 SkScalar fInvResScaleSquared; 147 SkScalar fInvResScaleSquared;
148 148
149 SkVector fFirstNormal, fPrevNormal, fFirstUnitNormal, fPrevUnitNormal; 149 SkVector fFirstNormal, fPrevNormal, fFirstUnitNormal, fPrevUnitNormal;
150 SkPoint fFirstPt, fPrevPt; // on original path 150 SkPoint fFirstPt, fPrevPt; // on original path
151 SkPoint fFirstOuterPt; 151 SkPoint fFirstOuterPt;
152 int fSegmentCount; 152 int fSegmentCount;
153 bool fPrevIsLine; 153 bool fPrevIsLine;
154 bool fAutoClose;
155 bool fReverseInner;
154 156
155 SkStrokerPriv::CapProc fCapper; 157 SkStrokerPriv::CapProc fCapper;
156 SkStrokerPriv::JoinProc fJoiner; 158 SkStrokerPriv::JoinProc fJoiner;
157 159
158 SkPath fInner, fOuter; // outer is our working answer, inner is temp 160 SkPath fInner, fOuter; // outer is our working answer, inner is temp
159 SkPath fExtra; // added as extra complete contours 161 SkPath fExtra; // added as extra complete contours
160 162
161 enum StrokeType { 163 enum StrokeType {
162 kOuter_StrokeType = 1, // use sign-opposite values later to flip pe rpendicular axis 164 kOuter_StrokeType = 1, // use sign-opposite values later to flip pe rpendicular axis
163 kInner_StrokeType = -1 165 kInner_StrokeType = -1
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 282
281 void SkPathStroker::finishContour(bool close, bool currIsLine) { 283 void SkPathStroker::finishContour(bool close, bool currIsLine) {
282 if (fSegmentCount > 0) { 284 if (fSegmentCount > 0) {
283 SkPoint pt; 285 SkPoint pt;
284 286
285 if (close) { 287 if (close) {
286 fJoiner(&fOuter, &fInner, fPrevUnitNormal, fPrevPt, 288 fJoiner(&fOuter, &fInner, fPrevUnitNormal, fPrevPt,
287 fFirstUnitNormal, fRadius, fInvMiterLimit, 289 fFirstUnitNormal, fRadius, fInvMiterLimit,
288 fPrevIsLine, currIsLine); 290 fPrevIsLine, currIsLine);
289 fOuter.close(); 291 fOuter.close();
290 // now add fInner as its own contour 292 if (fReverseInner) {
291 fInner.getLastPt(&pt); 293 // now add fInner as its own contour
292 fOuter.moveTo(pt.fX, pt.fY); 294 fInner.getLastPt(&pt);
293 fOuter.reversePathTo(fInner); 295 fOuter.moveTo(pt.fX, pt.fY);
296 fOuter.reversePathTo(fInner);
297 } else {
298 fOuter.addPath(fInner);
299 }
294 fOuter.close(); 300 fOuter.close();
295 } else { // add caps to start and end 301 } else { // add caps to start and end
296 // cap the end 302 if (fReverseInner) {
297 fInner.getLastPt(&pt); 303 // cap the end
298 fCapper(&fOuter, fPrevPt, fPrevNormal, pt, 304 fInner.getLastPt(&pt);
299 currIsLine ? &fInner : nullptr); 305 fCapper(&fOuter, fPrevPt, fPrevNormal, pt,
300 fOuter.reversePathTo(fInner); 306 currIsLine ? &fInner : nullptr);
301 // cap the start 307 fOuter.reversePathTo(fInner);
302 fCapper(&fOuter, fFirstPt, -fFirstNormal, fFirstOuterPt, 308 // cap the start
303 fPrevIsLine ? &fInner : nullptr); 309 fCapper(&fOuter, fFirstPt, -fFirstNormal, fFirstOuterPt,
304 fOuter.close(); 310 fPrevIsLine ? &fInner : nullptr);
311 fOuter.close();
312 } else {
313 fOuter.addPath(fInner);
314 }
305 } 315 }
306 } 316 }
307 // since we may re-use fInner, we rewind instead of reset, to save on 317 // since we may re-use fInner, we rewind instead of reset, to save on
308 // reallocating its internal storage. 318 // reallocating its internal storage.
309 fInner.rewind(); 319 fInner.rewind();
310 fSegmentCount = -1; 320 fSegmentCount = -1;
311 } 321 }
312 322
313 /////////////////////////////////////////////////////////////////////////////// 323 ///////////////////////////////////////////////////////////////////////////////
314 324
315 SkPathStroker::SkPathStroker(const SkPath& src, 325 SkPathStroker::SkPathStroker(const SkPath& src,
316 SkScalar radius, SkScalar miterLimit, 326 SkScalar radius, SkScalar miterLimit,
317 SkPaint::Cap cap, SkPaint::Join join, SkScalar resS cale) 327 SkPaint::Cap cap, SkPaint::Join join, SkScalar resS cale,
328 bool autoClose, bool reverseInner)
318 : fRadius(radius) 329 : fRadius(radius)
319 , fResScale(resScale) { 330 , fResScale(resScale)
331 , fAutoClose(autoClose)
332 , fReverseInner(reverseInner) {
320 333
321 /* This is only used when join is miter_join, but we initialize it here 334 /* This is only used when join is miter_join, but we initialize it here
322 so that it is always defined, to fis valgrind warnings. 335 so that it is always defined, to fis valgrind warnings.
323 */ 336 */
324 fInvMiterLimit = 0; 337 fInvMiterLimit = 0;
325 338
326 if (join == SkPaint::kMiter_Join) { 339 if (join == SkPaint::kMiter_Join) {
327 if (miterLimit <= SK_Scalar1) { 340 if (miterLimit <= SK_Scalar1) {
328 join = SkPaint::kBevel_Join; 341 join = SkPaint::kBevel_Join;
329 } else { 342 } else {
(...skipping 17 matching lines...) Expand all
347 fInner.setIsVolatile(true); 360 fInner.setIsVolatile(true);
348 // TODO : write a common error function used by stroking and filling 361 // TODO : write a common error function used by stroking and filling
349 // The '4' below matches the fill scan converter's error term 362 // The '4' below matches the fill scan converter's error term
350 fInvResScale = SkScalarInvert(resScale * 4); 363 fInvResScale = SkScalarInvert(resScale * 4);
351 fInvResScaleSquared = fInvResScale * fInvResScale; 364 fInvResScaleSquared = fInvResScale * fInvResScale;
352 fRecursionDepth = 0; 365 fRecursionDepth = 0;
353 } 366 }
354 367
355 void SkPathStroker::moveTo(const SkPoint& pt) { 368 void SkPathStroker::moveTo(const SkPoint& pt) {
356 if (fSegmentCount > 0) { 369 if (fSegmentCount > 0) {
357 this->finishContour(false, false); 370 this->finishContour(fAutoClose, false);
358 } 371 }
359 fSegmentCount = 0; 372 fSegmentCount = 0;
360 fFirstPt = fPrevPt = pt; 373 fFirstPt = fPrevPt = pt;
361 } 374 }
362 375
363 void SkPathStroker::line_to(const SkPoint& currPt, const SkVector& normal) { 376 void SkPathStroker::line_to(const SkPoint& currPt, const SkVector& normal) {
364 fOuter.lineTo(currPt.fX + normal.fX, currPt.fY + normal.fY); 377 fOuter.lineTo(currPt.fX + normal.fX, currPt.fY + normal.fY);
365 fInner.lineTo(currPt.fX - normal.fX, currPt.fY - normal.fY); 378 fInner.lineTo(currPt.fX - normal.fX, currPt.fY - normal.fY);
366 } 379 }
367 380
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 /////////////////////////////////////////////////////////////////////////////// 1230 ///////////////////////////////////////////////////////////////////////////////
1218 1231
1219 #include "SkPaintDefaults.h" 1232 #include "SkPaintDefaults.h"
1220 1233
1221 SkStroke::SkStroke() { 1234 SkStroke::SkStroke() {
1222 fWidth = SK_Scalar1; 1235 fWidth = SK_Scalar1;
1223 fMiterLimit = SkPaintDefaults_MiterLimit; 1236 fMiterLimit = SkPaintDefaults_MiterLimit;
1224 fCap = SkPaint::kDefault_Cap; 1237 fCap = SkPaint::kDefault_Cap;
1225 fJoin = SkPaint::kDefault_Join; 1238 fJoin = SkPaint::kDefault_Join;
1226 fDoFill = false; 1239 fDoFill = false;
1240 fAutoClose = false;
1241 fReverseInner = true;
1227 } 1242 }
1228 1243
1229 SkStroke::SkStroke(const SkPaint& p) { 1244 SkStroke::SkStroke(const SkPaint& p) {
1230 fWidth = p.getStrokeWidth(); 1245 fWidth = p.getStrokeWidth();
1231 fMiterLimit = p.getStrokeMiter(); 1246 fMiterLimit = p.getStrokeMiter();
1232 fCap = (uint8_t)p.getStrokeCap(); 1247 fCap = (uint8_t)p.getStrokeCap();
1233 fJoin = (uint8_t)p.getStrokeJoin(); 1248 fJoin = (uint8_t)p.getStrokeJoin();
1234 fDoFill = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style); 1249 fDoFill = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style);
1250 fAutoClose = false;
1251 fReverseInner = true;
1235 } 1252 }
1236 1253
1237 SkStroke::SkStroke(const SkPaint& p, SkScalar width) { 1254 SkStroke::SkStroke(const SkPaint& p, SkScalar width) {
1238 fWidth = width; 1255 fWidth = width;
1239 fMiterLimit = p.getStrokeMiter(); 1256 fMiterLimit = p.getStrokeMiter();
1240 fCap = (uint8_t)p.getStrokeCap(); 1257 fCap = (uint8_t)p.getStrokeCap();
1241 fJoin = (uint8_t)p.getStrokeJoin(); 1258 fJoin = (uint8_t)p.getStrokeJoin();
1242 fDoFill = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style); 1259 fDoFill = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style);
1260 fAutoClose = false;
1261 fReverseInner = true;
1243 } 1262 }
1244 1263
1245 void SkStroke::setWidth(SkScalar width) { 1264 void SkStroke::setWidth(SkScalar width) {
1246 SkASSERT(width >= 0); 1265 SkASSERT(width >= 0);
1247 fWidth = width; 1266 fWidth = width;
1248 } 1267 }
1249 1268
1250 void SkStroke::setMiterLimit(SkScalar miterLimit) { 1269 void SkStroke::setMiterLimit(SkScalar miterLimit) {
1251 SkASSERT(miterLimit >= 0); 1270 SkASSERT(miterLimit >= 0);
1252 fMiterLimit = miterLimit; 1271 fMiterLimit = miterLimit;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 this->strokeRect(rect, dst, dir); 1329 this->strokeRect(rect, dst, dir);
1311 // our answer should preserve the inverseness of the src 1330 // our answer should preserve the inverseness of the src
1312 if (src.isInverseFillType()) { 1331 if (src.isInverseFillType()) {
1313 SkASSERT(!dst->isInverseFillType()); 1332 SkASSERT(!dst->isInverseFillType());
1314 dst->toggleInverseFillType(); 1333 dst->toggleInverseFillType();
1315 } 1334 }
1316 return; 1335 return;
1317 } 1336 }
1318 } 1337 }
1319 1338
1320 SkPathStroker stroker(src, radius, fMiterLimit, this->getCap(), this->getJ oin(), fResScale); 1339 SkPathStroker stroker(src, radius, fMiterLimit, this->getCap(), this->getJ oin(), fResScale, this->getAutoClose(), this->getReverseInner());
1321 SkPath::Iter iter(src, false); 1340 SkPath::Iter iter(src, false);
1322 SkPath::Verb lastSegment = SkPath::kMove_Verb; 1341 SkPath::Verb lastSegment = SkPath::kMove_Verb;
1323 1342
1324 for (;;) { 1343 for (;;) {
1325 SkPoint pts[4]; 1344 SkPoint pts[4];
1326 switch (iter.next(pts, false)) { 1345 switch (iter.next(pts, false)) {
1327 case SkPath::kMove_Verb: 1346 case SkPath::kMove_Verb:
1328 stroker.moveTo(pts[0]); 1347 stroker.moveTo(pts[0]);
1329 break; 1348 break;
1330 case SkPath::kLine_Verb: 1349 case SkPath::kLine_Verb:
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 case SkPaint::kRound_Join: 1485 case SkPaint::kRound_Join:
1467 dst->addRoundRect(r, radius, radius, dir); 1486 dst->addRoundRect(r, radius, radius, dir);
1468 break; 1487 break;
1469 default: 1488 default:
1470 break; 1489 break;
1471 } 1490 }
1472 1491
1473 if (fWidth < SkMinScalar(rw, rh) && !fDoFill) { 1492 if (fWidth < SkMinScalar(rw, rh) && !fDoFill) {
1474 r = rect; 1493 r = rect;
1475 r.inset(radius, radius); 1494 r.inset(radius, radius);
1476 dst->addRect(r, reverse_direction(dir)); 1495 dst->addRect(r, this->getReverseInner() ? reverse_direction(dir) : dir);
1477 } 1496 }
1478 } 1497 }
OLDNEW
« no previous file with comments | « src/core/SkStroke.h ('k') | src/gpu/GrAAConcavePathRenderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698