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

Unified Diff: src/pathops/SkPathOpsDebug.cpp

Issue 1037573004: cumulative pathops patch (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix pathopsinverse gm Created 5 years, 9 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
« no previous file with comments | « src/pathops/SkPathOpsDebug.h ('k') | src/pathops/SkPathOpsLine.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkPathOpsDebug.cpp
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index 7db93f5e969b5ba53689be47c5f9936f76601e20..0331f34e8a74d91ffb34f8b6d0b0d7f88f7cab25 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -7,6 +7,13 @@
#include "SkPathOpsDebug.h"
#include "SkPath.h"
+#if DEBUG_ANGLE
+#include "SkString.h"
+#endif
+
+#if DEBUG_VALIDATE
+extern bool FLAGS_runFail;
+#endif
#if defined SK_DEBUG || !FORCE_RELEASE
@@ -26,10 +33,10 @@ int SkPathOpsDebug::gSortCount;
const char* SkPathOpsDebug::kPathOpStr[] = {"diff", "sect", "union", "xor"};
#endif
-bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpan *>& chaseArray,
- const SkOpSpan* span) {
+bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpanBase* >& chaseArray,
+ const SkOpSpanBase* span) {
for (int index = 0; index < chaseArray.count(); ++index) {
- const SkOpSpan* entry = chaseArray[index];
+ const SkOpSpanBase* entry = chaseArray[index];
if (entry == span) {
return true;
}
@@ -65,6 +72,8 @@ void SkPathOpsDebug::WindingPrintf(int wind) {
SkDebugf("%d", wind);
}
}
+#endif // defined SK_DEBUG || !FORCE_RELEASE
+
#if DEBUG_SHOW_TEST_NAME
void* SkPathOpsDebug::CreateNameStr() {
@@ -97,470 +106,368 @@ void SkPathOpsDebug::ShowPath(const SkPath& one, const SkPath& two, SkPathOp op,
}
#endif
-#endif // defined SK_DEBUG || !FORCE_RELEASE
-
#include "SkOpAngle.h"
#include "SkOpSegment.h"
-#if DEBUG_SORT
-void SkOpAngle::debugLoop() const {
- const SkOpAngle* first = this;
- const SkOpAngle* next = this;
- do {
- next->dumpOne(true);
- SkDebugf("\n");
- next = next->fNext;
- } while (next && next != first);
-}
-#endif
-
-#if DEBUG_ANGLE
-void SkOpAngle::debugSameAs(const SkOpAngle* compare) const {
- SK_ALWAYSBREAK(fSegment == compare->fSegment);
- const SkOpSpan& startSpan = fSegment->span(fStart);
- const SkOpSpan& oStartSpan = fSegment->span(compare->fStart);
- SK_ALWAYSBREAK(startSpan.fToAngle == oStartSpan.fToAngle);
- SK_ALWAYSBREAK(startSpan.fFromAngle == oStartSpan.fFromAngle);
- const SkOpSpan& endSpan = fSegment->span(fEnd);
- const SkOpSpan& oEndSpan = fSegment->span(compare->fEnd);
- SK_ALWAYSBREAK(endSpan.fToAngle == oEndSpan.fToAngle);
- SK_ALWAYSBREAK(endSpan.fFromAngle == oEndSpan.fFromAngle);
-}
-#endif
-
-#if DEBUG_VALIDATE
-void SkOpAngle::debugValidateNext() const {
- const SkOpAngle* first = this;
- const SkOpAngle* next = first;
- SkTDArray<const SkOpAngle*>(angles);
- do {
-// SK_ALWAYSBREAK(next->fSegment->debugContains(next));
- angles.push(next);
- next = next->next();
- if (next == first) {
- break;
- }
- SK_ALWAYSBREAK(!angles.contains(next));
- if (!next) {
- return;
- }
- } while (true);
-}
-
-void SkOpAngle::debugValidateLoop() const {
- const SkOpAngle* first = this;
- const SkOpAngle* next = first;
- SK_ALWAYSBREAK(first->next() != first);
- int signSum = 0;
- int oppSum = 0;
- bool firstOperand = fSegment->operand();
- bool unorderable = false;
- do {
- unorderable |= next->fUnorderable;
- const SkOpSegment* segment = next->fSegment;
- bool operandsMatch = firstOperand == segment->operand();
- signSum += operandsMatch ? segment->spanSign(next) : segment->oppSign(next);
- oppSum += operandsMatch ? segment->oppSign(next) : segment->spanSign(next);
- const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
- if (segment->_xor()) {
-// SK_ALWAYSBREAK(span.fWindValue == 1);
-// SK_ALWAYSBREAK(span.fWindSum == SK_MinS32 || span.fWindSum == 1);
- }
- if (segment->oppXor()) {
- SK_ALWAYSBREAK(span.fOppValue == 0 || abs(span.fOppValue) == 1);
-// SK_ALWAYSBREAK(span.fOppSum == SK_MinS32 || span.fOppSum == 0 || abs(span.fOppSum) == 1);
- }
- next = next->next();
- if (!next) {
- return;
- }
- } while (next != first);
- if (unorderable) {
- return;
- }
- SK_ALWAYSBREAK(!signSum || fSegment->_xor());
- SK_ALWAYSBREAK(!oppSum || fSegment->oppXor());
- int lastWinding;
- int lastOppWinding;
- int winding;
- int oppWinding;
- do {
- const SkOpSegment* segment = next->fSegment;
- const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
- winding = span.fWindSum;
- if (winding != SK_MinS32) {
-// SK_ALWAYSBREAK(winding != 0);
- SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
- lastWinding = winding;
- int diffWinding = segment->spanSign(next);
- if (!segment->_xor()) {
- SK_ALWAYSBREAK(diffWinding != 0);
- bool sameSign = (winding > 0) == (diffWinding > 0);
- winding -= sameSign ? diffWinding : -diffWinding;
- SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
- SK_ALWAYSBREAK(abs(winding) <= abs(lastWinding));
- if (!sameSign) {
- SkTSwap(winding, lastWinding);
- }
- }
- lastOppWinding = oppWinding = span.fOppSum;
- if (oppWinding != SK_MinS32 && !segment->oppXor()) {
- int oppDiffWinding = segment->oppSign(next);
-// SK_ALWAYSBREAK(abs(oppDiffWinding) <= abs(diffWinding) || segment->_xor());
- if (oppDiffWinding) {
- bool oppSameSign = (oppWinding > 0) == (oppDiffWinding > 0);
- oppWinding -= oppSameSign ? oppDiffWinding : -oppDiffWinding;
- SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
- SK_ALWAYSBREAK(abs(oppWinding) <= abs(lastOppWinding));
- if (!oppSameSign) {
- SkTSwap(oppWinding, lastOppWinding);
- }
- }
- }
- firstOperand = segment->operand();
- break;
- }
- SK_ALWAYSBREAK(span.fOppSum == SK_MinS32);
- next = next->next();
- } while (next != first);
- if (winding == SK_MinS32) {
- return;
- }
- SK_ALWAYSBREAK(oppWinding == SK_MinS32 || SkPathOpsDebug::ValidWind(oppWinding));
- first = next;
- next = next->next();
- do {
- const SkOpSegment* segment = next->fSegment;
- lastWinding = winding;
- lastOppWinding = oppWinding;
- bool operandsMatch = firstOperand == segment->operand();
- if (operandsMatch) {
- if (!segment->_xor()) {
- winding -= segment->spanSign(next);
- SK_ALWAYSBREAK(winding != lastWinding);
- SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
- }
- if (!segment->oppXor()) {
- int oppDiffWinding = segment->oppSign(next);
- if (oppWinding != SK_MinS32) {
- oppWinding -= oppDiffWinding;
- SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
- } else {
- SK_ALWAYSBREAK(oppDiffWinding == 0);
- }
- }
- } else {
- if (!segment->oppXor()) {
- winding -= segment->oppSign(next);
- SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
- }
- if (!segment->_xor()) {
- oppWinding -= segment->spanSign(next);
- SK_ALWAYSBREAK(oppWinding != lastOppWinding);
- SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
- }
- }
- bool useInner = SkOpSegment::UseInnerWinding(lastWinding, winding);
- int sumWinding = useInner ? winding : lastWinding;
- bool oppUseInner = SkOpSegment::UseInnerWinding(lastOppWinding, oppWinding);
- int oppSumWinding = oppUseInner ? oppWinding : lastOppWinding;
- if (!operandsMatch) {
- SkTSwap(useInner, oppUseInner);
- SkTSwap(sumWinding, oppSumWinding);
- }
- const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
- if (winding == -lastWinding) {
- if (span.fWindSum != SK_MinS32) {
- SkDebugf("%s useInner=%d spanSign=%d lastWinding=%d winding=%d windSum=%d\n",
- __FUNCTION__,
- useInner, segment->spanSign(next), lastWinding, winding, span.fWindSum);
- }
- }
- if (oppWinding != SK_MinS32) {
- if (span.fOppSum != SK_MinS32) {
- SK_ALWAYSBREAK(span.fOppSum == oppSumWinding || segment->oppXor() || segment->_xor());
- }
- } else {
- SK_ALWAYSBREAK(!firstOperand);
- SK_ALWAYSBREAK(!segment->operand());
- SK_ALWAYSBREAK(!span.fOppValue);
- }
- next = next->next();
- } while (next != first);
-}
-#endif
-
#if DEBUG_SWAP_TOP
-bool SkOpSegment::controlsContainedByEnds(int tStart, int tEnd) const {
+int SkOpSegment::debugInflections(const SkOpSpanBase* start, const SkOpSpanBase* end) const {
if (fVerb != SkPath::kCubic_Verb) {
return false;
}
- SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
- return dst.controlsContainedByEnds();
-}
-#endif
-
-#if DEBUG_CONCIDENT
-// SK_ALWAYSBREAK if pair has not already been added
-void SkOpSegment::debugAddTPair(double t, const SkOpSegment& other, double otherT) const {
- for (int i = 0; i < fTs.count(); ++i) {
- if (fTs[i].fT == t && fTs[i].fOther == &other && fTs[i].fOtherT == otherT) {
- return;
- }
- }
- SK_ALWAYSBREAK(0);
-}
-#endif
-
-#if DEBUG_ANGLE
-void SkOpSegment::debugCheckPointsEqualish(int tStart, int tEnd) const {
- const SkPoint& basePt = fTs[tStart].fPt;
- while (++tStart < tEnd) {
- const SkPoint& cmpPt = fTs[tStart].fPt;
- SK_ALWAYSBREAK(SkDPoint::ApproximatelyEqual(basePt, cmpPt));
- }
-}
-#endif
-
-#if DEBUG_SWAP_TOP
-int SkOpSegment::debugInflections(int tStart, int tEnd) const {
- if (fVerb != SkPath::kCubic_Verb) {
- return false;
- }
- SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
+ SkDCubic dst = SkDCubic::SubDivide(fPts, start->t(), end->t());
double inflections[2];
return dst.findInflections(inflections);
}
#endif
-const SkOpAngle* SkOpSegment::debugLastAngle() const {
- const SkOpAngle* result = NULL;
- for (int index = 0; index < count(); ++index) {
- const SkOpSpan& span = this->span(index);
- if (span.fToAngle) {
+SkOpAngle* SkOpSegment::debugLastAngle() {
+ SkOpAngle* result = NULL;
+ SkOpSpan* span = this->head();
+ do {
+ if (span->toAngle()) {
SkASSERT(!result);
- result = span.fToAngle;
+ result = span->toAngle();
}
- }
+ } while ((span = span->next()->upCastable()));
SkASSERT(result);
return result;
}
void SkOpSegment::debugReset() {
- fTs.reset();
- fAngles.reset();
-}
-
-#if DEBUG_CONCIDENT
-void SkOpSegment::debugShowTs(const char* prefix) const {
- SkDebugf("%s %s id=%d", __FUNCTION__, prefix, fID);
- int lastWind = -1;
- int lastOpp = -1;
- double lastT = -1;
- int i;
- for (i = 0; i < fTs.count(); ++i) {
- bool change = lastT != fTs[i].fT || lastWind != fTs[i].fWindValue
- || lastOpp != fTs[i].fOppValue;
- if (change && lastWind >= 0) {
- SkDebugf(" t=%1.3g %1.9g,%1.9g w=%d o=%d]",
- lastT, xyAtT(i - 1).fX, xyAtT(i - 1).fY, lastWind, lastOpp);
- }
- if (change) {
- SkDebugf(" [o=%d", fTs[i].fOther->fID);
- lastWind = fTs[i].fWindValue;
- lastOpp = fTs[i].fOppValue;
- lastT = fTs[i].fT;
- } else {
- SkDebugf(",%d", fTs[i].fOther->fID);
- }
- }
- if (i <= 0) {
- return;
- }
- SkDebugf(" t=%1.3g %1.9g,%1.9g w=%d o=%d]",
- lastT, xyAtT(i - 1).fX, xyAtT(i - 1).fY, lastWind, lastOpp);
- if (fOperand) {
- SkDebugf(" operand");
- }
- if (done()) {
- SkDebugf(" done");
- }
- SkDebugf("\n");
+ this->init(this->fPts, this->contour(), this->verb());
}
-#endif
-#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
+#if DEBUG_ACTIVE_SPANS
void SkOpSegment::debugShowActiveSpans() const {
debugValidate();
if (done()) {
return;
}
-#if DEBUG_ACTIVE_SPANS_SHORT_FORM
int lastId = -1;
double lastT = -1;
-#endif
- for (int i = 0; i < fTs.count(); ++i) {
- if (fTs[i].fDone) {
+ const SkOpSpan* span = &fHead;
+ do {
+ if (span->done()) {
continue;
}
- SK_ALWAYSBREAK(i < fTs.count() - 1);
-#if DEBUG_ACTIVE_SPANS_SHORT_FORM
- if (lastId == fID && lastT == fTs[i].fT) {
+ if (lastId == fID && lastT == span->t()) {
continue;
}
lastId = fID;
- lastT = fTs[i].fT;
-#endif
+ lastT = span->t();
SkDebugf("%s id=%d", __FUNCTION__, fID);
SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
}
- const SkOpSpan* span = &fTs[i];
- SkDebugf(") t=%1.9g (%1.9g,%1.9g)", span->fT, xAtT(span), yAtT(span));
- int iEnd = i + 1;
- while (fTs[iEnd].fT < 1 && approximately_equal(fTs[i].fT, fTs[iEnd].fT)) {
- ++iEnd;
- }
- SkDebugf(" tEnd=%1.9g", fTs[iEnd].fT);
- const SkOpSegment* other = fTs[i].fOther;
- SkDebugf(" other=%d otherT=%1.9g otherIndex=%d windSum=",
- other->fID, fTs[i].fOtherT, fTs[i].fOtherIndex);
- if (fTs[i].fWindSum == SK_MinS32) {
+ const SkOpPtT* ptT = span->ptT();
+ SkDebugf(") t=%1.9g (%1.9g,%1.9g)", ptT->fT, ptT->fPt.fX, ptT->fPt.fY);
+ SkDebugf(" tEnd=%1.9g", span->next()->t());
+ SkDebugf(" windSum=");
+ if (span->windSum() == SK_MinS32) {
SkDebugf("?");
} else {
- SkDebugf("%d", fTs[i].fWindSum);
+ SkDebugf("%d", span->windSum());
}
- SkDebugf(" windValue=%d oppValue=%d\n", fTs[i].fWindValue, fTs[i].fOppValue);
- }
+ SkDebugf(" windValue=%d oppValue=%d", span->windValue(), span->oppValue());
+ SkDebugf("\n");
+ } while ((span = span->next()->upCastable()));
}
#endif
-#if DEBUG_MARK_DONE || DEBUG_UNSORTABLE
-void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding) {
- const SkPoint& pt = xyAtT(&span);
+#if DEBUG_MARK_DONE
+void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding) {
+ const SkPoint& pt = span->ptT()->fPt;
SkDebugf("%s id=%d", fun, fID);
SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
}
- SK_ALWAYSBREAK(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
- fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]);
- SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d windSum=",
- span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.fY,
- (&span)[1].fT, winding);
- if (span.fWindSum == SK_MinS32) {
+ SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
+ span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t());
+ if (winding == SK_MinS32) {
SkDebugf("?");
} else {
- SkDebugf("%d", span.fWindSum);
+ SkDebugf("%d", winding);
}
- SkDebugf(" windValue=%d\n", span.fWindValue);
+ SkDebugf(" windSum=");
+ if (span->windSum() == SK_MinS32) {
+ SkDebugf("?");
+ } else {
+ SkDebugf("%d", span->windSum());
+ }
+ SkDebugf(" windValue=%d\n", span->windValue());
}
-void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding,
+void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding,
int oppWinding) {
- const SkPoint& pt = xyAtT(&span);
+ const SkPoint& pt = span->ptT()->fPt;
SkDebugf("%s id=%d", fun, fID);
SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
}
- SK_ALWAYSBREAK(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
- fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]);
- SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d newOppSum=%d oppSum=",
- span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.fY,
- (&span)[1].fT, winding, oppWinding);
- if (span.fOppSum == SK_MinS32) {
+ SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
+ span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t(), winding, oppWinding);
+ if (winding == SK_MinS32) {
+ SkDebugf("?");
+ } else {
+ SkDebugf("%d", winding);
+ }
+ SkDebugf(" newOppSum=");
+ if (oppWinding == SK_MinS32) {
+ SkDebugf("?");
+ } else {
+ SkDebugf("%d", oppWinding);
+ }
+ SkDebugf(" oppSum=");
+ if (span->oppSum() == SK_MinS32) {
SkDebugf("?");
} else {
- SkDebugf("%d", span.fOppSum);
+ SkDebugf("%d", span->oppSum());
}
SkDebugf(" windSum=");
- if (span.fWindSum == SK_MinS32) {
+ if (span->windSum() == SK_MinS32) {
SkDebugf("?");
} else {
- SkDebugf("%d", span.fWindSum);
+ SkDebugf("%d", span->windSum());
}
- SkDebugf(" windValue=%d oppValue=%d\n", span.fWindValue, span.fOppValue);
+ SkDebugf(" windValue=%d oppValue=%d\n", span->windValue(), span->oppValue());
}
+
#endif
-#if DEBUG_SHOW_WINDING
-int SkOpSegment::debugShowWindingValues(int slotCount, int ofInterest) const {
- if (!(1 << fID & ofInterest)) {
- return 0;
- }
- int sum = 0;
- SkTArray<char, true> slots(slotCount * 2);
- memset(slots.begin(), ' ', slotCount * 2);
- for (int i = 0; i < fTs.count(); ++i) {
- // if (!(1 << fTs[i].fOther->fID & ofInterest)) {
- // continue;
- // }
- sum += fTs[i].fWindValue;
- slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue);
- sum += fTs[i].fOppValue;
- slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue);
- }
- SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begin(), slotCount,
- slots.begin() + slotCount);
- return sum;
+#if DEBUG_ANGLE
+SkString SkOpAngle::debugPart() const {
+ SkString result;
+ switch (this->segment()->verb()) {
+ case SkPath::kLine_Verb:
+ result.printf(LINE_DEBUG_STR " id=%d", LINE_DEBUG_DATA(fCurvePart),
+ this->segment()->debugID());
+ break;
+ case SkPath::kQuad_Verb:
+ result.printf(QUAD_DEBUG_STR " id=%d", QUAD_DEBUG_DATA(fCurvePart),
+ this->segment()->debugID());
+ break;
+ case SkPath::kCubic_Verb:
+ result.printf(CUBIC_DEBUG_STR " id=%d", CUBIC_DEBUG_DATA(fCurvePart),
+ this->segment()->debugID());
+ break;
+ default:
+ SkASSERT(0);
+ }
+ return result;
+}
+#endif
+
+#if DEBUG_SORT
+void SkOpAngle::debugLoop() const {
+ const SkOpAngle* first = this;
+ const SkOpAngle* next = this;
+ do {
+ next->dumpOne(true);
+ SkDebugf("\n");
+ next = next->fNext;
+ } while (next && next != first);
+ next = first;
+ do {
+ next->debugValidate();
+ next = next->fNext;
+ } while (next && next != first);
}
#endif
+void SkOpAngle::debugValidate() const {
+#if DEBUG_VALIDATE
+ const SkOpAngle* first = this;
+ const SkOpAngle* next = this;
+ int wind = 0;
+ int opp = 0;
+ int lastXor = -1;
+ int lastOppXor = -1;
+ do {
+ if (next->unorderable()) {
+ return;
+ }
+ const SkOpSpan* minSpan = next->start()->starter(next->end());
+ if (minSpan->windValue() == SK_MinS32) {
+ return;
+ }
+ bool op = next->segment()->operand();
+ bool isXor = next->segment()->isXor();
+ bool oppXor = next->segment()->oppXor();
+ SkASSERT(!DEBUG_LIMIT_WIND_SUM || between(0, minSpan->windValue(), DEBUG_LIMIT_WIND_SUM));
+ SkASSERT(!DEBUG_LIMIT_WIND_SUM
+ || between(-DEBUG_LIMIT_WIND_SUM, minSpan->oppValue(), DEBUG_LIMIT_WIND_SUM));
+ bool useXor = op ? oppXor : isXor;
+ SkASSERT(lastXor == -1 || lastXor == (int) useXor);
+ lastXor = (int) useXor;
+ wind += next->sign() * (op ? minSpan->oppValue() : minSpan->windValue());
+ if (useXor) {
+ wind &= 1;
+ }
+ useXor = op ? isXor : oppXor;
+ SkASSERT(lastOppXor == -1 || lastOppXor == (int) useXor);
+ lastOppXor = (int) useXor;
+ opp += next->sign() * (op ? minSpan->windValue() : minSpan->oppValue());
+ if (useXor) {
+ opp &= 1;
+ }
+ next = next->fNext;
+ } while (next && next != first);
+ SkASSERT(wind == 0);
+ SkASSERT(opp == 0 || !FLAGS_runFail);
+#endif
+}
+
+void SkOpAngle::debugValidateNext() const {
+#if !FORCE_RELEASE
+ const SkOpAngle* first = this;
+ const SkOpAngle* next = first;
+ SkTDArray<const SkOpAngle*>(angles);
+ do {
+// SK_ALWAYSBREAK(next->fSegment->debugContains(next));
+ angles.push(next);
+ next = next->next();
+ if (next == first) {
+ break;
+ }
+ SK_ALWAYSBREAK(!angles.contains(next));
+ if (!next) {
+ return;
+ }
+ } while (true);
+#endif
+}
+
void SkOpSegment::debugValidate() const {
#if DEBUG_VALIDATE
- int count = fTs.count();
- SK_ALWAYSBREAK(count >= 2);
- SK_ALWAYSBREAK(fTs[0].fT == 0);
- SK_ALWAYSBREAK(fTs[count - 1].fT == 1);
+ const SkOpSpanBase* span = &fHead;
+ double lastT = -1;
+ const SkOpSpanBase* prev = NULL;
+ int count = 0;
int done = 0;
- double t = -1;
- const SkOpSpan* last = NULL;
- bool tinyTFound = false;
- bool hasLoop = false;
- for (int i = 0; i < count; ++i) {
- const SkOpSpan& span = fTs[i];
- SK_ALWAYSBREAK(t <= span.fT);
- t = span.fT;
- int otherIndex = span.fOtherIndex;
- const SkOpSegment* other = span.fOther;
- SK_ALWAYSBREAK(other != this || fVerb == SkPath::kCubic_Verb);
- const SkOpSpan& otherSpan = other->fTs[otherIndex];
- SK_ALWAYSBREAK(otherSpan.fPt == span.fPt);
- SK_ALWAYSBREAK(otherSpan.fOtherT == t);
- SK_ALWAYSBREAK(&fTs[i] == &otherSpan.fOther->fTs[otherSpan.fOtherIndex]);
- done += span.fDone;
- if (last) {
- SK_ALWAYSBREAK(last->fT != span.fT || last->fOther != span.fOther);
- bool tsEqual = last->fT == span.fT;
- bool tsPreciselyEqual = precisely_equal(last->fT, span.fT);
- SK_ALWAYSBREAK(!tsEqual || tsPreciselyEqual);
- bool pointsEqual = last->fPt == span.fPt;
- bool pointsNearlyEqual = AlmostEqualUlps(last->fPt, span.fPt);
-#if 0 // bufferOverflow test triggers this
- SK_ALWAYSBREAK(!tsPreciselyEqual || pointsNearlyEqual);
+ do {
+ if (!span->final()) {
+ ++count;
+ done += span->upCast()->done() ? 1 : 0;
+ }
+ SkASSERT(span->segment() == this);
+ SkASSERT(!prev || prev->upCast()->next() == span);
+ SkASSERT(!prev || prev == span->prev());
+ prev = span;
+ double t = span->ptT()->fT;
+ SkASSERT(lastT < t);
+ lastT = t;
+ span->debugValidate();
+ } while (!span->final() && (span = span->upCast()->next()));
+ SkASSERT(count == fCount);
+ SkASSERT(done == fDoneCount);
+ SkASSERT(span->final());
+ span->debugValidate();
+#endif
+}
+
+bool SkOpSpanBase::debugCoinEndLoopCheck() const {
+ int loop = 0;
+ const SkOpSpanBase* next = this;
+ SkOpSpanBase* nextCoin;
+ do {
+ nextCoin = next->fCoinEnd;
+ SkASSERT(nextCoin == this || nextCoin->fCoinEnd != nextCoin);
+ for (int check = 1; check < loop - 1; ++check) {
+ const SkOpSpanBase* checkCoin = this->fCoinEnd;
+ const SkOpSpanBase* innerCoin = checkCoin;
+ for (int inner = check + 1; inner < loop; ++inner) {
+ innerCoin = innerCoin->fCoinEnd;
+ if (checkCoin == innerCoin) {
+ SkDebugf("*** bad coincident end loop ***\n");
+ return false;
+ }
+ }
+ }
+ ++loop;
+ } while ((next = nextCoin) && next != this);
+ return true;
+}
+
+void SkOpSpanBase::debugValidate() const {
+#if DEBUG_VALIDATE
+ const SkOpPtT* ptT = &fPtT;
+ SkASSERT(ptT->span() == this);
+ do {
+// SkASSERT(SkDPoint::RoughlyEqual(fPtT.fPt, ptT->fPt));
+ ptT->debugValidate();
+ ptT = ptT->next();
+ } while (ptT != &fPtT);
+ SkASSERT(this->debugCoinEndLoopCheck());
+ if (!this->final()) {
+ SkASSERT(this->upCast()->debugCoinLoopCheck());
+ }
+ if (fFromAngle) {
+ fFromAngle->debugValidate();
+ }
+ if (!this->final() && this->upCast()->toAngle()) {
+ this->upCast()->toAngle()->debugValidate();
+ }
#endif
-// SK_ALWAYSBREAK(!last->fTiny || !tsPreciselyEqual || span.fTiny || tinyTFound);
- SK_ALWAYSBREAK(last->fTiny || tsPreciselyEqual || !pointsEqual || hasLoop);
- SK_ALWAYSBREAK(!last->fTiny || pointsEqual);
- SK_ALWAYSBREAK(!last->fTiny || last->fDone);
- SK_ALWAYSBREAK(!last->fSmall || pointsNearlyEqual);
- SK_ALWAYSBREAK(!last->fSmall || last->fDone);
-// SK_ALWAYSBREAK(!last->fSmall || last->fTiny);
-// SK_ALWAYSBREAK(last->fTiny || !pointsEqual || last->fDone == span.fDone);
- if (last->fTiny) {
- tinyTFound |= !tsPreciselyEqual;
- } else {
- tinyTFound = false;
+}
+
+bool SkOpSpan::debugCoinLoopCheck() const {
+ int loop = 0;
+ const SkOpSpan* next = this;
+ SkOpSpan* nextCoin;
+ do {
+ nextCoin = next->fCoincident;
+ SkASSERT(nextCoin == this || nextCoin->fCoincident != nextCoin);
+ for (int check = 1; check < loop - 1; ++check) {
+ const SkOpSpan* checkCoin = this->fCoincident;
+ const SkOpSpan* innerCoin = checkCoin;
+ for (int inner = check + 1; inner < loop; ++inner) {
+ innerCoin = innerCoin->fCoincident;
+ if (checkCoin == innerCoin) {
+ SkDebugf("*** bad coincident loop ***\n");
+ return false;
+ }
+ }
+ }
+ ++loop;
+ } while ((next = nextCoin) && next != this);
+ return true;
+}
+
+#include "SkOpContour.h"
+
+int SkOpPtT::debugLoopLimit(bool report) const {
+ int loop = 0;
+ const SkOpPtT* next = this;
+ do {
+ for (int check = 1; check < loop - 1; ++check) {
+ const SkOpPtT* checkPtT = this->fNext;
+ const SkOpPtT* innerPtT = checkPtT;
+ for (int inner = check + 1; inner < loop; ++inner) {
+ innerPtT = innerPtT->fNext;
+ if (checkPtT == innerPtT) {
+ if (report) {
+ SkDebugf("*** bad ptT loop ***\n");
+ }
+ return loop;
+ }
}
}
- last = &span;
- hasLoop |= last->fLoop;
+ ++loop;
+ } while ((next = next->fNext) && next != this);
+ return 0;
+}
+
+void SkOpPtT::debugValidate() const {
+#if DEBUG_VALIDATE
+ if (contour()->globalState()->phase() == SkOpGlobalState::kIntersecting) {
+ return;
}
- SK_ALWAYSBREAK(done == fDoneSpans);
-// if (fAngles.count() ) {
-// fAngles.begin()->debugValidateLoop();
-// }
+ SkASSERT(fNext);
+ SkASSERT(fNext != this);
+ SkASSERT(fNext->fNext);
+ SkASSERT(debugLoopLimit(false) == 0);
#endif
}
« no previous file with comments | « src/pathops/SkPathOpsDebug.h ('k') | src/pathops/SkPathOpsLine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698