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

Side by Side Diff: src/pathops/SkPathOpsDebug.cpp

Issue 2237223002: pathops coincident work (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove unused code Created 4 years, 3 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 unified diff | Download patch
« no previous file with comments | « src/pathops/SkPathOpsDebug.h ('k') | src/pathops/SkPathOpsPoint.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkMutex.h" 8 #include "SkMutex.h"
9 #include "SkOpCoincidence.h" 9 #include "SkOpCoincidence.h"
10 #include "SkOpContour.h" 10 #include "SkOpContour.h"
11 #include "SkPath.h" 11 #include "SkPath.h"
12 #include "SkPathOpsDebug.h" 12 #include "SkPathOpsDebug.h"
13 #include "SkString.h" 13 #include "SkString.h"
14 14
15 #undef FAIL_IF
16 #define FAIL_IF(cond, coin) \
17 do { if (cond) log->record(kAddExpandedFail_Glitch, id, coin); } while (false)
18
19 #undef FAIL_WITH_NULL_IF
20 #define FAIL_WITH_NULL_IF(cond, span) \
21 do { if (cond) log->record(kAddExpandedFail_Glitch, id, span); } while (false)
22
23 #undef RETURN_FALSE_IF
24 #define RETURN_FALSE_IF(cond, span) \
25 do { if (cond) log->record(kAddExpandedFail_Glitch, id, span); } while (false)
26
15 class SkCoincidentSpans; 27 class SkCoincidentSpans;
16 28
17 #if DEBUG_VALIDATE 29 #if DEBUG_VALIDATE
18 extern bool FLAGS_runFail; 30 extern bool FLAGS_runFail;
19 #endif 31 #endif
20 32
21 #if DEBUG_SORT 33 #if DEBUG_SORT
22 int SkPathOpsDebug::gSortCountDefault = SK_MaxS32; 34 int SkPathOpsDebug::gSortCountDefault = SK_MaxS32;
23 int SkPathOpsDebug::gSortCount; 35 int SkPathOpsDebug::gSortCount;
24 #endif 36 #endif
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 kCollapsedOppValue_Glitch, 72 kCollapsedOppValue_Glitch,
61 kCollapsedSpan_Glitch, 73 kCollapsedSpan_Glitch,
62 kCollapsedWindValue_Glitch, 74 kCollapsedWindValue_Glitch,
63 kDeletedCoin_Glitch, 75 kDeletedCoin_Glitch,
64 kExpandCoin_Glitch, 76 kExpandCoin_Glitch,
65 kMarkCoinEnd_Glitch, 77 kMarkCoinEnd_Glitch,
66 kMarkCoinInsert_Glitch, 78 kMarkCoinInsert_Glitch,
67 kMarkCoinMissing_Glitch, 79 kMarkCoinMissing_Glitch,
68 kMarkCoinStart_Glitch, 80 kMarkCoinStart_Glitch,
69 kMergeContained_Glitch, 81 kMergeContained_Glitch,
82 kMergeMatches_Glitch,
70 kMissingCoin_Glitch, 83 kMissingCoin_Glitch,
71 kMissingDone_Glitch, 84 kMissingDone_Glitch,
72 kMissingIntersection_Glitch, 85 kMissingIntersection_Glitch,
73 kMoveMultiple_Glitch, 86 kMoveMultiple_Glitch,
74 kMoveNearbyClearAll_Glitch, 87 kMoveNearbyClearAll_Glitch,
75 kMoveNearbyClearAll2_Glitch, 88 kMoveNearbyClearAll2_Glitch,
76 kMoveNearbyMerge_Glitch, 89 kMoveNearbyMerge_Glitch,
77 kMoveNearbyMergeFinal_Glitch, 90 kMoveNearbyMergeFinal_Glitch,
78 kMoveNearbyRelease_Glitch, 91 kMoveNearbyRelease_Glitch,
79 kMoveNearbyReleaseFinal_Glitch, 92 kMoveNearbyReleaseFinal_Glitch,
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 case kCollapsedOppValue_Glitch: SkDebugf(" CollapsedOppValue"); brea k; 337 case kCollapsedOppValue_Glitch: SkDebugf(" CollapsedOppValue"); brea k;
325 case kCollapsedSpan_Glitch: SkDebugf(" CollapsedSpan"); break; 338 case kCollapsedSpan_Glitch: SkDebugf(" CollapsedSpan"); break;
326 case kCollapsedWindValue_Glitch: SkDebugf(" CollapsedWindValue"); br eak; 339 case kCollapsedWindValue_Glitch: SkDebugf(" CollapsedWindValue"); br eak;
327 case kDeletedCoin_Glitch: SkDebugf(" DeletedCoin"); break; 340 case kDeletedCoin_Glitch: SkDebugf(" DeletedCoin"); break;
328 case kExpandCoin_Glitch: SkDebugf(" ExpandCoin"); break; 341 case kExpandCoin_Glitch: SkDebugf(" ExpandCoin"); break;
329 case kMarkCoinEnd_Glitch: SkDebugf(" MarkCoinEnd"); break; 342 case kMarkCoinEnd_Glitch: SkDebugf(" MarkCoinEnd"); break;
330 case kMarkCoinInsert_Glitch: SkDebugf(" MarkCoinInsert"); break; 343 case kMarkCoinInsert_Glitch: SkDebugf(" MarkCoinInsert"); break;
331 case kMarkCoinMissing_Glitch: SkDebugf(" MarkCoinMissing"); break; 344 case kMarkCoinMissing_Glitch: SkDebugf(" MarkCoinMissing"); break;
332 case kMarkCoinStart_Glitch: SkDebugf(" MarkCoinStart"); break; 345 case kMarkCoinStart_Glitch: SkDebugf(" MarkCoinStart"); break;
333 case kMergeContained_Glitch: SkDebugf(" MergeContained"); break; 346 case kMergeContained_Glitch: SkDebugf(" MergeContained"); break;
347 case kMergeMatches_Glitch: SkDebugf(" MergeMatches"); break;
334 case kMissingCoin_Glitch: SkDebugf(" MissingCoin"); break; 348 case kMissingCoin_Glitch: SkDebugf(" MissingCoin"); break;
335 case kMissingDone_Glitch: SkDebugf(" MissingDone"); break; 349 case kMissingDone_Glitch: SkDebugf(" MissingDone"); break;
336 case kMissingIntersection_Glitch: SkDebugf(" MissingIntersection"); break; 350 case kMissingIntersection_Glitch: SkDebugf(" MissingIntersection"); break;
337 case kMoveMultiple_Glitch: SkDebugf(" MoveMultiple"); break; 351 case kMoveMultiple_Glitch: SkDebugf(" MoveMultiple"); break;
338 case kMoveNearbyClearAll_Glitch: SkDebugf(" MoveNearbyClearAll"); br eak; 352 case kMoveNearbyClearAll_Glitch: SkDebugf(" MoveNearbyClearAll"); br eak;
339 case kMoveNearbyClearAll2_Glitch: SkDebugf(" MoveNearbyClearAll2"); break; 353 case kMoveNearbyClearAll2_Glitch: SkDebugf(" MoveNearbyClearAll2"); break;
340 case kMoveNearbyMerge_Glitch: SkDebugf(" MoveNearbyMerge"); break; 354 case kMoveNearbyMerge_Glitch: SkDebugf(" MoveNearbyMerge"); break;
341 case kMoveNearbyMergeFinal_Glitch: SkDebugf(" MoveNearbyMergeFinal") ; break; 355 case kMoveNearbyMergeFinal_Glitch: SkDebugf(" MoveNearbyMergeFinal") ; break;
342 case kMoveNearbyRelease_Glitch: SkDebugf(" MoveNearbyRelease"); brea k; 356 case kMoveNearbyRelease_Glitch: SkDebugf(" MoveNearbyRelease"); brea k;
343 case kMoveNearbyReleaseFinal_Glitch: SkDebugf(" MoveNearbyReleaseFin al"); break; 357 case kMoveNearbyReleaseFinal_Glitch: SkDebugf(" MoveNearbyReleaseFin al"); break;
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 return cubic; 587 return cubic;
574 } 588 }
575 589
576 void SkDRect::debugInit() { 590 void SkDRect::debugInit() {
577 fLeft = fTop = fRight = fBottom = SK_ScalarNaN; 591 fLeft = fTop = fRight = fBottom = SK_ScalarNaN;
578 } 592 }
579 593
580 #include "SkOpAngle.h" 594 #include "SkOpAngle.h"
581 #include "SkOpSegment.h" 595 #include "SkOpSegment.h"
582 596
583 #if DEBUG_COINCIDENCE 597 #if DEBUG_COINCIDENCE_VERBOSE
584 // commented-out lines keep this in sync with addT() 598 // commented-out lines keep this in sync with addT()
585 const SkOpPtT* SkOpSegment::debugAddT(double t) const { 599 const SkOpPtT* SkOpSegment::debugAddT(double t, const char* id, SkPathOpsDebug: :GlitchLog* log) const {
586 debugValidate(); 600 debugValidate();
587 SkPoint pt = this->ptAtT(t); 601 SkPoint pt = this->ptAtT(t);
588 const SkOpSpanBase* span = &fHead; 602 const SkOpSpanBase* span = &fHead;
589 do { 603 do {
590 const SkOpPtT* result = span->ptT(); 604 const SkOpPtT* result = span->ptT();
591 if (t == result->fT || this->match(result, this, t, pt)) { 605 if (t == result->fT || this->match(result, this, t, pt)) {
592 // span->bumpSpanAdds(); 606 // span->bumpSpanAdds();
593 return result; 607 return result;
594 } 608 }
595 if (t < result->fT) { 609 if (t < result->fT) {
596 const SkOpSpan* prev = result->span()->prev(); 610 const SkOpSpan* prev = result->span()->prev();
597 FAIL_WITH_NULL_IF(!prev); 611 FAIL_WITH_NULL_IF(!prev, span);
598 // marks in global state that new op span has been allocated 612 // marks in global state that new op span has been allocated
599 this->globalState()->setAllocatedOpSpan(); 613 this->globalState()->setAllocatedOpSpan();
600 // span->init(this, prev, t, pt); 614 // span->init(this, prev, t, pt);
601 this->debugValidate(); 615 this->debugValidate();
602 // #if DEBUG_ADD_T 616 // #if DEBUG_ADD_T
603 // SkDebugf("%s insert t=%1.9g segID=%d spanID=%d\n", __FUNCTION__, t, 617 // SkDebugf("%s insert t=%1.9g segID=%d spanID=%d\n", __FUNCTION__, t,
604 // span->segment()->debugID(), span->debugID()); 618 // span->segment()->debugID(), span->debugID());
605 // #endif 619 // #endif
606 // span->bumpSpanAdds(); 620 // span->bumpSpanAdds();
607 return nullptr; 621 return nullptr;
608 } 622 }
609 FAIL_WITH_NULL_IF(span != &fTail); 623 FAIL_WITH_NULL_IF(span != &fTail, span);
610 } while ((span = span->upCast()->next())); 624 } while ((span = span->upCast()->next()));
611 SkASSERT(0); 625 SkASSERT(0);
612 return nullptr; // we never get here, but need this to satisfy compiler 626 return nullptr; // we never get here, but need this to satisfy compiler
613 } 627 }
614 #endif 628 #endif
615 629
616 #if DEBUG_ANGLE 630 #if DEBUG_ANGLE
617 void SkOpSegment::debugCheckAngleCoin() const { 631 void SkOpSegment::debugCheckAngleCoin() const {
618 const SkOpSpanBase* base = &fHead; 632 const SkOpSpanBase* base = &fHead;
619 const SkOpSpan* span; 633 const SkOpSpan* span;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 const SkOpCoincidence* coincidence = this->globalState()->coincidenc e(); 783 const SkOpCoincidence* coincidence = this->globalState()->coincidenc e();
770 const SkOpPtT* rootPriorPtT = priorPtT->span()->ptT(); 784 const SkOpPtT* rootPriorPtT = priorPtT->span()->ptT();
771 const SkOpPtT* rootPtT = ptT->span()->ptT(); 785 const SkOpPtT* rootPtT = ptT->span()->ptT();
772 const SkOpPtT* rootOppStart = oppStart->span()->ptT(); 786 const SkOpPtT* rootOppStart = oppStart->span()->ptT();
773 const SkOpPtT* rootOppEnd = oppEnd->span()->ptT(); 787 const SkOpPtT* rootOppEnd = oppEnd->span()->ptT();
774 if (coincidence->contains(rootPriorPtT, rootPtT, rootOppStart, rootO ppEnd)) { 788 if (coincidence->contains(rootPriorPtT, rootPtT, rootOppStart, rootO ppEnd)) {
775 goto swapBack; 789 goto swapBack;
776 } 790 }
777 if (testForCoincidence(rootPriorPtT, rootPtT, prior, spanBase, opp)) { 791 if (testForCoincidence(rootPriorPtT, rootPtT, prior, spanBase, opp)) {
778 // mark coincidence 792 // mark coincidence
779 #if DEBUG_COINCIDENCE 793 #if DEBUG_COINCIDENCE_VERBOSE
780 // SkDebugf("%s coinSpan=%d endSpan=%d oppSpan=%d oppEndSpan=%d\ n", __FUNCTION__, 794 // SkDebugf("%s coinSpan=%d endSpan=%d oppSpan=%d oppEndSpan=%d\ n", __FUNCTION__,
781 // rootPriorPtT->debugID(), rootPtT->debugID(), rootOppS tart->debugID(), 795 // rootPriorPtT->debugID(), rootPtT->debugID(), rootOppS tart->debugID(),
782 // rootOppEnd->debugID()); 796 // rootOppEnd->debugID());
783 #endif 797 #endif
784 log->record(kMissingCoin_Glitch, id, priorPtT, ptT, oppStart, op pEnd); 798 log->record(kMissingCoin_Glitch, id, priorPtT, ptT, oppStart, op pEnd);
785 // coincidences->add(rootPriorPtT, rootPtT, rootOppStart, root OppEnd); 799 // coincidences->add(rootPriorPtT, rootPtT, rootOppStart, root OppEnd);
786 // } 800 // }
787 #if DEBUG_COINCIDENCE 801 #if DEBUG_COINCIDENCE
788 // SkASSERT(coincidences->contains(rootPriorPtT, rootPtT, rootOpp Start, rootOppEnd); 802 // SkASSERT(coincidences->contains(rootPriorPtT, rootPtT, rootOpp Start, rootOppEnd);
789 #endif 803 #endif
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 } 886 }
873 const SkOpPtT* matchPtT = startPtT; 887 const SkOpPtT* matchPtT = startPtT;
874 do { 888 do {
875 if (matchPtT->segment() == oppPtTSegment) { 889 if (matchPtT->segment() == oppPtTSegment) {
876 goto foundMatch; 890 goto foundMatch;
877 } 891 }
878 } while ((matchPtT = matchPtT->next()) != startPtT); 892 } while ((matchPtT = matchPtT->next()) != startPtT);
879 goto tryNextSpan; 893 goto tryNextSpan;
880 foundMatch: // merge oppTest and oppSpan 894 foundMatch: // merge oppTest and oppSpan
881 oppSegment->debugValidate(); 895 oppSegment->debugValidate();
882 if (oppTest == &oppSegment->fTail || oppTest == &oppSegment- >fHead) { 896 oppTest->debugMergeMatches(id, glitches, oppSpan);
883 SkASSERT(oppSpan != &oppSegment->fHead); // don't expect collapse 897 oppTest->debugAddOpp(id, glitches, oppSpan);
884 SkASSERT(oppSpan != &oppSegment->fTail);
885 glitches->record(kMoveMultiple_Glitch, id, oppTest, oppS pan);
886 } else {
887 glitches->record(kMoveMultiple_Glitch, id, oppSpan, oppT est);
888 }
889 oppSegment->debugValidate(); 898 oppSegment->debugValidate();
890 goto checkNextSpan; 899 goto checkNextSpan;
891 } 900 }
892 tryNextSpan: 901 tryNextSpan:
893 ; 902 ;
894 } while (oppTest != oppLast && (oppTest = oppTest->upCast()->next()) ); 903 } while (oppTest != oppLast && (oppTest = oppTest->upCast()->next()) );
895 } while ((testPtT = testPtT->next()) != startPtT); 904 } while ((testPtT = testPtT->next()) != startPtT);
896 checkNextSpan: 905 checkNextSpan:
897 ; 906 ;
898 } while ((test = test->final() ? nullptr : test->upCast()->next())); 907 } while ((test = test->final() ? nullptr : test->upCast()->next()));
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 #ifdef SK_DEBUG 1256 #ifdef SK_DEBUG
1248 void SkCoincidentSpans::debugStartCheck(const SkOpSpanBase* outer, const SkOpSpa nBase* over, 1257 void SkCoincidentSpans::debugStartCheck(const SkOpSpanBase* outer, const SkOpSpa nBase* over,
1249 const SkOpGlobalState* debugState) const { 1258 const SkOpGlobalState* debugState) const {
1250 SkASSERT(coinPtTEnd()->span() == over || !debugState->debugRunFail()); 1259 SkASSERT(coinPtTEnd()->span() == over || !debugState->debugRunFail());
1251 SkASSERT(oppPtTEnd()->span() == outer || !debugState->debugRunFail()); 1260 SkASSERT(oppPtTEnd()->span() == outer || !debugState->debugRunFail());
1252 } 1261 }
1253 #endif 1262 #endif
1254 1263
1255 #if DEBUG_COINCIDENCE_VERBOSE 1264 #if DEBUG_COINCIDENCE_VERBOSE
1256 /* Commented-out lines keep this in sync with expand */ 1265 /* Commented-out lines keep this in sync with expand */
1266 // expand the range by checking adjacent spans for coincidence
1257 bool SkCoincidentSpans::debugExpand(const char* id, SkPathOpsDebug::GlitchLog* l og) const { 1267 bool SkCoincidentSpans::debugExpand(const char* id, SkPathOpsDebug::GlitchLog* l og) const {
1258 bool expanded = false; 1268 bool expanded = false;
1259 const SkOpSegment* segment = coinPtTStart()->segment(); 1269 const SkOpSegment* segment = coinPtTStart()->segment();
1260 const SkOpSegment* oppSegment = oppPtTStart()->segment(); 1270 const SkOpSegment* oppSegment = oppPtTStart()->segment();
1261 do { 1271 do {
1262 const SkOpSpan* start = coinPtTStart()->span()->upCast(); 1272 const SkOpSpan* start = coinPtTStart()->span()->upCast();
1263 const SkOpSpan* prev = start->prev(); 1273 const SkOpSpan* prev = start->prev();
1264 const SkOpPtT* oppPtT; 1274 const SkOpPtT* oppPtT;
1265 if (!prev || !(oppPtT = prev->contains(oppSegment))) { 1275 if (!prev || !(oppPtT = prev->contains(oppSegment))) {
1266 break; 1276 break;
1267 } 1277 }
1268 double midT = (prev->t() + start->t()) / 2; 1278 double midT = (prev->t() + start->t()) / 2;
1269 if (!segment->isClose(midT, oppSegment)) { 1279 if (!segment->isClose(midT, oppSegment)) {
1270 break; 1280 break;
1271 } 1281 }
1272 if (log) log->record(kExpandCoin_Glitch, id, this, prev->ptT(), oppPtT); 1282 if (log) log->record(kExpandCoin_Glitch, id, this, prev->ptT(), oppPtT);
1273 expanded = true; 1283 expanded = true;
1274 } while (false); // actual continues while expansion is possible 1284 } while (false); // actual continues while expansion is possible
1275 do { 1285 do {
1276 const SkOpSpanBase* end = coinPtTEnd()->span(); 1286 const SkOpSpanBase* end = coinPtTEnd()->span();
1277 SkOpSpanBase* next = end->final() ? nullptr : end->upCast()->next(); 1287 SkOpSpanBase* next = end->final() ? nullptr : end->upCast()->next();
1288 if (next && next->deleted()) {
1289 break;
1290 }
1278 const SkOpPtT* oppPtT; 1291 const SkOpPtT* oppPtT;
1279 if (!next || !(oppPtT = next->contains(oppSegment))) { 1292 if (!next || !(oppPtT = next->contains(oppSegment))) {
1280 break; 1293 break;
1281 } 1294 }
1282 double midT = (end->t() + next->t()) / 2; 1295 double midT = (end->t() + next->t()) / 2;
1283 if (!segment->isClose(midT, oppSegment)) { 1296 if (!segment->isClose(midT, oppSegment)) {
1284 break; 1297 break;
1285 } 1298 }
1286 if (log) log->record(kExpandCoin_Glitch, id, this, next->ptT(), oppPtT); 1299 if (log) log->record(kExpandCoin_Glitch, id, this, next->ptT(), oppPtT);
1287 expanded = true; 1300 expanded = true;
1288 } while (false); // actual continues while expansion is possible 1301 } while (false); // actual continues while expansion is possible
1289 return expanded; 1302 return expanded;
1290 } 1303 }
1291 1304
1292 #undef FAIL_IF
1293 #define FAIL_IF(cond) do { if (cond) log->record(kAddExpandedFail_Glitch, id, c oin); } while (false)
1294
1295 /* Commented-out lines keep this in sync with addExpanded */ 1305 /* Commented-out lines keep this in sync with addExpanded */
1296 // for each coincident pair, match the spans 1306 // for each coincident pair, match the spans
1297 // if the spans don't match, add the mssing pt to the segment and loop it in the opposite span 1307 // if the spans don't match, add the mssing pt to the segment and loop it in the opposite span
1298 void SkOpCoincidence::debugAddExpanded(const char* id, SkPathOpsDebug::GlitchLog * log) const { 1308 void SkOpCoincidence::debugAddExpanded(const char* id, SkPathOpsDebug::GlitchLog * log) const {
1299 const SkCoincidentSpans* coin = this->fHead; 1309 const SkCoincidentSpans* coin = this->fHead;
1300 if (!coin) { 1310 if (!coin) {
1301 return; 1311 return;
1302 } 1312 }
1303 do { 1313 do {
1304 const SkOpPtT* startPtT = coin->coinPtTStart(); 1314 const SkOpPtT* startPtT = coin->coinPtTStart();
1305 const SkOpPtT* oStartPtT = coin->oppPtTStart(); 1315 const SkOpPtT* oStartPtT = coin->oppPtTStart();
1306 SkASSERT(startPtT->contains(oStartPtT)); 1316 SkASSERT(startPtT->contains(oStartPtT));
1307 SkASSERT(coin->coinPtTEnd()->contains(coin->oppPtTEnd())); 1317 SkASSERT(coin->coinPtTEnd()->contains(coin->oppPtTEnd()));
1308 const SkOpSpanBase* start = startPtT->span(); 1318 const SkOpSpanBase* start = startPtT->span();
1309 const SkOpSpanBase* oStart = oStartPtT->span(); 1319 const SkOpSpanBase* oStart = oStartPtT->span();
1310 const SkOpSpanBase* end = coin->coinPtTEnd()->span(); 1320 const SkOpSpanBase* end = coin->coinPtTEnd()->span();
1311 const SkOpSpanBase* oEnd = coin->oppPtTEnd()->span(); 1321 const SkOpSpanBase* oEnd = coin->oppPtTEnd()->span();
1312 FAIL_IF(oEnd->deleted()); 1322 FAIL_IF(oEnd->deleted(), coin);
1323 FAIL_IF(!start->upCastable(), coin);
1313 const SkOpSpanBase* test = start->upCast()->next(); 1324 const SkOpSpanBase* test = start->upCast()->next();
1314 const SkOpSpanBase* oTest = coin->flipped() ? oStart->prev() : oStart->u pCast()->next(); 1325 const SkOpSpanBase* oTest = coin->flipped() ? oStart->prev() : oStart->u pCast()->next();
1315 if (!oTest) { 1326 if (!oTest) {
1316 return; 1327 return;
1317 } 1328 }
1318 while (test != end || oTest != oEnd) { 1329 while (test != end || oTest != oEnd) {
1319 if (!test->ptT()->contains(oTest->segment()) 1330 if (!test->ptT()->contains(oTest->segment())
1320 || !oTest->ptT()->contains(start->segment())) { 1331 || !oTest->ptT()->contains(start->segment())) {
1321 // use t ranges to guess which one is missing 1332 // use t ranges to guess which one is missing
1322 double startRange = coin->coinPtTEnd()->fT - startPtT->fT; 1333 double startRange = coin->coinPtTEnd()->fT - startPtT->fT;
1323 FAIL_IF(!startRange); 1334 FAIL_IF(!startRange, coin);
1324 double startPart = (test->t() - startPtT->fT) / startRange; 1335 double startPart = (test->t() - startPtT->fT) / startRange;
1325 double oStartRange = coin->oppPtTEnd()->fT - oStartPtT->fT; 1336 double oStartRange = coin->oppPtTEnd()->fT - oStartPtT->fT;
1326 FAIL_IF(!oStartRange); 1337 FAIL_IF(!oStartRange, coin);
1327 double oStartPart = (oTest->t() - oStartPtT->fT) / oStartRange; 1338 double oStartPart = (oTest->t() - oStartPtT->fT) / oStartRange;
1328 FAIL_IF(startPart == oStartPart); 1339 FAIL_IF(startPart == oStartPart, coin);
1329 bool startOver = false; 1340 bool startOver = false;
1330 if (startPart < oStartPart) 1341 if (startPart < oStartPart)
1331 log->record(kAddExpandedCoin_Glitch, id, // strange deb ug formatting lines up with original 1342 log->record(kAddExpandedCoin_Glitch, id, // strange deb ug formatting lines up with original
1332 oStartPtT->fT + oStartRange * startPart, test); 1343 oStartPtT->fT + oStartRange * startPart, test);
1333 else log->record(kAddExpandedCoin_Glitch, id, 1344 else log->record(kAddExpandedCoin_Glitch, id,
1334 startPtT->fT + startRange * oStartPart, oTest); 1345 startPtT->fT + startRange * oStartPart, oTest);
1335 if (false) { 1346 if (false) {
1336 SkASSERT(0); 1347 SkASSERT(0);
1337 return; 1348 return;
1338 } 1349 }
1339 if (startOver) { 1350 if (startOver) {
1340 test = start; 1351 test = start;
1341 oTest = oStart; 1352 oTest = oStart;
1342 } 1353 }
1343 } 1354 }
1344 if (test != end) { 1355 if (test != end) {
1356 if (!test->upCastable()) {
1357 return;
1358 }
1345 test = test->upCast()->next(); 1359 test = test->upCast()->next();
1346 } 1360 }
1347 if (oTest != oEnd) { 1361 if (oTest != oEnd) {
1348 oTest = coin->flipped() ? oTest->prev() : oTest->upCast()->next( ); 1362 oTest = coin->flipped() ? oTest->prev() : oTest->upCast()->next( );
1349 if (!oTest) { 1363 if (!oTest) {
1350 return; 1364 return;
1351 } 1365 }
1352 } 1366 }
1353 } 1367 }
1354 } while ((coin = coin->next())); 1368 } while ((coin = coin->next()));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 SkTSwap(oppTs, oppTe); 1400 SkTSwap(oppTs, oppTe);
1387 } 1401 }
1388 if (swap) { 1402 if (swap) {
1389 SkTSwap(oppTs, oppTe); 1403 SkTSwap(oppTs, oppTe);
1390 } 1404 }
1391 const SkOpSegment* coinSeg = coinPtTStart->segment(); 1405 const SkOpSegment* coinSeg = coinPtTStart->segment();
1392 const SkOpSegment* oppSeg = oppPtTStart->segment(); 1406 const SkOpSegment* oppSeg = oppPtTStart->segment();
1393 if (coinSeg == oppSeg) { 1407 if (coinSeg == oppSeg) {
1394 return; 1408 return;
1395 } 1409 }
1396 return this->debugAddOrOverlap(coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe , id, log); 1410 return this->debugAddOrOverlap(id, log, coinSeg, oppSeg, coinTs, coinTe, opp Ts, oppTe);
1397 } 1411 }
1398 1412
1399 /* Commented-out lines keep this in sync addOrOverlap() */ 1413 /* Commented-out lines keep this in sync addOrOverlap() */
1400 void SkOpCoincidence::debugAddOrOverlap(const SkOpSegment* coinSeg, const SkOpSe gment* oppSeg, 1414 // If this is called by addEndMovedSpans(), a returned false propogates out to a n abort.
1401 double coinTs, double coinTe, double oppTs, double oppTe, const char* id , SkPathOpsDebug::GlitchLog* log) const { 1415 // If this is called by AddIfMissing(), a returned false indicates there was not hing to add
1416 void SkOpCoincidence::debugAddOrOverlap(const char* id, SkPathOpsDebug::GlitchLo g* log,
1417 const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
1418 double coinTs, double coinTe, double oppTs, double oppTe) const {
1402 SkTDArray<SkCoincidentSpans*> overlaps; 1419 SkTDArray<SkCoincidentSpans*> overlaps;
1403 SkASSERT(!fTop); // this is (correctly) reversed in addifMissing() 1420 SkASSERT(!fTop); // this is (correctly) reversed in addifMissing()
1404 if (fTop && !this->checkOverlap(fTop, coinSeg, oppSeg, coinTs, coinTe, oppTs , oppTe, &overlaps)) { 1421 if (fTop && !this->checkOverlap(fTop, coinSeg, oppSeg, coinTs, coinTe, oppTs , oppTe, &overlaps)) {
1405 return; 1422 return;
1406 } 1423 }
1407 if (fHead && !this->checkOverlap(fHead, coinSeg, oppSeg, coinTs, 1424 if (fHead && !this->checkOverlap(fHead, coinSeg, oppSeg, coinTs,
1408 coinTe, oppTs, oppTe, &overlaps)) { 1425 coinTe, oppTs, oppTe, &overlaps)) {
1409 return; 1426 return;
1410 } 1427 }
1411 const SkCoincidentSpans* overlap = overlaps.count() ? overlaps[0] : nullptr; 1428 const SkCoincidentSpans* overlap = overlaps.count() ? overlaps[0] : nullptr;
1412 for (int index = 1; index < overlaps.count(); ++index) { // combine overlaps before continuing 1429 for (int index = 1; index < overlaps.count(); ++index) { // combine overlaps before continuing
1413 const SkCoincidentSpans* test = overlaps[index]; 1430 const SkCoincidentSpans* test = overlaps[index];
1414 if (overlap->coinPtTStart()->fT > test->coinPtTStart()->fT) { 1431 if (overlap->coinPtTStart()->fT > test->coinPtTStart()->fT) {
1415 log->record(kAddOrOverlap_Glitch, id, overlap, test->coinPtTStart()) ; 1432 log->record(kAddOrOverlap_Glitch, id, overlap, test->coinPtTStart()) ;
1416 } 1433 }
1417 if (overlap->coinPtTEnd()->fT < test->coinPtTEnd()->fT) { 1434 if (overlap->coinPtTEnd()->fT < test->coinPtTEnd()->fT) {
1418 log->record(kAddOrOverlap_Glitch, id, overlap, test->coinPtTEnd()); 1435 log->record(kAddOrOverlap_Glitch, id, overlap, test->coinPtTEnd());
1419 } 1436 }
1420 if (overlap->flipped() 1437 if (overlap->flipped()
1421 ? overlap->oppPtTStart()->fT < test->oppPtTStart()->fT 1438 ? overlap->oppPtTStart()->fT < test->oppPtTStart()->fT
1422 : overlap->oppPtTStart()->fT > test->oppPtTStart()->fT) { 1439 : overlap->oppPtTStart()->fT > test->oppPtTStart()->fT) {
1423 log->record(kAddOrOverlap_Glitch, id, overlap, test->oppPtTStart()); 1440 log->record(kAddOrOverlap_Glitch, id, overlap, test->oppPtTStart());
1424 } 1441 }
1425 if (overlap->flipped() 1442 if (overlap->flipped()
1426 ? overlap->oppPtTEnd()->fT > test->oppPtTEnd()->fT 1443 ? overlap->oppPtTEnd()->fT > test->oppPtTEnd()->fT
1427 : overlap->oppPtTEnd()->fT < test->oppPtTEnd()->fT) { 1444 : overlap->oppPtTEnd()->fT < test->oppPtTEnd()->fT) {
1428 log->record(kAddOrOverlap_Glitch, id, overlap, test->oppPtTEnd()); 1445 log->record(kAddOrOverlap_Glitch, id, overlap, test->oppPtTEnd());
1429 } 1446 }
1430 if (!fHead) { 1447 if (!fHead) { this->debugRelease(id, log, fHead, test);
1431 SkAssertResult(true); 1448 this->debugRelease(id, log, fTop, test);
1432 } 1449 }
1433 } 1450 }
1434 const SkOpPtT* cs = coinSeg->existing(coinTs, oppSeg); 1451 const SkOpPtT* cs = coinSeg->existing(coinTs, oppSeg);
1435 const SkOpPtT* ce = coinSeg->existing(coinTe, oppSeg); 1452 const SkOpPtT* ce = coinSeg->existing(coinTe, oppSeg);
1436 if (overlap && cs && ce && overlap->contains(cs, ce)) { 1453 RETURN_FALSE_IF(overlap && cs && ce && overlap->contains(cs, ce), coinSeg);
1437 return; 1454 RETURN_FALSE_IF(cs != ce || !cs, coinSeg);
1438 }
1439 SkASSERT(cs != ce || !cs);
1440 const SkOpPtT* os = oppSeg->existing(oppTs, coinSeg); 1455 const SkOpPtT* os = oppSeg->existing(oppTs, coinSeg);
1441 const SkOpPtT* oe = oppSeg->existing(oppTe, coinSeg); 1456 const SkOpPtT* oe = oppSeg->existing(oppTe, coinSeg);
1442 if (overlap && os && oe && overlap->contains(os, oe)) { 1457 RETURN_FALSE_IF(overlap && os && oe && overlap->contains(os, oe), oppSeg);
1443 return;
1444 }
1445 SkASSERT(true || !cs || !cs->deleted()); 1458 SkASSERT(true || !cs || !cs->deleted());
1446 SkASSERT(true || !os || !os->deleted()); 1459 SkASSERT(true || !os || !os->deleted());
1447 SkASSERT(true || !ce || !ce->deleted()); 1460 SkASSERT(true || !ce || !ce->deleted());
1448 SkASSERT(true || !oe || !oe->deleted()); 1461 SkASSERT(true || !oe || !oe->deleted());
1449 const SkOpPtT* csExisting = !cs ? coinSeg->existing(coinTs, nullptr) : nullp tr; 1462 const SkOpPtT* csExisting = !cs ? coinSeg->existing(coinTs, nullptr) : nullp tr;
1450 const SkOpPtT* ceExisting = !ce ? coinSeg->existing(coinTe, nullptr) : nullp tr; 1463 const SkOpPtT* ceExisting = !ce ? coinSeg->existing(coinTe, nullptr) : nullp tr;
1451 if (csExisting && csExisting == ceExisting) { 1464 RETURN_FALSE_IF(csExisting && csExisting == ceExisting, coinSeg);
1452 return; 1465 RETURN_FALSE_IF(csExisting && (csExisting == ce ||
1453 } 1466 csExisting->contains(ceExisting ? ceExisting : ce)), coinSeg);
1454 if (csExisting && (csExisting == ce || csExisting->contains(ceExisting ? ceE xisting : ce))) { 1467 RETURN_FALSE_IF(ceExisting && (ceExisting == cs ||
1455 return; 1468 ceExisting->contains(csExisting ? csExisting : cs)), coinSeg);
1456 }
1457 if (ceExisting && (ceExisting == cs || ceExisting->contains(csExisting ? csE xisting : cs))) {
1458 return;
1459 }
1460 const SkOpPtT* osExisting = !os ? oppSeg->existing(oppTs, nullptr) : nullptr ; 1469 const SkOpPtT* osExisting = !os ? oppSeg->existing(oppTs, nullptr) : nullptr ;
1461 const SkOpPtT* oeExisting = !oe ? oppSeg->existing(oppTe, nullptr) : nullptr ; 1470 const SkOpPtT* oeExisting = !oe ? oppSeg->existing(oppTe, nullptr) : nullptr ;
1462 if (osExisting && osExisting == oeExisting) { 1471 RETURN_FALSE_IF(osExisting && osExisting == oeExisting, oppSeg);
1463 return; 1472 RETURN_FALSE_IF(osExisting && (osExisting == oe ||
1464 } 1473 osExisting->contains(oeExisting ? oeExisting : oe)), oppSeg);
1465 if (osExisting && (osExisting == oe || osExisting->contains(oeExisting ? oeE xisting : oe))) { 1474 RETURN_FALSE_IF(oeExisting && (oeExisting == os ||
1466 return; 1475 oeExisting->contains(osExisting ? osExisting : os)), oppSeg);
1467 }
1468 if (oeExisting && (oeExisting == os || oeExisting->contains(osExisting ? osE xisting : os))) {
1469 return;
1470 }
1471 bool csDeleted = false, osDeleted = false, ceDeleted = false, oeDeleted = f alse; 1476 bool csDeleted = false, osDeleted = false, ceDeleted = false, oeDeleted = f alse;
1472 this->debugValidate(); 1477 this->debugValidate();
1473 if (!cs || !os) { 1478 if (!cs || !os) {
1474 if (!cs) 1479 if (!cs)
1475 cs = coinSeg->debugAddT(coinTs); 1480 cs = coinSeg->debugAddT(coinTs, id, log);
1476 if (!os) 1481 if (!os)
1477 os = oppSeg->debugAddT(oppTs); 1482 os = oppSeg->debugAddT(oppTs, id, log);
1478 if (cs && os) cs->span()->debugAddOppAndMerge(id, log, os->span(), &csDe leted, &osDeleted); 1483 // RETURN_FALSE_IF(callerAborts, !csWritable || !osWritable);
1484 if (cs && os) cs->span()->debugAddOpp(id, log, os->span());
1479 // cs = csWritable; 1485 // cs = csWritable;
1480 // os = osWritable; 1486 // os = osWritable->active();
1481 if ((ce && ce->deleted()) || (oe && oe->deleted())) { 1487 RETURN_FALSE_IF((ce && ce->deleted()) || (oe && oe->deleted()), coinSeg) ;
1482 return;
1483 }
1484 } 1488 }
1485 if (!ce || !oe) { 1489 if (!ce || !oe) {
1486 if (!ce) 1490 if (!ce)
1487 ce = coinSeg->debugAddT(coinTe); 1491 ce = coinSeg->debugAddT(coinTe, id, log);
1488 if (!oe) 1492 if (!oe)
1489 oe = oppSeg->debugAddT(oppTe); 1493 oe = oppSeg->debugAddT(oppTe, id, log);
1490 if (ce && oe) ce->span()->debugAddOppAndMerge(id, log, oe->span(), &ceDe leted, &oeDeleted); 1494 if (ce && oe) ce->span()->debugAddOpp(id, log, oe->span());
1491 // ce = ceWritable; 1495 // ce = ceWritable;
1492 // oe = oeWritable; 1496 // oe = oeWritable;
1493 } 1497 }
1494 this->debugValidate(); 1498 this->debugValidate();
1495 if (csDeleted || osDeleted || ceDeleted || oeDeleted) { 1499 RETURN_FALSE_IF(csDeleted, coinSeg);
1496 return; 1500 RETURN_FALSE_IF(osDeleted, oppSeg);
1497 } 1501 RETURN_FALSE_IF(ceDeleted, coinSeg);
1498 if (!cs || !ce || cs->contains(ce) || !os || !oe || os->contains(oe)) { 1502 RETURN_FALSE_IF(oeDeleted, oppSeg);
1499 return; 1503 RETURN_FALSE_IF(!cs || !ce || cs->contains(ce) || !os || !oe || os->contains (oe), coinSeg);
1500 }
1501 // bool result = true; 1504 // bool result = true;
1502 if (overlap) { 1505 if (overlap) {
1503 if (overlap->coinPtTStart()->segment() == coinSeg) { 1506 if (overlap->coinPtTStart()->segment() == coinSeg) {
1504 log->record(kAddMissingExtend_Glitch, id, coinSeg, coinTs, coinT e, oppSeg, oppTs, oppTe); 1507 log->record(kAddMissingExtend_Glitch, id, coinSeg, coinTs, coinT e, oppSeg, oppTs, oppTe);
1505 } else { 1508 } else {
1506 if (oppTs > oppTe) { 1509 if (oppTs > oppTe) {
1507 SkTSwap(coinTs, coinTe); 1510 SkTSwap(coinTs, coinTe);
1508 SkTSwap(oppTs, oppTe); 1511 SkTSwap(oppTs, oppTe);
1509 } 1512 }
1510 log->record(kAddMissingExtend_Glitch, id, oppSeg, oppTs, oppTe, coin Seg, coinTs, coinTe); 1513 log->record(kAddMissingExtend_Glitch, id, oppSeg, oppTs, oppTe, coin Seg, coinTs, coinTe);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 } 1595 }
1593 } 1596 }
1594 this->debugValidate(); 1597 this->debugValidate();
1595 } 1598 }
1596 } while ((outer = outer->next())); 1599 } while ((outer = outer->next()));
1597 // this->restoreHead(); 1600 // this->restoreHead();
1598 return; 1601 return;
1599 } 1602 }
1600 1603
1601 // Commented-out lines keep this in sync with release() 1604 // Commented-out lines keep this in sync with release()
1605 void SkOpCoincidence::debugRelease(const char* id, SkPathOpsDebug::GlitchLog* lo g, const SkCoincidentSpans* coin, const SkCoincidentSpans* remove) const {
1606 const SkCoincidentSpans* head = coin;
1607 const SkCoincidentSpans* prev = nullptr;
1608 const SkCoincidentSpans* next;
1609 do {
1610 next = coin->next();
1611 if (coin == remove) {
1612 if (prev) {
1613 // prev->setNext(next);
1614 } else if (head == fHead) {
1615 // fHead = next;
1616 } else {
1617 // fTop = next;
1618 }
1619 log->record(kReleasedSpan_Glitch, id, coin);
1620 }
1621 prev = coin;
1622 } while ((coin = next));
1623 return;
1624 }
1625
1602 void SkOpCoincidence::debugRelease(const char* id, SkPathOpsDebug::GlitchLog* lo g, const SkOpSegment* deleted) const { 1626 void SkOpCoincidence::debugRelease(const char* id, SkPathOpsDebug::GlitchLog* lo g, const SkOpSegment* deleted) const {
1603 const SkCoincidentSpans* coin = fHead; 1627 const SkCoincidentSpans* coin = fHead;
1604 if (!coin) { 1628 if (!coin) {
1605 return; 1629 return;
1606 } 1630 }
1607 do { 1631 do {
1608 if (coin->coinPtTStart()->segment() == deleted 1632 if (coin->coinPtTStart()->segment() == deleted
1609 || coin->coinPtTEnd()->segment() == deleted 1633 || coin->coinPtTEnd()->segment() == deleted
1610 || coin->oppPtTStart()->segment() == deleted 1634 || coin->oppPtTStart()->segment() == deleted
1611 || coin->oppPtTEnd()->segment() == deleted) { 1635 || coin->oppPtTEnd()->segment() == deleted) {
1612 log->record(kReleasedSpan_Glitch, id, coin); 1636 log->record(kReleasedSpan_Glitch, id, coin);
1613 } 1637 }
1614 } while ((coin = coin->next())); 1638 } while ((coin = coin->next()));
1615 } 1639 }
1616 1640
1641
1617 // Commented-out lines keep this in sync with reorder() 1642 // Commented-out lines keep this in sync with reorder()
1618 // iterate through all coincident pairs, looking for ranges greater than 1 1643 // iterate through all coincident pairs, looking for ranges greater than 1
1619 // if found, see if the opposite pair can match it -- which may require 1644 // if found, see if the opposite pair can match it -- which may require
1620 // reordering the ptT pairs 1645 // reordering the ptT pairs
1621 void SkOpCoincidence::debugReorder(const char* id, SkPathOpsDebug::GlitchLog* lo g) const { 1646 void SkOpCoincidence::debugReorder(const char* id, SkPathOpsDebug::GlitchLog* lo g) const {
1622 const SkCoincidentSpans* coin = fHead; 1647 const SkCoincidentSpans* coin = fHead;
1623 if (!coin) { 1648 if (!coin) {
1624 return; 1649 return;
1625 } 1650 }
1626 do { 1651 do {
1627 // most commonly, concidence are one span long; check for that first 1652 // most commonly, concidence are one span long; check for that first
1628 int intervals = coin->spanCount(); 1653 int intervals = coin->spanCount();
1629 if (intervals = 1) { 1654 if (intervals <= 0) {
1655 return;
1656 }
1657 if (1 == intervals) {
1630 #if DEBUG_COINCIDENCE_VERBOSE 1658 #if DEBUG_COINCIDENCE_VERBOSE
1631 // SkASSERT(!coin->debugExpand(nullptr, nullptr)); 1659 // SkASSERT(!coin->debugExpand(nullptr, nullptr));
1632 #endif 1660 #endif
1633 continue; 1661 continue;
1634 } 1662 }
1635 coin->debugExpand(id, log); 1663 coin->debugExpand(id, log);
1636 if (coin->spanCount() <= 0) { 1664 if (coin->spanCount() <= 0) {
1637 return; 1665 return;
1638 } 1666 }
1639 // check to see if every span in coin has a mate in opp 1667 // check to see if every span in coin has a mate in opp
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 } 1730 }
1703 1731
1704 // Commented-out lines keep this in sync with mark() 1732 // Commented-out lines keep this in sync with mark()
1705 /* this sets up the coincidence links in the segments when the coincidence cross es multiple spans */ 1733 /* this sets up the coincidence links in the segments when the coincidence cross es multiple spans */
1706 void SkOpCoincidence::debugMark(const char* id, SkPathOpsDebug::GlitchLog* log) const { 1734 void SkOpCoincidence::debugMark(const char* id, SkPathOpsDebug::GlitchLog* log) const {
1707 const SkCoincidentSpans* coin = fHead; 1735 const SkCoincidentSpans* coin = fHead;
1708 if (!coin) { 1736 if (!coin) {
1709 return; 1737 return;
1710 } 1738 }
1711 do { 1739 do {
1740 if (!coin->coinPtTStartWritable()->span()->upCastable()) {
1741 return;
1742 }
1712 const SkOpSpan* start = coin->coinPtTStartWritable()->span()->upCast(); 1743 const SkOpSpan* start = coin->coinPtTStartWritable()->span()->upCast();
1713 // SkASSERT(start->deleted()); 1744 // SkASSERT(start->deleted());
1714 const SkOpSpanBase* end = coin->coinPtTEndWritable()->span(); 1745 const SkOpSpanBase* end = coin->coinPtTEndWritable()->span();
1715 // SkASSERT(end->deleted()); 1746 // SkASSERT(end->deleted());
1716 const SkOpSpanBase* oStart = coin->oppPtTStartWritable()->span(); 1747 const SkOpSpanBase* oStart = coin->oppPtTStartWritable()->span();
1717 // SkASSERT(oStart->deleted()); 1748 // SkASSERT(oStart->deleted());
1718 const SkOpSpanBase* oEnd = coin->oppPtTEndWritable()->span(); 1749 const SkOpSpanBase* oEnd = coin->oppPtTEndWritable()->span();
1719 // SkASSERT(oEnd->deleted()); 1750 // SkASSERT(oEnd->deleted());
1720 bool flipped = coin->flipped(); 1751 bool flipped = coin->flipped();
1721 if (flipped) { 1752 if (flipped) {
1722 SkTSwap(oStart, oEnd); 1753 SkTSwap(oStart, oEnd);
1723 } 1754 }
1724 /* coin and opp spans may not match up. Mark the ends, and then let the interior 1755 /* coin and opp spans may not match up. Mark the ends, and then let the interior
1725 get marked as many times as the spans allow */ 1756 get marked as many times as the spans allow */
1726 start->debugInsertCoincidence(id, log, oStart->upCast()); 1757 start->debugInsertCoincidence(id, log, oStart->upCast());
1727 end->debugInsertCoinEnd(id, log, oEnd); 1758 end->debugInsertCoinEnd(id, log, oEnd);
1728 const SkOpSegment* segment = start->segment(); 1759 const SkOpSegment* segment = start->segment();
1729 const SkOpSegment* oSegment = oStart->segment(); 1760 const SkOpSegment* oSegment = oStart->segment();
1730 const SkOpSpanBase* next = start; 1761 const SkOpSpanBase* next = start;
1731 const SkOpSpanBase* oNext = oStart; 1762 const SkOpSpanBase* oNext = oStart;
1732 while ((next = next->upCast()->next()) != end) { 1763 while ((next = next->upCast()->next()) != end) {
1764 if (!next->upCastable()) {
1765 return;
1766 }
1733 if (next->upCast()->debugInsertCoincidence(id, log, oSegment, flippe d), false) { 1767 if (next->upCast()->debugInsertCoincidence(id, log, oSegment, flippe d), false) {
1734 return; 1768 return;
1735 } 1769 }
1736 } 1770 }
1737 while ((oNext = oNext->upCast()->next()) != oEnd) { 1771 while ((oNext = oNext->upCast()->next()) != oEnd) {
1772 if (!oNext->upCastable()) {
1773 return;
1774 }
1738 if (oNext->upCast()->debugInsertCoincidence(id, log, segment, flippe d), false) { 1775 if (oNext->upCast()->debugInsertCoincidence(id, log, segment, flippe d), false) {
1739 return; 1776 return;
1740 } 1777 }
1741 } 1778 }
1742 } while ((coin = coin->next())); 1779 } while ((coin = coin->next()));
1743 return; 1780 return;
1744 } 1781 }
1745 #endif 1782 #endif
1746 1783
1747 #if DEBUG_COINCIDENCE_VERBOSE 1784 #if DEBUG_COINCIDENCE_VERBOSE
1748 // Commented-out lines keep this in sync with markCollapsed() 1785 // Commented-out lines keep this in sync with markCollapsed()
1749 void SkOpCoincidence::debugMarkCollapsed(const char* id, SkPathOpsDebug::GlitchL og* log, const SkCoincidentSpans* coin, const SkOpPtT* test) const { 1786 void SkOpCoincidence::debugMarkCollapsed(const char* id, SkPathOpsDebug::GlitchL og* log, const SkCoincidentSpans* coin, const SkOpPtT* test) const {
1787 const SkCoincidentSpans* head = coin;
1750 while (coin) { 1788 while (coin) {
1751 if (coin->collapsed(test)) { 1789 if (coin->collapsed(test)) {
1752 if (zero_or_one(coin->coinPtTStart()->fT) && zero_or_one(coin->coinP tTEnd()->fT)) { 1790 if (zero_or_one(coin->coinPtTStart()->fT) && zero_or_one(coin->coinP tTEnd()->fT)) {
1753 log->record(kCollapsedCoin_Glitch, id, coin); 1791 log->record(kCollapsedCoin_Glitch, id, coin);
1754 } 1792 }
1755 if (zero_or_one(coin->oppPtTStart()->fT) && zero_or_one(coin->oppPtT End()->fT)) { 1793 if (zero_or_one(coin->oppPtTStart()->fT) && zero_or_one(coin->oppPtT End()->fT)) {
1756 log->record(kCollapsedCoin_Glitch, id, coin); 1794 log->record(kCollapsedCoin_Glitch, id, coin);
1757 } 1795 }
1796 this->debugRelease(id, log, head, coin);
1758 } 1797 }
1759 coin = coin->next(); 1798 coin = coin->next();
1760 } 1799 }
1761 } 1800 }
1762 1801
1763 // Commented-out lines keep this in sync with markCollapsed() 1802 // Commented-out lines keep this in sync with markCollapsed()
1764 void SkOpCoincidence::debugMarkCollapsed(const char* id, SkPathOpsDebug::GlitchL og* log, const SkOpPtT* test) const { 1803 void SkOpCoincidence::debugMarkCollapsed(const char* id, SkPathOpsDebug::GlitchL og* log, const SkOpPtT* test) const {
1765 this->debugMarkCollapsed(id, log, fHead, test); 1804 this->debugMarkCollapsed(id, log, fHead, test);
1766 this->debugMarkCollapsed(id, log, fTop, test); 1805 this->debugMarkCollapsed(id, log, fTop, test);
1767 } 1806 }
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 } while (!span->final() && (span = span->upCast()->next())); 2067 } while (!span->final() && (span = span->upCast()->next()));
2029 SkASSERT(count == fCount); 2068 SkASSERT(count == fCount);
2030 SkASSERT(done == fDoneCount); 2069 SkASSERT(done == fDoneCount);
2031 SkASSERT(count >= fDoneCount); 2070 SkASSERT(count >= fDoneCount);
2032 SkASSERT(span->final()); 2071 SkASSERT(span->final());
2033 span->debugValidate(); 2072 span->debugValidate();
2034 #endif 2073 #endif
2035 } 2074 }
2036 2075
2037 #if DEBUG_COINCIDENCE_VERBOSE 2076 #if DEBUG_COINCIDENCE_VERBOSE
2038 // Commented-out lines keep this in sync with addOppAndMerge() 2077
2039 // If the added points envelop adjacent spans, merge them in. 2078 // Commented-out lines keep this in sync with addOpp()
2040 void SkOpSpanBase::debugAddOppAndMerge(const char* id, SkPathOpsDebug::GlitchLog * log, const SkOpSpanBase* opp, bool* spanDeleted, bool* oppDeleted) const { 2079 void SkOpSpanBase::debugAddOpp(const char* id, SkPathOpsDebug::GlitchLog* log, c onst SkOpSpanBase* opp) const {
2041 const SkOpPtT* oppPrev = this->ptT()->debugOppPrev(opp->ptT()); 2080 const SkOpPtT* oppPrev = this->ptT()->oppPrev(opp->ptT());
2042 if (oppPrev) { 2081 if (!oppPrev) {
2043 this->ptT()->debugAddOpp(opp->ptT(), oppPrev);
2044 this->debugCheckForCollapsedCoincidence(id, log);
2045 }
2046 // compute bounds of points in span
2047 SkPathOpsBounds bounds;
2048 bounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_ScalarMin);
2049 const SkOpPtT* head = this->ptT();
2050 const SkOpPtT* nextPt = head;
2051 do {
2052 bounds.add(nextPt->fPt);
2053 } while ((nextPt = nextPt->next()) != head);
2054 if (!bounds.width() && !bounds.height()) {
2055 return; 2082 return;
2056 } 2083 }
2057 this->debugMergeContained(id, log, bounds, spanDeleted); 2084 this->debugMergeMatches(id, log, opp);
2058 opp->debugMergeContained(id, log, bounds, oppDeleted); 2085 this->ptT()->debugAddOpp(opp->ptT(), oppPrev);
2086 this->debugCheckForCollapsedCoincidence(id, log);
2059 } 2087 }
2060 2088
2061 // Commented-out lines keep this in sync with checkForCollapsedCoincidence() 2089 // Commented-out lines keep this in sync with checkForCollapsedCoincidence()
2062 void SkOpSpanBase::debugCheckForCollapsedCoincidence(const char* id, SkPathOpsDe bug::GlitchLog* log) const { 2090 void SkOpSpanBase::debugCheckForCollapsedCoincidence(const char* id, SkPathOpsDe bug::GlitchLog* log) const {
2063 const SkOpCoincidence* coins = this->globalState()->coincidence(); 2091 const SkOpCoincidence* coins = this->globalState()->coincidence();
2064 if (coins->isEmpty()) { 2092 if (coins->isEmpty()) {
2065 return; 2093 return;
2066 } 2094 }
2067 // the insert above may have put both ends of a coincident run in the same span 2095 // the insert above may have put both ends of a coincident run in the same span
2068 // for each coincident ptT in loop; see if its opposite in is also in the loop 2096 // for each coincident ptT in loop; see if its opposite in is also in the loop
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 current = next; 2172 current = next;
2145 } else { 2173 } else {
2146 log->record(kMergeContained_Glitch, id, next, current); 2174 log->record(kMergeContained_Glitch, id, next, current);
2147 current = next; 2175 current = next;
2148 } 2176 }
2149 } 2177 }
2150 #if DEBUG_COINCIDENCE 2178 #if DEBUG_COINCIDENCE
2151 // this->globalState()->coincidence()->debugValidate(); 2179 // this->globalState()->coincidence()->debugValidate();
2152 #endif 2180 #endif
2153 } 2181 }
2182
2183 // Commented-out lines keep this in sync with mergeMatches()
2184 // Look to see if pt-t linked list contains same segment more than once
2185 // if so, and if each pt-t is directly pointed to by spans in that segment,
2186 // merge them
2187 // keep the points, but remove spans so that the segment doesn't have 2 or more
2188 // spans pointing to the same pt-t loop at different loop elements
2189 void SkOpSpanBase::debugMergeMatches(const char* id, SkPathOpsDebug::GlitchLog* log, const SkOpSpanBase* opp) const {
2190 const SkOpPtT* test = &fPtT;
2191 const SkOpPtT* testNext;
2192 const SkOpPtT* stop = test;
2193 do {
2194 testNext = test->next();
2195 if (test->deleted()) {
2196 continue;
2197 }
2198 const SkOpSpanBase* testBase = test->span();
2199 SkASSERT(testBase->ptT() == test);
2200 const SkOpSegment* segment = test->segment();
2201 if (segment->done()) {
2202 continue;
2203 }
2204 const SkOpPtT* inner = opp->ptT();
2205 const SkOpPtT* innerStop = inner;
2206 do {
2207 if (inner->segment() != segment) {
2208 continue;
2209 }
2210 if (inner->deleted()) {
2211 continue;
2212 }
2213 const SkOpSpanBase* innerBase = inner->span();
2214 SkASSERT(innerBase->ptT() == inner);
2215 // when the intersection is first detected, the span base is marked if there are
2216 // more than one point in the intersection.
2217 // if (!innerBase->hasMultipleHint() && !testBase->hasMultipleHint()) {
2218 if (!zero_or_one(inner->fT)) {
2219 log->record(kMergeMatches_Glitch, id, innerBase, test);
2220 } else {
2221 SkASSERT(inner->fT != test->fT);
2222 if (!zero_or_one(test->fT)) {
2223 log->record(kMergeMatches_Glitch, id, testBase, inner);
2224 } else {
2225 log->record(kMergeMatches_Glitch, id, segment);
2226 // SkDEBUGCODE(testBase->debugSetDeleted());
2227 // test->setDeleted();
2228 // SkDEBUGCODE(innerBase->debugSetDeleted());
2229 // inner->setDeleted();
2230 }
2231 }
2232 #ifdef SK_DEBUG // assert if another undeleted entry points to segment
2233 const SkOpPtT* debugInner = inner;
2234 while ((debugInner = debugInner->next()) != innerStop) {
2235 if (debugInner->segment() != segment) {
2236 continue;
2237 }
2238 if (debugInner->deleted()) {
2239 continue;
2240 }
2241 SkOPASSERT(0);
2242 }
2243 #endif
2244 break;
2245 // }
2246 break;
2247 } while ((inner = inner->next()) != innerStop);
2248 } while ((test = testNext) != stop);
2249 this->debugCheckForCollapsedCoincidence(id, log);
2250 }
2251
2154 #endif 2252 #endif
2155 2253
2156 void SkOpSpanBase::debugResetCoinT() const { 2254 void SkOpSpanBase::debugResetCoinT() const {
2157 #if DEBUG_COINCIDENCE_ORDER 2255 #if DEBUG_COINCIDENCE_ORDER
2158 const SkOpPtT* ptT = &fPtT; 2256 const SkOpPtT* ptT = &fPtT;
2159 do { 2257 do {
2160 ptT->debugResetCoinT(); 2258 ptT->debugResetCoinT();
2161 ptT = ptT->next(); 2259 ptT = ptT->next();
2162 } while (ptT != &fPtT); 2260 } while (ptT != &fPtT);
2163 #endif 2261 #endif
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
2503 #endif 2601 #endif
2504 SkPath::FillType fillType = path.getFillType(); 2602 SkPath::FillType fillType = path.getFillType();
2505 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver seEvenOdd_FillType); 2603 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver seEvenOdd_FillType);
2506 if (includeDeclaration) { 2604 if (includeDeclaration) {
2507 SkDebugf(" SkPath %s;\n", name); 2605 SkDebugf(" SkPath %s;\n", name);
2508 } 2606 }
2509 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); 2607 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]);
2510 iter.setPath(path); 2608 iter.setPath(path);
2511 showPathContours(iter, name); 2609 showPathContours(iter, name);
2512 } 2610 }
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsDebug.h ('k') | src/pathops/SkPathOpsPoint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698