aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2017-09-05 18:11:55 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-06 14:40:18 +0000
commit38702ab43b2857f2fe06afb8dad1339d76a2fd84 (patch)
tree27e730da0f22d7e400215876308491168dd0aec2 /src/pathops
parent5fccf9d8017ab8c288548ab566cf78e698ac721f (diff)
possible fix for pathops timeout
fuzzer causes pathops to loop somewhere finding complex intersections, but does not have a reproducible test case. Somewhat grasping at straws, the failing condition in this CL was triggered by the fuzzer tests, but may or may not be related to the hang. TBR=reed@google.com Bug: 754434 Change-Id: Ia8edc0709cec559b277ed83a5ad6feb67d8088c6 Reviewed-on: https://skia-review.googlesource.com/42780 Reviewed-by: Cary Clark <caryclark@skia.org> Commit-Queue: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'src/pathops')
-rw-r--r--src/pathops/SkPathOpsTSect.h29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h
index ef0799de4f..a89785542f 100644
--- a/src/pathops/SkPathOpsTSect.h
+++ b/src/pathops/SkPathOpsTSect.h
@@ -309,7 +309,7 @@ private:
SkTSpan<TCurve, OppCurve>* prev(SkTSpan<TCurve, OppCurve>* ) const;
void removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp);
void recoverCollapsed();
- void removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween);
+ bool removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween);
void removeAllBut(const SkTSpan<OppCurve, TCurve>* keep, SkTSpan<TCurve, OppCurve>* span,
SkTSect<OppCurve, TCurve>* opp);
bool removeSpan(SkTSpan<TCurve, OppCurve>* span);
@@ -324,7 +324,7 @@ private:
SkTSpan<TCurve, OppCurve>* spanAtT(double t, SkTSpan<TCurve, OppCurve>** priorSpan);
SkTSpan<TCurve, OppCurve>* tail();
bool trim(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp);
- void unlinkSpan(SkTSpan<TCurve, OppCurve>* span);
+ bool unlinkSpan(SkTSpan<TCurve, OppCurve>* span);
bool updateBounded(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>* last,
SkTSpan<OppCurve, TCurve>* oppFirst);
void validate() const;
@@ -1273,8 +1273,12 @@ bool SkTSect<TCurve, OppCurve>::extractCoincident(
this->validateBounded();
sect2->validateBounded();
last = first->fNext;
- this->removeCoincident(first, false);
- sect2->removeCoincident(oppFirst, true);
+ if (!this->removeCoincident(first, false)) {
+ return false;
+ }
+ if (!sect2->removeCoincident(oppFirst, true)) {
+ return false;
+ }
if (deleteEmptySpans) {
if (!this->deleteEmptySpans() || !sect2->deleteEmptySpans()) {
*result = nullptr;
@@ -1737,8 +1741,10 @@ void SkTSect<TCurve, OppCurve>::removeByPerpendicular(SkTSect<OppCurve, TCurve>*
}
template<typename TCurve, typename OppCurve>
-void SkTSect<TCurve, OppCurve>::removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween) {
- this->unlinkSpan(span);
+bool SkTSect<TCurve, OppCurve>::removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween) {
+ if (!this->unlinkSpan(span)) {
+ return false;
+ }
if (isBetween || between(0, span->fCoinStart.perpT(), 1)) {
--fActiveCount;
span->fNext = fCoincident;
@@ -1746,6 +1752,7 @@ void SkTSect<TCurve, OppCurve>::removeCoincident(SkTSpan<TCurve, OppCurve>* span
} else {
this->markSpanGone(span);
}
+ return true;
}
template<typename TCurve, typename OppCurve>
@@ -1761,7 +1768,9 @@ void SkTSect<TCurve, OppCurve>::removedEndCheck(SkTSpan<TCurve, OppCurve>* span)
template<typename TCurve, typename OppCurve>
bool SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) {\
this->removedEndCheck(span);
- this->unlinkSpan(span);
+ if (!this->unlinkSpan(span)) {
+ return false;
+ }
return this->markSpanGone(span);
}
@@ -1864,13 +1873,16 @@ bool SkTSect<TCurve, OppCurve>::trim(SkTSpan<TCurve, OppCurve>* span,
}
template<typename TCurve, typename OppCurve>
-void SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) {
+bool SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) {
SkTSpan<TCurve, OppCurve>* prev = span->fPrev;
SkTSpan<TCurve, OppCurve>* next = span->fNext;
if (prev) {
prev->fNext = next;
if (next) {
next->fPrev = prev;
+ if (next->fStartT > next->fEndT) {
+ return false;
+ }
next->validate();
}
} else {
@@ -1879,6 +1891,7 @@ void SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) {
next->fPrev = nullptr;
}
}
+ return true;
}
template<typename TCurve, typename OppCurve>