ccpr: Fix a couple issues with tessellation and winding

Bug: skia:
Change-Id: I7c7851230e0ed19719b06e833cbf45c0ef78ddae
Reviewed-on: https://skia-review.googlesource.com/107908
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
Chris Dalton 2018-02-15 12:27:29 -07:00 committed by Skia Commit-Bot
parent 06f593cd13
commit 45e46604bb
2 changed files with 23 additions and 17 deletions

View File

@ -107,7 +107,6 @@ void GrCCPathParser::parsePath(const SkPath& path, const SkPoint* deviceSpacePts
fCurrPathPointsIdx = fGeometry.points().count();
fCurrPathVerbsIdx = fGeometry.verbs().count();
fCurrPathPrimitiveCounts = PrimitiveTallies();
fCurrPathFillType = path.getFillType();
fGeometry.beginPath();
@ -177,9 +176,11 @@ void GrCCPathParser::saveParsedPath(ScissorMode scissorMode, const SkIRect& clip
const SkTArray<SkPoint, true>& pts = fGeometry.points();
int ptsIdx = fCurrPathPointsIdx;
// Build an SkPath of the Redbook fan.
// Build an SkPath of the Redbook fan. We use "winding" fill type right now because we are
// producing a coverage count, and must fill in every region that has non-zero wind. The
// path processor will convert coverage count to the appropriate fill type later.
SkPath fan;
fan.setFillType(fCurrPathFillType);
fan.setFillType(SkPath::kWinding_FillType);
SkASSERT(GrCCGeometry::Verb::kBeginPath == verbs[fCurrPathVerbsIdx]);
for (int i = fCurrPathVerbsIdx + 1; i < fGeometry.verbs().count(); ++i) {
switch (verbs[i]) {
@ -216,18 +217,23 @@ void GrCCPathParser::saveParsedPath(ScissorMode scissorMode, const SkIRect& clip
SkRect::Make(clippedDevIBounds), &vertices);
SkASSERT(0 == count % 3);
for (int i = 0; i < count; i += 3) {
SkASSERT(vertices[i].fWinding == vertices[i + 1].fWinding);
SkASSERT(vertices[i].fWinding == vertices[i + 2].fWinding);
if (1 == abs(vertices[i].fWinding)) {
// Ensure this triangle's points actually wind in the same direction as fWinding.
float ax = vertices[i].fPos.fX - vertices[i + 1].fPos.fX;
float ay = vertices[i].fPos.fY - vertices[i + 1].fPos.fY;
float bx = vertices[i].fPos.fX - vertices[i + 2].fPos.fX;
float by = vertices[i].fPos.fY - vertices[i + 2].fPos.fY;
float wind = ay*bx - ax*by;
if ((wind > 0) != (vertices[i].fWinding > 0)) {
std::swap(vertices[i + 1].fPos, vertices[i + 2].fPos);
}
int tessWinding = vertices[i].fWinding;
SkASSERT(tessWinding == vertices[i + 1].fWinding);
SkASSERT(tessWinding == vertices[i + 2].fWinding);
// Ensure this triangle's points actually wind in the same direction as tessWinding.
// CCPR shaders use the sign of wind to determine which direction to bloat, so even for
// "wound" triangles the winding sign and point ordering need to agree.
float ax = vertices[i].fPos.fX - vertices[i + 1].fPos.fX;
float ay = vertices[i].fPos.fY - vertices[i + 1].fPos.fY;
float bx = vertices[i].fPos.fX - vertices[i + 2].fPos.fX;
float by = vertices[i].fPos.fY - vertices[i + 2].fPos.fY;
float wind = ax*by - ay*bx;
if ((wind > 0) != (-tessWinding > 0)) { // Tessellator has opposite winding sense.
std::swap(vertices[i + 1].fPos, vertices[i + 2].fPos);
}
if (1 == abs(tessWinding)) {
++fCurrPathPrimitiveCounts.fTriangles;
} else {
++fCurrPathPrimitiveCounts.fWoundTriangles;
@ -328,7 +334,8 @@ static void emit_tessellated_fan(const GrTessellator::WindingVertex* vertices, i
} else {
quadPointInstanceData[indices->fWoundTriangles++].set(
vertices[i].fPos, vertices[i+1].fPos, vertices[i + 2].fPos, atlasOffset,
static_cast<float>(vertices[i].fWinding));
// Tessellator has opposite winding sense.
-static_cast<float>(vertices[i].fWinding));
}
}
}

View File

@ -114,7 +114,6 @@ private:
int fCurrPathPointsIdx;
int fCurrPathVerbsIdx;
PrimitiveTallies fCurrPathPrimitiveCounts;
SkPath::FillType fCurrPathFillType;
GrCCGeometry fGeometry;
SkSTArray<32, PathInfo, true> fPathsInfo;