OLD | NEW |
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 | 7 |
8 #include "GrDefaultPathRenderer.h" | 8 #include "GrDefaultPathRenderer.h" |
9 | 9 |
10 #include "GrContext.h" | 10 #include "GrContext.h" |
11 #include "GrDefaultGeoProcFactory.h" | 11 #include "GrDefaultGeoProcFactory.h" |
12 #include "GrDrawState.h" | 12 #include "GrDrawState.h" |
13 #include "GrPathUtils.h" | 13 #include "GrPathUtils.h" |
| 14 #include "SkGeometry.h" |
14 #include "SkString.h" | 15 #include "SkString.h" |
15 #include "SkStrokeRec.h" | 16 #include "SkStrokeRec.h" |
16 #include "SkTLazy.h" | 17 #include "SkTLazy.h" |
17 #include "SkTraceEvent.h" | 18 #include "SkTraceEvent.h" |
18 | 19 |
19 | |
20 GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport, | 20 GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport, |
21 bool stencilWrapOpsSupport) | 21 bool stencilWrapOpsSupport) |
22 : fSeparateStencil(separateStencilSupport) | 22 : fSeparateStencil(separateStencilSupport) |
23 , fStencilWrapOps(stencilWrapOpsSupport) { | 23 , fStencilWrapOps(stencilWrapOpsSupport) { |
24 } | 24 } |
25 | 25 |
26 | 26 |
27 //////////////////////////////////////////////////////////////////////////////// | 27 //////////////////////////////////////////////////////////////////////////////// |
28 // Stencil rules for paths | 28 // Stencil rules for paths |
29 | 29 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 // when drawing lines we're appending line segments along | 182 // when drawing lines we're appending line segments along |
183 // the contour. When applying the other fill rules we're | 183 // the contour. When applying the other fill rules we're |
184 // drawing triangle fans around fanCenterIdx. | 184 // drawing triangle fans around fanCenterIdx. |
185 if (!hairLine) { | 185 if (!hairLine) { |
186 *((*indices)++) = fanCenterIdx; | 186 *((*indices)++) = fanCenterIdx; |
187 } | 187 } |
188 *((*indices)++) = edgeV0Idx; | 188 *((*indices)++) = edgeV0Idx; |
189 *((*indices)++) = edgeV0Idx + 1; | 189 *((*indices)++) = edgeV0Idx + 1; |
190 } | 190 } |
191 | 191 |
| 192 static inline void add_quad(SkPoint** vert, const SkPoint* base, const SkPoint p
ts[], |
| 193 SkScalar srcSpaceTolSqd, SkScalar srcSpaceTol, bool
indexed, |
| 194 bool isHairline, uint16_t subpathIdxStart, uint16_t*
* idx) { |
| 195 // first pt of quad is the pt we ended on in previous step |
| 196 uint16_t firstQPtIdx = (uint16_t)(*vert - base) - 1; |
| 197 uint16_t numPts = (uint16_t) |
| 198 GrPathUtils::generateQuadraticPoints( |
| 199 pts[0], pts[1], pts[2], |
| 200 srcSpaceTolSqd, vert, |
| 201 GrPathUtils::quadraticPointCount(pts, srcSpaceTol)); |
| 202 if (indexed) { |
| 203 for (uint16_t i = 0; i < numPts; ++i) { |
| 204 append_countour_edge_indices(isHairline, subpathIdxStart, |
| 205 firstQPtIdx + i, idx); |
| 206 } |
| 207 } |
| 208 } |
| 209 |
192 bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target, | 210 bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target, |
193 GrDrawState* drawState, | 211 GrDrawState* drawState, |
194 GrPrimitiveType* primType, | 212 GrPrimitiveType* primType, |
195 int* vertexCnt, | 213 int* vertexCnt, |
196 int* indexCnt, | 214 int* indexCnt, |
197 GrDrawTarget::AutoReleaseGeometry* arg, | 215 GrDrawTarget::AutoReleaseGeometry* arg, |
198 const SkPath& path, | 216 const SkPath& path, |
199 const SkStrokeRec& stroke, | 217 const SkStrokeRec& stroke, |
200 SkScalar srcSpaceTol) { | 218 SkScalar srcSpaceTol) { |
201 { | 219 { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 SkPoint pts[4]; | 267 SkPoint pts[4]; |
250 | 268 |
251 bool first = true; | 269 bool first = true; |
252 int subpath = 0; | 270 int subpath = 0; |
253 | 271 |
254 SkPath::Iter iter(path, false); | 272 SkPath::Iter iter(path, false); |
255 | 273 |
256 for (;;) { | 274 for (;;) { |
257 SkPath::Verb verb = iter.next(pts); | 275 SkPath::Verb verb = iter.next(pts); |
258 switch (verb) { | 276 switch (verb) { |
259 case SkPath::kConic_Verb: | |
260 SkASSERT(0); | |
261 break; | |
262 case SkPath::kMove_Verb: | 277 case SkPath::kMove_Verb: |
263 if (!first) { | 278 if (!first) { |
264 uint16_t currIdx = (uint16_t) (vert - base); | 279 uint16_t currIdx = (uint16_t) (vert - base); |
265 subpathIdxStart = currIdx; | 280 subpathIdxStart = currIdx; |
266 ++subpath; | 281 ++subpath; |
267 } | 282 } |
268 *vert = pts[0]; | 283 *vert = pts[0]; |
269 vert++; | 284 vert++; |
270 break; | 285 break; |
271 case SkPath::kLine_Verb: | 286 case SkPath::kLine_Verb: |
272 if (indexed) { | 287 if (indexed) { |
273 uint16_t prevIdx = (uint16_t)(vert - base) - 1; | 288 uint16_t prevIdx = (uint16_t)(vert - base) - 1; |
274 append_countour_edge_indices(isHairline, subpathIdxStart, | 289 append_countour_edge_indices(isHairline, subpathIdxStart, |
275 prevIdx, &idx); | 290 prevIdx, &idx); |
276 } | 291 } |
277 *(vert++) = pts[1]; | 292 *(vert++) = pts[1]; |
278 break; | 293 break; |
279 case SkPath::kQuad_Verb: { | 294 case SkPath::kConic_Verb: { |
280 // first pt of quad is the pt we ended on in previous step | 295 SkScalar weight = iter.conicWeight(); |
281 uint16_t firstQPtIdx = (uint16_t)(vert - base) - 1; | 296 SkAutoConicToQuads converter; |
282 uint16_t numPts = (uint16_t) | 297 // Converting in src-space, hance the finer tolerance (0.25) |
283 GrPathUtils::generateQuadraticPoints( | 298 // TODO: find a way to do this in dev-space so the tolerance mea
ns something |
284 pts[0], pts[1], pts[2], | 299 const SkPoint* quadPts = converter.computeQuads(pts, weight, 0.2
5f); |
285 srcSpaceTolSqd, &vert, | 300 for (int i = 0; i < converter.countQuads(); ++i) { |
286 GrPathUtils::quadraticPointCount(pts, srcSpaceTol)); | 301 add_quad(&vert, base, quadPts + i*2, srcSpaceTolSqd, srcSpac
eTol, indexed, |
287 if (indexed) { | 302 isHairline, subpathIdxStart, &idx); |
288 for (uint16_t i = 0; i < numPts; ++i) { | |
289 append_countour_edge_indices(isHairline, subpathIdxStart
, | |
290 firstQPtIdx + i, &idx); | |
291 } | |
292 } | 303 } |
293 break; | 304 break; |
294 } | 305 } |
| 306 case SkPath::kQuad_Verb: |
| 307 add_quad(&vert, base, pts, srcSpaceTolSqd, srcSpaceTol, indexed, |
| 308 isHairline, subpathIdxStart, &idx); |
| 309 break; |
295 case SkPath::kCubic_Verb: { | 310 case SkPath::kCubic_Verb: { |
296 // first pt of cubic is the pt we ended on in previous step | 311 // first pt of cubic is the pt we ended on in previous step |
297 uint16_t firstCPtIdx = (uint16_t)(vert - base) - 1; | 312 uint16_t firstCPtIdx = (uint16_t)(vert - base) - 1; |
298 uint16_t numPts = (uint16_t) GrPathUtils::generateCubicPoints( | 313 uint16_t numPts = (uint16_t) GrPathUtils::generateCubicPoints( |
299 pts[0], pts[1], pts[2], pts[3], | 314 pts[0], pts[1], pts[2], pts[3], |
300 srcSpaceTolSqd, &vert, | 315 srcSpaceTolSqd, &vert, |
301 GrPathUtils::cubicPointCount(pts, srcSpaceTol)); | 316 GrPathUtils::cubicPointCount(pts, srcSpaceTol)); |
302 if (indexed) { | 317 if (indexed) { |
303 for (uint16_t i = 0; i < numPts; ++i) { | 318 for (uint16_t i = 0; i < numPts; ++i) { |
304 append_countour_edge_indices(isHairline, subpathIdxStart
, | 319 append_countour_edge_indices(isHairline, subpathIdxStart
, |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 return true; | 538 return true; |
524 } | 539 } |
525 | 540 |
526 bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target, | 541 bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target, |
527 const GrDrawState* drawState, | 542 const GrDrawState* drawState, |
528 const SkMatrix& viewMatrix, | 543 const SkMatrix& viewMatrix, |
529 const SkPath& path, | 544 const SkPath& path, |
530 const SkStrokeRec& stroke, | 545 const SkStrokeRec& stroke, |
531 bool antiAlias) const { | 546 bool antiAlias) const { |
532 // this class can draw any path with any fill but doesn't do any anti-aliasi
ng. | 547 // this class can draw any path with any fill but doesn't do any anti-aliasi
ng. |
533 | 548 return !antiAlias && (stroke.isFillStyle() || IsStrokeHairlineOrEquivalent(s
troke, |
534 return !antiAlias && !(SkPath::kConic_SegmentMask & path.getSegmentMasks())
&& | 549 v
iewMatrix, |
535 (stroke.isFillStyle() || IsStrokeHairlineOrEquivalent(stroke, viewMatrix
, NULL)); | 550 N
ULL)); |
536 } | 551 } |
537 | 552 |
538 bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, | 553 bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, |
539 GrDrawState* drawState, | 554 GrDrawState* drawState, |
540 GrColor color, | 555 GrColor color, |
541 const SkMatrix& viewMatrix, | 556 const SkMatrix& viewMatrix, |
542 const SkPath& path, | 557 const SkPath& path, |
543 const SkStrokeRec& stroke, | 558 const SkStrokeRec& stroke, |
544 bool antiAlias) { | 559 bool antiAlias) { |
545 return this->internalDrawPath(target, | 560 return this->internalDrawPath(target, |
546 drawState, | 561 drawState, |
547 color, | 562 color, |
548 viewMatrix, | 563 viewMatrix, |
549 path, | 564 path, |
550 stroke, | 565 stroke, |
551 false); | 566 false); |
552 } | 567 } |
553 | 568 |
554 void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target, | 569 void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target, |
555 GrDrawState* drawState, | 570 GrDrawState* drawState, |
556 const SkMatrix& viewMatrix, | 571 const SkMatrix& viewMatrix, |
557 const SkPath& path, | 572 const SkPath& path, |
558 const SkStrokeRec& stroke) { | 573 const SkStrokeRec& stroke) { |
559 SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); | 574 SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); |
560 SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); | 575 SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); |
561 this->internalDrawPath(target, drawState, GrColor_WHITE, viewMatrix, path, s
troke, true); | 576 this->internalDrawPath(target, drawState, GrColor_WHITE, viewMatrix, path, s
troke, true); |
562 } | 577 } |
OLD | NEW |