Use correct line->cubic for fixed-count stroke tessellation

Removes the (p0,p0,p1,p1) encoding of a line, to favor the 1/3,2/3
mixed form that the wedge path tessellator also uses. This has the
benefit of Wang's formula evaluating to 0 for a cubic of that form.

Change-Id: I4d86fcaf528c29288c4735f1cf8d9517654dd700
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/504417
Reviewed-by: Christopher Dalton <csmartdalton@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Michael Ludwig 2022-02-04 09:35:41 -05:00 committed by SkCQ
parent 0596094b81
commit 4eb6e56b19
3 changed files with 6 additions and 16 deletions

View File

@ -160,20 +160,14 @@ public:
skvx::bit_pun<float2>(pts[2]));
}
// TODO: Currently stroked lines are encoded as [p0,p0,p1,p1] and detected in the shaders;
// usage of this should be converted over to writeLineAsCubic() and that should be how all
// lines are handled w/o any need for shader detection.
AI void writeLine(float2 p0, float2 p1) {
this->writePatch(p0, p0, p1, p1, kCubicCurveType);
// Write a line that is automatically converted into an equivalent cubic.
AI void writeLine(float4 p0p1) {
this->writeCubic(p0p1.lo, (p0p1.zwxy() - p0p1) * (1/3.f) + p0p1, p0p1.hi);
}
AI void writeLine(float2 p0, float2 p1) { this->writeLine({p0, p1}); }
AI void writeLine(SkPoint p0, SkPoint p1) {
this->writeLine(skvx::bit_pun<float2>(p0), skvx::bit_pun<float2>(p1));
}
// Write a line that is automatically converted into an equivalent cubic.
AI void writeLineAsCubic(float4 p0p1) {
this->writeCubic(p0p1.lo, (p0p1.zwxy() - p0p1) * (1/3.f) + p0p1, p0p1.hi);
}
AI void writeLineAsCubic(float2 p0, float2 p1) { this->writeLineAsCubic({p0, p1}); }
// Write a triangle by setting it to a conic with w=Inf, and using a distinct
// explicit curve type for when inf isn't supported in shaders.

View File

@ -162,7 +162,7 @@ void PathWedgeTessellator::writePatches(PatchWriter& patchWriter,
case SkPathVerb::kLine: {
// Explicitly convert the line to an equivalent cubic w/ four distinct
// control points because it fans better and avoids double-hitting pixels.
patchWriter.writeLineAsCubic(m.map2Points(pts));
patchWriter.writeLine(m.map2Points(pts));
lastPoint = pts[1];
break;
}
@ -243,7 +243,7 @@ void PathWedgeTessellator::writePatches(PatchWriter& patchWriter,
}
if (lastPoint != startPoint) {
SkPoint pts[2] = {lastPoint, startPoint};
patchWriter.writeLineAsCubic(m.map2Points(pts));
patchWriter.writeLine(m.map2Points(pts));
}
}
}

View File

@ -124,10 +124,6 @@ void GrStrokeTessellationShader::InstancedImpl::onEmitCode(EmitArgs& args, GrGPA
} else {
numParametricSegments = wangs_formula_conic(PARAMETRIC_PRECISION, p0, p1, p2, w);
}
if (p0 == p1 && p2 == p3) {
// This is how we describe lines, but Wang's formula does not return 1 in this case.
numParametricSegments = 1;
}
// Find the starting and ending tangents.
float2 tan0 = ((p0 == p1) ? (p1 == p2) ? p3 : p2 : p1) - p0;