Index: src/pathops/SkOpSegment.cpp |
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp |
index a9e20fd11afab182f9f0a4c7a0adbac3c6336884..08f4f7eace9844c52b3f154dbce7635e6a618210 100644 |
--- a/src/pathops/SkOpSegment.cpp |
+++ b/src/pathops/SkOpSegment.cpp |
@@ -32,6 +32,8 @@ static const bool gActiveEdge[kXOR_PathOp + 1][2][2][2][2] = { |
#undef F |
#undef T |
+enum { kOutsideTrackedTCount = 16 }; // FIXME: determine what this should be |
+ |
// OPTIMIZATION: does the following also work, and is it any faster? |
// return outerWinding * innerWinding > 0 |
// || ((outerWinding + innerWinding < 0) ^ ((outerWinding - innerWinding) < 0))) |
@@ -44,7 +46,7 @@ bool SkOpSegment::UseInnerWinding(int outerWinding, int innerWinding) { |
return result; |
} |
-bool SkOpSegment::activeAngle(int index, int* done, SkTDArray<SkOpAngle>* angles) { |
+bool SkOpSegment::activeAngle(int index, int* done, SkTArray<SkOpAngle, true>* angles) { |
if (activeAngleInner(index, done, angles)) { |
return true; |
} |
@@ -63,14 +65,14 @@ bool SkOpSegment::activeAngle(int index, int* done, SkTDArray<SkOpAngle>* angles |
return false; |
} |
-bool SkOpSegment::activeAngleOther(int index, int* done, SkTDArray<SkOpAngle>* angles) { |
+bool SkOpSegment::activeAngleOther(int index, int* done, SkTArray<SkOpAngle, true>* angles) { |
SkOpSpan* span = &fTs[index]; |
SkOpSegment* other = span->fOther; |
int oIndex = span->fOtherIndex; |
return other->activeAngleInner(oIndex, done, angles); |
} |
-bool SkOpSegment::activeAngleInner(int index, int* done, SkTDArray<SkOpAngle>* angles) { |
+bool SkOpSegment::activeAngleInner(int index, int* done, SkTArray<SkOpAngle, true>* angles) { |
int next = nextExactSpan(index, 1); |
if (next > 0) { |
SkOpSpan& upSpan = fTs[index]; |
@@ -204,11 +206,11 @@ bool SkOpSegment::activeWinding(int index, int endIndex, int* maxWinding, int* s |
return result; |
} |
-void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end) const { |
+void SkOpSegment::addAngle(SkTArray<SkOpAngle, true>* anglesPtr, int start, int end) const { |
SkASSERT(start != end); |
- SkOpAngle* angle = anglesPtr->append(); |
+ SkOpAngle& angle = anglesPtr->push_back(); |
#if DEBUG_ANGLE |
- SkTDArray<SkOpAngle>& angles = *anglesPtr; |
+ SkTArray<SkOpAngle, true>& angles = *anglesPtr; |
if (angles.count() > 1) { |
const SkOpSegment* aSeg = angles[0].segment(); |
int aStart = angles[0].start(); |
@@ -224,7 +226,7 @@ void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end) |
} |
} |
#endif |
- angle->set(this, start, end); |
+ angle.set(this, start, end); |
} |
void SkOpSegment::addCancelOutsides(double tStart, double oStart, SkOpSegment* other, double oEnd) { |
@@ -299,7 +301,7 @@ void SkOpSegment::addCancelOutsides(double tStart, double oStart, SkOpSegment* o |
} |
} |
-void SkOpSegment::addCoinOutsides(const SkTDArray<double>& outsideTs, SkOpSegment* other, |
+void SkOpSegment::addCoinOutsides(const SkTArray<double, true>& outsideTs, SkOpSegment* other, |
double oEnd) { |
// walk this to outsideTs[0] |
// walk other to outsideTs[1] |
@@ -566,8 +568,8 @@ void SkOpSegment::addTCancel(double startT, double endT, SkOpSegment* other, |
double tRatio = (oEndT - oStartT) / (endT - startT); |
SkOpSpan* test = &fTs[index]; |
SkOpSpan* oTest = &other->fTs[oIndex]; |
- SkTDArray<double> outsideTs; |
- SkTDArray<double> oOutsideTs; |
+ SkSTArray<kOutsideTrackedTCount, double, true> outsideTs; |
+ SkSTArray<kOutsideTrackedTCount, double, true> oOutsideTs; |
do { |
bool decrement = test->fWindValue && oTest->fWindValue; |
bool track = test->fWindValue || oTest->fWindValue; |
@@ -658,7 +660,7 @@ int SkOpSegment::addUnsortableT(SkOpSegment* other, bool start, const SkPoint& p |
} |
int SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index, |
- SkTDArray<double>* outsideTs) { |
+ SkTArray<double, true>* outsideTs) { |
int oWindValue = oTest.fWindValue; |
int oOppValue = oTest.fOppValue; |
if (opp) { |
@@ -681,7 +683,7 @@ int SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index, |
// intermediate T values (using this as the master, other as the follower) |
// and walk other conditionally -- hoping that it catches up in the end |
int SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, double oEndT, int& oIndex, |
- SkTDArray<double>* oOutsideTs) { |
+ SkTArray<double, true>* oOutsideTs) { |
SkOpSpan* const oTest = &fTs[oIndex]; |
SkOpSpan* oEnd = oTest; |
const double startT = test.fT; |
@@ -719,8 +721,8 @@ void SkOpSegment::addTCoincident(double startT, double endT, SkOpSegment* other, |
} |
SkOpSpan* test = &fTs[index]; |
SkOpSpan* oTest = &other->fTs[oIndex]; |
- SkTDArray<double> outsideTs; |
- SkTDArray<double> oOutsideTs; |
+ SkSTArray<kOutsideTrackedTCount, double, true> outsideTs; |
+ SkSTArray<kOutsideTrackedTCount, double, true> oOutsideTs; |
do { |
// if either span has an opposite value and the operands don't match, resolve first |
// SkASSERT(!test->fDone || !oTest->fDone); |
@@ -775,7 +777,7 @@ void SkOpSegment::addTPair(double t, SkOpSegment* other, double otherT, bool bor |
other->matchWindingValue(otherInsertedAt, otherT, borrowWind); |
} |
-void SkOpSegment::addTwoAngles(int start, int end, SkTDArray<SkOpAngle>* angles) const { |
+void SkOpSegment::addTwoAngles(int start, int end, SkTArray<SkOpAngle, true>* angles) const { |
// add edge leading into junction |
int min = SkMin32(end, start); |
if (fTs[min].fWindValue > 0 || fTs[min].fOppValue != 0) { |
@@ -817,7 +819,7 @@ bool SkOpSegment::betweenTs(int lesser, double testT, int greater) const { |
return approximately_between(fTs[lesser].fT, testT, fTs[greater].fT); |
} |
-void SkOpSegment::buildAngles(int index, SkTDArray<SkOpAngle>* angles, bool includeOpp) const { |
+void SkOpSegment::buildAngles(int index, SkTArray<SkOpAngle, true>* angles, bool includeOpp) const { |
double referenceT = fTs[index].fT; |
int lesser = index; |
while (--lesser >= 0 && (includeOpp || fTs[lesser].fOther->fOperand == fOperand) |
@@ -830,7 +832,7 @@ void SkOpSegment::buildAngles(int index, SkTDArray<SkOpAngle>* angles, bool incl |
&& precisely_negative(fTs[index].fT - referenceT)); |
} |
-void SkOpSegment::buildAnglesInner(int index, SkTDArray<SkOpAngle>* angles) const { |
+void SkOpSegment::buildAnglesInner(int index, SkTArray<SkOpAngle, true>* angles) const { |
const SkOpSpan* span = &fTs[index]; |
SkOpSegment* other = span->fOther; |
// if there is only one live crossing, and no coincidence, continue |
@@ -850,12 +852,12 @@ void SkOpSegment::buildAnglesInner(int index, SkTDArray<SkOpAngle>* angles) cons |
} |
int SkOpSegment::computeSum(int startIndex, int endIndex, bool binary) { |
- SkTDArray<SkOpAngle> angles; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
addTwoAngles(startIndex, endIndex, &angles); |
buildAngles(endIndex, &angles, false); |
// OPTIMIZATION: check all angles to see if any have computed wind sum |
// before sorting (early exit if none) |
- SkTDArray<SkOpAngle*> sorted; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
// FIXME?: Not sure if this sort must be ordered or if the relaxed ordering is OK ... |
bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_SortAngleKind); |
#if DEBUG_SORT |
@@ -1137,12 +1139,12 @@ SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart |
return other; |
} |
// more than one viable candidate -- measure angles to find best |
- SkTDArray<SkOpAngle> angles; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
SkASSERT(startIndex - endIndex != 0); |
SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); |
addTwoAngles(startIndex, end, &angles); |
buildAngles(end, &angles, true); |
- SkTDArray<SkOpAngle*> sorted; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_SortAngleKind); |
int angleCount = angles.count(); |
int firstIndex = findStartingEdge(sorted, startIndex, end); |
@@ -1259,12 +1261,12 @@ SkOpSegment* SkOpSegment::findNextWinding(SkTDArray<SkOpSpan*>* chase, int* next |
return other; |
} |
// more than one viable candidate -- measure angles to find best |
- SkTDArray<SkOpAngle> angles; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
SkASSERT(startIndex - endIndex != 0); |
SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); |
addTwoAngles(startIndex, end, &angles); |
buildAngles(end, &angles, true); |
- SkTDArray<SkOpAngle*> sorted; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_SortAngleKind); |
int angleCount = angles.count(); |
int firstIndex = findStartingEdge(sorted, startIndex, end); |
@@ -1388,12 +1390,12 @@ SkOpSegment* SkOpSegment::findNextXor(int* nextStart, int* nextEnd, bool* unsort |
SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count()); |
return other; |
} |
- SkTDArray<SkOpAngle> angles; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
SkASSERT(startIndex - endIndex != 0); |
SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); |
addTwoAngles(startIndex, end, &angles); |
buildAngles(end, &angles, false); |
- SkTDArray<SkOpAngle*> sorted; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_SortAngleKind); |
if (!sortable) { |
*unsortable = true; |
@@ -1449,7 +1451,7 @@ SkOpSegment* SkOpSegment::findNextXor(int* nextStart, int* nextEnd, bool* unsort |
return nextSegment; |
} |
-int SkOpSegment::findStartingEdge(const SkTDArray<SkOpAngle*>& sorted, int start, int end) { |
+int SkOpSegment::findStartingEdge(const SkTArray<SkOpAngle*, true>& sorted, int start, int end) { |
int angleCount = sorted.count(); |
int firstIndex = -1; |
for (int angleIndex = 0; angleIndex < angleCount; ++angleIndex) { |
@@ -1631,11 +1633,11 @@ SkOpSegment* SkOpSegment::findTop(int* tIndexPtr, int* endIndexPtr, bool* unsort |
} |
// if the topmost T is not on end, or is three-way or more, find left |
// look for left-ness from tLeft to firstT (matching y of other) |
- SkTDArray<SkOpAngle> angles; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
SkASSERT(firstT - end != 0); |
addTwoAngles(end, firstT, &angles); |
buildAngles(firstT, &angles, true); |
- SkTDArray<SkOpAngle*> sorted; |
+ SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMayBeUnordered_SortAngleKind); |
int first = SK_MaxS32; |
SkScalar top = SK_ScalarMax; |
@@ -2343,15 +2345,17 @@ void SkOpSegment::setUpWindings(int index, int endIndex, int* sumMiWinding, int* |
// exclusion in find top and others. This could be optimized to only mark |
// adjacent spans that unsortable. However, this makes it difficult to later |
// determine starting points for edge detection in find top and the like. |
-bool SkOpSegment::SortAngles(const SkTDArray<SkOpAngle>& angles, SkTDArray<SkOpAngle*>* angleList, |
+bool SkOpSegment::SortAngles(const SkTArray<SkOpAngle, true>& angles, |
+ SkTArray<SkOpAngle*, true>* angleList, |
SortAngleKind orderKind) { |
bool sortable = true; |
int angleCount = angles.count(); |
int angleIndex; |
- angleList->setReserve(angleCount); |
+// FIXME: caller needs to use SkTArray constructor with reserve count |
+// angleList->setReserve(angleCount); |
for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) { |
const SkOpAngle& angle = angles[angleIndex]; |
- *angleList->append() = const_cast<SkOpAngle*>(&angle); |
+ angleList->push_back(const_cast<SkOpAngle*>(&angle)); |
#if DEBUG_ANGLE |
(*(angleList->end() - 1))->setID(angleIndex); |
#endif |
@@ -2470,11 +2474,11 @@ bool SkOpSegment::isTiny(int index) const { |
return fTs[index].fTiny; |
} |
-void SkOpSegment::TrackOutside(SkTDArray<double>* outsideTs, double end, double start) { |
+void SkOpSegment::TrackOutside(SkTArray<double, true>* outsideTs, double end, double start) { |
int outCount = outsideTs->count(); |
if (outCount == 0 || !approximately_negative(end - (*outsideTs)[outCount - 2])) { |
- *outsideTs->append() = end; |
- *outsideTs->append() = start; |
+ outsideTs->push_back(end); |
+ outsideTs->push_back(start); |
} |
} |
@@ -2763,8 +2767,9 @@ void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int |
#endif |
#if DEBUG_SORT || DEBUG_SWAP_TOP |
-void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first, |
- const int contourWinding, const int oppContourWinding) const { |
+void SkOpSegment::debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true>& angles, |
+ int first, const int contourWinding, |
+ const int oppContourWinding) const { |
if (--gDebugSortCount < 0) { |
return; |
} |
@@ -2872,7 +2877,8 @@ void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& an |
} while (index != first); |
} |
-void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first) { |
+void SkOpSegment::debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true>& angles, |
+ int first) { |
const SkOpAngle* firstAngle = angles[first]; |
const SkOpSegment* segment = firstAngle->segment(); |
int winding = segment->updateWinding(firstAngle); |
@@ -2888,8 +2894,7 @@ int SkOpSegment::debugShowWindingValues(int slotCount, int ofInterest) const { |
return 0; |
} |
int sum = 0; |
- SkTDArray<char> slots; |
- slots.setCount(slotCount * 2); |
+ SkTArray<char, true> slots(slotCount * 2); |
memset(slots.begin(), ' ', slotCount * 2); |
for (int i = 0; i < fTs.count(); ++i) { |
// if (!(1 << fTs[i].fOther->fID & ofInterest)) { |