aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkPathOpsTSect.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/pathops/SkPathOpsTSect.h')
-rw-r--r--src/pathops/SkPathOpsTSect.h71
1 files changed, 56 insertions, 15 deletions
diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h
index 07b983a1fa..1e483ea0ca 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, &sect1->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, &sect2->fHeap)) {
break;
}