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

Unified Diff: src/pathops/SkOpSpan.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/SkOpSpan.h ('k') | src/pathops/SkOpTAllocator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkOpSpan.cpp
diff --git a/src/pathops/SkPathOpsPostSect.cpp b/src/pathops/SkOpSpan.cpp
old mode 100644
new mode 100755
similarity index 55%
copy from src/pathops/SkPathOpsPostSect.cpp
copy to src/pathops/SkOpSpan.cpp
index 15a1900ce3b1ad48a8a62768d5564379873cda51..37d5120019dae9dc772762dd9d974626b966b6db
--- a/src/pathops/SkPathOpsPostSect.cpp
+++ b/src/pathops/SkOpSpan.cpp
@@ -17,8 +17,8 @@ SkOpContour* SkOpPtT::contour() const {
return segment()->contour();
}
-SkOpDebugState* SkOpPtT::debugState() const {
- return PATH_OPS_DEBUG_RELEASE(contour()->debugState(), NULL);
+SkOpGlobalState* SkOpPtT::globalState() const {
+ return contour()->globalState();
}
void SkOpPtT::init(SkOpSpanBase* span, double t, const SkPoint& pt, bool duplicate) {
@@ -28,7 +28,7 @@ void SkOpPtT::init(SkOpSpanBase* span, double t, const SkPoint& pt, bool duplica
fNext = this;
fDuplicatePt = duplicate;
fDeleted = false;
- PATH_OPS_DEBUG_CODE(fID = ++span->debugState()->fPtTID);
+ PATH_OPS_DEBUG_CODE(fID = span->globalState()->nextPtTID());
}
bool SkOpPtT::onEnd() const {
@@ -40,12 +40,23 @@ bool SkOpPtT::onEnd() const {
return span == segment->head() || span == segment->tail();
}
+SkOpPtT* SkOpPtT::prev() {
+ SkOpPtT* result = this;
+ SkOpPtT* next = this;
+ while ((next = next->fNext) != this) {
+ result = next;
+ }
+ SkASSERT(result->fNext == this);
+ return result;
+}
+
SkOpPtT* SkOpPtT::remove() {
SkOpPtT* prev = this;
do {
SkOpPtT* next = prev->fNext;
if (next == this) {
- prev->removeNext();
+ prev->removeNext(this);
+ SkASSERT(prev->fNext != prev);
fDeleted = true;
return prev;
}
@@ -55,14 +66,15 @@ SkOpPtT* SkOpPtT::remove() {
return NULL;
}
-void SkOpPtT::removeNext() {
+void SkOpPtT::removeNext(SkOpPtT* kept) {
SkASSERT(this->fNext);
SkOpPtT* next = this->fNext;
+ SkASSERT(this != next->fNext);
this->fNext = next->fNext;
SkOpSpanBase* span = next->span();
next->setDeleted();
if (span->ptT() == next) {
- span->upCast()->detach();
+ span->upCast()->detach(kept);
}
}
@@ -199,7 +211,7 @@ void SkOpSpanBase::alignInner() {
// omit aliases that alignment makes redundant
if ((!ptT->alias() || test->alias()) && (ptT->onEnd() || !test->onEnd())) {
SkASSERT(test->alias());
- prev->removeNext();
+ prev->removeNext(ptT);
test = prev;
} else {
SkASSERT(ptT->alias());
@@ -224,6 +236,17 @@ bool SkOpSpanBase::contains(const SkOpSpanBase* span) const {
return false;
}
+SkOpPtT* SkOpSpanBase::contains(const SkOpSegment* segment) {
+ SkOpPtT* start = &fPtT;
+ SkOpPtT* walk = start;
+ while ((walk = walk->next()) != start) {
+ if (walk->segment() == segment) {
+ return walk;
+ }
+ }
+ return NULL;
+}
+
bool SkOpSpanBase::containsCoinEnd(const SkOpSegment* segment) const {
SkASSERT(this->segment() != segment);
const SkOpSpanBase* next = this;
@@ -239,8 +262,8 @@ SkOpContour* SkOpSpanBase::contour() const {
return segment()->contour();
}
-SkOpDebugState* SkOpSpanBase::debugState() const {
- return PATH_OPS_DEBUG_RELEASE(contour()->debugState(), NULL);
+SkOpGlobalState* SkOpSpanBase::globalState() const {
+ return contour()->globalState();
}
void SkOpSpanBase::initBase(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoint& pt) {
@@ -252,7 +275,7 @@ void SkOpSpanBase::initBase(SkOpSegment* segment, SkOpSpan* prev, double t, cons
fAligned = true;
fChased = false;
PATH_OPS_DEBUG_CODE(fCount = 1);
- PATH_OPS_DEBUG_CODE(fID = ++debugState()->fSpanID);
+ PATH_OPS_DEBUG_CODE(fID = globalState()->nextSpanID());
}
// this pair of spans share a common t value or point; merge them and eliminate duplicates
@@ -261,7 +284,7 @@ void SkOpSpanBase::merge(SkOpSpan* span) {
SkOpPtT* spanPtT = span->ptT();
SkASSERT(this->t() != spanPtT->fT);
SkASSERT(!zero_or_one(spanPtT->fT));
- span->detach();
+ span->detach(this->ptT());
SkOpPtT* remainder = spanPtT->next();
ptT()->insert(spanPtT);
while (remainder != spanPtT) {
@@ -280,14 +303,6 @@ tryNextRemainder:
}
}
-void SkOpSpanBase::mergeBaseAttributes(SkOpSpanBase* span) {
- SkASSERT(!span->fChased);
- SkASSERT(!span->fFromAngle);
- if (this->upCastable() && span->upCastable()) {
- this->upCast()->mergeAttributes(span->upCast());
- }
-}
-
void SkOpSpan::applyCoincidence(SkOpSpan* opp) {
SkASSERT(!final());
SkASSERT(0); // incomplete
@@ -295,16 +310,16 @@ void SkOpSpan::applyCoincidence(SkOpSpan* opp) {
bool SkOpSpan::containsCoincidence(const SkOpSegment* segment) const {
SkASSERT(this->segment() != segment);
- const SkOpSpan* next = this;
- while ((next = next->fCoincident) != this) {
+ const SkOpSpan* next = fCoincident;
+ do {
if (next->segment() == segment) {
return true;
}
- }
+ } while ((next = next->fCoincident) != this);
return false;
}
-void SkOpSpan::detach() {
+void SkOpSpan::detach(SkOpPtT* kept) {
SkASSERT(!final());
SkOpSpan* prev = this->prev();
SkASSERT(prev);
@@ -313,6 +328,7 @@ void SkOpSpan::detach() {
prev->setNext(next);
next->setPrev(prev);
this->segment()->detach(this);
+ this->globalState()->coincidence()->fixUp(this->ptT(), kept);
this->ptT()->setDeleted();
}
@@ -328,175 +344,12 @@ void SkOpSpan::init(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoin
segment->bumpCount();
}
-void SkOpSpan::mergeAttributes(SkOpSpan* span) {
- SkASSERT(!span->fToAngle);
- if (span->fCoincident) {
- this->insertCoincidence(span);
- }
-}
-
-void SkOpCoincidence::add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
- SkOpPtT* oppPtTEnd, bool flipped, SkChunkAlloc* allocator) {
- SkCoincidentSpans* coinRec = SkOpTAllocator<SkCoincidentSpans>::Allocate(allocator);
- SkOpSpanBase* coinEnd = coinPtTEnd->span();
- SkOpSpanBase* oppEnd = oppPtTEnd->span();
- SkOpSpan* coinStart = coinPtTStart->span()->upCast();
- SkASSERT(coinStart == coinStart->starter(coinEnd));
- SkOpSpan* oppStart = (flipped ? oppPtTEnd : oppPtTStart)->span()->upCast();
- SkASSERT(oppStart == oppStart->starter(oppEnd));
- coinStart->insertCoincidence(oppStart);
- coinEnd->insertCoinEnd(oppEnd);
- coinRec->fNext = this->fHead;
- coinRec->fCoinPtTStart = coinPtTStart;
- coinRec->fCoinPtTEnd = coinPtTEnd;
- coinRec->fOppPtTStart = oppPtTStart;
- coinRec->fOppPtTEnd = oppPtTEnd;
- coinRec->fFlipped = flipped;
- this->fHead = coinRec;
-}
-
-bool SkOpCoincidence::contains(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
- SkOpPtT* oppPtTEnd, bool flipped) {
- SkCoincidentSpans* coin = fHead;
- if (!coin) {
- return false;
- }
- do {
- if (coin->fCoinPtTStart == coinPtTStart && coin->fCoinPtTEnd == coinPtTEnd
- && coin->fOppPtTStart == oppPtTStart && coin->fOppPtTEnd == oppPtTEnd
- && coin->fFlipped == flipped) {
- return true;
- }
- } while ((coin = coin->fNext));
- return false;
-}
-
-// walk span sets in parallel, moving winding from one to the other
-void SkOpCoincidence::apply() {
- SkCoincidentSpans* coin = fHead;
- if (!coin) {
- return;
- }
- do {
- SkOpSpanBase* end = coin->fCoinPtTEnd->span();
- SkOpSpan* start = coin->fCoinPtTStart->span()->upCast();
- SkASSERT(start == start->starter(end));
- bool flipped = coin->fFlipped;
- SkOpSpanBase* oEnd = (flipped ? coin->fOppPtTStart : coin->fOppPtTEnd)->span();
- SkOpSpan* oStart = (flipped ? coin->fOppPtTEnd : coin->fOppPtTStart)->span()->upCast();
- SkASSERT(oStart == oStart->starter(oEnd));
- SkOpSegment* segment = start->segment();
- SkOpSegment* oSegment = oStart->segment();
- bool operandSwap = segment->operand() != oSegment->operand();
- if (flipped) {
- do {
- SkOpSpanBase* oNext = oStart->next();
- if (oNext == oEnd) {
- break;
- }
- oStart = oNext->upCast();
- } while (true);
- }
- bool isXor = segment->isXor();
- bool oppXor = oSegment->isXor();
- do {
- int windValue = start->windValue();
- int oWindValue = oStart->windValue();
- int oppValue = start->oppValue();
- int oOppValue = oStart->oppValue();
- // winding values are added or subtracted depending on direction and wind type
- // same or opposite values are summed depending on the operand value
- if (windValue >= oWindValue) {
- if (operandSwap) {
- SkTSwap(oWindValue, oOppValue);
- }
- if (flipped) {
- windValue -= oWindValue;
- oppValue -= oOppValue;
- } else {
- windValue += oWindValue;
- oppValue += oOppValue;
- }
- if (isXor) {
- windValue &= 1;
- }
- if (oppXor) {
- oppValue &= 1;
- }
- oWindValue = oOppValue = 0;
- } else {
- if (operandSwap) {
- SkTSwap(windValue, oppValue);
- }
- if (flipped) {
- oWindValue -= windValue;
- oOppValue -= oppValue;
- } else {
- oWindValue += windValue;
- oOppValue += oppValue;
- }
- if (isXor) {
- oOppValue &= 1;
- }
- if (oppXor) {
- oWindValue &= 1;
- }
- windValue = oppValue = 0;
- }
- start->setWindValue(windValue);
- start->setOppValue(oppValue);
- oStart->setWindValue(oWindValue);
- oStart->setOppValue(oOppValue);
- if (!windValue && !oppValue) {
- segment->markDone(start);
- }
- if (!oWindValue && !oOppValue) {
- oSegment->markDone(oStart);
- }
- SkOpSpanBase* next = start->next();
- SkOpSpanBase* oNext = flipped ? oStart->prev() : oStart->next();
- if (next == end) {
- break;
- }
- start = next->upCast();
- oStart = oNext->upCast();
- } while (true);
- } while ((coin = coin->fNext));
-}
-
-void SkOpCoincidence::mark() {
- SkCoincidentSpans* coin = fHead;
- if (!coin) {
+void SkOpSpan::setOppSum(int oppSum) {
+ SkASSERT(!final());
+ if (fOppSum != SK_MinS32 && fOppSum != oppSum) {
+ this->globalState()->setWindingFailed();
return;
}
- do {
- SkOpSpanBase* end = coin->fCoinPtTEnd->span();
- SkOpSpanBase* oldEnd = end;
- SkOpSpan* start = coin->fCoinPtTStart->span()->starter(&end);
- SkOpSpanBase* oEnd = coin->fOppPtTEnd->span();
- SkOpSpanBase* oOldEnd = oEnd;
- SkOpSpanBase* oStart = coin->fOppPtTStart->span()->starter(&oEnd);
- bool flipped = (end == oldEnd) != (oEnd == oOldEnd);
- if (flipped) {
- SkTSwap(oStart, oEnd);
- }
- SkOpSpanBase* next = start;
- SkOpSpanBase* oNext = oStart;
- do {
- next = next->upCast()->next();
- oNext = flipped ? oNext->prev() : oNext->upCast()->next();
- if (next == end) {
- SkASSERT(oNext == oEnd);
- break;
- }
- if (!next->containsCoinEnd(oNext)) {
- next->insertCoinEnd(oNext);
- }
- SkOpSpan* nextSpan = next->upCast();
- SkOpSpan* oNextSpan = oNext->upCast();
- if (!nextSpan->containsCoincidence(oNextSpan)) {
- nextSpan->insertCoincidence(oNextSpan);
- }
- } while (true);
- } while ((coin = coin->fNext));
+ SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(oppSum) <= DEBUG_LIMIT_WIND_SUM);
+ fOppSum = oppSum;
}
« no previous file with comments | « src/pathops/SkOpSpan.h ('k') | src/pathops/SkOpTAllocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698