| OLD | NEW |
| 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" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 } | 56 } |
| 57 return false; | 57 return false; |
| 58 } | 58 } |
| 59 #endif | 59 #endif |
| 60 | 60 |
| 61 #if DEBUG_COINCIDENCE_VERBOSE | 61 #if DEBUG_COINCIDENCE_VERBOSE |
| 62 enum GlitchType { | 62 enum GlitchType { |
| 63 kAddCorruptCoin_Glitch, | 63 kAddCorruptCoin_Glitch, |
| 64 kAddExpandedCoin_Glitch, | 64 kAddExpandedCoin_Glitch, |
| 65 kAddExpandedFail_Glitch, | 65 kAddExpandedFail_Glitch, |
| 66 kAddIfCollapsed_Glitch, |
| 66 kAddIfMissingCoin_Glitch, | 67 kAddIfMissingCoin_Glitch, |
| 67 kAddMissingCoin_Glitch, | 68 kAddMissingCoin_Glitch, |
| 68 kAddMissingExtend_Glitch, | 69 kAddMissingExtend_Glitch, |
| 69 kAddOrOverlap_Glitch, | 70 kAddOrOverlap_Glitch, |
| 70 kCollapsedCoin_Glitch, | 71 kCollapsedCoin_Glitch, |
| 71 kCollapsedDone_Glitch, | 72 kCollapsedDone_Glitch, |
| 72 kCollapsedOppValue_Glitch, | 73 kCollapsedOppValue_Glitch, |
| 73 kCollapsedSpan_Glitch, | 74 kCollapsedSpan_Glitch, |
| 74 kCollapsedWindValue_Glitch, | 75 kCollapsedWindValue_Glitch, |
| 75 kDeletedCoin_Glitch, | 76 kDeletedCoin_Glitch, |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 mask |= 1 << glitch.fType; | 280 mask |= 1 << glitch.fType; |
| 280 } | 281 } |
| 281 for (int index = 0; index < kGlitchType_Count; ++index) { | 282 for (int index = 0; index < kGlitchType_Count; ++index) { |
| 282 SkDebugf(mask & (1 << index) ? "x" : "-"); | 283 SkDebugf(mask & (1 << index) ? "x" : "-"); |
| 283 } | 284 } |
| 284 SkDebugf(" %s\n", id); | 285 SkDebugf(" %s\n", id); |
| 285 for (int index = 0; index < glitches.fGlitches.count(); ++index) { | 286 for (int index = 0; index < glitches.fGlitches.count(); ++index) { |
| 286 const SpanGlitch& glitch = glitches.fGlitches[index]; | 287 const SpanGlitch& glitch = glitches.fGlitches[index]; |
| 287 SkDebugf("%02d: ", index); | 288 SkDebugf("%02d: ", index); |
| 288 if (glitch.fBase) { | 289 if (glitch.fBase) { |
| 289 SkDebugf(" base=%d", glitch.fBase->debugID()); | 290 SkDebugf(" seg/base=%d/%d", glitch.fBase->segment()->debugID(), |
| 291 glitch.fBase->debugID()); |
| 290 } | 292 } |
| 291 if (glitch.fSuspect) { | 293 if (glitch.fSuspect) { |
| 292 SkDebugf(" base=%d", glitch.fSuspect->debugID()); | 294 SkDebugf(" seg/base=%d/%d", glitch.fSuspect->segment()->debugID(), |
| 295 glitch.fSuspect->debugID()); |
| 293 } | 296 } |
| 294 if (glitch.fSegment) { | 297 if (glitch.fSegment) { |
| 295 SkDebugf(" segment=%d", glitch.fSegment->debugID()); | 298 SkDebugf(" segment=%d", glitch.fSegment->debugID()); |
| 296 } | 299 } |
| 297 if (glitch.fCoinSpan) { | 300 if (glitch.fCoinSpan) { |
| 298 SkDebugf(" coinSpan=%d", glitch.fCoinSpan->debugID()); | 301 SkDebugf(" coinSeg/Span/PtT=%d/%d/%d", glitch.fCoinSpan->segment()->
debugID(), |
| 302 glitch.fCoinSpan->span()->debugID(), glitch.fCoinSpan->debug
ID()); |
| 299 } | 303 } |
| 300 if (glitch.fEndSpan) { | 304 if (glitch.fEndSpan) { |
| 301 SkDebugf(" endSpan=%d", glitch.fEndSpan->debugID()); | 305 SkDebugf(" endSpan=%d", glitch.fEndSpan->debugID()); |
| 302 } | 306 } |
| 303 if (glitch.fOppSpan) { | 307 if (glitch.fOppSpan) { |
| 304 SkDebugf(" oppSpan=%d", glitch.fOppSpan->debugID()); | 308 SkDebugf(" oppSeg/Span/PtT=%d/%d/%d", glitch.fOppSpan->segment()->de
bugID(), |
| 309 glitch.fOppSpan->span()->debugID(), glitch.fOppSpan->debugID
()); |
| 305 } | 310 } |
| 306 if (glitch.fOppEndSpan) { | 311 if (glitch.fOppEndSpan) { |
| 307 SkDebugf(" oppEndSpan=%d", glitch.fOppEndSpan->debugID()); | 312 SkDebugf(" oppEndSpan=%d", glitch.fOppEndSpan->debugID()); |
| 308 } | 313 } |
| 309 if (!SkScalarIsNaN(glitch.fStartT)) { | 314 if (!SkScalarIsNaN(glitch.fStartT)) { |
| 310 SkDebugf(" startT=%g", glitch.fStartT); | 315 SkDebugf(" startT=%g", glitch.fStartT); |
| 311 } | 316 } |
| 312 if (!SkScalarIsNaN(glitch.fEndT)) { | 317 if (!SkScalarIsNaN(glitch.fEndT)) { |
| 313 SkDebugf(" endT=%g", glitch.fEndT); | 318 SkDebugf(" endT=%g", glitch.fEndT); |
| 314 } | 319 } |
| 315 if (glitch.fOppSegment) { | 320 if (glitch.fOppSegment) { |
| 316 SkDebugf(" segment=%d", glitch.fOppSegment->debugID()); | 321 SkDebugf(" segment=%d", glitch.fOppSegment->debugID()); |
| 317 } | 322 } |
| 318 if (!SkScalarIsNaN(glitch.fOppStartT)) { | 323 if (!SkScalarIsNaN(glitch.fOppStartT)) { |
| 319 SkDebugf(" oppStartT=%g", glitch.fOppStartT); | 324 SkDebugf(" oppStartT=%g", glitch.fOppStartT); |
| 320 } | 325 } |
| 321 if (!SkScalarIsNaN(glitch.fOppEndT)) { | 326 if (!SkScalarIsNaN(glitch.fOppEndT)) { |
| 322 SkDebugf(" oppEndT=%g", glitch.fOppEndT); | 327 SkDebugf(" oppEndT=%g", glitch.fOppEndT); |
| 323 } | 328 } |
| 324 if (!SkScalarIsNaN(glitch.fPt.fX) || !SkScalarIsNaN(glitch.fPt.fY)) { | 329 if (!SkScalarIsNaN(glitch.fPt.fX) || !SkScalarIsNaN(glitch.fPt.fY)) { |
| 325 SkDebugf(" pt=%g,%g", glitch.fPt.fX, glitch.fPt.fY); | 330 SkDebugf(" pt=%g,%g", glitch.fPt.fX, glitch.fPt.fY); |
| 326 } | 331 } |
| 327 switch (glitch.fType) { | 332 switch (glitch.fType) { |
| 328 case kAddCorruptCoin_Glitch: SkDebugf(" AddCorruptCoin"); break; | 333 case kAddCorruptCoin_Glitch: SkDebugf(" AddCorruptCoin"); break; |
| 329 case kAddExpandedCoin_Glitch: SkDebugf(" AddExpandedCoin"); break; | 334 case kAddExpandedCoin_Glitch: SkDebugf(" AddExpandedCoin"); break; |
| 330 case kAddExpandedFail_Glitch: SkDebugf(" AddExpandedFail"); break; | 335 case kAddExpandedFail_Glitch: SkDebugf(" AddExpandedFail"); break; |
| 336 case kAddIfCollapsed_Glitch: SkDebugf(" AddIfCollapsed"); break;; br
eak; |
| 331 case kAddIfMissingCoin_Glitch: SkDebugf(" AddIfMissingCoin"); break; | 337 case kAddIfMissingCoin_Glitch: SkDebugf(" AddIfMissingCoin"); break; |
| 332 case kAddMissingCoin_Glitch: SkDebugf(" AddMissingCoin"); break; | 338 case kAddMissingCoin_Glitch: SkDebugf(" AddMissingCoin"); break; |
| 333 case kAddMissingExtend_Glitch: SkDebugf(" AddMissingExtend"); break; | 339 case kAddMissingExtend_Glitch: SkDebugf(" AddMissingExtend"); break; |
| 334 case kAddOrOverlap_Glitch: SkDebugf(" AAddOrOverlap"); break; | 340 case kAddOrOverlap_Glitch: SkDebugf(" AAddOrOverlap"); break; |
| 335 case kCollapsedCoin_Glitch: SkDebugf(" CollapsedCoin"); break; | 341 case kCollapsedCoin_Glitch: SkDebugf(" CollapsedCoin"); break; |
| 336 case kCollapsedDone_Glitch: SkDebugf(" CollapsedDone"); break; | 342 case kCollapsedDone_Glitch: SkDebugf(" CollapsedDone"); break; |
| 337 case kCollapsedOppValue_Glitch: SkDebugf(" CollapsedOppValue"); brea
k; | 343 case kCollapsedOppValue_Glitch: SkDebugf(" CollapsedOppValue"); brea
k; |
| 338 case kCollapsedSpan_Glitch: SkDebugf(" CollapsedSpan"); break; | 344 case kCollapsedSpan_Glitch: SkDebugf(" CollapsedSpan"); break; |
| 339 case kCollapsedWindValue_Glitch: SkDebugf(" CollapsedWindValue"); br
eak; | 345 case kCollapsedWindValue_Glitch: SkDebugf(" CollapsedWindValue"); br
eak; |
| 340 case kDeletedCoin_Glitch: SkDebugf(" DeletedCoin"); break; | 346 case kDeletedCoin_Glitch: SkDebugf(" DeletedCoin"); break; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 357 case kMoveNearbyReleaseFinal_Glitch: SkDebugf(" MoveNearbyReleaseFin
al"); break; | 363 case kMoveNearbyReleaseFinal_Glitch: SkDebugf(" MoveNearbyReleaseFin
al"); break; |
| 358 case kReleasedSpan_Glitch: SkDebugf(" ReleasedSpan"); break; | 364 case kReleasedSpan_Glitch: SkDebugf(" ReleasedSpan"); break; |
| 359 case kUnaligned_Glitch: SkDebugf(" Unaligned"); break; | 365 case kUnaligned_Glitch: SkDebugf(" Unaligned"); break; |
| 360 case kUnalignedHead_Glitch: SkDebugf(" UnalignedHead"); break; | 366 case kUnalignedHead_Glitch: SkDebugf(" UnalignedHead"); break; |
| 361 case kUnalignedTail_Glitch: SkDebugf(" UnalignedTail"); break; | 367 case kUnalignedTail_Glitch: SkDebugf(" UnalignedTail"); break; |
| 362 default: SkASSERT(0); | 368 default: SkASSERT(0); |
| 363 } | 369 } |
| 364 SkDebugf("\n"); | 370 SkDebugf("\n"); |
| 365 } | 371 } |
| 366 contourList->globalState()->debugSetCheckHealth(false); | 372 contourList->globalState()->debugSetCheckHealth(false); |
| 367 #if DEBUG_ACTIVE_SPANS | 373 #if 0 && DEBUG_ACTIVE_SPANS |
| 368 SkDebugf("active after %s:\n", id); | 374 SkDebugf("active after %s:\n", id); |
| 369 ShowActiveSpans(contourList); | 375 ShowActiveSpans(contourList); |
| 370 #endif | 376 #endif |
| 371 #endif | 377 #endif |
| 372 } | 378 } |
| 373 #endif | 379 #endif |
| 374 | 380 |
| 375 #if defined SK_DEBUG || !FORCE_RELEASE | 381 #if defined SK_DEBUG || !FORCE_RELEASE |
| 376 void SkPathOpsDebug::MathematicaIze(char* str, size_t bufferLen) { | 382 void SkPathOpsDebug::MathematicaIze(char* str, size_t bufferLen) { |
| 377 size_t len = strlen(str); | 383 size_t len = strlen(str); |
| (...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 if (!oTest) { | 1369 if (!oTest) { |
| 1364 return; | 1370 return; |
| 1365 } | 1371 } |
| 1366 } | 1372 } |
| 1367 } | 1373 } |
| 1368 } while ((coin = coin->next())); | 1374 } while ((coin = coin->next())); |
| 1369 return; | 1375 return; |
| 1370 } | 1376 } |
| 1371 | 1377 |
| 1372 /* Commented-out lines keep this in sync with addIfMissing() */ | 1378 /* Commented-out lines keep this in sync with addIfMissing() */ |
| 1373 void SkOpCoincidence::debugAddIfMissing(const SkCoincidentSpans* outer, const Sk
OpPtT* over1s, | 1379 void SkOpCoincidence::debugAddIfMissing(const char* id, SkPathOpsDebug::GlitchLo
g* log, const SkCoincidentSpans* outer, const SkOpPtT* over1s, |
| 1374 const SkOpPtT* over1e, const char* id, SkPathOpsDebug::GlitchLog* lo
g) const { | 1380 const SkOpPtT* over1e) const { |
| 1375 // SkASSERT(fTop); | 1381 // SkASSERT(fTop); |
| 1376 if (fTop && alreadyAdded(fTop, outer, over1s, over1e)) { // in debug, fTop
may be null | 1382 if (fTop && alreadyAdded(fTop, outer, over1s, over1e)) { // in debug, fTop
may be null |
| 1377 return; | 1383 return; |
| 1378 } | 1384 } |
| 1379 if (fHead && alreadyAdded(fHead, outer, over1s, over1e)) { | 1385 if (fHead && alreadyAdded(fHead, outer, over1s, over1e)) { |
| 1380 return; | 1386 return; |
| 1381 } | 1387 } |
| 1382 log->record(kAddIfMissingCoin_Glitch, id, outer->coinPtTStart(), outer->coin
PtTEnd(), over1s, over1e); | 1388 log->record(kAddIfMissingCoin_Glitch, id, outer->coinPtTStart(), outer->coin
PtTEnd(), over1s, over1e); |
| 1383 this->debugValidate(); | 1389 this->debugValidate(); |
| 1384 return; | 1390 return; |
| 1385 } | 1391 } |
| 1386 | 1392 |
| 1387 /* Commented-out lines keep this in sync addIfMissing() */ | 1393 /* Commented-out lines keep this in sync addIfMissing() */ |
| 1388 void SkOpCoincidence::debugAddIfMissing(const SkOpPtT* over1s, const SkOpPtT* ov
er1e, | 1394 // note that over1s, over1e, over2s, over2e are ordered |
| 1389 const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd
, | 1395 void SkOpCoincidence::debugAddIfMissing(const char* id, SkPathOpsDebug::GlitchLo
g* log, const SkOpPtT* over1s, const SkOpPtT* over2s, |
| 1390 const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, | 1396 double tStart, double tEnd, const SkOpSegment* coinSeg, const SkOpSegmen
t* oppSeg, |
| 1391 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, const char* id, Sk
PathOpsDebug::GlitchLog* log) const { | 1397 const SkOpPtT* over1e, const SkOpPtT* over2e) const { |
| 1398 SkASSERT(tStart < tEnd); |
| 1399 SkASSERT(over1s->fT < over1e->fT); |
| 1400 SkASSERT(between(over1s->fT, tStart, over1e->fT)); |
| 1401 SkASSERT(between(over1s->fT, tEnd, over1e->fT)); |
| 1402 SkASSERT(over2s->fT < over2e->fT); |
| 1403 SkASSERT(between(over2s->fT, tStart, over2e->fT)); |
| 1404 SkASSERT(between(over2s->fT, tEnd, over2e->fT)); |
| 1405 SkASSERT(over1s->segment() == over1e->segment()); |
| 1406 SkASSERT(over2s->segment() == over2e->segment()); |
| 1407 SkASSERT(over1s->segment() == over2s->segment()); |
| 1408 SkASSERT(over1s->segment() != coinSeg); |
| 1409 SkASSERT(over1s->segment() != oppSeg); |
| 1410 SkASSERT(coinSeg != oppSeg); |
| 1392 double coinTs, coinTe, oppTs, oppTe; | 1411 double coinTs, coinTe, oppTs, oppTe; |
| 1393 TRange(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coi
nTe); | 1412 coinTs = TRange(over1s, tStart, coinSeg SkDEBUGPARAMS(over1e)); |
| 1394 TRange(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe)
; | 1413 coinTe = TRange(over1s, tEnd, coinSeg SkDEBUGPARAMS(over1e)); |
| 1395 bool swap = coinTs > coinTe; | 1414 if (coinSeg->collapsed(coinTs, coinTe)) { |
| 1396 if (swap) { | 1415 return log->record(kAddIfCollapsed_Glitch, id, coinSeg); |
| 1416 } |
| 1417 oppTs = TRange(over2s, tStart, oppSeg SkDEBUGPARAMS(over2e)); |
| 1418 oppTe = TRange(over2s, tEnd, oppSeg SkDEBUGPARAMS(over2e)); |
| 1419 if (oppSeg->collapsed(oppTs, oppTe)) { |
| 1420 return log->record(kAddIfCollapsed_Glitch, id, oppSeg); |
| 1421 } |
| 1422 if (coinTs > coinTe) { |
| 1397 SkTSwap(coinTs, coinTe); | 1423 SkTSwap(coinTs, coinTe); |
| 1398 } | |
| 1399 if ((over1s->fT < over1e->fT) != (over2s->fT < over2e->fT)) { | |
| 1400 SkTSwap(oppTs, oppTe); | 1424 SkTSwap(oppTs, oppTe); |
| 1401 } | 1425 } |
| 1402 if (swap) { | 1426 return this->debugAddOrOverlap(id, log, coinSeg, oppSeg, coinTs, coinTe, opp
Ts, oppTe |
| 1403 SkTSwap(oppTs, oppTe); | 1427 ); |
| 1404 } | |
| 1405 const SkOpSegment* coinSeg = coinPtTStart->segment(); | |
| 1406 const SkOpSegment* oppSeg = oppPtTStart->segment(); | |
| 1407 if (coinSeg == oppSeg) { | |
| 1408 return; | |
| 1409 } | |
| 1410 return this->debugAddOrOverlap(id, log, coinSeg, oppSeg, coinTs, coinTe, opp
Ts, oppTe); | |
| 1411 } | 1428 } |
| 1412 | 1429 |
| 1413 /* Commented-out lines keep this in sync addOrOverlap() */ | 1430 /* Commented-out lines keep this in sync addOrOverlap() */ |
| 1414 // If this is called by addEndMovedSpans(), a returned false propogates out to a
n abort. | 1431 // If this is called by addEndMovedSpans(), a returned false propogates out to a
n abort. |
| 1415 // If this is called by AddIfMissing(), a returned false indicates there was not
hing to add | 1432 // 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, | 1433 void SkOpCoincidence::debugAddOrOverlap(const char* id, SkPathOpsDebug::GlitchLo
g* log, |
| 1417 const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, | 1434 const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, |
| 1418 double coinTs, double coinTe, double oppTs, double oppTe) const { | 1435 double coinTs, double coinTe, double oppTs, double oppTe) const { |
| 1419 SkTDArray<SkCoincidentSpans*> overlaps; | 1436 SkTDArray<SkCoincidentSpans*> overlaps; |
| 1420 SkASSERT(!fTop); // this is (correctly) reversed in addifMissing() | 1437 SkASSERT(!fTop); // this is (correctly) reversed in addifMissing() |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 oe = oppSeg->debugAddT(oppTe, id, log); | 1510 oe = oppSeg->debugAddT(oppTe, id, log); |
| 1494 if (ce && oe) ce->span()->debugAddOpp(id, log, oe->span()); | 1511 if (ce && oe) ce->span()->debugAddOpp(id, log, oe->span()); |
| 1495 // ce = ceWritable; | 1512 // ce = ceWritable; |
| 1496 // oe = oeWritable; | 1513 // oe = oeWritable; |
| 1497 } | 1514 } |
| 1498 this->debugValidate(); | 1515 this->debugValidate(); |
| 1499 RETURN_FALSE_IF(csDeleted, coinSeg); | 1516 RETURN_FALSE_IF(csDeleted, coinSeg); |
| 1500 RETURN_FALSE_IF(osDeleted, oppSeg); | 1517 RETURN_FALSE_IF(osDeleted, oppSeg); |
| 1501 RETURN_FALSE_IF(ceDeleted, coinSeg); | 1518 RETURN_FALSE_IF(ceDeleted, coinSeg); |
| 1502 RETURN_FALSE_IF(oeDeleted, oppSeg); | 1519 RETURN_FALSE_IF(oeDeleted, oppSeg); |
| 1503 RETURN_FALSE_IF(!cs || !ce || cs->contains(ce) || !os || !oe || os->contains
(oe), coinSeg); | 1520 RETURN_FALSE_IF(!cs || !ce || cs == ce || cs->contains(ce) || !os || !oe ||
os == oe || os->contains(oe), coinSeg); |
| 1504 // bool result = true; | 1521 bool result = true; |
| 1505 if (overlap) { | 1522 if (overlap) { |
| 1506 if (overlap->coinPtTStart()->segment() == coinSeg) { | 1523 if (overlap->coinPtTStart()->segment() == coinSeg) { |
| 1507 log->record(kAddMissingExtend_Glitch, id, coinSeg, coinTs, coinT
e, oppSeg, oppTs, oppTe); | 1524 log->record(kAddMissingExtend_Glitch, id, coinSeg, coinTs, coinT
e, oppSeg, oppTs, oppTe); |
| 1508 } else { | 1525 } else { |
| 1509 if (oppTs > oppTe) { | 1526 if (oppTs > oppTe) { |
| 1510 SkTSwap(coinTs, coinTe); | 1527 SkTSwap(coinTs, coinTe); |
| 1511 SkTSwap(oppTs, oppTe); | 1528 SkTSwap(oppTs, oppTe); |
| 1512 } | 1529 } |
| 1513 log->record(kAddMissingExtend_Glitch, id, oppSeg, oppTs, oppTe, coin
Seg, coinTs, coinTe); | 1530 log->record(kAddMissingExtend_Glitch, id, oppSeg, oppTs, oppTe, coin
Seg, coinTs, coinTe); |
| 1514 } | 1531 } |
| 1515 #if DEBUG_COINCIDENCE_VERBOSE | 1532 #if 0 && DEBUG_COINCIDENCE_VERBOSE |
| 1516 // if (result) { | 1533 if (result) { |
| 1517 // overlap->debugShow(); | 1534 overlap->debugShow(); |
| 1518 // } | 1535 } |
| 1519 #endif | 1536 #endif |
| 1520 } else { | 1537 } else { |
| 1521 log->record(kAddMissingCoin_Glitch, id, coinSeg, coinTs, coinTe, oppSeg,
oppTs, oppTe); | 1538 log->record(kAddMissingCoin_Glitch, id, coinSeg, coinTs, coinTe, oppSeg,
oppTs, oppTe); |
| 1522 #if DEBUG_COINCIDENCE_VERBOSE | 1539 #if 0 && DEBUG_COINCIDENCE_VERBOSE |
| 1523 // fHead->debugShow(); | 1540 fHead->debugShow(); |
| 1524 #endif | 1541 #endif |
| 1525 } | 1542 } |
| 1526 this->debugValidate(); | 1543 this->debugValidate(); |
| 1527 return; | 1544 return (void) result; |
| 1528 } | 1545 } |
| 1529 | 1546 |
| 1530 // Extra commented-out lines keep this in sync with addMissing() | 1547 // Extra commented-out lines keep this in sync with addMissing() |
| 1531 /* detects overlaps of different coincident runs on same segment */ | 1548 /* detects overlaps of different coincident runs on same segment */ |
| 1532 /* does not detect overlaps for pairs without any segments in common */ | 1549 /* does not detect overlaps for pairs without any segments in common */ |
| 1533 // returns true if caller should loop again | 1550 // returns true if caller should loop again |
| 1534 void SkOpCoincidence::debugAddMissing(const char* id, SkPathOpsDebug::GlitchLog*
log) const { | 1551 void SkOpCoincidence::debugAddMissing(const char* id, SkPathOpsDebug::GlitchLog*
log) const { |
| 1535 const SkCoincidentSpans* outer = fHead; | 1552 const SkCoincidentSpans* outer = fHead; |
| 1536 if (!outer) { | 1553 if (!outer) { |
| 1537 return; | 1554 return; |
| 1538 } | 1555 } |
| 1539 // bool added = false; | 1556 // bool added = false; |
| 1540 // fTop = outer; | 1557 // fTop = outer; |
| 1541 // fHead = nullptr; | 1558 // fHead = nullptr; |
| 1542 do { | 1559 do { |
| 1543 // addifmissing can modify the list that this is walking | 1560 // addifmissing can modify the list that this is walking |
| 1544 // save head so that walker can iterate over old data unperturbed | 1561 // save head so that walker can iterate over old data unperturbed |
| 1545 // addifmissing adds to head freely then add saved head in the end | 1562 // addifmissing adds to head freely then add saved head in the end |
| 1546 const SkOpSegment* outerCoin = outer->coinPtTStart()->segment(); | 1563 const SkOpPtT* ocs = outer->coinPtTStart(); |
| 1547 const SkOpSegment* outerOpp = outer->oppPtTStart()->segment(); | 1564 SkASSERT(!ocs->deleted()); |
| 1548 if (outerCoin->done() || outerOpp->done()) { | 1565 const SkOpSegment* outerCoin = ocs->segment(); |
| 1549 continue; | 1566 SkASSERT(!outerCoin->done()); // if it's done, should have already been
removed from list |
| 1550 } | 1567 const SkOpPtT* oos = outer->oppPtTStart(); |
| 1568 SkASSERT(!oos->deleted()); |
| 1569 const SkOpSegment* outerOpp = oos->segment(); |
| 1570 SkASSERT(!outerOpp->done()); |
| 1571 // SkOpSegment* outerCoinWritable = const_cast<SkOpSegment*>(outerCoin); |
| 1572 // SkOpSegment* outerOppWritable = const_cast<SkOpSegment*>(outerOpp); |
| 1551 const SkCoincidentSpans* inner = outer; | 1573 const SkCoincidentSpans* inner = outer; |
| 1552 while ((inner = inner->next())) { | 1574 while ((inner = inner->next())) { |
| 1553 this->debugValidate(); | 1575 this->debugValidate(); |
| 1554 double overS, overE; | 1576 double overS, overE; |
| 1555 const SkOpSegment* innerCoin = inner->coinPtTStart()->segment(); | 1577 const SkOpPtT* ics = inner->coinPtTStart(); |
| 1556 const SkOpSegment* innerOpp = inner->oppPtTStart()->segment(); | 1578 SkASSERT(!ics->deleted()); |
| 1557 if (innerCoin->done() || innerOpp->done()) { | 1579 const SkOpSegment* innerCoin = ics->segment(); |
| 1558 continue; | 1580 SkASSERT(!innerCoin->done()); |
| 1559 } | 1581 const SkOpPtT* ios = inner->oppPtTStart(); |
| 1582 SkASSERT(!ios->deleted()); |
| 1583 const SkOpSegment* innerOpp = ios->segment(); |
| 1584 SkASSERT(!innerOpp->done()); |
| 1585 // SkOpSegment* innerCoinWritable = const_cast<SkOpSegment*>(innerCoi
n); |
| 1586 // SkOpSegment* innerOppWritable = const_cast<SkOpSegment*>(innerOpp)
; |
| 1560 if (outerCoin == innerCoin) { | 1587 if (outerCoin == innerCoin) { |
| 1561 if (outerOpp != innerOpp | 1588 const SkOpPtT* oce = outer->coinPtTEnd(); |
| 1562 && this->overlap(outer->coinPtTStart(), outer->coinPtTEn
d(), | 1589 SkASSERT(!oce->deleted()); |
| 1563 inner->coinPtTStart(), inner->coinPtTEnd(), &overS, &ove
rE)) { | 1590 const SkOpPtT* ice = inner->coinPtTEnd(); |
| 1564 this->debugAddIfMissing(outer->coinPtTStart(), outer->coinPt
TEnd(), | 1591 SkASSERT(!ice->deleted()); |
| 1565 inner->coinPtTStart(), inner->coinPtTEnd(), overS, o
verE, | 1592 if (outerOpp != innerOpp && this->overlap(ocs, oce, ics, ice, &o
verS, &overE)) { |
| 1566 outer->oppPtTStart(), outer->oppPtTEnd(), | 1593 this->debugAddIfMissing(id, log, ocs->starter(oce), ics->sta
rter(ice), |
| 1567 inner->oppPtTStart(), inner->oppPtTEnd(), id, log); | 1594 overS, overE, outerOpp, innerOpp, |
| 1595 ocs->debugEnder(oce), |
| 1596 ics->debugEnder(ice)); |
| 1568 } | 1597 } |
| 1569 } else if (outerCoin == innerOpp) { | 1598 } else if (outerCoin == innerOpp) { |
| 1570 if (outerOpp != innerCoin | 1599 const SkOpPtT* oce = outer->coinPtTEnd(); |
| 1571 && this->overlap(outer->coinPtTStart(), outer->coinPtTEn
d(), | 1600 SkASSERT(!oce->deleted()); |
| 1572 inner->oppPtTStart(), inner->oppPtTEnd(), &overS, &overE
)) { | 1601 const SkOpPtT* ioe = inner->oppPtTEnd(); |
| 1573 this->debugAddIfMissing(outer->coinPtTStart(), outer->coinPt
TEnd(), | 1602 SkASSERT(!ioe->deleted()); |
| 1574 inner->oppPtTStart(), inner->oppPtTEnd(), overS, ove
rE, | 1603 if (outerOpp != innerCoin && this->overlap(ocs, oce, ios, ioe, &
overS, &overE)) { |
| 1575 outer->oppPtTStart(), outer->oppPtTEnd(), | 1604 this->debugAddIfMissing(id, log, ocs->starter(oce), ios->sta
rter(ioe), |
| 1576 inner->coinPtTStart(), inner->coinPtTEnd(), id, log)
; | 1605 overS, overE, outerOpp, innerCoin, |
| 1606 ocs->debugEnder(oce), |
| 1607 ios->debugEnder(ioe)); |
| 1577 } | 1608 } |
| 1578 } else if (outerOpp == innerCoin) { | 1609 } else if (outerOpp == innerCoin) { |
| 1610 const SkOpPtT* ooe = outer->oppPtTEnd(); |
| 1611 SkASSERT(!ooe->deleted()); |
| 1612 const SkOpPtT* ice = inner->coinPtTEnd(); |
| 1613 SkASSERT(!ice->deleted()); |
| 1579 SkASSERT(outerCoin != innerOpp); | 1614 SkASSERT(outerCoin != innerOpp); |
| 1580 if (this->overlap(outer->oppPtTStart(), outer->oppPtTEnd(), | 1615 if (this->overlap(oos, ooe, ics, ice, &overS, &overE)) { |
| 1581 inner->coinPtTStart(), inner->coinPtTEnd(), &overS, &ove
rE)) { | 1616 this->debugAddIfMissing(id, log, oos->starter(ooe), ics->sta
rter(ice), |
| 1582 this->debugAddIfMissing(outer->oppPtTStart(), outer->oppPtTE
nd(), | 1617 overS, overE, outerCoin, innerOpp, |
| 1583 inner->coinPtTStart(), inner->coinPtTEnd(), overS, o
verE, | 1618 oos->debugEnder(ooe), |
| 1584 outer->coinPtTStart(), outer->coinPtTEnd(), | 1619 ics->debugEnder(ice)); |
| 1585 inner->oppPtTStart(), inner->oppPtTEnd(), id, log); | |
| 1586 } | 1620 } |
| 1587 } else if (outerOpp == innerOpp) { | 1621 } else if (outerOpp == innerOpp) { |
| 1622 const SkOpPtT* ooe = outer->oppPtTEnd(); |
| 1623 SkASSERT(!ooe->deleted()); |
| 1624 const SkOpPtT* ioe = inner->oppPtTEnd(); |
| 1625 SkASSERT(!ioe->deleted()); |
| 1588 SkASSERT(outerCoin != innerCoin); | 1626 SkASSERT(outerCoin != innerCoin); |
| 1589 if (this->overlap(outer->oppPtTStart(), outer->oppPtTEnd(), | 1627 if (this->overlap(oos, ooe, ios, ioe, &overS, &overE)) { |
| 1590 inner->oppPtTStart(), inner->oppPtTEnd(), &overS, &overE
)) { | 1628 this->debugAddIfMissing(id, log, oos->starter(ooe), ios->sta
rter(ioe), |
| 1591 this->debugAddIfMissing(outer->oppPtTStart(), outer->oppPtTE
nd(), | 1629 overS, overE, outerCoin, innerCoin, |
| 1592 inner->oppPtTStart(), inner->oppPtTEnd(), overS, ove
rE, | 1630 oos->debugEnder(ooe), |
| 1593 outer->coinPtTStart(), outer->coinPtTEnd(), | 1631 ios->debugEnder(ioe)); |
| 1594 inner->coinPtTStart(), inner->coinPtTEnd(), id, log)
; | |
| 1595 } | 1632 } |
| 1596 } | 1633 } |
| 1597 this->debugValidate(); | 1634 this->debugValidate(); |
| 1598 } | 1635 } |
| 1599 } while ((outer = outer->next())); | 1636 } while ((outer = outer->next())); |
| 1600 // this->restoreHead(); | 1637 // this->restoreHead(); |
| 1601 return; | 1638 return; |
| 1602 } | 1639 } |
| 1603 | 1640 |
| 1604 // Commented-out lines keep this in sync with release() | 1641 // Commented-out lines keep this in sync with release() |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2435 const SkOpPtT* test = this; | 2472 const SkOpPtT* test = this; |
| 2436 for (int index = 0; index < links; ++index) { | 2473 for (int index = 0; index < links; ++index) { |
| 2437 if (ptT == test) { | 2474 if (ptT == test) { |
| 2438 return nullptr; | 2475 return nullptr; |
| 2439 } | 2476 } |
| 2440 test = test->next(); | 2477 test = test->next(); |
| 2441 } | 2478 } |
| 2442 } while (true); | 2479 } while (true); |
| 2443 } | 2480 } |
| 2444 | 2481 |
| 2482 const SkOpPtT* SkOpPtT::debugEnder(const SkOpPtT* end) const { |
| 2483 return fT < end->fT ? end : this; |
| 2484 } |
| 2485 |
| 2445 int SkOpPtT::debugLoopLimit(bool report) const { | 2486 int SkOpPtT::debugLoopLimit(bool report) const { |
| 2446 int loop = 0; | 2487 int loop = 0; |
| 2447 const SkOpPtT* next = this; | 2488 const SkOpPtT* next = this; |
| 2448 do { | 2489 do { |
| 2449 for (int check = 1; check < loop - 1; ++check) { | 2490 for (int check = 1; check < loop - 1; ++check) { |
| 2450 const SkOpPtT* checkPtT = this->fNext; | 2491 const SkOpPtT* checkPtT = this->fNext; |
| 2451 const SkOpPtT* innerPtT = checkPtT; | 2492 const SkOpPtT* innerPtT = checkPtT; |
| 2452 for (int inner = check + 1; inner < loop; ++inner) { | 2493 for (int inner = check + 1; inner < loop; ++inner) { |
| 2453 innerPtT = innerPtT->fNext; | 2494 innerPtT = innerPtT->fNext; |
| 2454 if (checkPtT == innerPtT) { | 2495 if (checkPtT == innerPtT) { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2601 #endif | 2642 #endif |
| 2602 SkPath::FillType fillType = path.getFillType(); | 2643 SkPath::FillType fillType = path.getFillType(); |
| 2603 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); | 2644 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); |
| 2604 if (includeDeclaration) { | 2645 if (includeDeclaration) { |
| 2605 SkDebugf(" SkPath %s;\n", name); | 2646 SkDebugf(" SkPath %s;\n", name); |
| 2606 } | 2647 } |
| 2607 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); | 2648 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); |
| 2608 iter.setPath(path); | 2649 iter.setPath(path); |
| 2609 showPathContours(iter, name); | 2650 showPathContours(iter, name); |
| 2610 } | 2651 } |
| OLD | NEW |