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

Unified Diff: src/gpu/batches/GrAAConvexTessellator.cpp

Issue 2280943003: fixed 'corners' of paths in GrAAConvexTessellator (Closed)
Patch Set: oops Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/batches/GrAAConvexTessellator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/batches/GrAAConvexTessellator.cpp
diff --git a/src/gpu/batches/GrAAConvexTessellator.cpp b/src/gpu/batches/GrAAConvexTessellator.cpp
index 7e28d24e9339f35d92263b66bd27f025c5793f9f..2c069f634205a385b991ac9f091105aac14d1b7f 100644
--- a/src/gpu/batches/GrAAConvexTessellator.cpp
+++ b/src/gpu/batches/GrAAConvexTessellator.cpp
@@ -29,6 +29,9 @@ static const SkScalar kConicTolerance = 0.5f;
// dot product below which we use a round cap between curve segments
static const SkScalar kRoundCapThreshold = 0.8f;
+// dot product above which we consider two adjacent curves to be part of the "same" curve
+static const SkScalar kCurveConnectionThreshold = 0.95f;
+
static SkScalar intersect(const SkPoint& p0, const SkPoint& n0,
const SkPoint& p1, const SkPoint& n1) {
const SkPoint v = p1 - p0;
@@ -60,14 +63,14 @@ int GrAAConvexTessellator::addPt(const SkPoint& pt,
SkScalar depth,
SkScalar coverage,
bool movable,
- bool isCurve) {
+ CurveState curve) {
this->validate();
int index = fPts.count();
*fPts.push() = pt;
*fCoverages.push() = coverage;
*fMovable.push() = movable;
- *fIsCurve.push() = isCurve;
+ *fCurveState.push() = curve;
this->validate();
return index;
@@ -146,6 +149,19 @@ void GrAAConvexTessellator::computeBisectors() {
} else {
fBisectors[cur].negate(); // make the bisector face in
}
+ if (fCurveState[prev] == kIndeterminate_CurveState) {
+ if (fCurveState[cur] == kSharp_CurveState) {
+ fCurveState[prev] = kSharp_CurveState;
+ } else {
+ if (SkScalarAbs(fNorms[cur].dot(fNorms[prev])) > kCurveConnectionThreshold) {
+ fCurveState[prev] = kCurve_CurveState;
+ fCurveState[cur] = kCurve_CurveState;
+ } else {
+ fCurveState[prev] = kSharp_CurveState;
+ fCurveState[cur] = kSharp_CurveState;
+ }
+ }
+ }
SkASSERT(SkScalarNearlyEqual(1.0f, fBisectors[cur].length()));
}
@@ -304,7 +320,7 @@ bool GrAAConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& pat
while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
switch (verb) {
case SkPath::kLine_Verb:
- this->lineTo(m, pts[1], false);
+ this->lineTo(m, pts[1], kSharp_CurveState);
break;
case SkPath::kQuad_Verb:
this->quadTo(m, pts);
@@ -461,11 +477,11 @@ void GrAAConvexTessellator::createOuterRing(const Ring& previousRing, SkScalar o
perp2.scale(outset);
perp2 += fPts[originalIdx];
- bool isCurve = fIsCurve[originalIdx];
+ CurveState curve = fCurveState[originalIdx];
// We know it isn't a duplicate of the prior point (since it and this
// one are just perpendicular offsets from the non-merged polygon points)
- int perp1Idx = this->addPt(perp1, -outset, coverage, false, isCurve);
+ int perp1Idx = this->addPt(perp1, -outset, coverage, false, curve);
nextRing->addIdx(perp1Idx, originalIdx);
int perp2Idx;
@@ -473,11 +489,11 @@ void GrAAConvexTessellator::createOuterRing(const Ring& previousRing, SkScalar o
if (duplicate_pt(perp2, this->point(perp1Idx))) {
perp2Idx = perp1Idx;
} else {
- perp2Idx = this->addPt(perp2, -outset, coverage, false, isCurve);
+ perp2Idx = this->addPt(perp2, -outset, coverage, false, curve);
}
if (perp2Idx != perp1Idx) {
- if (isCurve) {
+ if (curve == kCurve_CurveState) {
// bevel or round depending upon curvature
SkScalar dotProd = normal1.dot(normal2);
if (dotProd < kRoundCapThreshold) {
@@ -492,7 +508,7 @@ void GrAAConvexTessellator::createOuterRing(const Ring& previousRing, SkScalar o
// For very shallow angles all the corner points could fuse
if (!duplicate_pt(miter, this->point(perp1Idx))) {
int miterIdx;
- miterIdx = this->addPt(miter, -outset, coverage, false, false);
+ miterIdx = this->addPt(miter, -outset, coverage, false, kSharp_CurveState);
nextRing->addIdx(miterIdx, originalIdx);
// The two triangles for the corner
this->addTri(originalIdx, perp1Idx, miterIdx);
@@ -520,7 +536,8 @@ void GrAAConvexTessellator::createOuterRing(const Ring& previousRing, SkScalar o
// For very shallow angles all the corner points could fuse
if (!duplicate_pt(miter, this->point(perp1Idx))) {
int miterIdx;
- miterIdx = this->addPt(miter, -outset, coverage, false, false);
+ miterIdx = this->addPt(miter, -outset, coverage, false,
+ kSharp_CurveState);
nextRing->addIdx(miterIdx, originalIdx);
// The two triangles for the corner
this->addTri(originalIdx, perp1Idx, miterIdx);
@@ -704,7 +721,7 @@ bool GrAAConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing
SkScalar coverage = compute_coverage(depth, initialDepth, initialCoverage,
targetDepth, targetCoverage);
newIdx = this->addPt(fCandidateVerts.point(i), depth, coverage,
- fCandidateVerts.originatingIdx(i) != -1, false);
+ fCandidateVerts.originatingIdx(i) != -1, kSharp_CurveState);
} else {
SkASSERT(fCandidateVerts.originatingIdx(i) != -1);
this->updatePt(fCandidateVerts.originatingIdx(i), fCandidateVerts.point(i), depth,
@@ -823,7 +840,7 @@ bool GrAAConvexTessellator::Ring::isConvex(const GrAAConvexTessellator& tess) co
#endif
-void GrAAConvexTessellator::lineTo(SkPoint p, bool isCurve) {
+void GrAAConvexTessellator::lineTo(SkPoint p, CurveState curve) {
if (this->numPts() > 0 && duplicate_pt(p, this->lastPoint())) {
return;
}
@@ -834,7 +851,7 @@ void GrAAConvexTessellator::lineTo(SkPoint p, bool isCurve) {
// The old last point is on the line from the second to last to the new point
this->popLastPt();
fNorms.pop();
- fIsCurve.pop();
+ fCurveState.pop();
// double-check that the new last point is not a duplicate of the new point. In an ideal
// world this wouldn't be necessary (since it's only possible for non-convex paths), but
// floating point precision issues mean it can actually happen on paths that were determined
@@ -844,7 +861,7 @@ void GrAAConvexTessellator::lineTo(SkPoint p, bool isCurve) {
}
}
SkScalar initialRingCoverage = fStrokeWidth < 0.0f ? 0.5f : 1.0f;
- this->addPt(p, 0.0f, initialRingCoverage, false, isCurve);
+ this->addPt(p, 0.0f, initialRingCoverage, false, curve);
if (this->numPts() > 1) {
*fNorms.push() = fPts.top() - fPts[fPts.count()-2];
SkDEBUGCODE(SkScalar len =) SkPoint::Normalize(&fNorms.top());
@@ -853,9 +870,9 @@ void GrAAConvexTessellator::lineTo(SkPoint p, bool isCurve) {
}
}
-void GrAAConvexTessellator::lineTo(const SkMatrix& m, SkPoint p, bool isCurve) {
+void GrAAConvexTessellator::lineTo(const SkMatrix& m, SkPoint p, CurveState curve) {
m.mapPoints(&p, 1);
- this->lineTo(p, isCurve);
+ this->lineTo(p, curve);
}
void GrAAConvexTessellator::quadTo(SkPoint pts[3]) {
@@ -865,9 +882,10 @@ void GrAAConvexTessellator::quadTo(SkPoint pts[3]) {
int count = GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2],
kQuadTolerance, &target, maxCount);
fPointBuffer.setCount(count);
- for (int i = 0; i < count; i++) {
- lineTo(fPointBuffer[i], true);
+ for (int i = 0; i < count - 1; i++) {
+ lineTo(fPointBuffer[i], kCurve_CurveState);
}
+ lineTo(fPointBuffer[count - 1], kIndeterminate_CurveState);
}
void GrAAConvexTessellator::quadTo(const SkMatrix& m, SkPoint pts[3]) {
@@ -887,9 +905,10 @@ void GrAAConvexTessellator::cubicTo(const SkMatrix& m, SkPoint pts[4]) {
int count = GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3],
kCubicTolerance, &target, maxCount);
fPointBuffer.setCount(count);
- for (int i = 0; i < count; i++) {
- lineTo(fPointBuffer[i], true);
+ for (int i = 0; i < count - 1; i++) {
+ lineTo(fPointBuffer[i], kCurve_CurveState);
}
+ lineTo(fPointBuffer[count - 1], kIndeterminate_CurveState);
}
// include down here to avoid compilation errors caused by "-" overload in SkGeometry.h
« no previous file with comments | « src/gpu/batches/GrAAConvexTessellator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698