Index: src/gpu/GrAAFlatteningConvexTessellator.cpp |
diff --git a/src/gpu/GrAAConvexTessellator.cpp b/src/gpu/GrAAFlatteningConvexTessellator.cpp |
similarity index 73% |
copy from src/gpu/GrAAConvexTessellator.cpp |
copy to src/gpu/GrAAFlatteningConvexTessellator.cpp |
index 5a1e4c2dfedcc56671ca4e80ddb01a34ba5b1919..8aca476d6c45e98e468f222455da8f09d73bc58c 100644 |
--- a/src/gpu/GrAAConvexTessellator.cpp |
+++ b/src/gpu/GrAAFlatteningConvexTessellator.cpp |
@@ -5,11 +5,12 @@ |
* found in the LICENSE file. |
*/ |
-#include "GrAAConvexTessellator.h" |
+#include "GrAAFlatteningConvexTessellator.h" |
#include "SkCanvas.h" |
#include "SkPath.h" |
#include "SkPoint.h" |
#include "SkString.h" |
+#include "GrPathUtils.h" |
// Next steps: |
// use in AAConvexPathRenderer |
@@ -49,21 +50,23 @@ static SkScalar abs_dist_from_line(const SkPoint& p0, const SkVector& v, const S |
return SkScalarAbs(dist); |
} |
-int GrAAConvexTessellator::addPt(const SkPoint& pt, |
+int GrAAFlatteningConvexTessellator::addPt(const SkPoint& pt, |
robertphillips
2015/05/27 18:10:54
line these guys up ?
|
SkScalar depth, |
- bool movable) { |
+ bool movable, |
+ bool isCurve) { |
this->validate(); |
int index = fPts.count(); |
*fPts.push() = pt; |
*fDepths.push() = depth; |
*fMovable.push() = movable; |
+ *fIsCurve.push() = isCurve; |
this->validate(); |
return index; |
} |
-void GrAAConvexTessellator::popLastPt() { |
+void GrAAFlatteningConvexTessellator::popLastPt() { |
this->validate(); |
fPts.pop(); |
@@ -73,7 +76,7 @@ void GrAAConvexTessellator::popLastPt() { |
this->validate(); |
} |
-void GrAAConvexTessellator::popFirstPtShuffle() { |
+void GrAAFlatteningConvexTessellator::popFirstPtShuffle() { |
this->validate(); |
fPts.removeShuffle(0); |
@@ -83,7 +86,7 @@ void GrAAConvexTessellator::popFirstPtShuffle() { |
this->validate(); |
} |
-void GrAAConvexTessellator::updatePt(int index, |
+void GrAAFlatteningConvexTessellator::updatePt(int index, |
robertphillips
2015/05/27 18:10:54
line up ?
|
const SkPoint& pt, |
SkScalar depth) { |
this->validate(); |
@@ -93,7 +96,7 @@ void GrAAConvexTessellator::updatePt(int index, |
fDepths[index] = depth; |
} |
-void GrAAConvexTessellator::addTri(int i0, int i1, int i2) { |
+void GrAAFlatteningConvexTessellator::addTri(int i0, int i1, int i2) { |
if (i0 == i1 || i1 == i2 || i2 == i0) { |
return; |
} |
@@ -103,7 +106,7 @@ void GrAAConvexTessellator::addTri(int i0, int i1, int i2) { |
*fIndices.push() = i2; |
} |
-void GrAAConvexTessellator::rewind() { |
+void GrAAFlatteningConvexTessellator::rewind() { |
fPts.rewind(); |
fDepths.rewind(); |
fMovable.rewind(); |
@@ -111,7 +114,7 @@ void GrAAConvexTessellator::rewind() { |
fNorms.rewind(); |
fInitialRing.rewind(); |
fCandidateVerts.rewind(); |
-#if GR_AA_CONVEX_TESSELLATOR_VIZ |
+#if GR_AA_FLATTENING_CONVEX_TESSELLATOR_VIZ |
fRings.rewind(); // TODO: leak in this case! |
#else |
fRings[0].rewind(); |
@@ -119,7 +122,7 @@ void GrAAConvexTessellator::rewind() { |
#endif |
} |
-void GrAAConvexTessellator::computeBisectors() { |
+void GrAAFlatteningConvexTessellator::computeBisectors() { |
fBisectors.setCount(fNorms.count()); |
int prev = fBisectors.count() - 1; |
@@ -143,11 +146,11 @@ void GrAAConvexTessellator::computeBisectors() { |
// The general idea here is to, conceptually, start with the original polygon and slide |
// the vertices along the bisectors until the first intersection. At that |
// point two of the edges collapse and the process repeats on the new polygon. |
-// The polygon state is captured in the Ring class while the GrAAConvexTessellator |
+// The polygon state is captured in the Ring class while the GrAAFlatteningConvexTessellator |
// controls the iteration. The CandidateVerts holds the formative points for the |
// next ring. |
-bool GrAAConvexTessellator::tessellate(const SkMatrix& m, const SkPath& path) { |
- static const int kMaxNumRings = 8; |
+bool GrAAFlatteningConvexTessellator::tessellate(const SkMatrix& m, const SkPath& path) { |
+ static const int kMaxNumRings = 1; |
SkDEBUGCODE(fShouldCheckDepths = true;) |
@@ -190,7 +193,7 @@ bool GrAAConvexTessellator::tessellate(const SkMatrix& m, const SkPath& path) { |
return true; |
} |
-SkScalar GrAAConvexTessellator::computeDepthFromEdge(int edgeIdx, const SkPoint& p) const { |
+SkScalar GrAAFlatteningConvexTessellator::computeDepthFromEdge(int edgeIdx, const SkPoint& p) const { |
SkASSERT(edgeIdx < fNorms.count()); |
SkPoint v = p - fPts[edgeIdx]; |
@@ -201,7 +204,7 @@ SkScalar GrAAConvexTessellator::computeDepthFromEdge(int edgeIdx, const SkPoint& |
// Find a point that is 'desiredDepth' away from the 'edgeIdx'-th edge and lies |
// along the 'bisector' from the 'startIdx'-th point. |
-bool GrAAConvexTessellator::computePtAlongBisector(int startIdx, |
+bool GrAAFlatteningConvexTessellator::computePtAlongBisector(int startIdx, |
robertphillips
2015/05/27 18:10:54
line up ?
|
const SkVector& bisector, |
int edgeIdx, |
SkScalar desiredDepth, |
@@ -235,8 +238,7 @@ bool GrAAConvexTessellator::computePtAlongBisector(int startIdx, |
return true; |
} |
-bool GrAAConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& path) { |
- SkASSERT(SkPath::kLine_SegmentMask == path.getSegmentMasks()); |
+bool GrAAFlatteningConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& path) { |
SkASSERT(SkPath::kConvex_Convexity == path.getConvexity()); |
// Outer ring: 3*numPts |
@@ -250,8 +252,6 @@ bool GrAAConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& pat |
fNorms.setReserve(path.countPoints()); |
- SkScalar minCross = SK_ScalarMax, maxCross = -SK_ScalarMax; |
- |
// TODO: is there a faster way to extract the points from the path? Perhaps |
// get all the points via a new entry point, transform them all in bulk |
// and then walk them to find duplicates? |
@@ -261,38 +261,16 @@ bool GrAAConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& pat |
while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
switch (verb) { |
case SkPath::kLine_Verb: |
- m.mapPoints(&pts[1], 1); |
- if (this->numPts() > 0 && duplicate_pt(pts[1], this->lastPoint())) { |
- continue; |
- } |
- |
- SkASSERT(fPts.count() <= 1 || fPts.count() == fNorms.count()+1); |
- if (this->numPts() >= 2 && |
- abs_dist_from_line(fPts.top(), fNorms.top(), pts[1]) < kClose) { |
- // The old last point is on the line from the second to last to the new point |
- this->popLastPt(); |
- fNorms.pop(); |
- } |
- |
- this->addPt(pts[1], 0.0f, false); |
- if (this->numPts() > 1) { |
- *fNorms.push() = fPts.top() - fPts[fPts.count()-2]; |
- SkDEBUGCODE(SkScalar len =) SkPoint::Normalize(&fNorms.top()); |
- SkASSERT(len > 0.0f); |
- SkASSERT(SkScalarNearlyEqual(1.0f, fNorms.top().length())); |
- } |
- |
- if (this->numPts() >= 3) { |
- int cur = this->numPts()-1; |
- SkScalar cross = SkPoint::CrossProduct(fNorms[cur-1], fNorms[cur-2]); |
- maxCross = SkTMax(maxCross, cross); |
- minCross = SkTMin(minCross, cross); |
- } |
+ lineTo(m, pts[1], false); |
bsalomon
2015/05/27 17:11:07
style nit, for (non-static) method calls we prefix
ethannicholas
2015/05/27 19:22:30
Done.
|
break; |
case SkPath::kQuad_Verb: |
- case SkPath::kConic_Verb: |
+ quadTo(m, pts); |
+ break; |
case SkPath::kCubic_Verb: |
- SkASSERT(false); |
+ cubicTo(m, pts); |
+ break; |
+ case SkPath::kConic_Verb: |
+ conicTo(m, pts, iter.conicWeight()); |
break; |
case SkPath::kMove_Verb: |
case SkPath::kClose_Verb: |
@@ -344,14 +322,9 @@ bool GrAAConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& pat |
// Check the cross produce of the final trio |
SkScalar cross = SkPoint::CrossProduct(fNorms[0], fNorms.top()); |
robertphillips
2015/05/27 18:10:54
Hmmm ...
ethannicholas
2015/05/27 19:22:30
The work to compute the min & max cross products s
|
- maxCross = SkTMax(maxCross, cross); |
- minCross = SkTMin(minCross, cross); |
- |
- if (maxCross > 0.0f) { |
- SkASSERT(minCross >= 0.0f); |
+ if (cross > 0.0f) { |
fSide = SkPoint::kRight_Side; |
} else { |
- SkASSERT(minCross <= 0.0f); |
fSide = SkPoint::kLeft_Side; |
} |
@@ -374,8 +347,8 @@ bool GrAAConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& pat |
return true; |
} |
-GrAAConvexTessellator::Ring* GrAAConvexTessellator::getNextRing(Ring* lastRing) { |
-#if GR_AA_CONVEX_TESSELLATOR_VIZ |
+GrAAFlatteningConvexTessellator::Ring* GrAAFlatteningConvexTessellator::getNextRing(Ring* lastRing) { |
+#if GR_AA_FLATTENING_CONVEX_TESSELLATOR_VIZ |
Ring* ring = *fRings.push() = SkNEW(Ring); |
ring->setReserve(fInitialRing.numPts()); |
ring->rewind(); |
@@ -389,14 +362,14 @@ GrAAConvexTessellator::Ring* GrAAConvexTessellator::getNextRing(Ring* lastRing) |
#endif |
} |
-void GrAAConvexTessellator::fanRing(const Ring& ring) { |
+void GrAAFlatteningConvexTessellator::fanRing(const Ring& ring) { |
// fan out from point 0 |
for (int cur = 1; cur < ring.numPts()-1; ++cur) { |
this->addTri(ring.index(0), ring.index(cur), ring.index(cur+1)); |
} |
} |
-void GrAAConvexTessellator::createOuterRing() { |
+void GrAAFlatteningConvexTessellator::createOuterRing() { |
// For now, we're only generating one outer ring (at the start). This |
// could be relaxed for stroking use cases. |
SkASSERT(0 == fIndices.count()); |
@@ -404,76 +377,108 @@ void GrAAConvexTessellator::createOuterRing() { |
const int numPts = fPts.count(); |
- // For each vertex of the original polygon we add three points to the |
- // outset polygon - one extending perpendicular to each impinging edge |
- // and one along the bisector. Two triangles are added for each corner |
- // and two are added along each edge. |
int prev = numPts - 1; |
int lastPerpIdx = -1, firstPerpIdx = -1, newIdx0, newIdx1, newIdx2; |
for (int cur = 0; cur < numPts; ++cur) { |
- // The perpendicular point for the last edge |
- SkPoint temp = fNorms[prev]; |
- temp.scale(fTargetDepth); |
- temp += fPts[cur]; |
- |
- // 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) |
- newIdx0 = this->addPt(temp, -fTargetDepth, false); |
- |
- // The bisector outset point |
- temp = fBisectors[cur]; |
- temp.scale(-fTargetDepth); // the bisectors point in |
- temp += fPts[cur]; |
- |
- // For very shallow angles all the corner points could fuse |
- if (duplicate_pt(temp, this->point(newIdx0))) { |
- newIdx1 = newIdx0; |
- } else { |
- newIdx1 = this->addPt(temp, -fTargetDepth, false); |
+ if (fIsCurve[cur]) { |
+ // Inside a curve, we assume that the curvature is shallow enough (due to tesselation) |
+ // that we only need one corner point. Mathematically, the distance the corner point |
+ // gets shifted out should depend on the angle between the two line segments (as in |
+ // mitering), but again due to tesselation we assume that this angle is small and |
+ // therefore the correction factor is negligible and we do not bother with it. |
bsalomon
2015/05/27 17:11:07
Is it reasonable to have an assert that verifies t
ethannicholas
2015/05/27 19:22:30
Done.
|
+ |
+ // The bisector outset point |
+ SkPoint temp = fBisectors[cur]; |
+ temp.scale(-fTargetDepth); // the bisectors point in |
+ temp += fPts[cur]; |
+ |
+ newIdx1 = this->addPt(temp, -fTargetDepth, false, true); |
+ |
+ if (0 == cur) { |
+ // Store the index of the first perpendicular point to finish up |
+ firstPerpIdx = newIdx1; |
+ SkASSERT(-1 == lastPerpIdx); |
+ } else { |
+ // The triangles for the previous edge |
+ this->addTri(prev, newIdx1, cur); |
+ this->addTri(prev, lastPerpIdx, newIdx1); |
+ } |
+ |
+ prev = cur; |
+ // Track the last perpendicular outset point so we can construct the |
+ // trailing edge triangles. |
+ lastPerpIdx = newIdx1; |
} |
- |
- // The perpendicular point for the next edge. |
- temp = fNorms[cur]; |
- temp.scale(fTargetDepth); |
- temp += fPts[cur]; |
- |
- // For very shallow angles all the corner points could fuse. |
- if (duplicate_pt(temp, this->point(newIdx1))) { |
- newIdx2 = newIdx1; |
- } else { |
- newIdx2 = this->addPt(temp, -fTargetDepth, false); |
+ else { |
+ // For each vertex of the original polygon we add three points to the |
+ // outset polygon - one extending perpendicular to each impinging edge |
+ // and one along the bisector. Two triangles are added for each corner |
+ // and two are added along each edge. |
+ |
+ // The perpendicular point for the last edge |
+ SkPoint temp = fNorms[prev]; |
+ temp.scale(fTargetDepth); |
+ temp += fPts[cur]; |
+ |
+ // 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) |
+ newIdx0 = this->addPt(temp, -fTargetDepth, false, false); |
+ |
+ // The bisector outset point |
+ temp = fBisectors[cur]; |
+ temp.scale(-fTargetDepth); // the bisectors point in |
+ temp += fPts[cur]; |
+ |
+ // For very shallow angles all the corner points could fuse |
+ if (duplicate_pt(temp, this->point(newIdx0))) { |
+ newIdx1 = newIdx0; |
+ } else { |
+ newIdx1 = this->addPt(temp, -fTargetDepth, false, false); |
+ } |
+ |
+ // The perpendicular point for the next edge. |
+ temp = fNorms[cur]; |
+ temp.scale(fTargetDepth); |
+ temp += fPts[cur]; |
+ |
+ // For very shallow angles all the corner points could fuse. |
+ if (duplicate_pt(temp, this->point(newIdx1))) { |
+ newIdx2 = newIdx1; |
+ } else { |
+ newIdx2 = this->addPt(temp, -fTargetDepth, false, false); |
+ } |
+ |
+ if (0 == cur) { |
+ // Store the index of the first perpendicular point to finish up |
+ firstPerpIdx = newIdx0; |
+ SkASSERT(-1 == lastPerpIdx); |
+ } else { |
+ // The triangles for the previous edge |
+ this->addTri(prev, newIdx0, cur); |
+ this->addTri(prev, lastPerpIdx, newIdx0); |
+ } |
+ |
+ // The two triangles for the corner |
+ this->addTri(cur, newIdx0, newIdx1); |
+ this->addTri(cur, newIdx1, newIdx2); |
+ |
+ prev = cur; |
+ // Track the last perpendicular outset point so we can construct the |
+ // trailing edge triangles. |
+ lastPerpIdx = newIdx2; |
} |
- |
- if (0 == cur) { |
- // Store the index of the first perpendicular point to finish up |
- firstPerpIdx = newIdx0; |
- SkASSERT(-1 == lastPerpIdx); |
- } else { |
- // The triangles for the previous edge |
- this->addTri(prev, newIdx0, cur); |
- this->addTri(prev, lastPerpIdx, newIdx0); |
- } |
- |
- // The two triangles for the corner |
- this->addTri(cur, newIdx0, newIdx1); |
- this->addTri(cur, newIdx1, newIdx2); |
- |
- prev = cur; |
- // Track the last perpendicular outset point so we can construct the |
- // trailing edge triangles. |
- lastPerpIdx = newIdx2; |
} |
// pick up the final edge rect |
- this->addTri(numPts-1, firstPerpIdx, 0); |
- this->addTri(numPts-1, lastPerpIdx, firstPerpIdx); |
+ this->addTri(numPts - 1, firstPerpIdx, 0); |
+ this->addTri(numPts - 1, lastPerpIdx, firstPerpIdx); |
this->validate(); |
} |
// Something went wrong in the creation of the next ring. Mark the last good |
// ring as being at the desired depth and fan it. |
-void GrAAConvexTessellator::terminate(const Ring& ring) { |
+void GrAAFlatteningConvexTessellator::terminate(const Ring& ring) { |
for (int i = 0; i < ring.numPts(); ++i) { |
fDepths[ring.index(i)] = fTargetDepth; |
} |
@@ -482,7 +487,7 @@ void GrAAConvexTessellator::terminate(const Ring& ring) { |
} |
// return true when processing is complete |
-bool GrAAConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing) { |
+bool GrAAFlatteningConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing) { |
bool done = false; |
fCandidateVerts.rewind(); |
@@ -592,7 +597,7 @@ bool GrAAConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing |
// if the originating index is still valid then this point wasn't |
// fused (and is thus movable) |
newIdx = this->addPt(fCandidateVerts.point(i), depth, |
- fCandidateVerts.originatingIdx(i) != -1); |
+ fCandidateVerts.originatingIdx(i) != -1, false); |
} else { |
SkASSERT(fCandidateVerts.originatingIdx(i) != -1); |
this->updatePt(fCandidateVerts.originatingIdx(i), fCandidateVerts.point(i), depth); |
@@ -626,20 +631,20 @@ bool GrAAConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing |
return done; |
} |
-void GrAAConvexTessellator::validate() const { |
+void GrAAFlatteningConvexTessellator::validate() const { |
SkASSERT(fPts.count() == fDepths.count()); |
SkASSERT(fPts.count() == fMovable.count()); |
SkASSERT(0 == (fIndices.count() % 3)); |
} |
////////////////////////////////////////////////////////////////////////////// |
-void GrAAConvexTessellator::Ring::init(const GrAAConvexTessellator& tess) { |
+void GrAAFlatteningConvexTessellator::Ring::init(const GrAAFlatteningConvexTessellator& tess) { |
this->computeNormals(tess); |
this->computeBisectors(tess); |
SkASSERT(this->isConvex(tess)); |
} |
-void GrAAConvexTessellator::Ring::init(const SkTDArray<SkVector>& norms, |
+void GrAAFlatteningConvexTessellator::Ring::init(const SkTDArray<SkVector>& norms, |
const SkTDArray<SkVector>& bisectors) { |
for (int i = 0; i < fPts.count(); ++i) { |
fPts[i].fNorm = norms[i]; |
@@ -648,7 +653,7 @@ void GrAAConvexTessellator::Ring::init(const SkTDArray<SkVector>& norms, |
} |
// Compute the outward facing normal at each vertex. |
-void GrAAConvexTessellator::Ring::computeNormals(const GrAAConvexTessellator& tess) { |
+void GrAAFlatteningConvexTessellator::Ring::computeNormals(const GrAAFlatteningConvexTessellator& tess) { |
for (int cur = 0; cur < fPts.count(); ++cur) { |
int next = (cur + 1) % fPts.count(); |
@@ -661,7 +666,7 @@ void GrAAConvexTessellator::Ring::computeNormals(const GrAAConvexTessellator& te |
} |
} |
-void GrAAConvexTessellator::Ring::computeBisectors(const GrAAConvexTessellator& tess) { |
+void GrAAFlatteningConvexTessellator::Ring::computeBisectors(const GrAAFlatteningConvexTessellator& tess) { |
int prev = fPts.count() - 1; |
for (int cur = 0; cur < fPts.count(); prev = cur, ++cur) { |
fPts[cur].fBisector = fPts[cur].fNorm + fPts[prev].fNorm; |
@@ -683,7 +688,7 @@ void GrAAConvexTessellator::Ring::computeBisectors(const GrAAConvexTessellator& |
////////////////////////////////////////////////////////////////////////////// |
#ifdef SK_DEBUG |
// Is this ring convex? |
-bool GrAAConvexTessellator::Ring::isConvex(const GrAAConvexTessellator& tess) const { |
+bool GrAAFlatteningConvexTessellator::Ring::isConvex(const GrAAFlatteningConvexTessellator& tess) const { |
if (fPts.count() < 3) { |
return false; |
} |
@@ -739,7 +744,7 @@ static SkScalar capsule_depth(const SkPoint& p0, const SkPoint& p1, |
return perpDist; |
} |
-SkScalar GrAAConvexTessellator::computeRealDepth(const SkPoint& p) const { |
+SkScalar GrAAFlatteningConvexTessellator::computeRealDepth(const SkPoint& p) const { |
SkScalar minDist = SK_ScalarMax; |
int closestSign, sign; |
@@ -759,7 +764,7 @@ SkScalar GrAAConvexTessellator::computeRealDepth(const SkPoint& p) const { |
} |
// Verify that the incrementally computed depths are close to the actual depths. |
-void GrAAConvexTessellator::checkAllDepths() const { |
+void GrAAFlatteningConvexTessellator::checkAllDepths() const { |
for (int cur = 0; cur < this->numPts(); ++cur) { |
SkScalar realDepth = this->computeRealDepth(this->point(cur)); |
SkScalar computedDepth = this->depth(cur); |
@@ -768,8 +773,78 @@ void GrAAConvexTessellator::checkAllDepths() const { |
} |
#endif |
+#define kQuadTolerance 0.2f |
+#define kCubicTolerance 0.2f |
+#define kConicTolerance 0.5f |
+ |
+void GrAAFlatteningConvexTessellator::lineTo(const SkMatrix& m, SkPoint p, bool isCurve) { |
+ m.mapPoints(&p, 1); |
+ if (this->numPts() > 0 && duplicate_pt(p, this->lastPoint())) { |
+ return; |
+ } |
+ |
+ SkASSERT(fPts.count() <= 1 || fPts.count() == fNorms.count()+1); |
+ if (this->numPts() >= 2 && |
+ abs_dist_from_line(fPts.top(), fNorms.top(), p) < kClose) { |
+ // The old last point is on the line from the second to last to the new point |
+ this->popLastPt(); |
+ fNorms.pop(); |
+ fIsCurve.pop(); |
+ } |
+ this->addPt(p, 0.0f, false, isCurve); |
+ if (this->numPts() > 1) { |
+ *fNorms.push() = fPts.top() - fPts[fPts.count()-2]; |
+ SkDEBUGCODE(SkScalar len =) SkPoint::Normalize(&fNorms.top()); |
+ SkASSERT(len > 0.0f); |
+ SkASSERT(SkScalarNearlyEqual(1.0f, fNorms.top().length())); |
+ } |
+} |
+ |
+void GrAAFlatteningConvexTessellator::quadTo(const SkMatrix& m, SkPoint* pts) { |
+ int maxCount = GrPathUtils::quadraticPointCount(pts, kQuadTolerance); |
+ fPointBuffer.setReserve(maxCount); |
+ SkPoint* target = fPointBuffer.begin(); |
+ int count = GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2], |
+ kQuadTolerance, &target, maxCount); |
+ fPointBuffer.setCount(count); |
+ for (int i = 0; i < count; i++) { |
+ lineTo(m, fPointBuffer[i], true); |
+ } |
+} |
+ |
+void GrAAFlatteningConvexTessellator::cubicTo(const SkMatrix& m, SkPoint* pts) { |
+ int maxCount = GrPathUtils::cubicPointCount(pts, kCubicTolerance); |
+ fPointBuffer.setReserve(maxCount); |
+ SkPoint* target = fPointBuffer.begin(); |
+ 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(m, fPointBuffer[i], true); |
+ } |
+} |
+ |
+// include down here to avoid compilation errors caused by "-" overload in SkGeometry.h |
bsalomon
2015/05/27 17:11:07
What's the error?
ethannicholas
2015/05/27 19:22:30
In file included from ../../src/gpu/GrAAFlattening
|
+#include "SkGeometry.h" |
+ |
+void GrAAFlatteningConvexTessellator::conicTo(const SkMatrix& m, SkPoint* pts, SkScalar w) { |
+ SkAutoConicToQuads quadder; |
+ const SkPoint* quads = quadder.computeQuads(pts, w, kConicTolerance); |
+ SkPoint lastPoint = *(quads++); |
+ int count = quadder.countQuads(); |
+ for (int i = 0; i < count; ++i) { |
+ SkPoint quadPts[3]; |
+ quadPts[0] = lastPoint; |
+ quadPts[1] = quads[0]; |
+ quadPts[2] = i == count - 1 ? pts[2] : quads[1]; |
+ quadTo(m, quadPts); |
+ lastPoint = quadPts[2]; |
+ quads += 2; |
+ } |
+} |
+ |
////////////////////////////////////////////////////////////////////////////// |
-#if GR_AA_CONVEX_TESSELLATOR_VIZ |
+#if GR_AA_FLATTENING_CONVEX_TESSELLATOR_VIZ |
static const SkScalar kPointRadius = 0.02f; |
static const SkScalar kArrowStrokeWidth = 0.0f; |
static const SkScalar kArrowLength = 0.2f; |
@@ -812,7 +887,7 @@ static void draw_arrow(SkCanvas*canvas, const SkPoint& p, const SkPoint &n, |
paint); |
} |
-void GrAAConvexTessellator::Ring::draw(SkCanvas* canvas, const GrAAConvexTessellator& tess) const { |
+void GrAAFlatteningConvexTessellator::Ring::draw(SkCanvas* canvas, const GrAAFlatteningConvexTessellator& tess) const { |
bsalomon
2015/05/27 17:11:07
nit, 100 col wrap
ethannicholas
2015/05/27 19:22:30
Done.
|
SkPaint paint; |
paint.setTextSize(kEdgeTextSize); |
@@ -844,7 +919,7 @@ void GrAAConvexTessellator::Ring::draw(SkCanvas* canvas, const GrAAConvexTessell |
} |
} |
-void GrAAConvexTessellator::draw(SkCanvas* canvas) const { |
+void GrAAFlatteningConvexTessellator::draw(SkCanvas* canvas) const { |
for (int i = 0; i < fIndices.count(); i += 3) { |
SkASSERT(fIndices[i] < this->numPts()) ; |
SkASSERT(fIndices[i+1] < this->numPts()) ; |