| 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 |