OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAAHairLinePathRenderer.h" | 9 #include "GrAAHairLinePathRenderer.h" |
10 | 10 |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 IntArray* quadSubdivCnts) { | 210 IntArray* quadSubdivCnts) { |
211 SkPath::Iter iter(path, false); | 211 SkPath::Iter iter(path, false); |
212 | 212 |
213 int totalQuadCount = 0; | 213 int totalQuadCount = 0; |
214 GrRect bounds; | 214 GrRect bounds; |
215 GrIRect ibounds; | 215 GrIRect ibounds; |
216 | 216 |
217 bool persp = m.hasPerspective(); | 217 bool persp = m.hasPerspective(); |
218 | 218 |
219 for (;;) { | 219 for (;;) { |
220 GrPoint pts[4]; | 220 GrPoint pathPts[4]; |
221 GrPoint devPts[4]; | 221 GrPoint devPts[4]; |
222 SkPath::Verb verb = iter.next(pts); | 222 SkPath::Verb verb = iter.next(pathPts); |
223 switch (verb) { | 223 switch (verb) { |
224 case SkPath::kMove_Verb: | 224 case SkPath::kMove_Verb: |
225 break; | 225 break; |
226 case SkPath::kLine_Verb: | 226 case SkPath::kLine_Verb: |
227 m.mapPoints(devPts, pts, 2); | 227 m.mapPoints(devPts, pathPts, 2); |
228 bounds.setBounds(devPts, 2); | 228 bounds.setBounds(devPts, 2); |
229 bounds.outset(SK_Scalar1, SK_Scalar1); | 229 bounds.outset(SK_Scalar1, SK_Scalar1); |
230 bounds.roundOut(&ibounds); | 230 bounds.roundOut(&ibounds); |
231 if (SkIRect::Intersects(devClipBounds, ibounds)) { | 231 if (SkIRect::Intersects(devClipBounds, ibounds)) { |
232 SkPoint* pts = lines->push_back_n(2); | 232 SkPoint* pts = lines->push_back_n(2); |
233 pts[0] = devPts[0]; | 233 pts[0] = devPts[0]; |
234 pts[1] = devPts[1]; | 234 pts[1] = devPts[1]; |
235 } | 235 } |
236 break; | 236 break; |
237 case SkPath::kQuad_Verb: | 237 case SkPath::kQuad_Verb: { |
238 m.mapPoints(devPts, pts, 3); | 238 SkPoint choppedPts[5]; |
239 bounds.setBounds(devPts, 3); | 239 // Chopping the quad helps when the quad is either degenerate or
nearly degenerate. |
240 bounds.outset(SK_Scalar1, SK_Scalar1); | 240 // When it is degenerate it allows the approximation with lines
to work since the |
241 bounds.roundOut(&ibounds); | 241 // chop point (if there is one) will be at the parabola's vertex
. In the nearly |
242 if (SkIRect::Intersects(devClipBounds, ibounds)) { | 242 // degenerate the QuadUVMatrix computed for the points is almost
singular which |
243 int subdiv = num_quad_subdivs(devPts); | 243 // can cause rendering artifacts. |
244 GrAssert(subdiv >= -1); | 244 int n = SkChopQuadAtMaxCurvature(pathPts, choppedPts); |
245 if (-1 == subdiv) { | 245 for (int i = 0; i < n; ++i) { |
246 SkPoint* pts = lines->push_back_n(4); | 246 SkPoint* quadPts = choppedPts + i * 2; |
247 pts[0] = devPts[0]; | 247 m.mapPoints(devPts, quadPts, 3); |
248 pts[1] = devPts[1]; | 248 bounds.setBounds(devPts, 3); |
249 pts[2] = devPts[1]; | 249 bounds.outset(SK_Scalar1, SK_Scalar1); |
250 pts[3] = devPts[2]; | 250 bounds.roundOut(&ibounds); |
251 } else { | 251 |
252 // when in perspective keep quads in src space | 252 if (SkIRect::Intersects(devClipBounds, ibounds)) { |
253 SkPoint* qPts = persp ? pts : devPts; | 253 int subdiv = num_quad_subdivs(devPts); |
254 SkPoint* pts = quads->push_back_n(3); | 254 GrAssert(subdiv >= -1); |
255 pts[0] = qPts[0]; | 255 if (-1 == subdiv) { |
256 pts[1] = qPts[1]; | 256 SkPoint* pts = lines->push_back_n(4); |
257 pts[2] = qPts[2]; | 257 pts[0] = devPts[0]; |
258 quadSubdivCnts->push_back() = subdiv; | 258 pts[1] = devPts[1]; |
259 totalQuadCount += 1 << subdiv; | 259 pts[2] = devPts[1]; |
| 260 pts[3] = devPts[2]; |
| 261 } else { |
| 262 // when in perspective keep quads in src space |
| 263 SkPoint* qPts = persp ? quadPts : devPts; |
| 264 SkPoint* pts = quads->push_back_n(3); |
| 265 pts[0] = qPts[0]; |
| 266 pts[1] = qPts[1]; |
| 267 pts[2] = qPts[2]; |
| 268 quadSubdivCnts->push_back() = subdiv; |
| 269 totalQuadCount += 1 << subdiv; |
| 270 } |
260 } | 271 } |
261 } | 272 } |
262 break; | 273 break; |
| 274 } |
263 case SkPath::kCubic_Verb: | 275 case SkPath::kCubic_Verb: |
264 m.mapPoints(devPts, pts, 4); | 276 m.mapPoints(devPts, pathPts, 4); |
265 bounds.setBounds(devPts, 4); | 277 bounds.setBounds(devPts, 4); |
266 bounds.outset(SK_Scalar1, SK_Scalar1); | 278 bounds.outset(SK_Scalar1, SK_Scalar1); |
267 bounds.roundOut(&ibounds); | 279 bounds.roundOut(&ibounds); |
268 if (SkIRect::Intersects(devClipBounds, ibounds)) { | 280 if (SkIRect::Intersects(devClipBounds, ibounds)) { |
269 PREALLOC_PTARRAY(32) q; | 281 PREALLOC_PTARRAY(32) q; |
270 // we don't need a direction if we aren't constraining the s
ubdivision | 282 // we don't need a direction if we aren't constraining the s
ubdivision |
271 static const SkPath::Direction kDummyDir = SkPath::kCCW_Dire
ction; | 283 static const SkPath::Direction kDummyDir = SkPath::kCCW_Dire
ction; |
272 // We convert cubics to quadratics (for now). | 284 // We convert cubics to quadratics (for now). |
273 // In perspective have to do conversion in src space. | 285 // In perspective have to do conversion in src space. |
274 if (persp) { | 286 if (persp) { |
275 SkScalar tolScale = | 287 SkScalar tolScale = |
276 GrPathUtils::scaleToleranceToSrc(SK_Scalar1, m, | 288 GrPathUtils::scaleToleranceToSrc(SK_Scalar1, m, |
277 path.getBounds()); | 289 path.getBounds()); |
278 GrPathUtils::convertCubicToQuads(pts, tolScale, false, k
DummyDir, &q); | 290 GrPathUtils::convertCubicToQuads(pathPts, tolScale, fals
e, kDummyDir, &q); |
279 } else { | 291 } else { |
280 GrPathUtils::convertCubicToQuads(devPts, SK_Scalar1, fal
se, kDummyDir, &q); | 292 GrPathUtils::convertCubicToQuads(devPts, SK_Scalar1, fal
se, kDummyDir, &q); |
281 } | 293 } |
282 for (int i = 0; i < q.count(); i += 3) { | 294 for (int i = 0; i < q.count(); i += 3) { |
283 SkPoint* qInDevSpace; | 295 SkPoint* qInDevSpace; |
284 // bounds has to be calculated in device space, but q is | 296 // bounds has to be calculated in device space, but q is |
285 // in src space when there is perspective. | 297 // in src space when there is perspective. |
286 if (persp) { | 298 if (persp) { |
287 m.mapPoints(devPts, &q[i], 3); | 299 m.mapPoints(devPts, &q[i], 3); |
288 bounds.setBounds(devPts, 3); | 300 bounds.setBounds(devPts, 3); |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 const SkPath& path, | 720 const SkPath& path, |
709 GrDrawTarget* target, | 721 GrDrawTarget* target, |
710 int* lineCnt, | 722 int* lineCnt, |
711 int* quadCnt, | 723 int* quadCnt, |
712 GrDrawTarget::AutoReleaseGeometry* arg, | 724 GrDrawTarget::AutoReleaseGeometry* arg, |
713 SkRect* devBounds) { | 725 SkRect* devBounds) { |
714 GrDrawState* drawState = target->drawState(); | 726 GrDrawState* drawState = target->drawState(); |
715 int rtHeight = drawState->getRenderTarget()->height(); | 727 int rtHeight = drawState->getRenderTarget()->height(); |
716 | 728 |
717 GrIRect devClipBounds; | 729 GrIRect devClipBounds; |
718 target->getClip()->getConservativeBounds(drawState->getRenderTarget(), | 730 target->getClip()->getConservativeBounds(drawState->getRenderTarget(), &devC
lipBounds); |
719 &devClipBounds); | |
720 | 731 |
721 SkMatrix viewM = drawState->getViewMatrix(); | 732 SkMatrix viewM = drawState->getViewMatrix(); |
722 | 733 |
723 // All the vertices that we compute are within 1 of path control points with
the exception of | 734 // All the vertices that we compute are within 1 of path control points with
the exception of |
724 // one of the bounding vertices for each quad. The add_quads() function will
update the bounds | 735 // one of the bounding vertices for each quad. The add_quads() function will
update the bounds |
725 // for each quad added. | 736 // for each quad added. |
726 *devBounds = path.getBounds(); | 737 *devBounds = path.getBounds(); |
727 viewM.mapRect(devBounds); | 738 viewM.mapRect(devBounds); |
728 devBounds->outset(SK_Scalar1, SK_Scalar1); | 739 devBounds->outset(SK_Scalar1, SK_Scalar1); |
729 | 740 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 0, // startI | 895 0, // startI |
885 kVertsPerQuad*n, // vCount | 896 kVertsPerQuad*n, // vCount |
886 kIdxsPerQuad*n, // iCount | 897 kIdxsPerQuad*n, // iCount |
887 &devBounds); | 898 &devBounds); |
888 quads += n; | 899 quads += n; |
889 } | 900 } |
890 target->resetIndexSource(); | 901 target->resetIndexSource(); |
891 | 902 |
892 return true; | 903 return true; |
893 } | 904 } |
OLD | NEW |