Index: src/pathops/SkPathOpsTSect.h |
diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h |
index 07b983a1fa35052fbb74e1d127941079b6cb01ea..1e483ea0caddb957d7bbc2162ce70b1b8f70c8f6 100644 |
--- a/src/pathops/SkPathOpsTSect.h |
+++ b/src/pathops/SkPathOpsTSect.h |
@@ -99,6 +99,13 @@ public: |
} |
const SkTSect<OppCurve, TCurve>* debugOpp() const; |
+ |
+#ifdef SK_DEBUG |
+ void debugSetGlobalState(SkOpGlobalState* state) { |
+ fDebugGlobalState = state; |
+ } |
+#endif |
+ |
const SkTSpan* debugSpan(int ) const; |
const SkTSpan* debugT(double t) const; |
#ifdef SK_DEBUG |
@@ -118,10 +125,12 @@ public: |
SkTSpan<OppCurve, TCurve>* findOppT(double t) const { |
SkTSpan<OppCurve, TCurve>* result = oppT(t); |
- SkASSERT(result); |
+ SkOPASSERT(result); |
return result; |
} |
+ SkDEBUGCODE(SkOpGlobalState* globalState() const { return fDebugGlobalState; }) |
+ |
bool hasOppT(double t) const { |
return SkToBool(oppT(t)); |
} |
@@ -208,6 +217,7 @@ private: |
SkOpDebugBool fIsLinear; |
SkOpDebugBool fIsLine; |
SkOpDebugBool fDeleted; |
+ SkDEBUGCODE(SkOpGlobalState* fDebugGlobalState); |
SkDEBUGCODE_(SkTSect<TCurve, OppCurve>* fDebugSect); |
PATH_OPS_DEBUG_T_SECT_CODE(int fID); |
friend class SkTSect<TCurve, OppCurve>; |
@@ -254,6 +264,7 @@ private: |
SkTSpan<TCurve, OppCurve>* addSplitAt(SkTSpan<TCurve, OppCurve>* span, double t) { |
SkTSpan<TCurve, OppCurve>* result = this->addOne(); |
+ SkDEBUGCODE(result->debugSetGlobalState(this->globalState())); |
result->splitAt(span, t, &fHeap); |
result->initBounds(fCurve); |
span->initBounds(fCurve); |
@@ -383,6 +394,7 @@ template<typename TCurve, typename OppCurve> |
SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addFollowing( |
SkTSpan<TCurve, OppCurve>* prior) { |
SkTSpan<TCurve, OppCurve>* result = this->addOne(); |
+ SkDEBUGCODE(result->debugSetGlobalState(this->globalState())); |
result->fStartT = prior ? prior->fEndT : 0; |
SkTSpan<TCurve, OppCurve>* next = prior ? prior->fNext : fHead; |
result->fEndT = next ? next->fStartT : 1; |
@@ -397,6 +409,7 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addFollowing( |
next->fPrev = result; |
} |
result->resetBounds(fCurve); |
+ result->validate(); |
return result; |
} |
@@ -730,7 +743,7 @@ bool SkTSpan<TCurve, OppCurve>::removeBounded(const SkTSpan<OppCurve, TCurve>* o |
prev = bounded; |
bounded = boundedNext; |
} |
- SkASSERT(0); |
+ SkOPASSERT(0); |
return false; |
} |
@@ -756,6 +769,7 @@ bool SkTSpan<TCurve, OppCurve>::splitAt(SkTSpan* work, double t, SkChunkAlloc* h |
if (fNext) { |
fNext->fPrev = this; |
} |
+ this->validate(); |
SkTSpanBounded<OppCurve, TCurve>* bounded = work->fBounded; |
fBounded = nullptr; |
while (bounded) { |
@@ -772,17 +786,21 @@ bool SkTSpan<TCurve, OppCurve>::splitAt(SkTSpan* work, double t, SkChunkAlloc* h |
template<typename TCurve, typename OppCurve> |
void SkTSpan<TCurve, OppCurve>::validate() const { |
-#if DEBUG_T_SECT |
+#if DEBUG_VALIDATE |
+ SkASSERT(this != fPrev); |
+ SkASSERT(this != fNext); |
SkASSERT(fNext == nullptr || fNext != fPrev); |
SkASSERT(fNext == nullptr || this == fNext->fPrev); |
SkASSERT(fPrev == nullptr || this == fPrev->fNext); |
+ this->validateBounded(); |
+#endif |
+#if DEBUG_T_SECT |
SkASSERT(fBounds.width() || fBounds.height() || fCollapsed); |
SkASSERT(fBoundsMax == SkTMax(fBounds.width(), fBounds.height())); |
SkASSERT(0 <= fStartT); |
SkASSERT(fEndT <= 1); |
SkASSERT(fStartT <= fEndT); |
SkASSERT(fBounded); |
- this->validateBounded(); |
if (fHasPerp) { |
if (fCoinStart.isCoincident()) { |
validatePerpT(fCoinStart.perpT()); |
@@ -803,8 +821,10 @@ void SkTSpan<TCurve, OppCurve>::validateBounded() const { |
while (testBounded) { |
SkDEBUGCODE_(const SkTSpan<OppCurve, TCurve>* overlap = testBounded->fBounded); |
SkASSERT(!overlap->fDeleted); |
+#if DEBUG_T_SECT |
SkASSERT(((this->debugID() ^ overlap->debugID()) & 1) == 1); |
SkASSERT(overlap->findOppSpan(this)); |
+#endif |
testBounded = testBounded->fNext; |
} |
#endif |
@@ -844,6 +864,7 @@ SkTSect<TCurve, OppCurve>::SkTSect(const TCurve& c |
PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugAllocatedCount(0)) |
{ |
fHead = addOne(); |
+ SkDEBUGCODE(fHead->debugSetGlobalState(debugGlobalState)); |
fHead->init(c); |
} |
@@ -982,6 +1003,9 @@ void SkTSect<TCurve, OppCurve>::coincidentCheck(SkTSect<OppCurve, TCurve>* sect2 |
if (!fHead || !sect2->fHead) { |
break; |
} |
+ if (!next || next->fDeleted) { |
+ break; |
+ } |
} while ((first = next)); |
} |
@@ -1145,7 +1169,7 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::extractCoincident( |
SkTSpan<TCurve, OppCurve>* prev = first->fPrev; |
SkASSERT(first->fCoinStart.isCoincident()); |
SkTSpan<OppCurve, TCurve>* oppFirst = first->findOppT(first->fCoinStart.perpT()); |
- SkASSERT(last->fCoinEnd.isCoincident()); |
+ SkOPASSERT(last->fCoinEnd.isCoincident()); |
bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); |
double coinStart; |
SkDEBUGCODE(double coinEnd); |
@@ -1176,10 +1200,14 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::extractCoincident( |
} |
// FIXME: incomplete : if we're not at the end, find end of coin |
SkTSpan<OppCurve, TCurve>* oppLast; |
- SkASSERT(last->fCoinEnd.isCoincident()); |
+ SkOPASSERT(last->fCoinEnd.isCoincident()); |
oppLast = last->findOppT(last->fCoinEnd.perpT()); |
SkDEBUGCODE(coinEnd = last->fEndT); |
- SkDEBUGCODE(oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT); |
+#ifdef SK_DEBUG |
+ if (!this->globalState() || !this->globalState()->debugSkipAssert()) { |
+ oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT; |
+ } |
+#endif |
if (!oppMatched) { |
SkTSwap(oppFirst, oppLast); |
SkTSwap(oppStartT, oppEndT); |
@@ -1187,8 +1215,11 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::extractCoincident( |
SkOPASSERT(oppStartT < oppEndT); |
SkASSERT(coinStart == first->fStartT); |
SkASSERT(coinEnd == last->fEndT); |
- SkASSERT(oppStartT == oppFirst->fStartT); |
- SkASSERT(oppEndT == oppLast->fEndT); |
+ SkOPASSERT(oppStartT == oppFirst->fStartT); |
+ SkOPASSERT(oppEndT == oppLast->fEndT); |
+ if (!oppFirst) { |
+ return nullptr; |
+ } |
// reduce coincident runs to single entries |
this->validate(); |
sect2->validate(); |
@@ -1250,7 +1281,7 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::findCoincidentRun( |
return first; |
} else { |
lastCandidate = nullptr; |
- SkASSERT(!first); |
+ SkOPASSERT(!first); |
} |
if (work == *lastPtr) { |
return first; |
@@ -1582,6 +1613,7 @@ void SkTSect<TCurve, OppCurve>::mergeCoincidence(SkTSect<OppCurve, TCurve>* sect |
smaller->fCoinEnd = larger->fCoinEnd; |
if (largerPrior) { |
largerPrior->fNext = larger->fNext; |
+ largerPrior->validate(); |
} else { |
fCoincident = larger->fNext; |
} |
@@ -1698,6 +1730,7 @@ void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first |
final->fPrev = first; |
} |
first->fNext = final; |
+ first->validate(); |
} |
template<typename TCurve, typename OppCurve> |
@@ -1784,6 +1817,7 @@ void SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) { |
prev->fNext = next; |
if (next) { |
next->fPrev = prev; |
+ next->validate(); |
} |
} else { |
fHead = next; |
@@ -1811,20 +1845,25 @@ bool SkTSect<TCurve, OppCurve>::updateBounded(SkTSpan<TCurve, OppCurve>* first, |
template<typename TCurve, typename OppCurve> |
void SkTSect<TCurve, OppCurve>::validate() const { |
-#if DEBUG_T_SECT |
+#if DEBUG_VALIDATE |
int count = 0; |
+ double last = 0; |
if (fHead) { |
const SkTSpan<TCurve, OppCurve>* span = fHead; |
SkASSERT(!span->fPrev); |
- SkDEBUGCODE(double last = 0); |
+ const SkTSpan<TCurve, OppCurve>* next; |
do { |
span->validate(); |
SkASSERT(span->fStartT >= last); |
- SkDEBUGCODE(last = span->fEndT); |
+ last = span->fEndT; |
++count; |
- } while ((span = span->fNext) != nullptr); |
+ next = span->fNext; |
+ SkASSERT(next != span); |
+ } while ((span = next) != nullptr); |
} |
SkASSERT(count == fActiveCount); |
+#endif |
+#if DEBUG_T_SECT |
SkASSERT(fActiveCount <= fDebugAllocatedCount); |
int deletedCount = 0; |
const SkTSpan<TCurve, OppCurve>* deleted = fDeleted; |
@@ -1843,7 +1882,7 @@ void SkTSect<TCurve, OppCurve>::validate() const { |
template<typename TCurve, typename OppCurve> |
void SkTSect<TCurve, OppCurve>::validateBounded() const { |
-#if DEBUG_T_SECT |
+#if DEBUG_VALIDATE |
if (!fHead) { |
return; |
} |
@@ -2075,6 +2114,7 @@ void SkTSect<TCurve, OppCurve>::BinarySearch(SkTSect<TCurve, OppCurve>* sect1, |
} |
// trim parts that don't intersect the opposite |
SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne(); |
+ SkDEBUGCODE(half1->debugSetGlobalState(sect1->globalState())); |
if (!half1->split(largest1, §1->fHeap)) { |
break; |
} |
@@ -2086,6 +2126,7 @@ void SkTSect<TCurve, OppCurve>::BinarySearch(SkTSect<TCurve, OppCurve>* sect1, |
} |
// trim parts that don't intersect the opposite |
SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); |
+ SkDEBUGCODE(half2->debugSetGlobalState(sect2->globalState())); |
if (!half2->split(largest2, §2->fHeap)) { |
break; |
} |