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 "SkPathOpsDebug.h" | 8 #include "SkPathOpsDebug.h" |
9 #include "SkPath.h" | 9 #include "SkPath.h" |
10 #include "SkString.h" | 10 #include "SkString.h" |
11 #include "SkThread.h" | 11 #include "SkThread.h" |
12 | 12 |
13 #if DEBUG_VALIDATE | 13 #if DEBUG_VALIDATE |
14 extern bool FLAGS_runFail; | 14 extern bool FLAGS_runFail; |
15 #endif | 15 #endif |
16 | 16 |
| 17 #if DEBUG_SORT |
| 18 int SkPathOpsDebug::gSortCountDefault = SK_MaxS32; |
| 19 int SkPathOpsDebug::gSortCount; |
| 20 #endif |
| 21 |
| 22 #if DEBUG_ACTIVE_OP |
| 23 const char* SkPathOpsDebug::kPathOpStr[] = {"diff", "sect", "union", "xor"}; |
| 24 #endif |
| 25 |
17 #if defined SK_DEBUG || !FORCE_RELEASE | 26 #if defined SK_DEBUG || !FORCE_RELEASE |
18 | 27 |
19 const char* SkPathOpsDebug::kLVerbStr[] = {"", "line", "quad", "cubic"}; | 28 const char* SkPathOpsDebug::kLVerbStr[] = {"", "line", "quad", "cubic"}; |
20 | 29 |
21 #if defined(SK_DEBUG) || !FORCE_RELEASE | 30 #if defined(SK_DEBUG) || !FORCE_RELEASE |
22 int SkPathOpsDebug::gContourID = 0; | 31 int SkPathOpsDebug::gContourID = 0; |
23 int SkPathOpsDebug::gSegmentID = 0; | 32 int SkPathOpsDebug::gSegmentID = 0; |
24 #endif | 33 #endif |
25 | 34 |
26 #if DEBUG_SORT || DEBUG_SWAP_TOP | |
27 int SkPathOpsDebug::gSortCountDefault = SK_MaxS32; | |
28 int SkPathOpsDebug::gSortCount; | |
29 #endif | |
30 | |
31 #if DEBUG_ACTIVE_OP | |
32 const char* SkPathOpsDebug::kPathOpStr[] = {"diff", "sect", "union", "xor"}; | |
33 #endif | |
34 | |
35 bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpanBase* >& chaseArray, | 35 bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpanBase* >& chaseArray, |
36 const SkOpSpanBase* span) { | 36 const SkOpSpanBase* span) { |
37 for (int index = 0; index < chaseArray.count(); ++index) { | 37 for (int index = 0; index < chaseArray.count(); ++index) { |
38 const SkOpSpanBase* entry = chaseArray[index]; | 38 const SkOpSpanBase* entry = chaseArray[index]; |
39 if (entry == span) { | 39 if (entry == span) { |
40 return true; | 40 return true; |
41 } | 41 } |
42 } | 42 } |
43 return false; | 43 return false; |
44 } | 44 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 | 128 |
129 void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp
, | 129 void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp
, |
130 const char* testName) { | 130 const char* testName) { |
131 SkAutoMutexAcquire ac(gTestMutex); | 131 SkAutoMutexAcquire ac(gTestMutex); |
132 show_function_header(testName); | 132 show_function_header(testName); |
133 ShowOnePath(a, "path", true); | 133 ShowOnePath(a, "path", true); |
134 ShowOnePath(b, "pathB", true); | 134 ShowOnePath(b, "pathB", true); |
135 show_op(shapeOp, "path", "pathB"); | 135 show_op(shapeOp, "path", "pathB"); |
136 } | 136 } |
137 | 137 |
| 138 #include "SkPathOpsCubic.h" |
| 139 #include "SkPathOpsQuad.h" |
| 140 |
| 141 SkDCubic SkDQuad::debugToCubic() const { |
| 142 SkDCubic cubic; |
| 143 cubic[0] = fPts[0]; |
| 144 cubic[2] = fPts[1]; |
| 145 cubic[3] = fPts[2]; |
| 146 cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3; |
| 147 cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3; |
| 148 cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3; |
| 149 cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3; |
| 150 return cubic; |
| 151 } |
| 152 |
138 #include "SkOpAngle.h" | 153 #include "SkOpAngle.h" |
| 154 #include "SkOpCoincidence.h" |
139 #include "SkOpSegment.h" | 155 #include "SkOpSegment.h" |
140 | 156 |
141 #if DEBUG_SWAP_TOP | |
142 int SkOpSegment::debugInflections(const SkOpSpanBase* start, const SkOpSpanBase*
end) const { | |
143 if (fVerb != SkPath::kCubic_Verb) { | |
144 return false; | |
145 } | |
146 SkDCubic dst = SkDCubic::SubDivide(fPts, start->t(), end->t()); | |
147 double inflections[2]; | |
148 return dst.findInflections(inflections); | |
149 } | |
150 #endif | |
151 | |
152 SkOpAngle* SkOpSegment::debugLastAngle() { | 157 SkOpAngle* SkOpSegment::debugLastAngle() { |
153 SkOpAngle* result = NULL; | 158 SkOpAngle* result = NULL; |
154 SkOpSpan* span = this->head(); | 159 SkOpSpan* span = this->head(); |
155 do { | 160 do { |
156 if (span->toAngle()) { | 161 if (span->toAngle()) { |
157 SkASSERT(!result); | 162 SkASSERT(!result); |
158 result = span->toAngle(); | 163 result = span->toAngle(); |
159 } | 164 } |
160 } while ((span = span->next()->upCastable())); | 165 } while ((span = span->next()->upCastable())); |
161 SkASSERT(result); | 166 SkASSERT(result); |
(...skipping 26 matching lines...) Expand all Loading... |
188 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); | 193 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); |
189 for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) { | 194 for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) { |
190 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY); | 195 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY); |
191 } | 196 } |
192 if (SkPath::kConic_Verb == fVerb) { | 197 if (SkPath::kConic_Verb == fVerb) { |
193 SkDebugf(" %1.9gf", fWeight); | 198 SkDebugf(" %1.9gf", fWeight); |
194 } | 199 } |
195 const SkOpPtT* ptT = span->ptT(); | 200 const SkOpPtT* ptT = span->ptT(); |
196 SkDebugf(") t=%1.9g (%1.9g,%1.9g)", ptT->fT, ptT->fPt.fX, ptT->fPt.fY); | 201 SkDebugf(") t=%1.9g (%1.9g,%1.9g)", ptT->fT, ptT->fPt.fX, ptT->fPt.fY); |
197 SkDebugf(" tEnd=%1.9g", span->next()->t()); | 202 SkDebugf(" tEnd=%1.9g", span->next()->t()); |
198 SkDebugf(" windSum="); | |
199 if (span->windSum() == SK_MinS32) { | 203 if (span->windSum() == SK_MinS32) { |
200 SkDebugf("?"); | 204 SkDebugf(" windSum=?"); |
201 } else { | 205 } else { |
202 SkDebugf("%d", span->windSum()); | 206 SkDebugf(" windSum=%d", span->windSum()); |
203 } | 207 } |
204 SkDebugf(" windValue=%d oppValue=%d", span->windValue(), span->oppValue(
)); | 208 if (span->oppValue() && span->oppSum() == SK_MinS32) { |
| 209 SkDebugf(" oppSum=?"); |
| 210 } else if (span->oppValue() || span->oppSum() != SK_MinS32) { |
| 211 SkDebugf(" oppSum=%d", span->oppSum()); |
| 212 } |
| 213 SkDebugf(" windValue=%d", span->windValue()); |
| 214 if (span->oppValue() || span->oppSum() != SK_MinS32) { |
| 215 SkDebugf(" oppValue=%d", span->oppValue()); |
| 216 } |
205 SkDebugf("\n"); | 217 SkDebugf("\n"); |
206 } while ((span = span->next()->upCastable())); | 218 } while ((span = span->next()->upCastable())); |
207 } | 219 } |
208 #endif | 220 #endif |
209 | 221 |
210 #if DEBUG_MARK_DONE | 222 #if DEBUG_MARK_DONE |
211 void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int
winding) { | 223 void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int
winding) { |
212 const SkPoint& pt = span->ptT()->fPt; | 224 const SkPoint& pt = span->ptT()->fPt; |
213 SkDebugf("%s id=%d", fun, this->debugID()); | 225 SkDebugf("%s id=%d", fun, this->debugID()); |
214 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); | 226 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 result.printf(CUBIC_DEBUG_STR " id=%d", CUBIC_DEBUG_DATA(fCurvePart)
, | 302 result.printf(CUBIC_DEBUG_STR " id=%d", CUBIC_DEBUG_DATA(fCurvePart)
, |
291 this->segment()->debugID()); | 303 this->segment()->debugID()); |
292 break; | 304 break; |
293 default: | 305 default: |
294 SkASSERT(0); | 306 SkASSERT(0); |
295 } | 307 } |
296 return result; | 308 return result; |
297 } | 309 } |
298 #endif | 310 #endif |
299 | 311 |
300 #if DEBUG_SORT || DEBUG_SWAP_TOP | 312 #if DEBUG_SORT |
301 void SkOpAngle::debugLoop() const { | 313 void SkOpAngle::debugLoop() const { |
302 const SkOpAngle* first = this; | 314 const SkOpAngle* first = this; |
303 const SkOpAngle* next = this; | 315 const SkOpAngle* next = this; |
304 do { | 316 do { |
305 next->dumpOne(true); | 317 next->dumpOne(true); |
306 SkDebugf("\n"); | 318 SkDebugf("\n"); |
307 next = next->fNext; | 319 next = next->fNext; |
308 } while (next && next != first); | 320 } while (next && next != first); |
309 next = first; | 321 next = first; |
310 do { | 322 do { |
(...skipping 21 matching lines...) Expand all Loading... |
332 } | 344 } |
333 bool op = next->segment()->operand(); | 345 bool op = next->segment()->operand(); |
334 bool isXor = next->segment()->isXor(); | 346 bool isXor = next->segment()->isXor(); |
335 bool oppXor = next->segment()->oppXor(); | 347 bool oppXor = next->segment()->oppXor(); |
336 SkASSERT(!DEBUG_LIMIT_WIND_SUM || between(0, minSpan->windValue(), DEBUG
_LIMIT_WIND_SUM)); | 348 SkASSERT(!DEBUG_LIMIT_WIND_SUM || between(0, minSpan->windValue(), DEBUG
_LIMIT_WIND_SUM)); |
337 SkASSERT(!DEBUG_LIMIT_WIND_SUM | 349 SkASSERT(!DEBUG_LIMIT_WIND_SUM |
338 || between(-DEBUG_LIMIT_WIND_SUM, minSpan->oppValue(), DEBUG_LIM
IT_WIND_SUM)); | 350 || between(-DEBUG_LIMIT_WIND_SUM, minSpan->oppValue(), DEBUG_LIM
IT_WIND_SUM)); |
339 bool useXor = op ? oppXor : isXor; | 351 bool useXor = op ? oppXor : isXor; |
340 SkASSERT(lastXor == -1 || lastXor == (int) useXor); | 352 SkASSERT(lastXor == -1 || lastXor == (int) useXor); |
341 lastXor = (int) useXor; | 353 lastXor = (int) useXor; |
342 wind += next->sign() * (op ? minSpan->oppValue() : minSpan->windValue())
; | 354 wind += next->debugSign() * (op ? minSpan->oppValue() : minSpan->windVal
ue()); |
343 if (useXor) { | 355 if (useXor) { |
344 wind &= 1; | 356 wind &= 1; |
345 } | 357 } |
346 useXor = op ? isXor : oppXor; | 358 useXor = op ? isXor : oppXor; |
347 SkASSERT(lastOppXor == -1 || lastOppXor == (int) useXor); | 359 SkASSERT(lastOppXor == -1 || lastOppXor == (int) useXor); |
348 lastOppXor = (int) useXor; | 360 lastOppXor = (int) useXor; |
349 opp += next->sign() * (op ? minSpan->windValue() : minSpan->oppValue()); | 361 opp += next->debugSign() * (op ? minSpan->windValue() : minSpan->oppValu
e()); |
350 if (useXor) { | 362 if (useXor) { |
351 opp &= 1; | 363 opp &= 1; |
352 } | 364 } |
353 next = next->fNext; | 365 next = next->fNext; |
354 } while (next && next != first); | 366 } while (next && next != first); |
355 SkASSERT(wind == 0); | 367 SkASSERT(wind == 0); |
356 SkASSERT(opp == 0 || !FLAGS_runFail); | 368 SkASSERT(opp == 0 || !FLAGS_runFail); |
357 #endif | 369 #endif |
358 } | 370 } |
359 | 371 |
(...skipping 10 matching lines...) Expand all Loading... |
370 break; | 382 break; |
371 } | 383 } |
372 SK_ALWAYSBREAK(!angles.contains(next)); | 384 SK_ALWAYSBREAK(!angles.contains(next)); |
373 if (!next) { | 385 if (!next) { |
374 return; | 386 return; |
375 } | 387 } |
376 } while (true); | 388 } while (true); |
377 #endif | 389 #endif |
378 } | 390 } |
379 | 391 |
| 392 void SkOpCoincidence::debugShowCoincidence() const { |
| 393 SkCoincidentSpans* span = fHead; |
| 394 while (span) { |
| 395 SkDebugf("%s - id=%d t=%1.9g tEnd=%1.9g\n", __FUNCTION__, |
| 396 span->fCoinPtTStart->segment()->debugID(), |
| 397 span->fCoinPtTStart->fT, span->fCoinPtTEnd->fT); |
| 398 SkDebugf("%s + id=%d t=%1.9g tEnd=%1.9g\n", __FUNCTION__, |
| 399 span->fOppPtTStart->segment()->debugID(), |
| 400 span->fOppPtTStart->fT, span->fOppPtTEnd->fT); |
| 401 span = span->fNext; |
| 402 } |
| 403 } |
| 404 |
380 void SkOpSegment::debugValidate() const { | 405 void SkOpSegment::debugValidate() const { |
381 #if DEBUG_VALIDATE | 406 #if DEBUG_VALIDATE |
382 const SkOpSpanBase* span = &fHead; | 407 const SkOpSpanBase* span = &fHead; |
383 double lastT = -1; | 408 double lastT = -1; |
384 const SkOpSpanBase* prev = NULL; | 409 const SkOpSpanBase* prev = NULL; |
385 int count = 0; | 410 int count = 0; |
386 int done = 0; | 411 int done = 0; |
387 do { | 412 do { |
388 if (!span->final()) { | 413 if (!span->final()) { |
389 ++count; | 414 ++count; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 SkDebugf("*** bad coincident loop ***\n"); | 492 SkDebugf("*** bad coincident loop ***\n"); |
468 return false; | 493 return false; |
469 } | 494 } |
470 } | 495 } |
471 } | 496 } |
472 ++loop; | 497 ++loop; |
473 } while ((next = nextCoin) && next != this); | 498 } while ((next = nextCoin) && next != this); |
474 return true; | 499 return true; |
475 } | 500 } |
476 | 501 |
| 502 // called only by test code |
| 503 int SkIntersections::debugCoincidentUsed() const { |
| 504 if (!fIsCoincident[0]) { |
| 505 SkASSERT(!fIsCoincident[1]); |
| 506 return 0; |
| 507 } |
| 508 int count = 0; |
| 509 SkDEBUGCODE(int count2 = 0;) |
| 510 for (int index = 0; index < fUsed; ++index) { |
| 511 if (fIsCoincident[0] & (1 << index)) { |
| 512 ++count; |
| 513 } |
| 514 #ifdef SK_DEBUG |
| 515 if (fIsCoincident[1] & (1 << index)) { |
| 516 ++count2; |
| 517 } |
| 518 #endif |
| 519 } |
| 520 SkASSERT(count == count2); |
| 521 return count; |
| 522 } |
| 523 |
477 #include "SkOpContour.h" | 524 #include "SkOpContour.h" |
478 | 525 |
479 int SkOpPtT::debugLoopLimit(bool report) const { | 526 int SkOpPtT::debugLoopLimit(bool report) const { |
480 int loop = 0; | 527 int loop = 0; |
481 const SkOpPtT* next = this; | 528 const SkOpPtT* next = this; |
482 do { | 529 do { |
483 for (int check = 1; check < loop - 1; ++check) { | 530 for (int check = 1; check < loop - 1; ++check) { |
484 const SkOpPtT* checkPtT = this->fNext; | 531 const SkOpPtT* checkPtT = this->fNext; |
485 const SkOpPtT* innerPtT = checkPtT; | 532 const SkOpPtT* innerPtT = checkPtT; |
486 for (int inner = check + 1; inner < loop; ++inner) { | 533 for (int inner = check + 1; inner < loop; ++inner) { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 #endif | 653 #endif |
607 SkPath::FillType fillType = path.getFillType(); | 654 SkPath::FillType fillType = path.getFillType(); |
608 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); | 655 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); |
609 if (includeDeclaration) { | 656 if (includeDeclaration) { |
610 SkDebugf(" SkPath %s;\n", name); | 657 SkDebugf(" SkPath %s;\n", name); |
611 } | 658 } |
612 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); | 659 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); |
613 iter.setPath(path); | 660 iter.setPath(path); |
614 showPathContours(iter, name); | 661 showPathContours(iter, name); |
615 } | 662 } |
OLD | NEW |