remove LEGACY_CONVEXITY code -- no more clients

Change-Id: Ifd33831b6a83a56685435ce8e4fbb218a147b34e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255981
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2019-11-22 12:59:01 -05:00 committed by Skia Commit-Bot
parent 189c98042f
commit 8ee77d8f42
3 changed files with 1 additions and 288 deletions

View File

@ -1959,288 +1959,6 @@ bool SkPath::isValidImpl() const {
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_LEGACY_PATH_CONVEXITY // for rebaselining Chrome
static int sign(SkScalar x) { return x < 0; }
#define kValueNeverReturnedBySign 2
enum DirChange {
kLeft_DirChange,
kRight_DirChange,
kStraight_DirChange,
kBackwards_DirChange,
kInvalid_DirChange
};
static bool almost_equal(SkScalar compA, SkScalar compB) {
// The error epsilon was empirically derived; worse case round rects
// with a mid point outset by 2x float epsilon in tests had an error
// of 12.
const int epsilon = 16;
if (!SkScalarIsFinite(compA) || !SkScalarIsFinite(compB)) {
return false;
}
// no need to check for small numbers because SkPath::Iter has removed degenerate values
int aBits = SkFloatAs2sCompliment(compA);
int bBits = SkFloatAs2sCompliment(compB);
return aBits < bBits + epsilon && bBits < aBits + epsilon;
}
// only valid for a single contour
struct Convexicator {
Convexicator()
: fPtCount(0)
, fConvexity(SkPath::kConvex_Convexity)
, fFirstDirection(SkPathPriv::kUnknown_FirstDirection)
, fIsFinite(true)
, fIsCurve(false)
, fBackwards(false) {
fExpectedDir = kInvalid_DirChange;
// warnings
fPriorPt.set(0,0);
fLastPt.set(0, 0);
fCurrPt.set(0, 0);
fLastVec.set(0, 0);
fFirstVec.set(0, 0);
fDx = fDy = 0;
fSx = fSy = kValueNeverReturnedBySign;
}
SkPath::Convexity getConvexity() const { return fConvexity; }
/** The direction returned is only valid if the path is determined convex */
SkPathPriv::FirstDirection getFirstDirection() const { return fFirstDirection; }
void addPt(const SkPoint& pt) {
if (SkPath::kConcave_Convexity == fConvexity || !fIsFinite) {
return;
}
if (0 == fPtCount) {
fCurrPt = pt;
++fPtCount;
} else {
SkVector vec = pt - fCurrPt;
SkScalar lengthSqd = SkPointPriv::LengthSqd(vec);
if (!SkScalarIsFinite(lengthSqd)) {
fIsFinite = false;
} else if (lengthSqd) {
fPriorPt = fLastPt;
fLastPt = fCurrPt;
fCurrPt = pt;
if (++fPtCount == 2) {
fFirstVec = fLastVec = vec;
} else {
SkASSERT(fPtCount > 2);
this->addVec(vec);
}
int sx = sign(vec.fX);
int sy = sign(vec.fY);
fDx += (sx != fSx);
fDy += (sy != fSy);
fSx = sx;
fSy = sy;
if (fDx > 3 || fDy > 3) {
fConvexity = SkPath::kConcave_Convexity;
}
}
}
}
void close() {
if (fPtCount > 2) {
this->addVec(fFirstVec);
}
}
DirChange directionChange(const SkVector& curVec) {
SkScalar cross = SkPoint::CrossProduct(fLastVec, curVec);
SkScalar smallest = SkTMin(fCurrPt.fX, SkTMin(fCurrPt.fY, SkTMin(fLastPt.fX, fLastPt.fY)));
SkScalar largest = SkTMax(fCurrPt.fX, SkTMax(fCurrPt.fY, SkTMax(fLastPt.fX, fLastPt.fY)));
largest = SkTMax(largest, -smallest);
if (!almost_equal(largest, largest + cross)) {
int sign = SkScalarSignAsInt(cross);
if (sign) {
return (1 == sign) ? kRight_DirChange : kLeft_DirChange;
}
}
if (cross) {
double dLastVecX = SkScalarToDouble(fLastPt.fX) - SkScalarToDouble(fPriorPt.fX);
double dLastVecY = SkScalarToDouble(fLastPt.fY) - SkScalarToDouble(fPriorPt.fY);
double dCurrVecX = SkScalarToDouble(fCurrPt.fX) - SkScalarToDouble(fLastPt.fX);
double dCurrVecY = SkScalarToDouble(fCurrPt.fY) - SkScalarToDouble(fLastPt.fY);
double dCross = dLastVecX * dCurrVecY - dLastVecY * dCurrVecX;
if (!approximately_zero_when_compared_to(dCross, SkScalarToDouble(largest))) {
int sign = SkScalarSignAsInt(SkDoubleToScalar(dCross));
if (sign) {
return (1 == sign) ? kRight_DirChange : kLeft_DirChange;
}
}
}
if (!SkScalarNearlyZero(SkPointPriv::LengthSqd(fLastVec),
SK_ScalarNearlyZero*SK_ScalarNearlyZero) &&
!SkScalarNearlyZero(SkPointPriv::LengthSqd(curVec),
SK_ScalarNearlyZero*SK_ScalarNearlyZero) &&
fLastVec.dot(curVec) < 0.0f) {
return kBackwards_DirChange;
}
return kStraight_DirChange;
}
bool hasBackwards() const {
return fBackwards;
}
bool isFinite() const {
return fIsFinite;
}
void setCurve(bool isCurve) {
fIsCurve = isCurve;
}
private:
void addVec(const SkVector& vec) {
SkASSERT(vec.fX || vec.fY);
DirChange dir = this->directionChange(vec);
switch (dir) {
case kLeft_DirChange: // fall through
case kRight_DirChange:
if (kInvalid_DirChange == fExpectedDir) {
fExpectedDir = dir;
fFirstDirection = (kRight_DirChange == dir) ? SkPathPriv::kCW_FirstDirection
: SkPathPriv::kCCW_FirstDirection;
} else if (dir != fExpectedDir) {
fConvexity = SkPath::kConcave_Convexity;
fFirstDirection = SkPathPriv::kUnknown_FirstDirection;
}
fLastVec = vec;
break;
case kStraight_DirChange:
break;
case kBackwards_DirChange:
if (fIsCurve) {
// If any of the subsequent dir is non-backward, it'll be concave.
// Otherwise, it's still convex.
fExpectedDir = dir;
}
fLastVec = vec;
fBackwards = true;
break;
case kInvalid_DirChange:
SK_ABORT("Use of invalid direction change flag");
break;
}
}
SkPoint fPriorPt;
SkPoint fLastPt;
SkPoint fCurrPt;
// fLastVec does not necessarily start at fLastPt. We only advance it when the cross product
// value with the current vec is deemed to be of a significant value.
SkVector fLastVec, fFirstVec;
int fPtCount; // non-degenerate points
DirChange fExpectedDir;
SkPath::Convexity fConvexity;
SkPathPriv::FirstDirection fFirstDirection;
int fDx, fDy, fSx, fSy;
bool fIsFinite;
bool fIsCurve;
bool fBackwards;
};
SkPath::Convexity SkPath::internalGetConvexity() const {
// Sometimes we think we need to calculate convexity but another thread already did.
auto c = this->getConvexityOrUnknown();
if (c != kUnknown_Convexity) {
return c;
}
SkPoint pts[4];
SkPath::Verb verb;
SkPath::Iter iter(*this, true);
int contourCount = 0;
int count;
Convexicator state;
if (!isFinite()) {
return kUnknown_Convexity;
}
while ((verb = iter.next(pts, false, false)) != SkPath::kDone_Verb) {
switch (verb) {
case kMove_Verb:
if (++contourCount > 1) {
this->setConvexity(kConcave_Convexity);
return kConcave_Convexity;
}
pts[1] = pts[0];
// fall through
case kLine_Verb:
count = 1;
state.setCurve(false);
break;
case kQuad_Verb:
// fall through
case kConic_Verb:
// fall through
case kCubic_Verb:
count = 2 + (kCubic_Verb == verb);
// As an additional enhancement, this could set curve true only
// if the curve is nonlinear
state.setCurve(true);
break;
case kClose_Verb:
state.setCurve(false);
state.close();
count = 0;
break;
default:
SkDEBUGFAIL("bad verb");
this->setConvexity(kConcave_Convexity);
return kConcave_Convexity;
}
for (int i = 1; i <= count; i++) {
state.addPt(pts[i]);
}
// early exit
if (!state.isFinite()) {
return kUnknown_Convexity;
}
if (kConcave_Convexity == state.getConvexity()) {
this->setConvexity(kConcave_Convexity);
return kConcave_Convexity;
}
}
this->setConvexity(state.getConvexity());
if (this->getConvexityOrUnknown() == kConvex_Convexity &&
this->getFirstDirection() == SkPathPriv::kUnknown_FirstDirection) {
if (state.getFirstDirection() == SkPathPriv::kUnknown_FirstDirection
&& !this->getBounds().isEmpty()
&& !state.hasBackwards()) {
this->setConvexity(Convexity::kConcave_Convexity);
} else {
this->setFirstDirection(state.getFirstDirection());
}
}
return this->getConvexityOrUnknown();
}
#else
static int sign(SkScalar x) { return x < 0; }
#define kValueNeverReturnedBySign 2
@ -2522,8 +2240,6 @@ bool SkPathPriv::IsConvex(const SkPoint points[], int count) {
|| state.reversals() < 3;
}
#endif
///////////////////////////////////////////////////////////////////////////////
class ContourIter {

View File

@ -158,7 +158,6 @@ public:
return path.fPathRef->conicWeights();
}
#ifndef SK_LEGACY_PATH_CONVEXITY
/** Returns true if path formed by pts is convex.
@param pts SkPoint array of path
@ -167,7 +166,6 @@ public:
@return true if pts represent a convex geometry
*/
static bool IsConvex(const SkPoint pts[], int count);
#endif
/** Returns true if the underlying SkPathRef has one single owner. */
static bool TestingOnly_unique(const SkPath& path) {

View File

@ -1321,7 +1321,7 @@ static void check_convexity(skiatest::Reporter* reporter, const SkPath& path,
SkPath copy(path); // we make a copy so that we don't cache the result on the passed in path.
SkPath::Convexity c = copy.getConvexity();
REPORTER_ASSERT(reporter, c == expected);
#ifndef SK_LEGACY_PATH_CONVEXITY
// test points-by-array interface
SkPath::Iter iter(path, true);
int initialMoves = 0;
@ -1337,7 +1337,6 @@ static void check_convexity(skiatest::Reporter* reporter, const SkPath& path,
bool isConvex = SkPathPriv::IsConvex(&points.front() + skip, points.size() - skip);
REPORTER_ASSERT(reporter, isConvex == (SkPath::kConvex_Convexity == expected));
}
#endif
}
static void test_path_crbug389050(skiatest::Reporter* reporter) {