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

Unified Diff: src/gpu/GrAAFlatteningConvexTessellator.cpp

Issue 1158803002: Added GrAAFlatteningConvexPathRenderer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: hopefully fixed windows build issues Created 5 years, 7 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
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()) ;

Powered by Google App Engine
This is Rietveld 408576698