Pass squared tolerances into GrPathUtils::generateXPoints()

The GrPathUtils::quadPointCount and cubicPointCount functions take a
tolerance value. The paired generateQuad/CubicPoints functions that will
fill up-to the returned point count from those first questions actually
takes the square of the tolerance value.

This was noticed in https://fiddle.skia.org/c/7e42210ddb6675fe8729c0ba5b07daf5
as the subtle linear artifacts around the rounded corners of the stroke.
GrAAConvexTessellator was not passing in the square value, so the point
generation would early-out sooner than it should have in this example.
Instead of using 16 vertices it used 8. Passing in the square fixes the
linear artifacts when testing locally.

I did an audit of other usages of these functions and SkShadowUtils also
needed to be updated. As part of this, I switched the constants over to
constexpr. The only other user of this function, default path renderer,
did not need to be updated.

Change-Id: I5e0acb8ebc8b4209f7924ca1e1674d1759da0d3e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/507926
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Auto-Submit: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Michael Ludwig 2022-02-12 15:02:22 -05:00 committed by SkCQ
parent 0c58105085
commit 43146e977f
2 changed files with 18 additions and 14 deletions

View File

@ -20,19 +20,21 @@
// test more degenerate cases
// The tolerance for fusing vertices and eliminating colinear lines (It is in device space).
static const SkScalar kClose = (SK_Scalar1 / 16);
static const SkScalar kCloseSqd = kClose * kClose;
static constexpr SkScalar kClose = (SK_Scalar1 / 16);
static constexpr SkScalar kCloseSqd = kClose * kClose;
// tesselation tolerance values, in device space pixels
static const SkScalar kQuadTolerance = 0.2f;
static const SkScalar kCubicTolerance = 0.2f;
static const SkScalar kConicTolerance = 0.25f;
static constexpr SkScalar kQuadTolerance = 0.2f;
static constexpr SkScalar kCubicTolerance = 0.2f;
static constexpr SkScalar kQuadToleranceSqd = kQuadTolerance * kQuadTolerance;
static constexpr SkScalar kCubicToleranceSqd = kCubicTolerance * kCubicTolerance;
static constexpr SkScalar kConicTolerance = 0.25f;
// dot product below which we use a round cap between curve segments
static const SkScalar kRoundCapThreshold = 0.8f;
static constexpr 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.8f;
static constexpr SkScalar kCurveConnectionThreshold = 0.8f;
static bool intersect(const SkPoint& p0, const SkPoint& n0,
const SkPoint& p1, const SkPoint& n1,
@ -964,7 +966,7 @@ void GrAAConvexTessellator::quadTo(const SkPoint pts[3]) {
fPointBuffer.setCount(maxCount);
SkPoint* target = fPointBuffer.begin();
int count = GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2],
kQuadTolerance, &target, maxCount);
kQuadToleranceSqd, &target, maxCount);
fPointBuffer.setCount(count);
for (int i = 0; i < count - 1; i++) {
this->lineTo(fPointBuffer[i], kCurve_CurveState);
@ -985,7 +987,7 @@ void GrAAConvexTessellator::cubicTo(const SkMatrix& m, const SkPoint srcPts[4])
fPointBuffer.setCount(maxCount);
SkPoint* target = fPointBuffer.begin();
int count = GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3],
kCubicTolerance, &target, maxCount);
kCubicToleranceSqd, &target, maxCount);
fPointBuffer.setCount(count);
for (int i = 0; i < count - 1; i++) {
this->lineTo(fPointBuffer[i], kCurve_CurveState);

View File

@ -726,10 +726,12 @@ void SkBaseShadowTessellator::stitchConcaveRings(const SkTDArray<SkPoint>& umbra
// tesselation tolerance values, in device space pixels
#if SK_SUPPORT_GPU
static const SkScalar kQuadTolerance = 0.2f;
static const SkScalar kCubicTolerance = 0.2f;
static constexpr SkScalar kQuadTolerance = 0.2f;
static constexpr SkScalar kCubicTolerance = 0.2f;
static constexpr SkScalar kQuadToleranceSqd = kQuadTolerance * kQuadTolerance;
static constexpr SkScalar kCubicToleranceSqd = kCubicTolerance * kCubicTolerance;
#endif
static const SkScalar kConicTolerance = 0.25f;
static constexpr SkScalar kConicTolerance = 0.25f;
// clamps the point to the nearest 16th of a pixel
static void sanitize_point(const SkPoint& in, SkPoint* out) {
@ -783,7 +785,7 @@ void SkBaseShadowTessellator::handleQuad(const SkPoint pts[3]) {
fPointBuffer.setCount(maxCount);
SkPoint* target = fPointBuffer.begin();
int count = GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2],
kQuadTolerance, &target, maxCount);
kQuadToleranceSqd, &target, maxCount);
fPointBuffer.setCount(count);
for (int i = 0; i < count; i++) {
this->handleLine(fPointBuffer[i]);
@ -808,7 +810,7 @@ void SkBaseShadowTessellator::handleCubic(const SkMatrix& m, SkPoint pts[4]) {
fPointBuffer.setCount(maxCount);
SkPoint* target = fPointBuffer.begin();
int count = GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3],
kCubicTolerance, &target, maxCount);
kCubicToleranceSqd, &target, maxCount);
fPointBuffer.setCount(count);
for (int i = 0; i < count; i++) {
this->handleLine(fPointBuffer[i]);